libisoburn-0.3.4/libisoburn/isofs_wrap.c File Reference

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "isoburn.h"
#include "libisoburn.h"

Include dependency graph for isofs_wrap.c:

Go to the source code of this file.

Data Structures

struct  ecma119_pri_vol_desc

Defines

#define Libisoburn_with_aaiP   yes
#define BP(a, b)   [(b) - (a) + 1]

Functions

static uint32_t iso_read_lsb (const uint8_t *buf, int bytes)
IsoImage * isoburn_get_attached_image (struct burn_drive *d)
 Get the image attached to a drive, if any.
static void isoburn_idle_free_function (void *ignored)
int isoburn_read_image (struct burn_drive *d, struct isoburn_read_opts *read_opts, IsoImage **image)
 Load the ISO filesystem directory tree from the media in the given drive.
int isoburn_attach_image (struct burn_drive *d, IsoImage *image)
 Set the IsoImage to be used with a drive.
int isoburn_activate_session (struct burn_drive *drive)
 Call this after isoburn_disc_write has finished and burn_drive_wrote_well() indicates success.
int isoburn_start_emulation (struct isoburn *o, int flag)
 Initialize the emulation of multi-session on random access media.
int isoburn_invalidate_iso (struct isoburn *o, int flag)
 Alters and writes the first 64 kB of a "media" to invalidate an ISO image.
int isoburn_set_read_pacifier (struct burn_drive *drive, int(*read_pacifier)(IsoImage *, IsoFileSource *), void *read_handle)
 Set a callback function for producing pacifier messages during the lengthy process of image reading.


Define Documentation

#define BP ( a,
 )     [(b) - (a) + 1]

Definition at line 35 of file isofs_wrap.c.

#define Libisoburn_with_aaiP   yes

Definition at line 30 of file isofs_wrap.c.


Function Documentation

static uint32_t iso_read_lsb ( const uint8_t *  buf,
int  bytes 
) [static]

Definition at line 75 of file isofs_wrap.c.

Referenced by isoburn_start_emulation().

00076 {
00077     int i;
00078     uint32_t ret = 0;
00079 
00080     for (i=0; i<bytes; i++) {
00081         ret += ((uint32_t) buf[i]) << (i*8);
00082     }
00083     return ret;
00084 }

int isoburn_activate_session ( struct burn_drive *  drive  ) 

Call this after isoburn_disc_write has finished and burn_drive_wrote_well() indicates success.

It will eventually complete the emulation of multi-session functionality, if needed at all. Let libisoburn decide. Not a wrapper, but peculiar to libisoburn.

Since:
0.1.0
Parameters:
d The output drive to which the session was written
Returns:
1 success , <=0 failure

Definition at line 281 of file isofs_wrap.c.

References isoburn::emulation_mode, isoburn::fabricated_disc_status, isoburn::fabricated_msc2, isoburn_find_emulator(), Libisoburn_target_head_sizE, isoburn::target_iso_head, and isoburn::zero_nwa.

Referenced by isoburn_invalidate_iso().

00282 {
00283  int ret;
00284  struct isoburn *o;
00285 
00286  ret = isoburn_find_emulator(&o, drive, 0);
00287  if (ret < 0)
00288    return -1;
00289 
00290  if (o->emulation_mode != 1)
00291    return 1; /* don't need to activate session */
00292  if (o->fabricated_msc2 >= 0)
00293    return 1; /* blind growing: do not alter anything outside the session */
00294  
00295  if (!(o->fabricated_disc_status == BURN_DISC_APPENDABLE ||
00296        (o->fabricated_disc_status == BURN_DISC_BLANK &&
00297         o->zero_nwa > 0)))
00298    return 1;
00299  
00300  ret = burn_random_access_write(drive, (off_t) 0, (char*)o->target_iso_head, 
00301                                 Libisoburn_target_head_sizE, 1);
00302 
00303  return ret;
00304 }

int isoburn_attach_image ( struct burn_drive *  d,
IsoImage *  image 
)

Set the IsoImage to be used with a drive.

This eventually releases the reference to the old IsoImage attached to the drive. Caution: Use with care. It hardly makes sense to replace an image that reflects a valid ISO image on media. This call is rather intended for writing a newly created and populated image to blank media. The use case in xorriso is to let an image survive the change or demise of the outdev target drive.

Since:
0.1.0
Parameters:
d The drive which shall be write target of the volset.
image The image that represents the image to be written. This image pointer MUST already be a valid reference suitable for iso_image_unref(). It may have been obtained by appropriate libisofs calls or by isoburn_read_image() with d==NULL.
Returns:
<=0 error , 1 = success

Definition at line 258 of file isofs_wrap.c.

References isoburn::image, isoburn_find_emulator(), and isoburn_msgs_submit().

00259 {
00260  int ret;
00261  struct isoburn *o;
00262 
00263  ret = isoburn_find_emulator(&o, d, 0);
00264  if (ret < 0 || o == NULL)
00265    return 0;
00266  if (image == NULL) {
00267    isoburn_msgs_submit(o, 0x00060000,
00268                        "Program error: isoburn_attach_image: image==NULL",
00269                        0, "FATAL", 0);
00270    return -1;
00271  }
00272  if(o->image != NULL)
00273    iso_image_unref(o->image);
00274  o->image = image;
00275  return(1);
00276 }

IsoImage* isoburn_get_attached_image ( struct burn_drive *  d  ) 

Get the image attached to a drive, if any.

Since:
0.1.0
Parameters:
d The drive to inquire
Returns:
A reference to attached image, or NULL if the drive has no image attached. This reference needs to be released via iso_image_unref() when it is not longer needed.

Definition at line 89 of file isofs_wrap.c.

References isoburn::image, and isoburn_find_emulator().

00090 {
00091  int ret;
00092  struct isoburn *o= NULL;
00093  ret = isoburn_find_emulator(&o, d, 0);
00094  if (ret < 0)
00095    return NULL;
00096   
00097  if (o == NULL) {
00098    return NULL;
00099  }
00100  iso_image_ref(o->image);
00101  return o->image;
00102 }

static void isoburn_idle_free_function ( void *  ignored  )  [static]

Definition at line 105 of file isofs_wrap.c.

Referenced by isoburn_read_image().

00106 {
00107  return;
00108 }

int isoburn_invalidate_iso ( struct isoburn o,
int  flag 
)

Alters and writes the first 64 kB of a "media" to invalidate an ISO image.

(It shall stay restorable by skilled humans, though). The result shall especially keep libisoburn from accepting the media image as ISO filesystem.

Parameters:
o A fully activated isoburn object. isoburn_start_emulation() was already called.
Returns:
<=0 error , 1 = success

Definition at line 390 of file isofs_wrap.c.

References isoburn::drive, isoburn_activate_session(), and isoburn::target_iso_head.

Referenced by isoburn_disc_erase().

00391 {
00392  /* 
00393   * replace CD001 with CDXX1 in PVM.
00394   * I think this is enought for invalidating an iso image
00395   */
00396  strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5);
00397  return isoburn_activate_session(o->drive);
00398 }

int isoburn_read_image ( struct burn_drive *  d,
struct isoburn_read_opts read_opts,
IsoImage **  image 
)

Load the ISO filesystem directory tree from the media in the given drive.

This will give libisoburn the base on which it can let libisofs perform image growing or image modification. The loaded volset gets attached to the drive object and handed out to the application. Not a wrapper, but peculiar to libisoburn.

Since:
0.1.0
Parameters:
d The drive which holds an existing ISO filesystem or blank media. d is allowed to be NULL which produces an empty ISO image. In this case one has to call before writing isoburn_attach_volset() with the volset from this call and with the intended output drive.
read_opts The read options which can be chosen by the application
image the image read, if the disc is blank it will have no files. This reference needs to be released via iso_image_unref() when it is not longer needed. The drive, if not NULL, will hold an own reference which it will release when it gets a new volset or when it gets released via isoburn_drive_release(). You can pass NULL if you already have a reference or you plan to obtain it later with isoburn_get_attached_image(). Of course, if you haven't specified a valid drive (i.e., if d == NULL), this parameter can't be NULL.
Returns:
<=0 error , 1 = success

Definition at line 113 of file isofs_wrap.c.

References isoburn_read_opts::dirmode, isoburn_read_opts::gid, isoburn_read_opts::hasElTorito, isoburn_read_opts::hasIso1999, isoburn_read_opts::hasJoliet, isoburn_read_opts::hasRR, isoburn::image, isoburn_read_opts::input_charset, isoburn::iso_data_source, isoburn_data_source_new(), isoburn_disc_get_msc1(), isoburn_disc_get_status(), isoburn_find_emulator(), isoburn_idle_free_function(), isoburn_msgs_submit(), isoburn_read_iso_head(), isoburn_report_iso_error(), isoburn_read_opts::mode, isoburn_read_opts::noaaip, isoburn_read_opts::noacl, isoburn_read_opts::noea, isoburn_read_opts::noiso1999, isoburn_read_opts::nojoliet, isoburn_read_opts::norock, isoburn_read_opts::preferjoliet, isoburn_read_opts::pretend_blank, isoburn::read_pacifier, isoburn::read_pacifier_handle, isoburn_read_opts::size, and isoburn_read_opts::uid.

00116 {
00117  int ret, int_num, dummy;
00118  IsoReadOpts *ropts= NULL;
00119  IsoReadImageFeatures *features= NULL;
00120  uint32_t ms_block;
00121  char msg[160];
00122  enum burn_disc_status status= BURN_DISC_BLANK;
00123  IsoDataSource *ds= NULL;
00124  struct isoburn *o= NULL;
00125 
00126  if(d != NULL) {
00127    ret = isoburn_find_emulator(&o, d, 0);
00128    if (ret < 0 || o == NULL)
00129      return 0;
00130    status = isoburn_disc_get_status(d);
00131  }
00132  if(read_opts==NULL) {
00133    isoburn_msgs_submit(o, 0x00060000,
00134                        "Program error: isoburn_read_image: read_opts==NULL",
00135                        0, "FATAL", 0);
00136    return(-1);
00137  }
00138  if (d == NULL || status == BURN_DISC_BLANK || read_opts->pretend_blank) {
00139 create_blank_image:;
00140    /*
00141     * Blank disc, we create a new image without files.
00142     */
00143    
00144    if (d == NULL) {
00145      /* New empty image without relation to a drive */
00146      if (image==NULL) {
00147        isoburn_msgs_submit(o, 0x00060000,
00148                            "Program error: isoburn_read_image: image==NULL",
00149                            0, "FATAL", 0);
00150        return -1;
00151      }
00152      /* create a new image */
00153      ret = iso_image_new("ISOIMAGE", image);
00154      if (ret < 0) {
00155        isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0);
00156        return ret;
00157      }
00158    } else {
00159      /* Blank new image for the drive */
00160      iso_image_unref(o->image);
00161      ret = iso_image_new("ISOIMAGE", &o->image);
00162      if (ret < 0) {
00163        isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0);
00164        return ret;
00165      }
00166      if (image) {
00167        *image = o->image;
00168        iso_image_ref(*image); /*protects object from premature free*/
00169      }
00170    }
00171    iso_image_set_ignore_aclea(*image,
00172                          (!!(read_opts->noacl)) | ((!!read_opts->noea) << 1) );
00173    return 1;
00174  }
00175  
00176  if (status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL) {
00177    isoburn_msgs_submit(o, 0x00060000,
00178                     "Program error: isoburn_read_image: incorrect disc status",
00179                     0, "FATAL", 0);
00180    return -4;   
00181  }
00182  
00183  memset((char *) &ropts, 0, sizeof(ropts));
00184 
00185  ret = isoburn_disc_get_msc1(d, &int_num);
00186  if (ret <= 0)
00187    return -2;
00188  ms_block= int_num;
00189  ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0);
00190  if (ret <= 0) {
00191    sprintf(msg, "No ISO 9660 image at LBA %d. Creating blank image.", int_num);
00192    isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0);
00193    goto create_blank_image;
00194  }
00195 
00196  /* create the data source */
00197  ret = iso_read_opts_new(&ropts, 0);
00198  if (ret < 0) {
00199    isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0);
00200    return ret;
00201  }
00202  /* Important: do not return until iso_read_opts_free() */
00203  iso_read_opts_set_start_block(ropts, ms_block);
00204  iso_read_opts_set_no_rockridge(ropts, read_opts->norock);
00205 
00206 #ifdef Libisoburn_with_aaiP
00207  iso_read_opts_set_no_aaip(ropts, read_opts->noaaip);
00208 #endif /* Libisoburn_with_aaiP */
00209 
00210  iso_read_opts_set_no_joliet(ropts, read_opts->nojoliet);
00211  iso_read_opts_set_no_iso1999(ropts, read_opts->noiso1999);
00212  iso_read_opts_set_preferjoliet(ropts, read_opts->preferjoliet);
00213  iso_read_opts_set_default_permissions(ropts,
00214                                        read_opts->mode, read_opts->dirmode);
00215  iso_read_opts_set_default_uid(ropts, read_opts->uid);
00216  iso_read_opts_set_default_gid(ropts, read_opts->gid);
00217  iso_read_opts_set_input_charset(ropts, read_opts->input_charset);
00218 
00219  /* <<< experimental API call of libisofs
00220  iso_read_opts_set_error_behavior(ropts, 1);
00221  */
00222 
00223  ds = isoburn_data_source_new(d);
00224  if(o->iso_data_source!=NULL)
00225    iso_data_source_unref(o->iso_data_source);
00226  o->iso_data_source= ds;
00227  iso_image_attach_data(o->image, o->read_pacifier_handle,
00228                        isoburn_idle_free_function);
00229  if(o->read_pacifier_handle==NULL)
00230    iso_tree_set_report_callback(o->image, NULL);
00231  else
00232    iso_tree_set_report_callback(o->image, o->read_pacifier);
00233  ret = iso_image_import(o->image, ds, ropts, &features);
00234  iso_tree_set_report_callback(o->image, NULL);
00235  iso_read_opts_free(ropts);
00236 
00237  if (ret < 0) {
00238    isoburn_report_iso_error(ret, "Cannot import image", 0, "FAILURE", 0);
00239    return ret;
00240  }
00241  /* Important: do not return until free(features) */
00242  if (image!=NULL) {
00243    *image = o->image;
00244    iso_image_ref(*image); /*protects object from premature free*/
00245  }
00246  read_opts->hasRR = iso_read_image_features_has_rockridge(features);
00247  read_opts->hasJoliet = iso_read_image_features_has_joliet(features);
00248  read_opts->hasIso1999 = iso_read_image_features_has_iso1999(features);
00249  read_opts->hasElTorito = iso_read_image_features_has_eltorito(features);
00250  read_opts->size = iso_read_image_features_get_size(features);
00251  iso_read_image_features_destroy(features);
00252  return 1;
00253 }

int isoburn_set_read_pacifier ( struct burn_drive *  drive,
int(*)(IsoImage *, IsoFileSource *)  read_pacifier,
void *  app_handle 
)

Set a callback function for producing pacifier messages during the lengthy process of image reading.

The callback function and the application handle are stored until they are needed for the underlying call to libisofs. Other than with libisofs the handle is managed entirely by the application. An idle .free() function is exposed to libisofs. The handle has to stay valid until isoburn_read_image() is done. It has to be detached by isoburn_set_read_pacifier(drive, NULL, NULL); before it may be removed from memory.

Since:
0.1.0
Parameters:
drive The drive which will be used with isoburn_read_image() It has to be aquired by an isoburn_* wrapper call.
read_pacifier The callback function
app_handle The app handle which the callback function can obtain via iso_image_get_attached_data() from its IsoImage*
Returns:
1 success, <=0 failure

Definition at line 402 of file isofs_wrap.c.

References isoburn_find_emulator(), isoburn::read_pacifier, and isoburn::read_pacifier_handle.

00405 {
00406  int ret;
00407  struct isoburn *o;
00408 
00409  ret = isoburn_find_emulator(&o, drive, 0);
00410  if(ret < 0 || o == NULL)
00411    return -1;
00412  o->read_pacifier_handle= read_handle;
00413  o->read_pacifier= read_pacifier;
00414  return(1);
00415 }

int isoburn_start_emulation ( struct isoburn o,
int  flag 
)

Initialize the emulation of multi-session on random access media.

The need for emulation is confirmed already.

Parameters:
o A freshly created isoburn object. isoburn_create_data_source() was already called, nevertheless.
Returns:
<=0 error , 1 = success

Definition at line 313 of file isofs_wrap.c.

References isoburn::drive, isoburn::fabricated_disc_status, iso_read_lsb(), isoburn_msgs_submit(), isoburn_set_start_byte(), Libisoburn_target_head_sizE, isoburn::target_iso_head, and isoburn::zero_nwa.

Referenced by isoburn_welcome_media().

00314 {
00315  int ret, i;
00316  off_t data_count;
00317  struct burn_drive *drive;
00318  struct ecma119_pri_vol_desc *pvm;
00319  
00320  if(o==NULL) {
00321    isoburn_msgs_submit(NULL, 0x00060000,
00322                        "Program error: isoburn_start_emulation: o==NULL",
00323                        0, "FATAL", 0);
00324    return -1;
00325  }
00326 
00327  drive= o->drive;
00328 
00329  /* we can assume 0 as start block for image */
00330  /* TODO what about ms? where we validate valid iso image in ms disc? */
00331  ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, 
00332                       (off_t) Libisoburn_target_head_sizE, &data_count, 2);
00333 
00334  /* an error means an empty disc */
00335  if (ret <= 0) {
00336    o->fabricated_disc_status= BURN_DISC_BLANK;
00337    return 1;
00338  }
00339 
00340  /* check first 64K. If 0's, the disc is treated as a blank disc, and thus
00341     overwritten without extra check. */
00342  i = Libisoburn_target_head_sizE;
00343  while (i && !o->target_iso_head[i-1]) 
00344    --i;
00345 
00346  if (!i) {
00347    o->fabricated_disc_status= BURN_DISC_BLANK;
00348    return 1;
00349  }
00350 
00351  pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048);
00352 
00353  if (!strncmp((char*)pvm->std_identifier, "CD001", 5)) {
00354    off_t size;
00355 
00356    /* sanity check */
00357    if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 
00358        || pvm->file_structure_version[0] != 1 ) {
00359      /* TODO for now I treat this as a full disc */
00360      o->fabricated_disc_status= BURN_DISC_FULL;
00361      return 1;
00362    }
00363 
00364    /* ok, PVM found, set size */
00365    size = (off_t) iso_read_lsb(pvm->vol_space_size, 4);
00366    size *= (off_t) 2048; /* block size in bytes */
00367    isoburn_set_start_byte(o, size, 0);
00368    o->fabricated_disc_status= BURN_DISC_APPENDABLE;
00369  } else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) {
00370 
00371    /* empty image */
00372    isoburn_set_start_byte(o, o->zero_nwa * 2048, 0);
00373    o->fabricated_disc_status= BURN_DISC_BLANK;
00374  } else {
00375    /* treat any disc in an unknown format as full */
00376    o->fabricated_disc_status= BURN_DISC_FULL;
00377  }
00378  return 1;
00379 }


Generated on Fri May 1 12:03:18 2009 for libisoburn by  doxygen 1.5.8