libisoburn-0.4.8.pl00/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 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 33 of file isofs_wrap.c.


Function Documentation

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

Definition at line 73 of file isofs_wrap.c.

Referenced by isoburn_start_emulation().

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

int isoburn_activate_session ( struct burn_drive *  d  ) 

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 276 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().

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

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 253 of file isofs_wrap.c.

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

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

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 87 of file isofs_wrap.c.

References isoburn::image, and isoburn_find_emulator().

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

static void isoburn_idle_free_function ( void *  ignored  )  [static]

Definition at line 103 of file isofs_wrap.c.

Referenced by isoburn_read_image().

00104 {
00105  return;
00106 }

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 404 of file isofs_wrap.c.

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

Referenced by isoburn_disc_erase().

00405 {
00406  /* 
00407   * replace CD001 with CDXX1 in PVM.
00408   * I think this is enought for invalidating an iso image
00409   */
00410  strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5);
00411  return isoburn_activate_session(o->drive);
00412 }

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 111 of file isofs_wrap.c.

References isoburn_read_opts::auto_input_charset, 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::noino, isoburn_read_opts::noiso1999, isoburn_read_opts::nojoliet, isoburn_read_opts::nomd5, 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.

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

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 416 of file isofs_wrap.c.

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

00419 {
00420  int ret;
00421  struct isoburn *o;
00422 
00423  ret = isoburn_find_emulator(&o, drive, 0);
00424  if(ret < 0 || o == NULL)
00425    return -1;
00426  o->read_pacifier_handle= read_handle;
00427  o->read_pacifier= read_pacifier;
00428  return(1);
00429 }

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 308 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().

00309 {
00310  int ret, i, capacity = -1, role;
00311  off_t data_count, to_read;
00312  struct burn_drive *drive;
00313  struct ecma119_pri_vol_desc *pvm;
00314  
00315  if(o==NULL) {
00316    isoburn_msgs_submit(NULL, 0x00060000,
00317                        "Program error: isoburn_start_emulation: o==NULL",
00318                        0, "FATAL", 0);
00319    return -1;
00320  }
00321 
00322  drive= o->drive;
00323 
00324  /* We can assume 0 as start block for image.
00325     The data there point to the most recent session.
00326  */
00327  role = burn_drive_get_drive_role(drive);
00328  ret = burn_get_read_capacity(drive, &capacity, 0);
00329  if (ret <= 0)
00330    capacity = -1;
00331  if (capacity > 0 || role == 2) {
00332    /* Might be a block device on a system where libburn cannot determine its
00333       size.  Try to read anyway. */
00334    memset(o->target_iso_head, 0, Libisoburn_target_head_sizE);
00335    to_read = Libisoburn_target_head_sizE;
00336    if(capacity > 0 && (off_t) capacity * (off_t) 2048 < to_read)
00337      to_read = (off_t) capacity * (off_t) 2048;
00338    ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, 
00339                         to_read, &data_count, 2);
00340    if (ret <= 0) {
00341      /* an error means a disc with no ISO image */
00342      if (capacity > 0)
00343        o->fabricated_disc_status= BURN_DISC_FULL;
00344      else
00345         o->fabricated_disc_status= BURN_DISC_BLANK;
00346      return 1;
00347    }
00348  } else {
00349    /* No read capacity means blank media */
00350    o->fabricated_disc_status= BURN_DISC_BLANK;
00351    return 1;
00352  }
00353 
00354  /* check first 64K. If 0's, the disc is treated as a blank disc, and thus
00355     overwritten without extra check. */
00356  i = Libisoburn_target_head_sizE;
00357  while (i && !o->target_iso_head[i-1]) 
00358    --i;
00359 
00360  if (!i) {
00361    o->fabricated_disc_status= BURN_DISC_BLANK;
00362    return 1;
00363  }
00364 
00365  pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048);
00366 
00367  if (!strncmp((char*)pvm->std_identifier, "CD001", 5)) {
00368    off_t size;
00369 
00370    /* sanity check */
00371    if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 
00372        || pvm->file_structure_version[0] != 1 ) {
00373      /* TODO for now I treat this as a full disc */
00374      o->fabricated_disc_status= BURN_DISC_FULL;
00375      return 1;
00376    }
00377 
00378    /* ok, PVM found, set size */
00379    size = (off_t) iso_read_lsb(pvm->vol_space_size, 4);
00380    size *= (off_t) 2048; /* block size in bytes */
00381    isoburn_set_start_byte(o, size, 0);
00382    o->fabricated_disc_status= BURN_DISC_APPENDABLE;
00383  } else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) {
00384 
00385    /* empty image */
00386    isoburn_set_start_byte(o, o->zero_nwa * 2048, 0);
00387    o->fabricated_disc_status= BURN_DISC_BLANK;
00388  } else {
00389    /* treat any disc in an unknown format as full */
00390    o->fabricated_disc_status= BURN_DISC_FULL;
00391  }
00392  return 1;
00393 }


Generated by  doxygen 1.6.2