"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/libisoburn/isoburn.c" (30 Jan 2021, 56167 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "isoburn.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.5.4.

    1 
    2 /*
    3   cc -g -c isoburn.c
    4 */
    5 
    6 /*
    7   Class core of libisoburn.
    8 
    9   Copyright 2007 - 2009 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
   10   Copyright 2007 - 2020 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 
   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 */
   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 
  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 
  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 
  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 
  230 int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag)
  231 {
  232  *pt= o->image;
  233  return(1);
  234 }
  235 
  236 
  237 int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag)
  238 {
  239  *pt= o->prev;
  240  return(1);
  241 }
  242 
  243 
  244 int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag)
  245 {
  246  *pt= o->next;
  247  return(1);
  248 }
  249 
  250 
  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 
  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 
  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 
  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 
  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 */
  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
  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    iso_write_opts_set_part_type_guid(wopts, i + 1,
  558                                      opts->appended_part_type_guids[i],
  559                                      opts->appended_part_gpt_flags[i] & 1);
  560  }
  561  iso_write_opts_set_appended_as_gpt(wopts, opts->appended_as_gpt);
  562  iso_write_opts_set_appended_as_apm(wopts, opts->appended_as_apm);
  563  iso_write_opts_set_part_like_isohybrid(wopts, opts->part_like_isohybrid);
  564  iso_write_opts_set_iso_mbr_part_type(wopts, opts->iso_mbr_part_type);
  565  iso_write_opts_set_iso_type_guid(wopts, opts->iso_gpt_type_guid, 
  566                                   opts->iso_gpt_flag & 1);
  567  iso_write_opts_set_disc_label(wopts, opts->ascii_disc_label);
  568 
  569  ret= 1;
  570 ex:
  571  return(ret);
  572 }
  573 
  574 
  575 /* @param flag bit0= modifying rather than growing
  576                bit1= prepare for early release of input drive:
  577                      wait until input and then disable image data source
  578 */
  579 static
  580 int isoburn_prepare_disc_aux(struct burn_drive *in_d, struct burn_drive *out_d,
  581                              struct burn_disc **disc,
  582                              struct isoburn_imgen_opts *opts, int flag)
  583 {
  584  struct burn_source *wsrc;
  585  struct burn_session *session;
  586  struct burn_track *track;
  587  struct isoburn *in_o, *out_o;
  588  IsoWriteOpts *wopts= NULL;
  589  enum burn_disc_status state;
  590  int ret, fifo_chunks, i, new_img, early_indev_release;
  591  uint32_t data_start= -1;
  592  size_t buffer_size= 0, buffer_free= 0;
  593  char *msg= NULL;
  594 
  595  msg= calloc(1, 160);
  596  if(msg == NULL)
  597    {ret= -1; goto ex;}
  598 
  599  new_img= flag&1;
  600  early_indev_release= flag&2;
  601 
  602  ret= isoburn_find_emulator(&in_o, in_d, 0);
  603  if(ret<0 || in_o==NULL)
  604    {ret= -1; goto ex;}
  605  ret= isoburn_find_emulator(&out_o, out_d, 0);
  606  if(ret<0 || out_o==NULL)
  607    {ret= -1; goto ex;}
  608  /* early end will be registered as failure */
  609  in_o->wrote_well= out_o->wrote_well= 0;
  610 
  611  if(new_img && early_indev_release) {
  612    isoburn_msgs_submit(in_o, 0x00060000,
  613       "Programming error: Wrong session setup: new_img && early_indev_release",
  614                        0, "FATAL", 0);
  615    {ret= -4; goto ex;}
  616  }
  617 
  618  out_o->do_tao = opts->do_tao;
  619  out_o->do_fsync = opts->do_fsync;
  620 
  621  state = isoburn_disc_get_status(in_d);
  622  if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE &&
  623      state != BURN_DISC_FULL) {
  624    isoburn_msgs_submit(in_o, 0x00060000, "Unsuitable source media state",
  625                     0, "FAILURE", 0);
  626    {ret= -2; goto ex;}
  627  }
  628  state = isoburn_disc_get_status(out_d);
  629  if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) {
  630    isoburn_msgs_submit(out_o, 0x00060000, "Unsuitable target media state",
  631                     0, "FAILURE", 0);
  632    {ret= -2; goto ex;}
  633  }
  634  if (state != BURN_DISC_BLANK && opts->libjte_handle != NULL) {
  635    isoburn_msgs_submit(out_o, 0x00060000,
  636                   "Jigdo Template Extraction works only on blank target media",
  637                   0, "FAILURE", 0);
  638    {ret= -2; goto ex;}
  639  }
  640  
  641  fifo_chunks= 32;
  642  if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){
  643    fifo_chunks= opts->fifo_size/2048;
  644    if(fifo_chunks*2048 < opts->fifo_size)
  645      fifo_chunks++;
  646  }
  647 
  648  ret= iso_write_opts_new(&wopts, 0);
  649  if (ret < 0) {
  650    isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0);
  651    goto ex;
  652  }
  653  ret= isoburn_make_iso_write_opts(out_o, opts, fifo_chunks, wopts, flag & 1);
  654  if(ret < 0)
  655    goto ex;
  656 
  657  ret = iso_image_create_burn_source(in_o->image, wopts, &wsrc);
  658  if (ret < 0) {
  659    isoburn_report_iso_error(ret, "Cannot create burn source", 0, "FAILURE", 0);
  660    {ret= -1; goto ex;}
  661  }
  662  if (early_indev_release) {
  663    for(i= 0; i<300; i++) {
  664 
  665      /* <<< ??? */
  666      if((i%30) == 0) {
  667        sprintf(msg, "Waiting for data in fifo since %d seconds", i/30);
  668        isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
  669      }
  670 
  671      usleep(100000);
  672      ret= iso_ring_buffer_get_status(wsrc, &buffer_size, &buffer_free);
  673      if(ret >0 && buffer_size != buffer_free)
  674    break;
  675    }
  676 
  677    /* <<< ??? */
  678    sprintf(msg,
  679            "After %.1f seconds: %d bytes of output available (fifo state=%d)",
  680            ((double) i+1) / 10.0, (int) (buffer_size - buffer_free), ret);
  681    isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
  682 
  683    if(in_o->iso_data_source!=NULL)
  684      isoburn_data_source_shutdown(in_o->iso_data_source, 0);
  685  }
  686 
  687  ret= iso_write_opts_get_data_start(wopts, &data_start, 0);
  688  opts->data_start_lba= -1;
  689  if(ret > 0 && data_start <= 0x7FFFFFFF)
  690    opts->data_start_lba= data_start;
  691  
  692  /* TODO check return values for failure. properly clean-up on error */
  693 
  694  out_o->iso_source= wsrc;
  695 
  696  *disc = burn_disc_create();
  697  session = burn_session_create();
  698  burn_disc_add_session(*disc, session, BURN_POS_END);
  699  track = burn_track_create();
  700  burn_track_set_source(track, out_o->iso_source);
  701  burn_session_add_track(session, track, BURN_POS_END);
  702 
  703  /* give up local references */
  704  burn_track_free(track);
  705  burn_session_free(session);
  706 
  707  in_o->wrote_well= out_o->wrote_well= -1; /* neutral */
  708  ret= 1;
  709 ex:
  710  if(wopts!=NULL)
  711    {iso_write_opts_free(wopts); wopts= NULL;}
  712  if(msg != NULL)
  713    free(msg);
  714  return ret;
  715 }
  716 
  717 
  718 int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc,
  719                          struct isoburn_imgen_opts *opts)
  720 {
  721  return isoburn_prepare_disc_aux(d, d, disc, opts, 0);
  722 }
  723 
  724 
  725 int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc,
  726                          struct isoburn_imgen_opts *opts,
  727                          struct burn_drive *out_drive)
  728 {
  729  int ret;
  730 
  731  ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 1);
  732  if (ret<=0)
  733    return ret;
  734  return 1; 
  735 }
  736 
  737 
  738 /* API since 0.2.2 */
  739 int isoburn_prepare_blind_grow(struct burn_drive *d, struct burn_disc **disc,
  740                                struct isoburn_imgen_opts *opts,
  741                                struct burn_drive *out_drive, int nwa)
  742 {  
  743  int ret;
  744  struct isoburn *o= NULL;
  745 
  746  ret= isoburn_find_emulator(&o, out_drive, 0);
  747  if(ret<0 || o==NULL)
  748    return(-1);
  749  if(nwa >= 0)
  750    o->fabricated_msc2= nwa;
  751  if(o->nwa == o->zero_nwa)
  752    o->nwa= o->zero_nwa= 0;
  753  else
  754    o->zero_nwa= 0;
  755  o->min_start_byte= 0;
  756  ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 2);
  757  if (ret<=0)
  758    return ret;
  759  return(1);
  760 }
  761 
  762 
  763 /* API @since 0.1.0
  764    @param flag bit0= this is a regular end, not an abort
  765                      give up source reference
  766 */
  767 int isoburn_cancel_prepared_write(struct burn_drive *d,
  768                                   struct burn_drive *output_drive, int flag)
  769 {
  770  int ret;
  771  struct isoburn *o= NULL;
  772 
  773  if(output_drive!=NULL) {
  774    ret= isoburn_find_emulator(&o, output_drive, 0);
  775    if(ret<0 || o==NULL)
  776      o= NULL;
  777    else if(o->iso_source==NULL)
  778      o= NULL;
  779  }
  780  if(o==NULL) {
  781    ret= isoburn_find_emulator(&o, d, 0);
  782    if(ret<0)
  783      return(-1);
  784    if(o==NULL)
  785      return(0);
  786    if(o->iso_source==NULL)
  787      return(0);
  788  }
  789  if(o->iso_source->read!=NULL)
  790    return(0);
  791  if(o->iso_source->version<1)
  792    return(0);
  793  o->iso_source->cancel(o->iso_source);
  794  burn_source_free(o->iso_source);
  795  o->iso_source= NULL;
  796  return(1);
  797 }
  798 
  799 
  800 /* API @since 0.1.0 */
  801 int isoburn_sync_after_write(struct burn_drive *d,
  802                              struct burn_drive *output_drive, int flag)
  803 {
  804  return isoburn_cancel_prepared_write(d, output_drive, 1);
  805 }
  806 
  807 
  808 void isoburn_version(int *major, int *minor, int *micro)
  809 {
  810  *major= isoburn_header_version_major;
  811  *minor= isoburn_header_version_minor;
  812  *micro= isoburn_header_version_micro;
  813 
  814 /* No more: values from version.h generated from version.h.in and
  815             macro values defined in configure.ac
  816 
  817  *major = ISOBURN_MAJOR_VERSION;
  818  *minor = ISOBURN_MINOR_VERSION;
  819  *micro = ISOBURN_MICRO_VERSION;
  820 */
  821 }
  822 
  823 
  824 int isoburn_is_compatible(int major, int minor, int micro, int flag)
  825 {
  826  int own_major, own_minor, own_micro;
  827 
  828  isoburn_version(&own_major, &own_minor, &own_micro);
  829  return(own_major > major ||
  830         (own_major == major && (own_minor > minor ||
  831          (own_minor == minor && own_micro >= micro))));
  832 }
  833 
  834 
  835 /* ----------------------------------------------------------------------- */
  836 /*
  837   Options for image reading.
  838 */
  839 /* ----------------------------------------------------------------------- */
  840 
  841 
  842 int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag)
  843 {
  844  struct isoburn_read_opts *o;
  845 
  846  o= (*new_o)= calloc(1, sizeof(struct isoburn_read_opts));
  847  if(o==NULL) {
  848    isoburn_msgs_submit(NULL, 0x00060000,
  849                      "Cannot allocate memory for read options", 0, "FATAL", 0);
  850    return(-1);
  851  }
  852  o->cache_tiles= Libisoburn_default_cache_tileS;
  853  o->cache_tile_blocks= Libisoburn_default_tile_blockS;
  854  o->norock= 0;
  855  o->nojoliet= 0;
  856  o->noiso1999= 1;
  857  o->do_ecma119_map= 0;
  858  o->map_mode= 1;
  859  o->do_joliet_map= 0;
  860  o->joliet_map_mode= 1;
  861  o->noaaip= 1;
  862  o->noacl= 1;
  863  o->noea= 1;
  864  o->noino= 1;
  865  o->nomd5= 1;
  866  o->preferjoliet= 0;
  867  o->uid= geteuid();
  868  o->gid= getegid();
  869  o->mode= 0444;
  870  o->dirmode= 0555;
  871  o->input_charset= NULL;
  872  o->truncate_mode= 1;
  873  o->truncate_length= 255;
  874  o->hasRR= 0;
  875  o->hasJoliet= 0;
  876  o->hasIso1999= 0;
  877  o->hasElTorito= 0;
  878  o->size= 0;
  879  o->pretend_blank= 1;
  880  o->displacement= 0;
  881  o->displacement_sign= 0;
  882  return(1);
  883 }
  884 
  885 
  886 int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag)
  887 {
  888  if(*o==NULL)
  889    return(0);
  890  free(*o);
  891  *o= NULL;
  892  return(1);
  893 }
  894 
  895 
  896 int isoburn_ropt_set_data_cache(struct isoburn_read_opts *o,
  897                                 int cache_tiles, int tile_blocks, int flag)
  898 {
  899  int i;
  900  char msg[80];
  901 
  902  if(cache_tiles < 1) {
  903    isoburn_msgs_submit(NULL, 0x00060000,
  904                      "Requested number of data cache tiles is too small (< 1)",
  905                      0, "SORRY", 0);
  906    return(0);
  907  }  
  908  if(((double) cache_tiles) * ((double) tile_blocks)
  909      > (double) Libisoburn_cache_max_sizE) {
  910    sprintf(msg, "Requested size of data cache exceeds limit of %.f blocks",
  911            (double) Libisoburn_cache_max_sizE);
  912    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "SORRY", 0);
  913    return(0);
  914  }
  915  for(i = 1; i <= Libisoburn_cache_max_sizE; i = i << 1)
  916    if(i == tile_blocks)
  917  break;
  918  if(i > Libisoburn_cache_max_sizE) {
  919    isoburn_msgs_submit(NULL, 0x00060000, 
  920          "Requested number of blocks per data cache tiles is not a power of 2",
  921          0, "SORRY", 0);
  922    return(0);
  923  }
  924  if(o != NULL) {
  925    o->cache_tiles= cache_tiles;
  926    o->cache_tile_blocks= tile_blocks;
  927  }
  928  return(1);
  929 } 
  930 
  931 
  932 int isoburn_ropt_get_data_cache(struct isoburn_read_opts *o,
  933                                  int *cache_tiles, int *tile_blocks,
  934                                  int *set_flag, int flag)
  935 {
  936  if((flag & 1) || o == NULL) {
  937    *cache_tiles= Libisoburn_default_cache_tileS;
  938    *tile_blocks= Libisoburn_default_tile_blockS;
  939    *set_flag= 0;
  940    return(1);
  941  }
  942  *cache_tiles= o->cache_tiles;
  943  *tile_blocks= o->cache_tile_blocks;
  944  *set_flag= 0;
  945  return(1);
  946 }
  947 
  948 
  949 int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext)
  950 {
  951  o->norock= !!(ext&1);
  952  o->nojoliet= !!(ext&2);
  953  o->noiso1999= !!(ext&4);
  954  o->preferjoliet= !!(ext&8);
  955  o->pretend_blank= !!(ext&16);
  956  o->noaaip= !!(ext & 32);
  957  o->noacl= !!(ext & 64);
  958  o->noea= !!(ext & 128);
  959  o->noino= !!(ext & 256);
  960  o->nomd5= (ext >> 9) & 3;
  961  o->do_ecma119_map= !!(ext & 2048);
  962  o->map_mode= (ext >> 12) & 3;
  963  o->do_joliet_map= !!(ext & 16384);
  964  o->joliet_map_mode= !!(ext & 32768);
  965  return(1);
  966 }
  967 
  968 
  969 int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext)
  970 {
  971  *ext= (!!o->norock) | ((!!o->nojoliet)<<1) | ((!!o->noiso1999)<<2) |
  972        ((!!o->preferjoliet)<<3) | ((!!o->pretend_blank)<<4) |
  973        ((!!o->noaaip) << 5) | ((!!o->noacl) << 6) | ((!!o->noea) << 7) |
  974        ((!!o->noino) << 8) | ((o->nomd5 & 3) << 9) |
  975        ((!!o->do_ecma119_map) << 11) | ((o->map_mode & 3) << 12) |
  976        ((!!o->do_joliet_map) << 14) | ((!!o->joliet_map_mode) << 15);
  977  return(1);
  978 }
  979 
  980 
  981 int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o,
  982                                    uid_t uid, gid_t gid, mode_t mode)
  983 {
  984  mode_t dirmode;
  985 
  986  o->uid= uid;
  987  o->gid= gid;
  988  o->mode= mode;
  989  dirmode= mode;
  990  if(dirmode & S_IRUSR)
  991    dirmode|= S_IXUSR;
  992  if(dirmode & S_IRGRP)
  993    dirmode|= S_IXGRP;
  994  if(dirmode & S_IROTH)
  995    dirmode|= S_IXOTH;
  996  o->dirmode= dirmode;
  997  return(1);
  998 }
  999 
 1000 
 1001 int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o,
 1002                                    uid_t *uid, gid_t *gid, mode_t *mode)
 1003 {
 1004  *uid= o->uid;
 1005  *gid= o->gid;
 1006  *mode= o->mode;
 1007  return(1);
 1008 }
 1009 
 1010 
 1011 int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o,
 1012                                        mode_t mode)
 1013 {
 1014  o->dirmode= mode;
 1015  return(1);
 1016 }
 1017 
 1018 
 1019 int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o,
 1020                                       mode_t *mode)
 1021 {
 1022  *mode= o->dirmode;
 1023  return(1);
 1024 }
 1025 
 1026 
 1027 int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o,
 1028                                    char *input_charset)
 1029 {
 1030  o->input_charset= input_charset;
 1031  return(1);
 1032 }
 1033 
 1034 
 1035 int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o,
 1036                                    char **input_charset)
 1037 {
 1038  *input_charset= o->input_charset;
 1039  return(1);
 1040 }
 1041 
 1042 
 1043 int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode)
 1044 {
 1045  o->auto_input_charset= mode & 1;
 1046  return(1);
 1047 }
 1048 
 1049 
 1050 int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode)
 1051 {
 1052  *mode= o->auto_input_charset;
 1053  return(1);
 1054 }
 1055 
 1056 
 1057 int isoburn_ropt_set_displacement(struct isoburn_read_opts *o,
 1058                                uint32_t displacement, int displacement_sign)
 1059 {
 1060  o->displacement= displacement;
 1061  o->displacement_sign= displacement_sign;
 1062  return(1);
 1063 }
 1064 
 1065 
 1066 int isoburn_ropt_get_displacement(struct isoburn_read_opts *o,
 1067                                uint32_t *displacement, int *displacement_sign)
 1068 {
 1069  *displacement= o->displacement;
 1070  *displacement_sign= o->displacement_sign;
 1071  return(1);
 1072 }
 1073 
 1074 
 1075 int isoburn_ropt_set_truncate_mode(struct isoburn_read_opts *o,
 1076                                    int mode, int length)
 1077 {
 1078  if(mode < 0 || mode > 1)
 1079    mode= 1;
 1080  if(length < 64)
 1081    length= 64;
 1082  if(length > 255)
 1083    length= 255;
 1084  o->truncate_mode= mode;
 1085  o->truncate_length= length;
 1086  return(1);
 1087 }
 1088 
 1089 
 1090 int isoburn_ropt_get_truncate_mode(struct isoburn_read_opts *o,
 1091                                    int *mode, int *length)
 1092 {
 1093  *mode= o->truncate_mode;
 1094  *length= o->truncate_length;
 1095  return(1);
 1096 }
 1097 
 1098 
 1099 int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
 1100                                uint32_t *size, int *has_what)
 1101 {
 1102  *size= o->size;
 1103  *has_what= (!!o->hasRR) | ((!!o->hasJoliet)<<1) |
 1104             ((!!o->hasIso1999)<<2) | ((!!o->hasElTorito)<<3); 
 1105  return(1);
 1106 }
 1107 
 1108 
 1109 int isoburn_ropt_get_tree_loaded(struct isoburn_read_opts *o,
 1110                                  int *tree, int *rr)
 1111 {
 1112  *tree= o->tree_loaded;
 1113  *rr= o->rr_loaded;
 1114  return(1);
 1115 }
 1116 
 1117 
 1118 /* ----------------------------------------------------------------------- */
 1119 /*
 1120   Options for image generation by libisofs and image transport to libburn.
 1121 */
 1122 /* ----------------------------------------------------------------------- */
 1123 
 1124 
 1125 int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag)
 1126 {
 1127  struct isoburn_imgen_opts *o;
 1128  int i;
 1129 
 1130  o= (*new_o)= calloc(1, sizeof(struct isoburn_imgen_opts));
 1131  if(o==NULL) {
 1132    isoburn_msgs_submit(NULL, 0x00060000,
 1133                        "Cannot allocate memory for image generation options",
 1134                        0, "FATAL", 0);
 1135    return(-1);
 1136  }
 1137  o->level= 2;
 1138  o->rockridge= 1;
 1139  o->joliet= 0;
 1140  o->iso1999= 0;
 1141  o->hardlinks= 0;
 1142  o->aaip = 0;
 1143  o->session_md5= 0;
 1144  o->file_md5= 0;
 1145  o->no_emul_toc= 0;
 1146  o->old_empty= 0;
 1147  o->untranslated_name_len = 0;
 1148  o->allow_dir_id_ext = 0;
 1149  o->omit_version_numbers= 0;
 1150  o->allow_deep_paths= 1;
 1151  o->rr_reloc_dir= NULL;
 1152  o->rr_reloc_flags= 0;
 1153  o->allow_longer_paths= 0;
 1154  o->max_37_char_filenames= 0;
 1155  o->no_force_dots= 0;
 1156  o->allow_lowercase= 0;
 1157  o->allow_full_ascii= 0;
 1158  o->allow_7bit_ascii= 0;
 1159  o->joliet_longer_paths= 0;
 1160  o->joliet_long_names= 0;
 1161  o->joliet_utf16= 0;
 1162  o->always_gmt= 0;
 1163  o->rrip_version_1_10= 0;
 1164  o->dir_rec_mtime= 0;
 1165  o->aaip_susp_1_10= 0;
 1166  o->sort_files= 0;
 1167  o->replace_dir_mode= 0;
 1168  o->replace_file_mode= 0;
 1169  o->replace_uid= 0;
 1170  o->replace_gid= 0;
 1171  o->dir_mode= 0555;
 1172  o->file_mode= 0444;
 1173  o->uid= 0;
 1174  o->gid= 0;
 1175  o->output_charset= NULL;
 1176  o->fifo_size= 4*1024*1024;
 1177  o->effective_lba= -1;
 1178  o->data_start_lba= -1;
 1179  o->system_area_data= NULL;
 1180  o->system_area_options= 0;
 1181  o->partition_offset= 0;
 1182  o->partition_secs_per_head= 0;
 1183  o->partition_heads_per_cyl= 0;
 1184  o->vol_creation_time= 0;
 1185  o->vol_modification_time= 0;
 1186  o->vol_expiration_time= 0;
 1187  o->vol_effective_time= 0;
 1188  o->libjte_handle= NULL;
 1189  o->tail_blocks= 0;
 1190  o->prep_partition= NULL;
 1191  o->prep_part_flag= 0;
 1192  o->efi_boot_partition= NULL;
 1193  o->efi_boot_part_flag= 0;
 1194  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
 1195    o->appended_partitions[i]= NULL;
 1196    o->appended_part_types[i]= 0;
 1197    o->appended_part_flags[i]= 0;
 1198    memset(o->appended_part_type_guids[i], 0, 16);
 1199    o->appended_part_gpt_flags[i]= 0;
 1200  }
 1201  o->appended_as_gpt= 0;
 1202  o->appended_as_apm= 0;
 1203  o->part_like_isohybrid= 0;
 1204  o->iso_mbr_part_type= -1;
 1205  memset(o->gpt_guid, 0, 16);
 1206  o->gpt_guid_mode= 0;
 1207  memset(o->hfsp_serial_number, 0, 8);
 1208  o->hfsp_block_size= 0;
 1209  o->apm_block_size= 0;
 1210  o->do_tao= 0;
 1211  o->do_fsync= 0;
 1212  return(1);
 1213 }
 1214 
 1215 
 1216 int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag)
 1217 {
 1218  int i;
 1219 
 1220  if(*o==NULL)
 1221    return(0);
 1222  if((*o)->rr_reloc_dir != NULL)
 1223    free((*o)->rr_reloc_dir);
 1224  if((*o)->prep_partition != NULL)
 1225    free((*o)->prep_partition);
 1226  if((*o)->efi_boot_partition != NULL)
 1227    free((*o)->efi_boot_partition);
 1228  for(i= 0; i < Libisoburn_max_appended_partitionS; i++)
 1229    if((*o)->appended_partitions[i] != NULL)
 1230      free((*o)->appended_partitions[i]);
 1231  if ((*o)->system_area_data != NULL)
 1232      free((*o)->system_area_data);
 1233  free(*o);
 1234  *o= NULL;
 1235  return(1);
 1236 }
 1237 
 1238 
 1239 int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level)
 1240 {
 1241  o->level= level;
 1242  return(1);
 1243 }
 1244 
 1245 
 1246 int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level)
 1247 {
 1248  *level= o->level;
 1249  return(1);
 1250 }
 1251 
 1252 
 1253 int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext)
 1254 {
 1255  o->rockridge= !!(ext&1);
 1256  o->joliet= !!(ext&2);
 1257  o->iso1999= !!(ext&4);
 1258  o->hardlinks= !!(ext & 8);
 1259  o->aaip= !!(ext & 32);
 1260  o->session_md5= !!(ext & 64);
 1261  o->file_md5= (ext & (128 | 256)) >> 7;
 1262  o->no_emul_toc= !!(ext & 512);
 1263  o->will_cancel= !!(ext & 1024);
 1264  o->old_empty= !!(ext & 2048);
 1265  o->hfsplus= !!(ext & 4096);
 1266  o->fat= !!(ext & 8192);
 1267  return(1);
 1268 }
 1269 
 1270 
 1271 int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext)
 1272 {
 1273  *ext= (!!o->rockridge) | ((!!o->joliet)<<1) | ((!!o->iso1999)<<2) |
 1274        ((!!o->hardlinks) << 3) | ((!!o->aaip) << 5) |
 1275        ((!!o->session_md5) << 6) | ((o->file_md5 & 3) << 7) |
 1276        ((!!o->no_emul_toc) << 9) | ((o->will_cancel) << 10) |
 1277        ((!!o->old_empty) << 11) | ((!!o->hfsplus) << 12) |
 1278        ((!!o->fat) << 13);
 1279  return(1);
 1280 }
 1281 
 1282 
 1283 int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax)
 1284 {
 1285  o->omit_version_numbers= (!!(relax&1)) |
 1286                           (2 * !!(relax & isoburn_igopt_only_iso_versions));
 1287  o->allow_deep_paths= !!(relax&2);
 1288  o->allow_longer_paths= !!(relax&4);
 1289  o->max_37_char_filenames= !!(relax&8);
 1290  o->no_force_dots= (!!(relax&16)) |
 1291                    (2 * !!(relax & isoburn_igopt_no_j_force_dots));
 1292  o->allow_lowercase= !!(relax&32);
 1293  o->allow_full_ascii= !!(relax&64);
 1294  o->joliet_longer_paths= !!(relax&128);
 1295  o->always_gmt= !!(relax & isoburn_igopt_always_gmt);
 1296  o->rrip_version_1_10= !!(relax & isoburn_igopt_rrip_version_1_10);
 1297  o->dir_rec_mtime= !!(relax & isoburn_igopt_dir_rec_mtime);
 1298  o->aaip_susp_1_10= !!(relax & isoburn_igopt_aaip_susp_1_10);
 1299  o->allow_dir_id_ext= !!(relax & isoburn_igopt_allow_dir_id_ext);
 1300  o->joliet_long_names= !!(relax & isoburn_igopt_joliet_long_names);
 1301  o->joliet_rec_mtime= !!(relax & isoburn_igopt_joliet_rec_mtime);
 1302  o->iso1999_rec_mtime= !!(relax & isoburn_igopt_iso1999_rec_mtime);
 1303  o->allow_7bit_ascii= !!(relax & isoburn_igopt_allow_7bit_ascii);
 1304  o->joliet_utf16= !!(relax & isoburn_igopt_joliet_utf16);
 1305  return(1);
 1306 }
 1307 
 1308 
 1309 int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax)
 1310 {
 1311  *relax= (!!o->omit_version_numbers)    | ((!!o->allow_deep_paths)<<1) |
 1312          ((!!o->allow_longer_paths)<<2) | ((!!o->max_37_char_filenames)<<3) |
 1313          ((!!(o->no_force_dots & 1))<<4)| ((!!o->allow_lowercase)<<5) |
 1314          ((!!o->allow_full_ascii)<<6)   | ((!!o->joliet_longer_paths)<<7) |
 1315          ((!!o->always_gmt)<<8)         | ((!!o->rrip_version_1_10)<<9) |
 1316          ((!!o->dir_rec_mtime)<<10)     | ((!!o->aaip_susp_1_10)<<11) |
 1317          ((!!(o->omit_version_numbers & 2))<<12) |
 1318          ((!!(o->no_force_dots & 2))<<13) |
 1319          ((!!o->allow_dir_id_ext) << 14) |
 1320          ((!!o->joliet_long_names) << 15) |
 1321          ((!!o->joliet_rec_mtime) << 16) |
 1322          ((!!o->iso1999_rec_mtime) << 17) |
 1323          ((!!o->allow_full_ascii) << 18) |
 1324          ((!!o->joliet_utf16) << 19);
 1325  return(1);
 1326 }
 1327 
 1328 
 1329 int isoburn_igopt_set_rr_reloc(struct isoburn_imgen_opts *o, char *name,
 1330                                int flags)
 1331 {
 1332  if(o->rr_reloc_dir != name) {
 1333    if(o->rr_reloc_dir != NULL)
 1334      free(o->rr_reloc_dir);
 1335    o->rr_reloc_dir= NULL;
 1336    if(name != NULL) {
 1337      o->rr_reloc_dir= strdup(name);
 1338      if(o->rr_reloc_dir == NULL) {
 1339        isoburn_msgs_submit(NULL, 0x00060000,
 1340                          "Cannot allocate memory for image generation options",
 1341                           0, "FATAL", 0);
 1342        return(-1);
 1343      }
 1344    }
 1345  }
 1346  o->rr_reloc_flags = flags & 1;
 1347  return 1;
 1348 }
 1349 
 1350 
 1351 int isoburn_igopt_get_rr_reloc(struct isoburn_imgen_opts *o, char **name,
 1352                                int *flags)
 1353 {
 1354  *name= o->rr_reloc_dir;
 1355  *flags= o->rr_reloc_flags;
 1356  return(1);
 1357 }
 1358 
 1359 
 1360 int isoburn_igopt_set_untranslated_name_len(struct isoburn_imgen_opts *o,
 1361                                             int len)
 1362 {
 1363  int ret;
 1364  IsoWriteOpts *opts = NULL;
 1365  char *msg= NULL;
 1366 
 1367  msg= calloc(1, 160);
 1368  if(msg == NULL)
 1369    {ret= -1; goto ex;}
 1370 
 1371  ret= iso_write_opts_new(&opts, 0);
 1372  if(ret < 0) {
 1373    isoburn_msgs_submit(NULL, 0x00060000,
 1374                  "Cannot create libisofs write options object", 0, "FATAL", 0);
 1375    {ret= 0; goto ex;}
 1376  }
 1377  ret= iso_write_opts_set_untranslated_name_len(opts, len);
 1378  if(ret < 0) {
 1379    ret= iso_write_opts_set_untranslated_name_len(opts, -1);
 1380    sprintf(msg,
 1381   "Improper value for maximum length of untranslated names (%d <-> -1 ... %d)",
 1382            len, ret);
 1383    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1384    iso_write_opts_free(opts);
 1385    {ret= 0; goto ex;}
 1386  }
 1387  o->untranslated_name_len= ret; /* Normalized len value */
 1388  iso_write_opts_free(opts);
 1389  ret= 1;
 1390 ex:;
 1391  if(msg != NULL)
 1392    free(msg);
 1393  return(ret);
 1394 }
 1395 
 1396 
 1397 int isoburn_igopt_get_untranslated_name_len(struct isoburn_imgen_opts *o,
 1398                                             int *len)
 1399 {
 1400  *len = o->untranslated_name_len;
 1401  return(1);
 1402 }
 1403 
 1404 
 1405 int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value)
 1406 {
 1407  o->sort_files= !!(value&1);
 1408  return(1);
 1409 }
 1410 
 1411 
 1412 int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value)
 1413 {
 1414  *value= !!o->sort_files;
 1415  return(1);
 1416 }
 1417 
 1418 
 1419 int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o,
 1420                                int replace_dir_mode, int replace_file_mode,
 1421                                mode_t dir_mode, mode_t file_mode)
 1422 {
 1423  o->replace_dir_mode= replace_dir_mode%3;
 1424  o->replace_file_mode= replace_file_mode%3;
 1425  o->dir_mode= dir_mode;
 1426  o->file_mode= file_mode;
 1427  return(1);
 1428 }
 1429 
 1430 
 1431 int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o,
 1432                                int *replace_dir_mode, int *replace_file_mode,
 1433                                mode_t *dir_mode, mode_t *file_mode)
 1434 {
 1435  *replace_dir_mode= o->replace_dir_mode%3;
 1436  *replace_file_mode= o->replace_file_mode%3;
 1437  *dir_mode= o->dir_mode;
 1438  *file_mode= o->file_mode;
 1439  return(1);
 1440 }
 1441 
 1442 
 1443 int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o,
 1444                                int replace_uid, int replace_gid,
 1445                                uid_t uid, gid_t gid)
 1446 {
 1447  o->replace_uid= replace_uid%3;
 1448  o->replace_gid= replace_gid%3;
 1449  o->uid= uid;
 1450  o->gid= gid;
 1451  return(1);
 1452 }
 1453 
 1454 int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o,
 1455                                int *replace_uid, int *replace_gid,
 1456                                uid_t *uid, gid_t *gid)
 1457 {
 1458  *replace_uid= o->replace_uid%3;
 1459  *replace_gid= o->replace_gid%3;
 1460  *uid= o->uid;
 1461  *gid= o->gid;
 1462  return(1);
 1463 }
 1464 
 1465 
 1466 int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o,
 1467                                  char *output_charset)
 1468 {
 1469  o->output_charset= output_charset;
 1470  return(1);
 1471 }
 1472 
 1473 
 1474 int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o,
 1475                                  char **output_charset)
 1476 {
 1477  *output_charset= o->output_charset;
 1478  return(1);
 1479 }
 1480 
 1481 
 1482 int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size)
 1483 {
 1484  o->fifo_size= fifo_size;
 1485  return(1);
 1486 }
 1487 
 1488 
 1489 int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size)
 1490 {
 1491  *fifo_size= o->fifo_size;
 1492  return(1);
 1493 }
 1494 
 1495 
 1496 int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba)
 1497 {
 1498  *lba= o->effective_lba;
 1499  return(1);
 1500 }
 1501 
 1502 
 1503 int isoburn_igopt_get_data_start(struct isoburn_imgen_opts *o, int *lba)
 1504 {
 1505  *lba= o->data_start_lba;
 1506  return(1);
 1507 }
 1508 
 1509 
 1510 int isoburn_igopt_set_scdbackup_tag(struct isoburn_imgen_opts *o, char *name,
 1511                                     char *timestamp, char *tag_written)
 1512 {
 1513  strncpy(o->scdbackup_tag_name, name, 80);
 1514  o->scdbackup_tag_name[80]= 0;
 1515  strncpy(o->scdbackup_tag_time, timestamp, 18);
 1516  o->scdbackup_tag_time[18]= 0;
 1517  o->scdbackup_tag_written = tag_written;
 1518  if(tag_written != NULL)
 1519    tag_written[0]= 0;
 1520  return(1);
 1521 }
 1522 
 1523 
 1524 int isoburn_igopt_get_scdbackup_tag(struct isoburn_imgen_opts *o,
 1525                                     char name[81], char timestamp[19],
 1526                                     char **tag_written)
 1527 {
 1528  strncpy(name, o->scdbackup_tag_name, 80);
 1529  name[80]= 0;
 1530  strncpy(timestamp, o->scdbackup_tag_time, 18);
 1531  timestamp[18]= 0;
 1532  *tag_written= o->scdbackup_tag_written;
 1533  return(1);
 1534 }
 1535 
 1536 
 1537 int isoburn_igopt_set_system_area(struct isoburn_imgen_opts *opts,
 1538                                   char data[32768], int options)
 1539 {
 1540  if (data == NULL) { /* Disable */
 1541    if (opts->system_area_data != NULL)
 1542      free(opts->system_area_data);
 1543    opts->system_area_data = NULL;
 1544  } else {
 1545    if (opts->system_area_data == NULL) {
 1546      opts->system_area_data = calloc(32768, 1);
 1547      if (opts->system_area_data == NULL)
 1548        return(-1);
 1549    }
 1550    memcpy(opts->system_area_data, data, 32768);
 1551  }
 1552  opts->system_area_options = options & 0xffff;
 1553  return(1);
 1554 }
 1555 
 1556 
 1557 int isoburn_igopt_get_system_area(struct isoburn_imgen_opts *opts, 
 1558                                   char data[32768], int *options)
 1559 {
 1560  *options= opts->system_area_options;
 1561  if(opts->system_area_data == NULL)
 1562    return(0);
 1563  memcpy(data, opts->system_area_data, 32768);
 1564  return(1);
 1565 }
 1566 
 1567 
 1568 int isoburn_igopt_set_pvd_times(struct isoburn_imgen_opts *opts,
 1569                         time_t vol_creation_time, time_t vol_modification_time,
 1570                         time_t vol_expiration_time, time_t vol_effective_time,
 1571                         char *vol_uuid)
 1572 {
 1573  opts->vol_creation_time = vol_creation_time;
 1574  opts->vol_modification_time = vol_modification_time;
 1575  opts->vol_expiration_time = vol_expiration_time;
 1576  opts->vol_effective_time = vol_effective_time;
 1577  strncpy(opts->vol_uuid, vol_uuid, 16);
 1578  opts->vol_uuid[16] = 0;
 1579  return(1);
 1580 }
 1581 
 1582 
 1583 int isoburn_igopt_get_pvd_times(struct isoburn_imgen_opts *opts,
 1584                       time_t *vol_creation_time, time_t *vol_modification_time,
 1585                       time_t *vol_expiration_time, time_t *vol_effective_time,
 1586                       char vol_uuid[17])
 1587 {
 1588  *vol_creation_time = opts->vol_creation_time;
 1589  *vol_modification_time = opts->vol_modification_time;
 1590  *vol_expiration_time = opts->vol_expiration_time;
 1591  *vol_effective_time = opts->vol_effective_time;
 1592  strcpy(vol_uuid, opts->vol_uuid);
 1593  return(1);
 1594 }
 1595 
 1596 
 1597 int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts,
 1598                                   uint32_t block_offset_2k,
 1599                                   int secs_512_per_head, int heads_per_cyl)
 1600 {
 1601  if (block_offset_2k > 0 && block_offset_2k < 16)
 1602    return(0);
 1603  opts->partition_offset = block_offset_2k;
 1604  opts->partition_secs_per_head = secs_512_per_head;
 1605  opts->partition_heads_per_cyl = heads_per_cyl;
 1606  return(1);
 1607 }
 1608 
 1609 
 1610 int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts,
 1611                                   uint32_t *block_offset_2k,
 1612                                   int *secs_512_per_head, int *heads_per_cyl)
 1613 {
 1614  *block_offset_2k = opts->partition_offset;
 1615  *secs_512_per_head = opts->partition_secs_per_head;
 1616  *heads_per_cyl = opts->partition_heads_per_cyl;
 1617  return 1;
 1618 }
 1619 
 1620 
 1621 int isoburn_igopt_attach_jte(struct isoburn_imgen_opts *opts,
 1622                              void *libjte_handle)
 1623 {
 1624  opts->libjte_handle = libjte_handle;
 1625  return 1;
 1626 }
 1627 
 1628 
 1629 int isoburn_igopt_detach_jte(struct isoburn_imgen_opts *opts,
 1630                              void **libjte_handle)
 1631 {
 1632  if(libjte_handle != NULL)
 1633    *libjte_handle = opts->libjte_handle;
 1634  opts->libjte_handle = NULL;
 1635  return 1;
 1636 }
 1637 
 1638 
 1639 int isoburn_igopt_set_tail_blocks(struct isoburn_imgen_opts *opts,
 1640                                   uint32_t num_blocks)
 1641 {
 1642   opts->tail_blocks = num_blocks;
 1643   return 1;
 1644 }
 1645 
 1646 int isoburn_igopt_get_tail_blocks(struct isoburn_imgen_opts *opts,
 1647                                   uint32_t *num_blocks)
 1648 {
 1649   *num_blocks = opts->tail_blocks;
 1650   return 1;
 1651 }
 1652 
 1653 
 1654 int isoburn_igopt_set_prep_partition(struct isoburn_imgen_opts *o,
 1655                                      char *path, int flag)
 1656 {
 1657  if(o->prep_partition != NULL)
 1658    free(o->prep_partition);
 1659  o->prep_partition= NULL;
 1660  o->prep_part_flag= 0;
 1661  if(path != NULL) {
 1662    o->prep_partition= strdup(path);
 1663    if(o->prep_partition == NULL) {
 1664      isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0);
 1665      return(-1);
 1666    }
 1667  }
 1668  o->prep_part_flag= flag & 1;
 1669  return(1);
 1670 }
 1671 
 1672 
 1673 int isoburn_igopt_get_prep_partition(struct isoburn_imgen_opts *opts,
 1674                                      char **path, int flag)
 1675 {
 1676  *path= opts->prep_partition;
 1677  if(flag & 1)
 1678    return(1 + (opts->prep_part_flag & 0x3fffffff));
 1679  return(1);
 1680 }
 1681 
 1682 
 1683 int isoburn_igopt_set_efi_bootp(struct isoburn_imgen_opts *o,
 1684                                 char *path, int flag)
 1685 {
 1686  if(o->efi_boot_partition != NULL)
 1687    free(o->efi_boot_partition);
 1688  o->efi_boot_partition= NULL;
 1689  o->efi_boot_part_flag= 0;
 1690  if(path != NULL) {
 1691    o->efi_boot_partition= strdup(path);
 1692    if(o->efi_boot_partition == NULL) {
 1693      isoburn_report_iso_error(ISO_OUT_OF_MEM, "Out of memory", 0, "FATAL", 0);
 1694      return(-1);
 1695    }
 1696  }
 1697  o->efi_boot_part_flag = flag & 1;
 1698  return(1);
 1699 }
 1700 
 1701 
 1702 int isoburn_igopt_get_efi_bootp(struct isoburn_imgen_opts *opts,
 1703                                 char **path, int flag)
 1704 {
 1705  *path= opts->efi_boot_partition;
 1706  if(flag & 1)
 1707    return(1 + (opts->efi_boot_part_flag & 0x3fffffff));
 1708  return(1);
 1709 }
 1710 
 1711 
 1712 int isoburn_igopt_set_partition_img(struct isoburn_imgen_opts *opts,
 1713                                   int partition_number, uint8_t partition_type,
 1714                                   char *image_path)
 1715 {
 1716  char msg[80];
 1717 
 1718  if (partition_number < 1 ||
 1719      partition_number > Libisoburn_max_appended_partitionS) {
 1720    sprintf(msg, "Partition number is out of range (1 ... %d)",
 1721            Libisoburn_max_appended_partitionS);
 1722    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1723    return(0);
 1724  }
 1725  if (opts->appended_partitions[partition_number - 1] != NULL)
 1726    free(opts->appended_partitions[partition_number - 1]);
 1727  opts->appended_partitions[partition_number - 1] = strdup(image_path);
 1728  if (opts->appended_partitions[partition_number - 1] == NULL)
 1729    return(-1);
 1730  opts->appended_part_types[partition_number - 1] = partition_type;
 1731  return(1);
 1732 }
 1733 
 1734 
 1735 int isoburn_igopt_get_partition_img(struct isoburn_imgen_opts *opts,
 1736                                     int num_entries,
 1737                                     uint8_t partition_types[],
 1738                                     char *image_paths[])
 1739 {
 1740  int i, max_entry= 0;
 1741 
 1742  for(i= 0; i < num_entries; i++)
 1743    image_paths[i]= NULL;
 1744  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
 1745    if(opts->appended_partitions[i] == NULL)
 1746  continue;
 1747    if(i < num_entries) {
 1748      image_paths[i]= opts->appended_partitions[i];
 1749      partition_types[i]= opts->appended_part_types[i];
 1750    }
 1751    max_entry= i + 1;
 1752  }
 1753  return(max_entry);
 1754 }
 1755 
 1756 
 1757 int isoburn_igopt_set_part_flag(struct isoburn_imgen_opts *opts,
 1758                                 int partition_number, int flag)
 1759 {
 1760  char msg[80];
 1761 
 1762  if (partition_number < 1 ||
 1763      partition_number > Libisoburn_max_appended_partitionS) {
 1764    sprintf(msg, "Partition number is out of range (1 ... %d)",
 1765            Libisoburn_max_appended_partitionS);
 1766    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1767    return(0);
 1768  }
 1769  opts->appended_part_flags[partition_number - 1]= flag;
 1770  return(1);
 1771 }
 1772 
 1773 
 1774 int isoburn_igopt_get_part_flags(struct isoburn_imgen_opts *opts,
 1775                                  int num_entries, int part_flags[])
 1776 {
 1777  int i, max_entry= 0;
 1778 
 1779  for(i= 0; i < num_entries; i++)
 1780    part_flags[i]= 0;
 1781  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
 1782    if(i < num_entries)
 1783      part_flags[i]= opts->appended_part_flags[i];
 1784    max_entry= i + 1;
 1785  }
 1786  return(max_entry);
 1787 }
 1788 
 1789 
 1790 int isoburn_igopt_set_appended_as_gpt(struct isoburn_imgen_opts *opts, int gpt)
 1791 {
 1792  opts->appended_as_gpt= !!gpt;
 1793  return(1);
 1794 }
 1795 
 1796 
 1797 int isoburn_igopt_get_appended_as_gpt(struct isoburn_imgen_opts *opts,
 1798                                       int *gpt)
 1799 {
 1800  *gpt= opts->appended_as_gpt;
 1801  return(1);
 1802 }
 1803 
 1804 
 1805 int isoburn_igopt_set_part_type_guid(struct isoburn_imgen_opts *opts,
 1806                                      int partition_number, uint8_t guid[16],
 1807                                      int valid)
 1808 {
 1809  char msg[80];
 1810 
 1811  if (partition_number < 1 ||
 1812      partition_number > Libisoburn_max_appended_partitionS) {
 1813    sprintf(msg, "Partition number is out of range (1 ... %d)",
 1814            Libisoburn_max_appended_partitionS);
 1815    isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1816    return(0);
 1817  }
 1818  if(valid)
 1819    memcpy(opts->appended_part_type_guids[partition_number - 1], guid, 16);
 1820  if(valid)
 1821    opts->appended_part_gpt_flags[partition_number - 1]|= 1;
 1822  else
 1823    opts->appended_part_gpt_flags[partition_number - 1]&= ~1;
 1824  return(1);
 1825 }
 1826 
 1827 int isoburn_igopt_get_part_type_guid(struct isoburn_imgen_opts *opts,
 1828                                      int num_entries, uint8_t guids[][16],
 1829                                      int valids[])
 1830 {
 1831  int i, max_entry= 0;
 1832 
 1833  for(i= 0; i < num_entries; i++) {
 1834    memset(guids[i], 0, 16);
 1835    valids[i]= 0;
 1836  }
 1837  for(i= 0; i < Libisoburn_max_appended_partitionS; i++) {
 1838    if(i < num_entries) {
 1839      memcpy(guids[i], opts->appended_part_type_guids[i], 16);
 1840      valids[i]= opts->appended_part_gpt_flags[i] & 1;
 1841    }
 1842    max_entry= i + 1;
 1843  }
 1844  return(max_entry);
 1845 }
 1846 
 1847 int isoburn_igopt_set_appended_as_apm(struct isoburn_imgen_opts *opts, int apm)
 1848 {
 1849  opts->appended_as_apm= !!apm;
 1850  return(1);
 1851 }
 1852 
 1853 
 1854 int isoburn_igopt_get_appended_as_apm(struct isoburn_imgen_opts *opts,
 1855                                       int *apm)
 1856 {
 1857  *apm= opts->appended_as_apm;
 1858  return(1);
 1859 }
 1860 
 1861 
 1862 int isoburn_igopt_set_part_like_isohybrid(struct isoburn_imgen_opts *opts,
 1863                                           int alike)
 1864 {
 1865  opts->part_like_isohybrid= !!alike;
 1866  return(1);
 1867 }
 1868 
 1869 
 1870 int isoburn_igopt_get_part_like_isohybrid(struct isoburn_imgen_opts *opts,
 1871                                           int *alike)
 1872 {
 1873  *alike= opts->part_like_isohybrid;
 1874  return(1);
 1875 }
 1876 
 1877 
 1878 int isoburn_igopt_set_iso_mbr_part_type(struct isoburn_imgen_opts *opts,
 1879                                         int part_type)
 1880 {
 1881  if(part_type < -1 || part_type > 255)
 1882    part_type = -1;
 1883  opts->iso_mbr_part_type = part_type;
 1884  return(1);
 1885 }
 1886 
 1887 
 1888 int isoburn_igopt_get_iso_mbr_part_type(struct isoburn_imgen_opts *opts,
 1889                                         int *part_type)
 1890 {
 1891  *part_type= opts->iso_mbr_part_type;
 1892  return(1);
 1893 }
 1894 
 1895 
 1896 int isoburn_igopt_set_iso_type_guid(struct isoburn_imgen_opts *opts,
 1897                                     uint8_t guid[16], int valid)
 1898 {
 1899  if(valid)
 1900    memcpy(opts->iso_gpt_type_guid, guid, 16);
 1901  opts->iso_gpt_flag= (opts->iso_gpt_flag & ~1) | !!valid;
 1902  return(1); 
 1903 }
 1904 
 1905 
 1906 int isoburn_igopt_get_iso_type_guid(struct isoburn_imgen_opts *opts,
 1907                                     uint8_t guid[16])
 1908 {
 1909  memcpy(guid, opts->iso_gpt_type_guid, 16);
 1910  return(opts->iso_gpt_flag & 1);
 1911 }
 1912 
 1913 
 1914 int isoburn_igopt_set_gpt_guid(struct isoburn_imgen_opts *opts,
 1915                                uint8_t guid[16], int mode)
 1916 {
 1917  if(mode < 0 || mode > 2) {
 1918    isoburn_msgs_submit(NULL, 0x00060000,
 1919                        "Unrecognized GPT disk GUID setup mode. (0 ... 2)",
 1920                        0, "FAILURE", 0);
 1921    return(0);
 1922  }
 1923  opts->gpt_guid_mode= mode;
 1924  if(opts->gpt_guid_mode == 1)
 1925     memcpy(opts->gpt_guid, guid, 16);
 1926  return 1;
 1927 }
 1928 
 1929 
 1930 int isoburn_igopt_get_gpt_guid(struct isoburn_imgen_opts *opts,
 1931                                uint8_t guid[16], int *mode)
 1932 {
 1933  if(opts->gpt_guid_mode == 1)
 1934    memcpy(guid, opts->gpt_guid, 16);
 1935  *mode = opts->gpt_guid_mode;
 1936  return(1);
 1937 }
 1938 
 1939 
 1940 int isoburn_igopt_set_disc_label(struct isoburn_imgen_opts *opts, char *label)
 1941 {
 1942     strncpy(opts->ascii_disc_label, label, Libisoburn_disc_label_sizE - 1);
 1943     opts->ascii_disc_label[Libisoburn_disc_label_sizE - 1] = 0;
 1944     return(1);
 1945 }
 1946 
 1947 
 1948 int isoburn_igopt_get_disc_label(struct isoburn_imgen_opts *opts, char **label)
 1949 {
 1950     *label= opts->ascii_disc_label;
 1951     return(1);
 1952 }
 1953 
 1954 
 1955 int isoburn_igopt_set_hfsp_serial_number(struct isoburn_imgen_opts *opts,
 1956                                          uint8_t serial_number[8])
 1957 {
 1958  memcpy(opts->hfsp_serial_number, serial_number, 8);
 1959  return(1);
 1960 }
 1961 
 1962 
 1963 int isoburn_igopt_get_hfsp_serial_number(struct isoburn_imgen_opts *opts,
 1964                                          uint8_t serial_number[8])
 1965 {
 1966  memcpy(serial_number, opts->hfsp_serial_number, 8);
 1967  return(1);
 1968 }
 1969 
 1970 
 1971 int isoburn_igopt_set_hfsp_block_size(struct isoburn_imgen_opts *opts,
 1972                                       int hfsp_block_size, int apm_block_size)
 1973 {
 1974  char msg[80];
 1975 
 1976  msg[0]= 0;
 1977  if(hfsp_block_size != -1) {
 1978    if(hfsp_block_size != 0 && hfsp_block_size != 512 &&
 1979        hfsp_block_size != 2048) {
 1980      sprintf(msg, "Not a supported HFS+ size (%d <-> 0, 512, 2048)",
 1981                   hfsp_block_size);
 1982      isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1983    }
 1984    opts->hfsp_block_size = hfsp_block_size;
 1985  }
 1986  if(apm_block_size != -1) {
 1987    if(apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048) {
 1988      sprintf(msg, "Not a supported APM block size (%d <-> 0, 512, 2048)",
 1989                   apm_block_size);
 1990      isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "FAILURE", 0);
 1991    }
 1992    opts->apm_block_size = apm_block_size;
 1993  }
 1994  if(msg[0])
 1995    return(0);
 1996  return(1);
 1997 }
 1998 
 1999 
 2000 int isoburn_igopt_get_hfsp_block_size(struct isoburn_imgen_opts *opts,
 2001                                      int *hfsp_block_size, int *apm_block_size)
 2002 {
 2003  *hfsp_block_size= opts->hfsp_block_size;
 2004  *apm_block_size= opts->apm_block_size;
 2005  return(1);
 2006 }
 2007 
 2008 
 2009 int isoburn_igopt_set_write_type(struct isoburn_imgen_opts *opts, int do_tao)
 2010 {
 2011  if(do_tao < -1 || do_tao > 1)
 2012    return(0);
 2013  opts->do_tao= do_tao;
 2014  return(1);
 2015 }
 2016 
 2017 
 2018 int isoburn_igopt_get_write_type(struct isoburn_imgen_opts *opts, int *do_tao)
 2019 {
 2020  *do_tao= opts->do_tao;
 2021  return(1);
 2022 }
 2023 
 2024 int isoburn_igopt_set_stdio_endsync(struct isoburn_imgen_opts *opts, 
 2025                                   int do_sync)
 2026 {
 2027  opts->do_fsync= !!do_sync;
 2028  return(1);
 2029 }
 2030 
 2031 int isoburn_igopt_get_stdio_endsync(struct isoburn_imgen_opts *opts, 
 2032                                   int *do_sync)
 2033 {
 2034  *do_sync= opts->do_fsync;
 2035  return(1);
 2036 }
 2037 
 2038 int isoburn_conv_name_chars(struct isoburn_imgen_opts *opts,
 2039                             char *name, size_t name_len,
 2040                             char **result, size_t *result_len, int flag)
 2041 {
 2042  int ret;
 2043  IsoWriteOpts *wopts= NULL;
 2044 
 2045  ret = iso_write_opts_new(&wopts, 0);
 2046  if (ret < 0) {
 2047    isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0);
 2048    goto ex;
 2049  }
 2050  ret= isoburn_make_iso_write_opts(NULL, opts, 0, wopts, 0);
 2051  if(ret < 0)
 2052    goto ex;
 2053  ret= iso_conv_name_chars(wopts, name, name_len, result, result_len, flag);
 2054 ex:;
 2055  if(wopts != NULL)
 2056    iso_write_opts_free(wopts); 
 2057  return(ret);
 2058 }