1 
2 /*
3   cc -g -c isoburn.c
4 */
5 
6 /*
7   Class core of libisoburn.
8 
9   Copyright 2007 - 2017 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
10                         Thomas Schmitt <scdbackup@gmx.net>
11 
12   Provided under GPL version 2 or later.
13 */
14 
15 #ifdef HAVE_CONFIG_H
16 #include "../config.h"
17 #endif
18 
19 /* ( derived from stub generated by CgeN on  Sat, 01 Sep 2007 12:04:36 GMT ) */
20 
21 #include <sys/types.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 
28 #ifndef Xorriso_standalonE
29 
30 #include <libburn/libburn.h>
31 
32 #include <libisofs/libisofs.h>
33 
34 #else /* ! Xorriso_standalonE */
35 
36 #include "../libisofs/libisofs.h"
37 #include "../libburn/libburn.h"
38 
39 #endif /* Xorriso_standalonE */
40 
41 
42 #include "libisoburn.h"
43 
44 #include "isoburn.h"
45 
46 
47 /* Default values for application provided msgs_submit methods.
48    To be attached to newly acquired drives.
49 */
50 int (*libisoburn_default_msgs_submit)
51     (void *handle, int error_code, char msg_text[],
52                  int os_errno, char severity[], int flag)= NULL;
53 void *libisoburn_default_msgs_submit_handle= NULL;
54 int libisoburn_default_msgs_submit_flag= 0;
55 
56 
57 /* ----------------------- isoburn_toc_entry  ---------------------- */
58 
59 
isoburn_toc_entry_new(struct isoburn_toc_entry ** objpt,struct isoburn_toc_entry * boss,int flag)60 int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt,
61                           struct isoburn_toc_entry *boss, int flag)
62 {
63  struct isoburn_toc_entry *o, *s;
64 
65  *objpt= o= (struct isoburn_toc_entry *)
66             malloc(sizeof(struct isoburn_toc_entry));
67  if(o==NULL) {
68    isoburn_msgs_submit(NULL, 0x00060000,
69                        "Cannot allocate memory for isoburn toc entry",
70                        0, "FATAL", 0);
71    return(-1);
72  }
73  o->session= 0;
74  o->track_no= 0;
75  o->start_lba= -1;
76  o->track_blocks= 0;
77  o->volid= NULL;
78  o->next= NULL;
79  if(boss!=NULL) {
80    for(s= boss; s->next!=NULL; s= s->next);
81    s->next= o;
82  }
83  return(1);
84 }
85 
86 
87 /* @param flag bit0= delete all subordinates too
88 */
isoburn_toc_entry_destroy(struct isoburn_toc_entry ** o,int flag)89 int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag)
90 {
91  if(*o==NULL)
92    return(0);
93  if(flag&1)
94    isoburn_toc_entry_destroy(&((*o)->next), flag);
95  if((*o)->volid != NULL)
96    free((*o)->volid);
97  free((char *) (*o));
98  *o= NULL;
99  return(1);
100 }
101 
102 
103 /* --------------------- end isoburn_toc_entry  -------------------- */
104 
105 /* --------------------------  isoburn  ----------------------- */
106 
107 
108 /* The global list of isoburn objects. Usually there is only one.
109    >>> we are not ready for multiple control threads yet. See >>> mutex .
110    Multiple burns under one control thread should work.
111 */
112 struct isoburn *isoburn_list_start= NULL;
113 
114 
isoburn_new(struct isoburn ** objpt,int flag)115 int isoburn_new(struct isoburn **objpt, int flag)
116 {
117  struct isoburn *o;
118  int ret;
119 
120  *objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn));
121  if(o==NULL) {
122    isoburn_msgs_submit(NULL, 0x00060000,
123                        "Cannot allocate memory for isoburn control object",
124                        0, "FATAL", 0);
125    return(-1);
126  }
127 
128  o->drive= NULL;
129  o->emulation_mode= 0;
130  o->fabricated_msc1= -1;
131  o->fabricated_msc2= -1;
132  o->zero_nwa= Libisoburn_overwriteable_starT;
133  o->min_start_byte= o->zero_nwa * 2048;
134  o->nwa= o->zero_nwa;
135  o->truncate= 0;
136  o->iso_source= NULL;
137  o->fabricated_disc_status= BURN_DISC_UNREADY;
138  o->media_read_error= 0;
139  o->toc= NULL;
140  o->wrote_well= -1;
141  o->loaded_partition_offset= 0;
142  o->target_iso_head_size= Libisoburn_target_head_sizE;
143  o->target_iso_head= NULL;
144  o->image= NULL;
145  o->image_start_lba= -1;
146  o->iso_data_source= NULL;
147  o->read_pacifier= NULL;
148  o->read_pacifier_handle= NULL;
149  o->msgs_submit= NULL;
150  o->msgs_submit_handle= NULL;
151  o->msgs_submit_flag= 0;
152  o->do_tao= 0;
153  o->do_fsync= 1;
154  o->prev= NULL;
155  o->next= NULL;
156  o->target_iso_head= calloc(1, o->target_iso_head_size);
157  if(o->target_iso_head == NULL) {
158    isoburn_report_iso_error(ISO_OUT_OF_MEM, "Cannot allocate overwrite buffer",
159                             0, "FATAL", 0);
160    goto failed;
161  }
162  ret= iso_image_new("ISOIMAGE", &o->image);
163  if(ret<0) {
164    isoburn_report_iso_error(ret, "Cannot create image object", 0, "FATAL", 0);
165    goto failed;
166  }
167  ret= isoburn_root_defaults(o->image, 0);
168  if(ret <= 0)
169    goto failed;
170  isoburn_link(o, isoburn_list_start, 1);
171  return(1);
172 failed:;
173  isoburn_destroy(objpt, 0);
174  return(-1);
175 }
176 
177 
isoburn_destroy(struct isoburn ** objpt,int flag)178 int isoburn_destroy(struct isoburn **objpt, int flag)
179 {
180  struct isoburn *o;
181 
182  o= *objpt;
183  if(o==NULL)
184    return(0);
185 
186  /* >>> mutex */
187 
188  if(o==isoburn_list_start)
189    isoburn_list_start= o->next;
190  if(o->prev!=NULL)
191    o->prev->next= o->next;
192  if(o->next!=NULL)
193    o->next->prev= o->prev;
194 
195  /* >>> end mutex */
196 
197  if(o->image!=NULL)
198    iso_image_unref(o->image);
199  if(o->toc!=NULL)
200    isoburn_toc_entry_destroy(&(o->toc), 1); /* all */
201  if(o->iso_source!=NULL)
202    burn_source_free(o->iso_source);
203  if(o->iso_data_source!=NULL)
204    iso_data_source_unref(o->iso_data_source);
205  if(o->target_iso_head != NULL)
206    free(o->target_iso_head);
207  free((char *) o);
208  *objpt= NULL;
209  return(1);
210 }
211 
212 
isoburn_destroy_all(struct isoburn ** objpt,int flag)213 int isoburn_destroy_all(struct isoburn **objpt, int flag)
214 {
215  struct isoburn *o,*n;
216 
217  o= *objpt;
218  if(o==NULL)
219    return(0);
220  for(;o->prev!=NULL;o= o->prev);
221  for(;o!=NULL;o= n) {
222    n= o->next;
223    isoburn_destroy(&o,0);
224  }
225  *objpt= NULL;
226  return(1);
227 }
228 
229 
isoburn_get_target_image(struct isoburn * o,IsoImage ** pt,int flag)230 int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag)
231 {
232  *pt= o->image;
233  return(1);
234 }
235 
236 
isoburn_get_prev(struct isoburn * o,struct isoburn ** pt,int flag)237 int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag)
238 {
239  *pt= o->prev;
240  return(1);
241 }
242 
243 
isoburn_get_next(struct isoburn * o,struct isoburn ** pt,int flag)244 int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag)
245 {
246  *pt= o->next;
247  return(1);
248 }
249 
250 
isoburn_link(struct isoburn * o,struct isoburn * link,int flag)251 int isoburn_link(struct isoburn *o, struct isoburn *link, int flag)
252 /*
253   bit0= insert as link->prev rather than as link->next
254 */
255 {
256 
257  /* >>> mutex */
258 
259  if(isoburn_list_start==NULL ||
260     (isoburn_list_start==link && (flag&1)))
261    isoburn_list_start= o;
262  if(o->prev!=NULL)
263    o->prev->next= o->next;
264  if(o->next!=NULL)
265    o->next->prev= o->prev;
266  o->prev= o->next= NULL;
267  if(link==NULL)
268    return(1);
269  if(flag&1) {
270    o->next= link;
271    o->prev= link->prev;
272    if(o->prev!=NULL)
273      o->prev->next= o;
274    link->prev= o;
275  } else {
276    o->prev= link;
277    o->next= link->next;
278    if(o->next!=NULL)
279      o->next->prev= o;
280    link->next= o;
281  }
282 
283  /* >>> end mutex */
284 
285  return(1);
286 }
287 
288 
isoburn_count(struct isoburn * o,int flag)289 int isoburn_count(struct isoburn *o, int flag)
290 /* flag: bit1= count from start of list */
291 {
292  int counter= 0;
293 
294  if(flag&2)
295    for(;o->prev!=NULL;o= o->prev);
296  for(;o!=NULL;o= o->next)
297    counter++;
298  return(counter);
299 }
300 
301 
isoburn_by_idx(struct isoburn * o,int idx,struct isoburn ** pt,int flag)302 int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag)
303 /* flag: bit0= fetch first (idx<0) or last (idx>0) item in list
304          bit1= address from start of list */
305 {
306  int i,abs_idx;
307  struct isoburn *npt;
308 
309  if(flag&2)
310    for(;o->prev!=NULL;o= o->prev);
311  abs_idx= (idx>0?idx:-idx);
312  *pt= o;
313  for(i= 0;(i<abs_idx || (flag&1)) && *pt!=NULL;i++) {
314    if(idx>0)
315      npt= o->next;
316    else
317      npt= o->prev;
318    if(npt==NULL && (flag&1))
319  break;
320    *pt= npt;
321  }
322  return(*pt!=NULL);
323 }
324 
325 
isoburn_find_by_drive(struct isoburn ** pt,struct burn_drive * d,int flag)326 int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag)
327 {
328  struct isoburn *o;
329 
330  *pt= NULL;
331  for(o= isoburn_list_start;o!=NULL;o= o->next)
332    if(o->drive==d) {
333      *pt= o;
334      return(1);
335    }
336  return(0);
337 }
338 
339 
isoburn_msgs_submit(struct isoburn * o,int error_code,char msg_text[],int os_errno,char severity[],int flag)340 int isoburn_msgs_submit(struct isoburn *o, int error_code, char msg_text[],
341                         int os_errno, char severity[], int flag)
342 {
343  int ret, use_drive_method= 0;
344 
345  if(o!=NULL)
346    if(o->msgs_submit!=NULL)
347      use_drive_method= 1;
348  if(use_drive_method) {
349    ret= o->msgs_submit(o->msgs_submit_handle, error_code, msg_text, os_errno,
350                        severity, o->msgs_submit_flag);
351    return(ret);
352  }
353  if(libisoburn_default_msgs_submit != NULL) {
354    ret= libisoburn_default_msgs_submit(libisoburn_default_msgs_submit_handle,
355                                      error_code, msg_text, os_errno, severity,
356                                      libisoburn_default_msgs_submit_flag);
357    return(ret);
358  }
359  /* Fallback: use message queue of libburn */
360  burn_msgs_submit(error_code, msg_text, os_errno, severity, NULL);
361  return(1);
362 }
363 
364 
365 /** Check whether the size of target_iso_head matches the given partition
366     offset. Eventually adjust size.
367 */
isoburn_adjust_target_iso_head(struct isoburn * o,uint32_t offst,int flag)368 int isoburn_adjust_target_iso_head(struct isoburn *o,
369                                    uint32_t offst, int flag)
370 {
371  uint8_t *new_buf;
372  uint32_t new_size;
373 
374  if((uint32_t) o->target_iso_head_size ==
375     Libisoburn_target_head_sizE + 2048 * offst)
376    return(1);
377  new_size= Libisoburn_target_head_sizE + 2048 * offst;
378  new_buf= calloc(1, new_size);
379  if(new_buf == NULL) {
380    isoburn_msgs_submit(o, 0x00060000,
381                        "Cannot re-allocate overwrite buffer", 0, "FATAL", 0);
382    return(-1);
383  }
384  memcpy(new_buf, o->target_iso_head,
385         (uint32_t) o->target_iso_head_size < new_size ?
386         (uint32_t) o->target_iso_head_size : new_size);
387  free(o->target_iso_head);
388  o->target_iso_head= new_buf;
389  o->target_iso_head_size= new_size;
390  if(o->nwa == o->zero_nwa)
391    o->nwa= Libisoburn_overwriteable_starT + offst;
392  o->zero_nwa= Libisoburn_overwriteable_starT + offst;
393  return(1);
394 }
395 
396 
397 /* @param out_o The output isoburn object may be NULL if no real write run is
398                 desired with opts.
399    @param flag bit0= modifying rather than growing
400 */
401 static
isoburn_make_iso_write_opts(struct isoburn * out_o,struct isoburn_imgen_opts * opts,int fifo_chunks,IsoWriteOpts * wopts,int flag)402 int isoburn_make_iso_write_opts(struct isoburn *out_o,
403                                 struct isoburn_imgen_opts *opts,
404                                 int fifo_chunks,
405                                 IsoWriteOpts *wopts,
406                                 int flag)
407 {
408  int ret, rec_mtime, new_img, lba, nwa, i, guid_mode;
409  struct burn_drive *out_d;
410 
411  new_img= flag&1;
412 
413  iso_write_opts_set_will_cancel(wopts, opts->will_cancel);
414  iso_write_opts_set_iso_level(wopts, opts->level);
415  iso_write_opts_set_rockridge(wopts, opts->rockridge);
416  iso_write_opts_set_joliet(wopts, opts->joliet);
417  iso_write_opts_set_hfsplus(wopts, opts->hfsplus);
418  iso_write_opts_set_hfsp_block_size(wopts, opts->hfsp_block_size,
419                                            opts->apm_block_size);
420  iso_write_opts_set_fat(wopts, opts->fat);
421  iso_write_opts_set_iso1999(wopts, opts->iso1999);
422  iso_write_opts_set_hardlinks(wopts, opts->hardlinks);
423  if(opts->hardlinks)
424    iso_write_opts_set_rrip_1_10_px_ino(wopts, 1);
425  iso_write_opts_set_aaip(wopts, opts->aaip);
426  iso_write_opts_set_old_empty(wopts, !!opts->old_empty);
427  iso_write_opts_set_untranslated_name_len(wopts, opts->untranslated_name_len);
428  iso_write_opts_set_allow_dir_id_ext(wopts, opts->allow_dir_id_ext);
429  iso_write_opts_set_omit_version_numbers(wopts, opts->omit_version_numbers);
430  iso_write_opts_set_allow_deep_paths(wopts, opts->allow_deep_paths);
431  iso_write_opts_set_rr_reloc(wopts, opts->rr_reloc_dir, opts->rr_reloc_flags);
432  iso_write_opts_set_allow_longer_paths(wopts, opts->allow_longer_paths);
433  iso_write_opts_set_max_37_char_filenames(wopts, opts->max_37_char_filenames);
434  iso_write_opts_set_no_force_dots(wopts, opts->no_force_dots);
435  iso_write_opts_set_allow_lowercase(wopts, opts->allow_lowercase);
436  iso_write_opts_set_allow_full_ascii(wopts, opts->allow_full_ascii);
437  iso_write_opts_set_allow_7bit_ascii(wopts, opts->allow_7bit_ascii);
438  iso_write_opts_set_relaxed_vol_atts(wopts, 1);
439  iso_write_opts_set_joliet_longer_paths(wopts, opts->joliet_longer_paths);
440  iso_write_opts_set_joliet_long_names(wopts, opts->joliet_long_names);
441  iso_write_opts_set_joliet_utf16(wopts, opts->joliet_utf16);
442  iso_write_opts_set_always_gmt(wopts, opts->always_gmt);
443  iso_write_opts_set_rrip_version_1_10(wopts, opts->rrip_version_1_10);
444  rec_mtime= 0;
445  if(opts->dir_rec_mtime)
446    rec_mtime|= 1;
447  else
448    rec_mtime|= (1 << 14);
449  if(opts->joliet_rec_mtime)
450    rec_mtime|= 2;
451  if(opts->iso1999_rec_mtime)
452    rec_mtime|= 4;
453  iso_write_opts_set_dir_rec_mtime(wopts, rec_mtime);
454  iso_write_opts_set_aaip_susp_1_10(wopts, opts->aaip_susp_1_10);
455  iso_write_opts_set_sort_files(wopts, opts->sort_files);
456  iso_write_opts_set_record_md5(wopts, opts->session_md5, opts->file_md5 & 3);
457  if(opts->scdbackup_tag_name[0] && opts->scdbackup_tag_time[0])
458    iso_write_opts_set_scdbackup_tag(wopts, opts->scdbackup_tag_name,
459                                     opts->scdbackup_tag_time,
460                                     opts->scdbackup_tag_written);
461  iso_write_opts_set_replace_mode(wopts, opts->replace_dir_mode,
462                 opts->replace_file_mode, opts->replace_uid, opts->replace_gid);
463  iso_write_opts_set_default_dir_mode(wopts, opts->dir_mode);
464  iso_write_opts_set_default_file_mode(wopts, opts->file_mode);
465  iso_write_opts_set_default_uid(wopts, opts->uid);
466  iso_write_opts_set_default_gid(wopts, opts->gid);
467  iso_write_opts_set_output_charset(wopts, opts->output_charset);
468  iso_write_opts_set_fifo_size(wopts, fifo_chunks);
469  ret = iso_write_opts_set_system_area(wopts, opts->system_area_data,
470                                       opts->system_area_options, 0);
471  if (ret < 0) {
472    isoburn_report_iso_error(ret, "Cannot set content of System Area",
473                             0, "FAILURE", 0);
474    {ret= -1; goto ex;}
475  }
476  iso_write_opts_set_pvd_times(wopts,
477                         opts->vol_creation_time, opts->vol_modification_time,
478                         opts->vol_expiration_time, opts->vol_effective_time,
479                         opts->vol_uuid);
480  guid_mode= opts->gpt_guid_mode;
481  if(opts->vol_uuid[0] == 0 && opts->gpt_guid_mode == 2)
482    guid_mode= 0;
483  iso_write_opts_set_gpt_guid(wopts, opts->gpt_guid, guid_mode);
484  iso_write_opts_attach_jte(wopts, opts->libjte_handle);
485  iso_write_opts_set_hfsp_serial_number(wopts, opts->hfsp_serial_number);
486 
487  if(out_o != NULL) {
488    out_d= out_o->drive;
489    ret= isoburn_adjust_target_iso_head(out_o, opts->partition_offset, 0);
490    if(ret <= 0)
491      {ret= -1; goto ex;}
492    if(out_o->nwa < out_o->zero_nwa)
493      out_o->zero_nwa= 0;
494    if(opts->no_emul_toc || opts->libjte_handle != NULL) {
495      if(out_o->nwa == out_o->zero_nwa &&
496         out_o->zero_nwa == Libisoburn_overwriteable_starT
497                            + opts->partition_offset
498         && out_o->emulation_mode == 1) {
499        out_o->nwa= 0;
500        out_o->zero_nwa= 0;
501        out_o->min_start_byte= 0;
502      }
503    }
504    ret = isoburn_disc_track_lba_nwa(out_d, NULL, 0, &lba, &nwa);
505    opts->effective_lba= nwa;
506    ret= isoburn_get_msc2(out_o, NULL, &nwa, 0);
507    if (ret != 1) {
508      isoburn_msgs_submit(out_o, 0x00060000,
509                    "Cannot determine next writeable address", 0, "FAILURE", 0);
510 
511      /* >>> NWA_V : If burn_next_track_damaged:
512             ??? Close track and session ?
513 	    ??? Issue a hint for a repair command ?
514      */;
515 
516      {ret= -3; goto ex;}
517    }
518    iso_write_opts_set_ms_block(wopts, nwa);
519    iso_write_opts_set_appendable(wopts, !new_img);
520    iso_write_opts_set_overwrite_buf(wopts,
521                                     nwa>0 ? out_o->target_iso_head : NULL);
522  }
523  iso_write_opts_set_part_offset(wopts, opts->partition_offset,
524                                 opts->partition_secs_per_head,
525                                 opts->partition_heads_per_cyl);
526  iso_write_opts_set_tail_blocks(wopts, opts->tail_blocks);
527  if(opts->prep_partition != NULL) {
528    ret = iso_write_opts_set_prep_img(wopts, opts->prep_partition,
529                                      opts->prep_part_flag & 1);
530    if(ret < 0) {
531      isoburn_report_iso_error(ret, "Cannot set path for PreP partition",
532                               0, "FAILURE", 0);
533      {ret= -1; goto ex;}
534    }
535  }
536  if(opts->efi_boot_partition != NULL) {
537    ret = iso_write_opts_set_efi_bootp(wopts, opts->efi_boot_partition,
538                                       opts->efi_boot_part_flag & 1);
539    if(ret < 0) {
540      isoburn_report_iso_error(ret, "Cannot set path for EFI system partition",
541                               0, "FAILURE", 0);
542      {ret= -1; goto ex;}
543    }
544  }
545  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
546    if(opts->appended_partitions[i] == NULL)
547  continue;
548    ret= iso_write_opts_set_partition_img(wopts, i + 1,
549                                          opts->appended_part_types[i],
550                                          opts->appended_partitions[i],
551                                          opts->appended_part_flags[i]);
552    if(ret < 0) {
553      isoburn_report_iso_error(ret, "Cannot set path for appended partition",
554                               0, "FAILURE", 0);
555      {ret= -1; goto ex;}
556    }
557  }
558  iso_write_opts_set_appended_as_gpt(wopts, opts->appended_as_gpt);
559  iso_write_opts_set_appended_as_apm(wopts, opts->appended_as_apm);
560  iso_write_opts_set_part_like_isohybrid(wopts, opts->part_like_isohybrid);
561  iso_write_opts_set_iso_mbr_part_type(wopts, opts->iso_mbr_part_type);
562  iso_write_opts_set_disc_label(wopts, opts->ascii_disc_label);
563 
564  ret= 1;
565 ex:
566  return(ret);
567 }
568 
569 
570 /* @param flag bit0= modifying rather than growing
571                bit1= prepare for early release of input drive:
572                      wait until input and then disable image data source
573 */
574 static
isoburn_prepare_disc_aux(struct burn_drive * in_d,struct burn_drive * out_d,struct burn_disc ** disc,struct isoburn_imgen_opts * opts,int flag)575 int isoburn_prepare_disc_aux(struct burn_drive *in_d, struct burn_drive *out_d,
576                              struct burn_disc **disc,
577                              struct isoburn_imgen_opts *opts, int flag)
578 {
579  struct burn_source *wsrc;
580  struct burn_session *session;
581  struct burn_track *track;
582  struct isoburn *in_o, *out_o;
583  IsoWriteOpts *wopts= NULL;
584  enum burn_disc_status state;
585  int ret, fifo_chunks, i, new_img, early_indev_release;
586  uint32_t data_start= -1;
587  size_t buffer_size= 0, buffer_free= 0;
588  char *msg= NULL;
589 
590  msg= calloc(1, 160);
591  if(msg == NULL)
592    {ret= -1; goto ex;}
593 
594  new_img= flag&1;
595  early_indev_release= flag&2;
596 
597  ret= isoburn_find_emulator(&in_o, in_d, 0);
598  if(ret<0 || in_o==NULL)
599    {ret= -1; goto ex;}
600  ret= isoburn_find_emulator(&out_o, out_d, 0);
601  if(ret<0 || out_o==NULL)
602    {ret= -1; goto ex;}
603  /* early end will be registered as failure */
604  in_o->wrote_well= out_o->wrote_well= 0;
605 
606  if(new_img && early_indev_release) {
607    isoburn_msgs_submit(in_o, 0x00060000,
608       "Programming error: Wrong session setup: new_img && early_indev_release",
609                        0, "FATAL", 0);
610    {ret= -4; goto ex;}
611  }
612 
613  out_o->do_tao = opts->do_tao;
614  out_o->do_fsync = opts->do_fsync;
615 
616  state = isoburn_disc_get_status(in_d);
617  if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE &&
618      state != BURN_DISC_FULL) {
619    isoburn_msgs_submit(in_o, 0x00060000, "Unsuitable source media state",
620                     0, "FAILURE", 0);
621    {ret= -2; goto ex;}
622  }
623  state = isoburn_disc_get_status(out_d);
624  if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) {
625    isoburn_msgs_submit(out_o, 0x00060000, "Unsuitable target media state",
626                     0, "FAILURE", 0);
627    {ret= -2; goto ex;}
628  }
629  if (state != BURN_DISC_BLANK && opts->libjte_handle != NULL) {
630    isoburn_msgs_submit(out_o, 0x00060000,
631                   "Jigdo Template Extraction works only on blank target media",
632                   0, "FAILURE", 0);
633    {ret= -2; goto ex;}
634  }
635 
636  fifo_chunks= 32;
637  if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){
638    fifo_chunks= opts->fifo_size/2048;
639    if(fifo_chunks*2048 < opts->fifo_size)
640      fifo_chunks++;
641  }
642 
643  ret= iso_write_opts_new(&wopts, 0);
644  if (ret < 0) {
645    isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0);
646    goto ex;
647  }
648  ret= isoburn_make_iso_write_opts(out_o, opts, fifo_chunks, wopts, flag & 1);
649  if(ret < 0)
650    goto ex;
651 
652  ret = iso_image_create_burn_source(in_o->image, wopts, &wsrc);
653  if (ret < 0) {
654    isoburn_report_iso_error(ret, "Cannot create burn source", 0, "FAILURE", 0);
655    {ret= -1; goto ex;}
656  }
657  if (early_indev_release) {
658    for(i= 0; i<300; i++) {
659 
660      /* <<< ??? */
661      if((i%30) == 0) {
662        sprintf(msg, "Waiting for data in fifo since %d seconds", i/30);
663        isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
664      }
665 
666      usleep(100000);
667      ret= iso_ring_buffer_get_status(wsrc, &buffer_size, &buffer_free);
668      if(ret >0 && buffer_size != buffer_free)
669    break;
670    }
671 
672    /* <<< ??? */
673    sprintf(msg,
674            "After %.1f seconds: %d bytes of output available (fifo state=%d)",
675            ((double) i+1) / 10.0, (int) (buffer_size - buffer_free), ret);
676    isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
677 
678    if(in_o->iso_data_source!=NULL)
679      isoburn_data_source_shutdown(in_o->iso_data_source, 0);
680  }
681 
682  ret= iso_write_opts_get_data_start(wopts, &data_start, 0);
683  opts->data_start_lba= -1;
684  if(ret > 0 && data_start <= 0x7FFFFFFF)
685    opts->data_start_lba= data_start;
686 
687  /* TODO check return values for failure. propertly clean-up on error */
688 
689  out_o->iso_source= wsrc;
690 
691  *disc = burn_disc_create();
692  session = burn_session_create();
693  burn_disc_add_session(*disc, session, BURN_POS_END);
694  track = burn_track_create();
695  burn_track_set_source(track, out_o->iso_source);
696  burn_session_add_track(session, track, BURN_POS_END);
697 
698  /* give up local references */
699  burn_track_free(track);
700  burn_session_free(session);
701 
702  in_o->wrote_well= out_o->wrote_well= -1; /* neutral */
703  ret= 1;
704 ex:
705  if(wopts!=NULL)
706    {iso_write_opts_free(wopts); wopts= NULL;}
707  if(msg != NULL)
708    free(msg);
709  return ret;
710 }
711 
712 
isoburn_prepare_disc(struct burn_drive * d,struct burn_disc ** disc,struct isoburn_imgen_opts * opts)713 int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc,
714                          struct isoburn_imgen_opts *opts)
715 {
716  return isoburn_prepare_disc_aux(d, d, disc, opts, 0);
717 }
718 
719 
isoburn_prepare_new_image(struct burn_drive * d,struct burn_disc ** disc,struct isoburn_imgen_opts * opts,struct burn_drive * out_drive)720 int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc,
721                          struct isoburn_imgen_opts *opts,
722                          struct burn_drive *out_drive)
723 {
724  int ret;
725 
726  ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 1);
727  if (ret<=0)
728    return ret;
729  return 1;
730 }
731 
732 
733 /* API since 0.2.2 */
isoburn_prepare_blind_grow(struct burn_drive * d,struct burn_disc ** disc,struct isoburn_imgen_opts * opts,struct burn_drive * out_drive,int nwa)734 int isoburn_prepare_blind_grow(struct burn_drive *d, struct burn_disc **disc,
735                                struct isoburn_imgen_opts *opts,
736                                struct burn_drive *out_drive, int nwa)
737 {
738  int ret;
739  struct isoburn *o= NULL;
740 
741  ret= isoburn_find_emulator(&o, out_drive, 0);
742  if(ret<0 || o==NULL)
743    return(-1);
744  if(nwa >= 0)
745    o->fabricated_msc2= nwa;
746  if(o->nwa == o->zero_nwa)
747    o->nwa= o->zero_nwa= 0;
748  else
749    o->zero_nwa= 0;
750  o->min_start_byte= 0;
751  ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 2);
752  if (ret<=0)
753    return ret;
754  return(1);
755 }
756 
757 
758 /* API @since 0.1.0
759    @param flag bit0= this is a regular end, not an abort
760                      give up source reference
761 */
isoburn_cancel_prepared_write(struct burn_drive * d,struct burn_drive * output_drive,int flag)762 int isoburn_cancel_prepared_write(struct burn_drive *d,
763                                   struct burn_drive *output_drive, int flag)
764 {
765  int ret;
766  struct isoburn *o= NULL;
767 
768  if(output_drive!=NULL) {
769    ret= isoburn_find_emulator(&o, output_drive, 0);
770    if(ret<0 || o==NULL)
771      o= NULL;
772    else if(o->iso_source==NULL)
773      o= NULL;
774  }
775  if(o==NULL) {
776    ret= isoburn_find_emulator(&o, d, 0);
777    if(ret<0)
778      return(-1);
779    if(o==NULL)
780      return(0);
781    if(o->iso_source==NULL)
782      return(0);
783  }
784  if(o->iso_source->read!=NULL)
785    return(0);
786  if(o->iso_source->version<1)
787    return(0);
788  o->iso_source->cancel(o->iso_source);
789  burn_source_free(o->iso_source);
790  o->iso_source= NULL;
791  return(1);
792 }
793 
794 
795 /* API @since 0.1.0 */
isoburn_sync_after_write(struct burn_drive * d,struct burn_drive * output_drive,int flag)796 int isoburn_sync_after_write(struct burn_drive *d,
797                              struct burn_drive *output_drive, int flag)
798 {
799  return isoburn_cancel_prepared_write(d, output_drive, 1);
800 }
801 
802 
isoburn_version(int * major,int * minor,int * micro)803 void isoburn_version(int *major, int *minor, int *micro)
804 {
805  *major= isoburn_header_version_major;
806  *minor= isoburn_header_version_minor;
807  *micro= isoburn_header_version_micro;
808 
809 /* No more: values from version.h generated from version.h.in and
810             macro values defined in configure.ac
811 
812  *major = ISOBURN_MAJOR_VERSION;
813  *minor = ISOBURN_MINOR_VERSION;
814  *micro = ISOBURN_MICRO_VERSION;
815 */
816 }
817 
818 
isoburn_is_compatible(int major,int minor,int micro,int flag)819 int isoburn_is_compatible(int major, int minor, int micro, int flag)
820 {
821  int own_major, own_minor, own_micro;
822 
823  isoburn_version(&own_major, &own_minor, &own_micro);
824  return(own_major > major ||
825         (own_major == major && (own_minor > minor ||
826          (own_minor == minor && own_micro >= micro))));
827 }
828 
829 
830 /* ----------------------------------------------------------------------- */
831 /*
832   Options for image reading.
833 */
834 /* ----------------------------------------------------------------------- */
835 
836 
isoburn_ropt_new(struct isoburn_read_opts ** new_o,int flag)837 int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag)
838 {
839  struct isoburn_read_opts *o;
840 
841  o= (*new_o)= calloc(1, sizeof(struct isoburn_read_opts));
842  if(o==NULL) {
843    isoburn_msgs_submit(NULL, 0x00060000,
844                      "Cannot allocate memory for read options", 0, "FATAL", 0);
845    return(-1);
846  }
847  o->cache_tiles= Libisoburn_default_cache_tileS;
848  o->cache_tile_blocks= Libisoburn_default_tile_blockS;
849  o->norock= 0;
850  o->nojoliet= 0;
851  o->noiso1999= 1;
852  o->do_ecma119_map= 0;
853  o->map_mode= 1;
854  o->noaaip= 1;
855  o->noacl= 1;
856  o->noea= 1;
857  o->noino= 1;
858  o->nomd5= 1;
859  o->preferjoliet= 0;
860  o->uid= geteuid();
861  o->gid= getegid();
862  o->mode= 0444;
863  o->dirmode= 0555;
864  o->input_charset= NULL;
865  o->truncate_mode= 1;
866  o->truncate_length= 255;
867  o->hasRR= 0;
868  o->hasJoliet= 0;
869  o->hasIso1999= 0;
870  o->hasElTorito= 0;
871  o->size= 0;
872  o->pretend_blank= 1;
873  o->displacement= 0;
874  o->displacement_sign= 0;
875  return(1);
876 }
877 
878 
isoburn_ropt_destroy(struct isoburn_read_opts ** o,int flag)879 int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag)
880 {
881  if(*o==NULL)
882    return(0);
883  free(*o);
884  *o= NULL;
885  return(1);
886 }
887 
888 
isoburn_ropt_set_data_cache(struct isoburn_read_opts * o,int cache_tiles,int tile_blocks,int flag)889 int isoburn_ropt_set_data_cache(struct isoburn_read_opts *o,
890                                 int cache_tiles, int tile_blocks, int flag)
891 {
892  int i;
893  char msg[80];
894 
895  if(cache_tiles < 1) {
896    isoburn_msgs_submit(NULL, 0x00060000,
897                      "Requested number of data cache tiles is too small (< 1)",
898                      0, "SORRY", 0);
899    return(0);
900  }
901  if(((double) cache_tiles) * ((double) tile_blocks)
902      > (double) Libisoburn_cache_max_sizE) {
903    sprintf(msg, "Requested size of data cache exceeds limit of %.f blocks",
904            (double) Libisoburn_cache_max_sizE);
905    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "SORRY", 0);
906    return(0);
907  }
908  for(i = 1; i <= Libisoburn_cache_max_sizE; i = i << 1)
909    if(i == tile_blocks)
910  break;
911  if(i > Libisoburn_cache_max_sizE) {
912    isoburn_msgs_submit(NULL, 0x00060000,
913          "Requested number of blocks per data cache tiles is not a power of 2",
914          0, "SORRY", 0);
915    return(0);
916  }
917  if(o != NULL) {
918    o->cache_tiles= cache_tiles;
919    o->cache_tile_blocks= tile_blocks;
920  }
921  return(1);
922 }
923 
924 
isoburn_ropt_get_data_cache(struct isoburn_read_opts * o,int * cache_tiles,int * tile_blocks,int * set_flag,int flag)925 int isoburn_ropt_get_data_cache(struct isoburn_read_opts *o,
926                                  int *cache_tiles, int *tile_blocks,
927                                  int *set_flag, int flag)
928 {
929  if((flag & 1) || o == NULL) {
930    *cache_tiles= Libisoburn_default_cache_tileS;
931    *tile_blocks= Libisoburn_default_tile_blockS;
932    *set_flag= 0;
933    return(1);
934  }
935  *cache_tiles= o->cache_tiles;
936  *tile_blocks= o->cache_tile_blocks;
937  *set_flag= 0;
938  return(1);
939 }
940 
941 
isoburn_ropt_set_extensions(struct isoburn_read_opts * o,int ext)942 int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext)
943 {
944  o->norock= !!(ext&1);
945  o->nojoliet= !!(ext&2);
946  o->noiso1999= !!(ext&4);
947  o->preferjoliet= !!(ext&8);
948  o->pretend_blank= !!(ext&16);
949  o->noaaip= !!(ext & 32);
950  o->noacl= !!(ext & 64);
951  o->noea= !!(ext & 128);
952  o->noino= !!(ext & 256);
953  o->nomd5= (ext >> 9) & 3;
954  o->do_ecma119_map= !!(ext & 2048);
955  o->map_mode= (ext >> 12) & 3;
956  return(1);
957 }
958 
959 
isoburn_ropt_get_extensions(struct isoburn_read_opts * o,int * ext)960 int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext)
961 {
962  *ext= (!!o->norock) | ((!!o->nojoliet)<<1) | ((!!o->noiso1999)<<2) |
963        ((!!o->preferjoliet)<<3) | ((!!o->pretend_blank)<<4) |
964        ((!!o->noaaip) << 5) | ((!!o->noacl) << 6) | ((!!o->noea) << 7) |
965        ((!!o->noino) << 8) | ((o->nomd5 & 3) << 9) |
966        ((!!o->do_ecma119_map) << 11) | ((o->map_mode & 3) << 12);
967  return(1);
968 }
969 
970 
isoburn_ropt_set_default_perms(struct isoburn_read_opts * o,uid_t uid,gid_t gid,mode_t mode)971 int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o,
972                                    uid_t uid, gid_t gid, mode_t mode)
973 {
974  mode_t dirmode;
975 
976  o->uid= uid;
977  o->gid= gid;
978  o->mode= mode;
979  dirmode= mode;
980  if(dirmode & S_IRUSR)
981    dirmode|= S_IXUSR;
982  if(dirmode & S_IRGRP)
983    dirmode|= S_IXGRP;
984  if(dirmode & S_IROTH)
985    dirmode|= S_IXOTH;
986  o->dirmode= dirmode;
987  return(1);
988 }
989 
990 
isoburn_ropt_get_default_perms(struct isoburn_read_opts * o,uid_t * uid,gid_t * gid,mode_t * mode)991 int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o,
992                                    uid_t *uid, gid_t *gid, mode_t *mode)
993 {
994  *uid= o->uid;
995  *gid= o->gid;
996  *mode= o->mode;
997  return(1);
998 }
999 
1000 
isoburn_ropt_set_default_dirperms(struct isoburn_read_opts * o,mode_t mode)1001 int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o,
1002                                        mode_t mode)
1003 {
1004  o->dirmode= mode;
1005  return(1);
1006 }
1007 
1008 
isoburn_ropt_get_default_dirperms(struct isoburn_read_opts * o,mode_t * mode)1009 int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o,
1010                                       mode_t *mode)
1011 {
1012  *mode= o->dirmode;
1013  return(1);
1014 }
1015 
1016 
isoburn_ropt_set_input_charset(struct isoburn_read_opts * o,char * input_charset)1017 int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o,
1018                                    char *input_charset)
1019 {
1020  o->input_charset= input_charset;
1021  return(1);
1022 }
1023 
1024 
isoburn_ropt_get_input_charset(struct isoburn_read_opts * o,char ** input_charset)1025 int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o,
1026                                    char **input_charset)
1027 {
1028  *input_charset= o->input_charset;
1029  return(1);
1030 }
1031 
1032 
isoburn_ropt_set_auto_incharset(struct isoburn_read_opts * o,int mode)1033 int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode)
1034 {
1035  o->auto_input_charset= mode & 1;
1036  return(1);
1037 }
1038 
1039 
isoburn_ropt_get_auto_incharset(struct isoburn_read_opts * o,int * mode)1040 int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode)
1041 {
1042  *mode= o->auto_input_charset;
1043  return(1);
1044 }
1045 
1046 
isoburn_ropt_set_displacement(struct isoburn_read_opts * o,uint32_t displacement,int displacement_sign)1047 int isoburn_ropt_set_displacement(struct isoburn_read_opts *o,
1048                                uint32_t displacement, int displacement_sign)
1049 {
1050  o->displacement= displacement;
1051  o->displacement_sign= displacement_sign;
1052  return(1);
1053 }
1054 
1055 
isoburn_ropt_get_displacement(struct isoburn_read_opts * o,uint32_t * displacement,int * displacement_sign)1056 int isoburn_ropt_get_displacement(struct isoburn_read_opts *o,
1057                                uint32_t *displacement, int *displacement_sign)
1058 {
1059  *displacement= o->displacement;
1060  *displacement_sign= o->displacement_sign;
1061  return(1);
1062 }
1063 
1064 
isoburn_ropt_set_truncate_mode(struct isoburn_read_opts * o,int mode,int length)1065 int isoburn_ropt_set_truncate_mode(struct isoburn_read_opts *o,
1066                                    int mode, int length)
1067 {
1068  if(mode < 0 || mode > 1)
1069    mode= 1;
1070  if(length < 64)
1071    length= 64;
1072  if(length > 255)
1073    length= 255;
1074  o->truncate_mode= mode;
1075  o->truncate_length= length;
1076  return(1);
1077 }
1078 
1079 
isoburn_ropt_get_truncate_mode(struct isoburn_read_opts * o,int * mode,int * length)1080 int isoburn_ropt_get_truncate_mode(struct isoburn_read_opts *o,
1081                                    int *mode, int *length)
1082 {
1083  *mode= o->truncate_mode;
1084  *length= o->truncate_length;
1085  return(1);
1086 }
1087 
1088 
isoburn_ropt_get_size_what(struct isoburn_read_opts * o,uint32_t * size,int * has_what)1089 int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
1090                                uint32_t *size, int *has_what)
1091 {
1092  *size= o->size;
1093  *has_what= (!!o->hasRR) | ((!!o->hasJoliet)<<1) |
1094             ((!!o->hasIso1999)<<2) | ((!!o->hasElTorito)<<3);
1095  return(1);
1096 }
1097 
1098 
1099 /* ----------------------------------------------------------------------- */
1100 /*
1101   Options for image generation by libisofs and image transport to libburn.
1102 */
1103 /* ----------------------------------------------------------------------- */
1104 
1105 
isoburn_igopt_new(struct isoburn_imgen_opts ** new_o,int flag)1106 int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag)
1107 {
1108  struct isoburn_imgen_opts *o;
1109  int i;
1110 
1111  o= (*new_o)= calloc(1, sizeof(struct isoburn_imgen_opts));
1112  if(o==NULL) {
1113    isoburn_msgs_submit(NULL, 0x00060000,
1114                        "Cannot allocate memory for image generation options",
1115                        0, "FATAL", 0);
1116    return(-1);
1117  }
1118  o->level= 2;
1119  o->rockridge= 1;
1120  o->joliet= 0;
1121  o->iso1999= 0;
1122  o->hardlinks= 0;
1123  o->aaip = 0;
1124  o->session_md5= 0;
1125  o->file_md5= 0;
1126  o->no_emul_toc= 0;
1127  o->old_empty= 0;
1128  o->untranslated_name_len = 0;
1129  o->allow_dir_id_ext = 0;
1130  o->omit_version_numbers= 0;
1131  o->allow_deep_paths= 1;
1132  o->rr_reloc_dir= NULL;
1133  o->rr_reloc_flags= 0;
1134  o->allow_longer_paths= 0;
1135  o->max_37_char_filenames= 0;
1136  o->no_force_dots= 0;
1137  o->allow_lowercase= 0;
1138  o->allow_full_ascii= 0;
1139  o->allow_7bit_ascii= 0;
1140  o->joliet_longer_paths= 0;
1141  o->joliet_long_names= 0;
1142  o->joliet_utf16= 0;
1143  o->always_gmt= 0;
1144  o->rrip_version_1_10= 0;
1145  o->dir_rec_mtime= 0;
1146  o->aaip_susp_1_10= 0;
1147  o->sort_files= 0;
1148  o->replace_dir_mode= 0;
1149  o->replace_file_mode= 0;
1150  o->replace_uid= 0;
1151  o->replace_gid= 0;
1152  o->dir_mode= 0555;
1153  o->file_mode= 0444;
1154  o->uid= 0;
1155  o->gid= 0;
1156  o->output_charset= NULL;
1157  o->fifo_size= 4*1024*1024;
1158  o->effective_lba= -1;
1159  o->data_start_lba= -1;
1160  o->system_area_data= NULL;
1161  o->system_area_options= 0;
1162  o->partition_offset= 0;
1163  o->partition_secs_per_head= 0;
1164  o->partition_heads_per_cyl= 0;
1165  o->vol_creation_time= 0;
1166  o->vol_modification_time= 0;
1167  o->vol_expiration_time= 0;
1168  o->vol_effective_time= 0;
1169  o->libjte_handle= NULL;
1170  o->tail_blocks= 0;
1171  o->prep_partition= NULL;
1172  o->prep_part_flag= 0;
1173  o->efi_boot_partition= NULL;
1174  o->efi_boot_part_flag= 0;
1175  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
1176    o->appended_partitions[i]= NULL;
1177    o->appended_part_types[i]= 0;
1178    o->appended_part_flags[i]= 0;
1179  }
1180  o->appended_as_gpt= 0;
1181  o->appended_as_apm= 0;
1182  o->part_like_isohybrid= 0;
1183  o->iso_mbr_part_type= -1;
1184  memset(o->gpt_guid, 0, 16);
1185  o->gpt_guid_mode= 0;
1186  memset(o->hfsp_serial_number, 0, 8);
1187  o->hfsp_block_size= 0;
1188  o->apm_block_size= 0;
1189  o->do_tao= 0;
1190  o->do_fsync= 0;
1191  return(1);
1192 }
1193 
1194 
isoburn_igopt_destroy(struct isoburn_imgen_opts ** o,int flag)1195 int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag)
1196 {
1197  int i;
1198 
1199  if(*o==NULL)
1200    return(0);
1201  if((*o)->rr_reloc_dir != NULL)
1202    free((*o)->rr_reloc_dir);
1203  if((*o)->prep_partition != NULL)
1204    free((*o)->prep_partition);
1205  if((*o)->efi_boot_partition != NULL)
1206    free((*o)->efi_boot_partition);
1207  for(i= 0; i < Libisoburn_max_appended_partitionS; i++)
1208    if((*o)->appended_partitions[i] != NULL)
1209      free((*o)->appended_partitions[i]);
1210  if ((*o)->system_area_data != NULL)
1211      free((*o)->system_area_data);
1212  free(*o);
1213  *o= NULL;
1214  return(1);
1215 }
1216 
1217 
isoburn_igopt_set_level(struct isoburn_imgen_opts * o,int level)1218 int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level)
1219 {
1220  o->level= level;
1221  return(1);
1222 }
1223 
1224 
isoburn_igopt_get_level(struct isoburn_imgen_opts * o,int * level)1225 int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level)
1226 {
1227  *level= o->level;
1228  return(1);
1229 }
1230 
1231 
isoburn_igopt_set_extensions(struct isoburn_imgen_opts * o,int ext)1232 int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext)
1233 {
1234  o->rockridge= !!(ext&1);
1235  o->joliet= !!(ext&2);
1236  o->iso1999= !!(ext&4);
1237  o->hardlinks= !!(ext & 8);
1238  o->aaip= !!(ext & 32);
1239  o->session_md5= !!(ext & 64);
1240  o->file_md5= (ext & (128 | 256)) >> 7;
1241  o->no_emul_toc= !!(ext & 512);
1242  o->will_cancel= !!(ext & 1024);
1243  o->old_empty= !!(ext & 2048);
1244  o->hfsplus= !!(ext & 4096);
1245  o->fat= !!(ext & 8192);
1246  return(1);
1247 }
1248 
1249 
isoburn_igopt_get_extensions(struct isoburn_imgen_opts * o,int * ext)1250 int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext)
1251 {
1252  *ext= (!!o->rockridge) | ((!!o->joliet)<<1) | ((!!o->iso1999)<<2) |
1253        ((!!o->hardlinks) << 3) | ((!!o->aaip) << 5) |
1254        ((!!o->session_md5) << 6) | ((o->file_md5 & 3) << 7) |
1255        ((!!o->no_emul_toc) << 9) | ((o->will_cancel) << 10) |
1256        ((!!o->old_empty) << 11) | ((!!o->hfsplus) << 12) |
1257        ((!!o->fat) << 13);
1258  return(1);
1259 }
1260 
1261 
isoburn_igopt_set_relaxed(struct isoburn_imgen_opts * o,int relax)1262 int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax)
1263 {
1264  o->omit_version_numbers= (!!(relax&1)) |
1265                           (2 * !!(relax & isoburn_igopt_only_iso_versions));
1266  o->allow_deep_paths= !!(relax&2);
1267  o->allow_longer_paths= !!(relax&4);
1268  o->max_37_char_filenames= !!(relax&8);
1269  o->no_force_dots= (!!(relax&16)) |
1270                    (2 * !!(relax & isoburn_igopt_no_j_force_dots));
1271  o->allow_lowercase= !!(relax&32);
1272  o->allow_full_ascii= !!(relax&64);
1273  o->joliet_longer_paths= !!(relax&128);
1274  o->always_gmt= !!(relax & isoburn_igopt_always_gmt);
1275  o->rrip_version_1_10= !!(relax & isoburn_igopt_rrip_version_1_10);
1276  o->dir_rec_mtime= !!(relax & isoburn_igopt_dir_rec_mtime);
1277  o->aaip_susp_1_10= !!(relax & isoburn_igopt_aaip_susp_1_10);
1278  o->allow_dir_id_ext= !!(relax & isoburn_igopt_allow_dir_id_ext);
1279  o->joliet_long_names= !!(relax & isoburn_igopt_joliet_long_names);
1280  o->joliet_rec_mtime= !!(relax & isoburn_igopt_joliet_rec_mtime);
1281  o->iso1999_rec_mtime= !!(relax & isoburn_igopt_iso1999_rec_mtime);
1282  o->allow_7bit_ascii= !!(relax & isoburn_igopt_allow_7bit_ascii);
1283  o->joliet_utf16= !!(relax & isoburn_igopt_joliet_utf16);
1284  return(1);
1285 }
1286 
1287 
isoburn_igopt_get_relaxed(struct isoburn_imgen_opts * o,int * relax)1288 int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax)
1289 {
1290  *relax= (!!o->omit_version_numbers)    | ((!!o->allow_deep_paths)<<1) |
1291          ((!!o->allow_longer_paths)<<2) | ((!!o->max_37_char_filenames)<<3) |
1292          ((!!(o->no_force_dots & 1))<<4)| ((!!o->allow_lowercase)<<5) |
1293          ((!!o->allow_full_ascii)<<6)   | ((!!o->joliet_longer_paths)<<7) |
1294          ((!!o->always_gmt)<<8)         | ((!!o->rrip_version_1_10)<<9) |
1295          ((!!o->dir_rec_mtime)<<10)     | ((!!o->aaip_susp_1_10)<<11) |
1296          ((!!(o->omit_version_numbers & 2))<<12) |
1297          ((!!(o->no_force_dots & 2))<<13) |
1298          ((!!o->allow_dir_id_ext) << 14) |
1299          ((!!o->joliet_long_names) << 15) |
1300          ((!!o->joliet_rec_mtime) << 16) |
1301          ((!!o->iso1999_rec_mtime) << 17) |
1302          ((!!o->allow_full_ascii) << 18) |
1303          ((!!o->joliet_utf16) << 19);
1304  return(1);
1305 }
1306 
1307 
isoburn_igopt_set_rr_reloc(struct isoburn_imgen_opts * o,char * name,int flags)1308 int isoburn_igopt_set_rr_reloc(struct isoburn_imgen_opts *o, char *name,
1309                                int flags)
1310 {
1311  if(o->rr_reloc_dir != name) {
1312    if(o->rr_reloc_dir != NULL)
1313      free(o->rr_reloc_dir);
1314    o->rr_reloc_dir= NULL;
1315    if(name != NULL) {
1316      o->rr_reloc_dir= strdup(name);
1317      if(o->rr_reloc_dir == NULL) {
1318        isoburn_msgs_submit(NULL, 0x00060000,
1319                          "Cannot allocate memory for image generation options",
1320                           0, "FATAL", 0);
1321        return(-1);
1322      }
1323    }
1324  }
1325  o->rr_reloc_flags = flags & 1;
1326  return 1;
1327 }
1328 
1329 
isoburn_igopt_get_rr_reloc(struct isoburn_imgen_opts * o,char ** name,int * flags)1330 int isoburn_igopt_get_rr_reloc(struct isoburn_imgen_opts *o, char **name,
1331                                int *flags)
1332 {
1333  *name= o->rr_reloc_dir;
1334  *flags= o->rr_reloc_flags;
1335  return(1);
1336 }
1337 
1338 
isoburn_igopt_set_untranslated_name_len(struct isoburn_imgen_opts * o,int len)1339 int isoburn_igopt_set_untranslated_name_len(struct isoburn_imgen_opts *o,
1340                                             int len)
1341 {
1342  int ret;
1343  IsoWriteOpts *opts = NULL;
1344  char *msg= NULL;
1345 
1346  msg= calloc(1, 160);
1347  if(msg == NULL)
1348    {ret= -1; goto ex;}
1349 
1350  ret= iso_write_opts_new(&opts, 0);
1351  if(ret < 0) {
1352    isoburn_msgs_submit(NULL, 0x00060000,
1353                  "Cannot create libisofs write options object", 0, "FATAL", 0);
1354    {ret= 0; goto ex;}
1355  }
1356  ret= iso_write_opts_set_untranslated_name_len(opts, len);
1357  if(ret < 0) {
1358    ret= iso_write_opts_set_untranslated_name_len(opts, -1);
1359    sprintf(msg,
1360   "Improper value for maximum length of untranslated names (%d <-> -1 ... %d)",
1361            len, ret);
1362    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
1363    iso_write_opts_free(opts);
1364    {ret= 0; goto ex;}
1365  }
1366  o->untranslated_name_len= ret; /* Normalized len value */
1367  iso_write_opts_free(opts);
1368  ret= 1;
1369 ex:;
1370  if(msg != NULL)
1371    free(msg);
1372  return(ret);
1373 }
1374 
1375 
isoburn_igopt_get_untranslated_name_len(struct isoburn_imgen_opts * o,int * len)1376 int isoburn_igopt_get_untranslated_name_len(struct isoburn_imgen_opts *o,
1377                                             int *len)
1378 {
1379  *len = o->untranslated_name_len;
1380  return(1);
1381 }
1382 
1383 
isoburn_igopt_set_sort_files(struct isoburn_imgen_opts * o,int value)1384 int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value)
1385 {
1386  o->sort_files= !!(value&1);
1387  return(1);
1388 }
1389 
1390 
isoburn_igopt_get_sort_files(struct isoburn_imgen_opts * o,int * value)1391 int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value)
1392 {
1393  *value= !!o->sort_files;
1394  return(1);
1395 }
1396 
1397 
isoburn_igopt_set_over_mode(struct isoburn_imgen_opts * o,int replace_dir_mode,int replace_file_mode,mode_t dir_mode,mode_t file_mode)1398 int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o,
1399                                int replace_dir_mode, int replace_file_mode,
1400                                mode_t dir_mode, mode_t file_mode)
1401 {
1402  o->replace_dir_mode= replace_dir_mode%3;
1403  o->replace_file_mode= replace_file_mode%3;
1404  o->dir_mode= dir_mode;
1405  o->file_mode= file_mode;
1406  return(1);
1407 }
1408 
1409 
isoburn_igopt_get_over_mode(struct isoburn_imgen_opts * o,int * replace_dir_mode,int * replace_file_mode,mode_t * dir_mode,mode_t * file_mode)1410 int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o,
1411                                int *replace_dir_mode, int *replace_file_mode,
1412                                mode_t *dir_mode, mode_t *file_mode)
1413 {
1414  *replace_dir_mode= o->replace_dir_mode%3;
1415  *replace_file_mode= o->replace_file_mode%3;
1416  *dir_mode= o->dir_mode;
1417  *file_mode= o->file_mode;
1418  return(1);
1419 }
1420 
1421 
isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts * o,int replace_uid,int replace_gid,uid_t uid,gid_t gid)1422 int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o,
1423                                int replace_uid, int replace_gid,
1424                                uid_t uid, gid_t gid)
1425 {
1426  o->replace_uid= replace_uid%3;
1427  o->replace_gid= replace_gid%3;
1428  o->uid= uid;
1429  o->gid= gid;
1430  return(1);
1431 }
1432 
isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts * o,int * replace_uid,int * replace_gid,uid_t * uid,gid_t * gid)1433 int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o,
1434                                int *replace_uid, int *replace_gid,
1435                                uid_t *uid, gid_t *gid)
1436 {
1437  *replace_uid= o->replace_uid%3;
1438  *replace_gid= o->replace_gid%3;
1439  *uid= o->uid;
1440  *gid= o->gid;
1441  return(1);
1442 }
1443 
1444 
isoburn_igopt_set_out_charset(struct isoburn_imgen_opts * o,char * output_charset)1445 int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o,
1446                                  char *output_charset)
1447 {
1448  o->output_charset= output_charset;
1449  return(1);
1450 }
1451 
1452 
isoburn_igopt_get_out_charset(struct isoburn_imgen_opts * o,char ** output_charset)1453 int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o,
1454                                  char **output_charset)
1455 {
1456  *output_charset= o->output_charset;
1457  return(1);
1458 }
1459 
1460 
isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts * o,int fifo_size)1461 int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size)
1462 {
1463  o->fifo_size= fifo_size;
1464  return(1);
1465 }
1466 
1467 
isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts * o,int * fifo_size)1468 int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size)
1469 {
1470  *fifo_size= o->fifo_size;
1471  return(1);
1472 }
1473 
1474 
isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts * o,int * lba)1475 int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba)
1476 {
1477  *lba= o->effective_lba;
1478  return(1);
1479 }
1480 
1481 
isoburn_igopt_get_data_start(struct isoburn_imgen_opts * o,int * lba)1482 int isoburn_igopt_get_data_start(struct isoburn_imgen_opts *o, int *lba)
1483 {
1484  *lba= o->data_start_lba;
1485  return(1);
1486 }
1487 
1488 
isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts * o,char * name,char * timestamp,char * tag_written)1489 int isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts *o, char *name,
1490                                     char *timestamp, char *tag_written)
1491 {
1492  strncpy(o->scdbackup_tag_name, name, 80);
1493  o->scdbackup_tag_name[80]= 0;
1494  strncpy(o->scdbackup_tag_time, timestamp, 18);
1495  o->scdbackup_tag_time[18]= 0;
1496  o->scdbackup_tag_written = tag_written;
1497  if(tag_written != NULL)
1498    tag_written[0]= 0;
1499  return(1);
1500 }
1501 
1502 
isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts * o,char name[81],char timestamp[19],char ** tag_written)1503 int isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts *o,
1504                                     char name[81], char timestamp[19],
1505                                     char **tag_written)
1506 {
1507  strncpy(name, o->scdbackup_tag_name, 80);
1508  name[80]= 0;
1509  strncpy(timestamp, o->scdbackup_tag_time, 18);
1510  timestamp[18]= 0;
1511  *tag_written= o->scdbackup_tag_written;
1512  return(1);
1513 }
1514 
1515 
isoburn_igopt_set_system_area(struct isoburn_imgen_opts * opts,char data[32768],int options)1516 int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *opts,
1517                                   char data[32768], int options)
1518 {
1519  if (data == NULL) { /* Disable */
1520    if (opts->system_area_data != NULL)
1521      free(opts->system_area_data);
1522    opts->system_area_data = NULL;
1523  } else {
1524    if (opts->system_area_data == NULL) {
1525      opts->system_area_data = calloc(32768, 1);
1526      if (opts->system_area_data == NULL)
1527        return(-1);
1528    }
1529    memcpy(opts->system_area_data, data, 32768);
1530  }
1531  opts->system_area_options = options & 0xffff;
1532  return(1);
1533 }
1534 
1535 
isoburn_igopt_get_system_area(struct isoburn_imgen_opts * opts,char data[32768],int * options)1536 int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *opts,
1537                                   char data[32768], int *options)
1538 {
1539  *options= opts->system_area_options;
1540  if(opts->system_area_data == NULL)
1541    return(0);
1542  memcpy(data, opts->system_area_data, 32768);
1543  return(1);
1544 }
1545 
1546 
isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts * opts,time_t vol_creation_time,time_t vol_modification_time,time_t vol_expiration_time,time_t vol_effective_time,char * vol_uuid)1547 int isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts *opts,
1548                         time_t vol_creation_time, time_t vol_modification_time,
1549                         time_t vol_expiration_time, time_t vol_effective_time,
1550                         char *vol_uuid)
1551 {
1552  opts->vol_creation_time = vol_creation_time;
1553  opts->vol_modification_time = vol_modification_time;
1554  opts->vol_expiration_time = vol_expiration_time;
1555  opts->vol_effective_time = vol_effective_time;
1556  strncpy(opts->vol_uuid, vol_uuid, 16);
1557  opts->vol_uuid[16] = 0;
1558  return(1);
1559 }
1560 
1561 
isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts * opts,time_t * vol_creation_time,time_t * vol_modification_time,time_t * vol_expiration_time,time_t * vol_effective_time,char vol_uuid[17])1562 int isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts *opts,
1563                       time_t *vol_creation_time, time_t *vol_modification_time,
1564                       time_t *vol_expiration_time, time_t *vol_effective_time,
1565                       char vol_uuid[17])
1566 {
1567  *vol_creation_time = opts->vol_creation_time;
1568  *vol_modification_time = opts->vol_modification_time;
1569  *vol_expiration_time = opts->vol_expiration_time;
1570  *vol_effective_time = opts->vol_effective_time;
1571  strcpy(vol_uuid, opts->vol_uuid);
1572  return(1);
1573 }
1574 
1575 
isoburn_igopt_set_part_offset(struct isoburn_imgen_opts * opts,uint32_t block_offset_2k,int secs_512_per_head,int heads_per_cyl)1576 int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts,
1577                                   uint32_t block_offset_2k,
1578                                   int secs_512_per_head, int heads_per_cyl)
1579 {
1580  if (block_offset_2k > 0 && block_offset_2k < 16)
1581    return(0);
1582  opts->partition_offset = block_offset_2k;
1583  opts->partition_secs_per_head = secs_512_per_head;
1584  opts->partition_heads_per_cyl = heads_per_cyl;
1585  return(1);
1586 }
1587 
1588 
isoburn_igopt_get_part_offset(struct isoburn_imgen_opts * opts,uint32_t * block_offset_2k,int * secs_512_per_head,int * heads_per_cyl)1589 int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts,
1590                                   uint32_t *block_offset_2k,
1591                                   int *secs_512_per_head, int *heads_per_cyl)
1592 {
1593  *block_offset_2k = opts->partition_offset;
1594  *secs_512_per_head = opts->partition_secs_per_head;
1595  *heads_per_cyl = opts->partition_heads_per_cyl;
1596  return 1;
1597 }
1598 
1599 
isoburn_igopt_attach_jte(struct isoburn_imgen_opts * opts,void * libjte_handle)1600 int isoburn_igopt_attach_jte(struct isoburn_imgen_opts *opts,
1601                              void *libjte_handle)
1602 {
1603  opts->libjte_handle = libjte_handle;
1604  return 1;
1605 }
1606 
1607 
isoburn_igopt_detach_jte(struct isoburn_imgen_opts * opts,void ** libjte_handle)1608 int isoburn_igopt_detach_jte(struct isoburn_imgen_opts *opts,
1609                              void **libjte_handle)
1610 {
1611  if(libjte_handle != NULL)
1612    *libjte_handle = opts->libjte_handle;
1613  opts->libjte_handle = NULL;
1614  return 1;
1615 }
1616 
1617 
isoburn_igopt_set_tail_blocks(struct isoburn_imgen_opts * opts,uint32_t num_blocks)1618 int isoburn_igopt_set_tail_blocks(struct isoburn_imgen_opts *opts,
1619                                   uint32_t num_blocks)
1620 {
1621   opts->tail_blocks = num_blocks;
1622   return 1;
1623 }
1624 
isoburn_igopt_get_tail_blocks(struct isoburn_imgen_opts * opts,uint32_t * num_blocks)1625 int isoburn_igopt_get_tail_blocks(struct isoburn_imgen_opts *opts,
1626                                   uint32_t *num_blocks)
1627 {
1628   *num_blocks = opts->tail_blocks;
1629   return 1;
1630 }
1631 
1632 
isoburn_igopt_set_prep_partition(struct isoburn_imgen_opts * o,char * path,int flag)1633 int isoburn_igopt_set_prep_partition(struct isoburn_imgen_opts *o,
1634                                      char *path, int flag)
1635 {
1636  if(o->prep_partition != NULL)
1637    free(o->prep_partition);
1638  o->prep_partition= NULL;
1639  o->prep_part_flag= 0;
1640  if(path != NULL) {
1641    o->prep_partition= strdup(path);
1642    if(o->prep_partition == NULL) {
1643      isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0);
1644      return(-1);
1645    }
1646  }
1647  o->prep_part_flag= flag & 1;
1648  return(1);
1649 }
1650 
1651 
isoburn_igopt_get_prep_partition(struct isoburn_imgen_opts * opts,char ** path,int flag)1652 int isoburn_igopt_get_prep_partition(struct isoburn_imgen_opts *opts,
1653                                      char **path, int flag)
1654 {
1655  *path= opts->prep_partition;
1656  if(flag & 1)
1657    return(1 + (opts->prep_part_flag & 0x3fffffff));
1658  return(1);
1659 }
1660 
1661 
isoburn_igopt_set_efi_bootp(struct isoburn_imgen_opts * o,char * path,int flag)1662 int isoburn_igopt_set_efi_bootp(struct isoburn_imgen_opts *o,
1663                                 char *path, int flag)
1664 {
1665  if(o->efi_boot_partition != NULL)
1666    free(o->efi_boot_partition);
1667  o->efi_boot_partition= NULL;
1668  o->efi_boot_part_flag= 0;
1669  if(path != NULL) {
1670    o->efi_boot_partition= strdup(path);
1671    if(o->efi_boot_partition == NULL) {
1672      isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0);
1673      return(-1);
1674    }
1675  }
1676  o->efi_boot_part_flag = flag & 1;
1677  return(1);
1678 }
1679 
1680 
isoburn_igopt_get_efi_bootp(struct isoburn_imgen_opts * opts,char ** path,int flag)1681 int isoburn_igopt_get_efi_bootp(struct isoburn_imgen_opts *opts,
1682                                 char **path, int flag)
1683 {
1684  *path= opts->efi_boot_partition;
1685  if(flag & 1)
1686    return(1 + (opts->efi_boot_part_flag & 0x3fffffff));
1687  return(1);
1688 }
1689 
1690 
isoburn_igopt_set_partition_img(struct isoburn_imgen_opts * opts,int partition_number,uint8_t partition_type,char * image_path)1691 int isoburn_igopt_set_partition_img(struct isoburn_imgen_opts *opts,
1692                                   int partition_number, uint8_t partition_type,
1693                                   char *image_path)
1694 {
1695  char msg[80];
1696 
1697  if (partition_number < 1 ||
1698      partition_number > Libisoburn_max_appended_partitionS) {
1699    sprintf(msg, "Partition number is out of range (1 ... %d)",
1700            Libisoburn_max_appended_partitionS);
1701    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
1702    return(0);
1703  }
1704  if (opts->appended_partitions[partition_number - 1] != NULL)
1705    free(opts->appended_partitions[partition_number - 1]);
1706  opts->appended_partitions[partition_number - 1] = strdup(image_path);
1707  if (opts->appended_partitions[partition_number - 1] == NULL)
1708    return(-1);
1709  opts->appended_part_types[partition_number - 1] = partition_type;
1710  return(1);
1711 }
1712 
1713 
isoburn_igopt_get_partition_img(struct isoburn_imgen_opts * opts,int num_entries,uint8_t partition_types[],char * image_paths[])1714 int isoburn_igopt_get_partition_img(struct isoburn_imgen_opts *opts,
1715                                     int num_entries,
1716                                     uint8_t partition_types[],
1717                                     char *image_paths[])
1718 {
1719  int i, max_entry= 0;
1720 
1721  for(i= 0; i < num_entries; i++)
1722    image_paths[i]= NULL;
1723  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
1724    if(opts->appended_partitions[i] == NULL)
1725  continue;
1726    if(i < num_entries) {
1727      image_paths[i]= opts->appended_partitions[i];
1728      partition_types[i]= opts->appended_part_types[i];
1729    }
1730    max_entry= i + 1;
1731  }
1732  return(max_entry);
1733 }
1734 
1735 
isoburn_igopt_set_part_flag(struct isoburn_imgen_opts * opts,int partition_number,int flag)1736 int isoburn_igopt_set_part_flag(struct isoburn_imgen_opts *opts,
1737                                 int partition_number, int flag)
1738 {
1739  char msg[80];
1740 
1741  if (partition_number < 1 ||
1742      partition_number > Libisoburn_max_appended_partitionS) {
1743    sprintf(msg, "Partition number is out of range (1 ... %d)",
1744            Libisoburn_max_appended_partitionS);
1745    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
1746    return(0);
1747  }
1748  opts->appended_part_flags[partition_number - 1]= flag;
1749  return(1);
1750 }
1751 
1752 
isoburn_igopt_get_part_flags(struct isoburn_imgen_opts * opts,int num_entries,int part_flags[])1753 int isoburn_igopt_get_part_flags(struct isoburn_imgen_opts *opts,
1754                                  int num_entries, int part_flags[])
1755 {
1756  int i, max_entry= 0;
1757 
1758  for(i= 0; i < num_entries; i++)
1759    part_flags[i]= 0;
1760  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
1761    if(i < num_entries)
1762      part_flags[i]= opts->appended_part_flags[i];
1763    max_entry= i + 1;
1764  }
1765  return(max_entry);
1766 }
1767 
1768 
isoburn_igopt_set_appended_as_gpt(struct isoburn_imgen_opts * opts,int gpt)1769 int isoburn_igopt_set_appended_as_gpt(struct isoburn_imgen_opts *opts, int gpt)
1770 {
1771  opts->appended_as_gpt= !!gpt;
1772  return(1);
1773 }
1774 
1775 
isoburn_igopt_get_appended_as_gpt(struct isoburn_imgen_opts * opts,int * gpt)1776 int isoburn_igopt_get_appended_as_gpt(struct isoburn_imgen_opts *opts,
1777                                       int *gpt)
1778 {
1779  *gpt= opts->appended_as_gpt;
1780  return(1);
1781 }
1782 
1783 
isoburn_igopt_set_appended_as_apm(struct isoburn_imgen_opts * opts,int apm)1784 int isoburn_igopt_set_appended_as_apm(struct isoburn_imgen_opts *opts, int apm)
1785 {
1786  opts->appended_as_apm= !!apm;
1787  return(1);
1788 }
1789 
1790 
isoburn_igopt_get_appended_as_apm(struct isoburn_imgen_opts * opts,int * apm)1791 int isoburn_igopt_get_appended_as_apm(struct isoburn_imgen_opts *opts,
1792                                       int *apm)
1793 {
1794  *apm= opts->appended_as_apm;
1795  return(1);
1796 }
1797 
1798 
isoburn_igopt_set_part_like_isohybrid(struct isoburn_imgen_opts * opts,int alike)1799 int isoburn_igopt_set_part_like_isohybrid(struct isoburn_imgen_opts *opts,
1800                                           int alike)
1801 {
1802  opts->part_like_isohybrid= !!alike;
1803  return(1);
1804 }
1805 
1806 
isoburn_igopt_get_part_like_isohybrid(struct isoburn_imgen_opts * opts,int * alike)1807 int isoburn_igopt_get_part_like_isohybrid(struct isoburn_imgen_opts *opts,
1808                                           int *alike)
1809 {
1810  *alike= opts->part_like_isohybrid;
1811  return(1);
1812 }
1813 
1814 
isoburn_igopt_set_iso_mbr_part_type(struct isoburn_imgen_opts * opts,int part_type)1815 int isoburn_igopt_set_iso_mbr_part_type(struct isoburn_imgen_opts *opts,
1816                                         int part_type)
1817 {
1818  if(part_type < -1 || part_type > 255)
1819    part_type = -1;
1820  opts->iso_mbr_part_type = part_type;
1821  return(1);
1822 }
1823 
1824 
isoburn_igopt_get_iso_mbr_part_type(struct isoburn_imgen_opts * opts,int * part_type)1825 int isoburn_igopt_get_iso_mbr_part_type(struct isoburn_imgen_opts *opts,
1826                                         int *part_type)
1827 {
1828  *part_type= opts->iso_mbr_part_type;
1829  return(1);
1830 }
1831 
1832 
isoburn_igopt_set_gpt_guid(struct isoburn_imgen_opts * opts,uint8_t guid[16],int mode)1833 int isoburn_igopt_set_gpt_guid(struct isoburn_imgen_opts *opts,
1834                                uint8_t guid[16], int mode)
1835 {
1836  if(mode < 0 || mode > 2) {
1837    isoburn_msgs_submit(NULL, 0x00060000,
1838                        "Unrecognized GPT disk GUID setup mode. (0 ... 2)",
1839                        0, "FAILURE", 0);
1840    return(0);
1841  }
1842  opts->gpt_guid_mode= mode;
1843  if(opts->gpt_guid_mode == 1)
1844     memcpy(opts->gpt_guid, guid, 16);
1845  return 1;
1846 }
1847 
1848 
isoburn_igopt_get_gpt_guid(struct isoburn_imgen_opts * opts,uint8_t guid[16],int * mode)1849 int isoburn_igopt_get_gpt_guid(struct isoburn_imgen_opts *opts,
1850                                uint8_t guid[16], int *mode)
1851 {
1852  if(opts->gpt_guid_mode == 1)
1853    memcpy(guid, opts->gpt_guid, 16);
1854  *mode = opts->gpt_guid_mode;
1855  return(1);
1856 }
1857 
1858 
isoburn_igopt_set_disc_label(struct isoburn_imgen_opts * opts,char * label)1859 int isoburn_igopt_set_disc_label(struct isoburn_imgen_opts *opts, char *label)
1860 {
1861     strncpy(opts->ascii_disc_label, label, Libisoburn_disc_label_sizE - 1);
1862     opts->ascii_disc_label[Libisoburn_disc_label_sizE - 1] = 0;
1863     return(1);
1864 }
1865 
1866 
isoburn_igopt_get_disc_label(struct isoburn_imgen_opts * opts,char ** label)1867 int isoburn_igopt_get_disc_label(struct isoburn_imgen_opts *opts, char **label)
1868 {
1869     *label= opts->ascii_disc_label;
1870     return(1);
1871 }
1872 
1873 
isoburn_igopt_set_hfsp_serial_number(struct isoburn_imgen_opts * opts,uint8_t serial_number[8])1874 int isoburn_igopt_set_hfsp_serial_number(struct isoburn_imgen_opts *opts,
1875                                          uint8_t serial_number[8])
1876 {
1877  memcpy(opts->hfsp_serial_number, serial_number, 8);
1878  return(1);
1879 }
1880 
1881 
isoburn_igopt_get_hfsp_serial_number(struct isoburn_imgen_opts * opts,uint8_t serial_number[8])1882 int isoburn_igopt_get_hfsp_serial_number(struct isoburn_imgen_opts *opts,
1883                                          uint8_t serial_number[8])
1884 {
1885  memcpy(serial_number, opts->hfsp_serial_number, 8);
1886  return(1);
1887 }
1888 
1889 
isoburn_igopt_set_hfsp_block_size(struct isoburn_imgen_opts * opts,int hfsp_block_size,int apm_block_size)1890 int isoburn_igopt_set_hfsp_block_size(struct isoburn_imgen_opts *opts,
1891                                       int hfsp_block_size, int apm_block_size)
1892 {
1893  char msg[80];
1894 
1895  msg[0]= 0;
1896  if(hfsp_block_size != -1) {
1897    if(hfsp_block_size != 0 && hfsp_block_size != 512 &&
1898        hfsp_block_size != 2048) {
1899      sprintf(msg, "Not a supported HFS+ size (%d <-> 0, 512, 2048)",
1900                   hfsp_block_size);
1901      isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
1902    }
1903    opts->hfsp_block_size = hfsp_block_size;
1904  }
1905  if(apm_block_size != -1) {
1906    if(apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048) {
1907      sprintf(msg, "Not a supported APM block size (%d <-> 0, 512, 2048)",
1908                   apm_block_size);
1909      isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
1910    }
1911    opts->apm_block_size = apm_block_size;
1912  }
1913  if(msg[0])
1914    return(0);
1915  return(1);
1916 }
1917 
1918 
isoburn_igopt_get_hfsp_block_size(struct isoburn_imgen_opts * opts,int * hfsp_block_size,int * apm_block_size)1919 int isoburn_igopt_get_hfsp_block_size(struct isoburn_imgen_opts *opts,
1920                                      int *hfsp_block_size, int *apm_block_size)
1921 {
1922  *hfsp_block_size= opts->hfsp_block_size;
1923  *apm_block_size= opts->apm_block_size;
1924  return(1);
1925 }
1926 
1927 
isoburn_igopt_set_write_type(struct isoburn_imgen_opts * opts,int do_tao)1928 int isoburn_igopt_set_write_type(struct isoburn_imgen_opts *opts, int do_tao)
1929 {
1930  if(do_tao < -1 || do_tao > 1)
1931    return(0);
1932  opts->do_tao= do_tao;
1933  return(1);
1934 }
1935 
1936 
isoburn_igopt_get_write_type(struct isoburn_imgen_opts * opts,int * do_tao)1937 int isoburn_igopt_get_write_type(struct isoburn_imgen_opts *opts, int *do_tao)
1938 {
1939  *do_tao= opts->do_tao;
1940  return(1);
1941 }
1942 
isoburn_igopt_set_stdio_endsync(struct isoburn_imgen_opts * opts,int do_sync)1943 int isoburn_igopt_set_stdio_endsync(struct isoburn_imgen_opts *opts,
1944                                   int do_sync)
1945 {
1946  opts->do_fsync= !!do_sync;
1947  return(1);
1948 }
1949 
isoburn_igopt_get_stdio_endsync(struct isoburn_imgen_opts * opts,int * do_sync)1950 int isoburn_igopt_get_stdio_endsync(struct isoburn_imgen_opts *opts,
1951                                   int *do_sync)
1952 {
1953  *do_sync= opts->do_fsync;
1954  return(1);
1955 }
1956 
isoburn_conv_name_chars(struct isoburn_imgen_opts * opts,char * name,size_t name_len,char ** result,size_t * result_len,int flag)1957 int isoburn_conv_name_chars(struct isoburn_imgen_opts *opts,
1958                             char *name, size_t name_len,
1959                             char **result, size_t *result_len, int flag)
1960 {
1961  int ret;
1962  IsoWriteOpts *wopts= NULL;
1963 
1964  ret = iso_write_opts_new(&wopts, 0);
1965  if (ret < 0) {
1966    isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0);
1967    goto ex;
1968  }
1969  ret= isoburn_make_iso_write_opts(NULL, opts, 0, wopts, 0);
1970  if(ret < 0)
1971    goto ex;
1972  ret= iso_conv_name_chars(wopts, name, name_len, result, result_len, flag);
1973 ex:;
1974  if(wopts != NULL)
1975    iso_write_opts_free(wopts);
1976  return(ret);
1977 }
1978