#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "isoburn.h"
#include "libisoburn.h"
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 BP | ( | a, | ||
b | ||||
) | [(b) - (a) + 1] |
Definition at line 34 of file isofs_wrap.c.
static uint32_t iso_read_lsb | ( | const uint8_t * | buf, | |
int | bytes | |||
) | [static] |
Definition at line 74 of file isofs_wrap.c.
Referenced by isoburn_start_emulation().
{ int i; uint32_t ret = 0; for (i=0; i<bytes; i++) { ret += ((uint32_t) buf[i]) << (i*8); } return ret; }
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.
d | The output drive to which the session was written |
Definition at line 278 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().
{ int ret; struct isoburn *o; ret = isoburn_find_emulator(&o, drive, 0); if (ret < 0) return -1; if (o->emulation_mode != 1) return 1; /* don't need to activate session */ if (o->fabricated_msc2 >= 0) return 1; /* blind growing: do not alter anything outside the session */ if (!(o->fabricated_disc_status == BURN_DISC_APPENDABLE || (o->fabricated_disc_status == BURN_DISC_BLANK && o->zero_nwa > 0))) return 1; ret = burn_random_access_write(drive, (off_t) 0, (char*)o->target_iso_head, Libisoburn_target_head_sizE, 1); return ret; }
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.
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. |
Definition at line 255 of file isofs_wrap.c.
References isoburn::image, isoburn_find_emulator(), and isoburn_msgs_submit().
{ int ret; struct isoburn *o; ret = isoburn_find_emulator(&o, d, 0); if (ret < 0 || o == NULL) return 0; if (image == NULL) { isoburn_msgs_submit(o, 0x00060000, "Program error: isoburn_attach_image: image==NULL", 0, "FATAL", 0); return -1; } if(o->image != NULL) iso_image_unref(o->image); o->image = image; return(1); }
IsoImage* isoburn_get_attached_image | ( | struct burn_drive * | d | ) |
Get the image attached to a drive, if any.
d | The drive to inquire |
Definition at line 88 of file isofs_wrap.c.
References isoburn::image, and isoburn_find_emulator().
{ int ret; struct isoburn *o= NULL; ret = isoburn_find_emulator(&o, d, 0); if (ret < 0) return NULL; if (o == NULL) { return NULL; } iso_image_ref(o->image); return o->image; }
static void isoburn_idle_free_function | ( | void * | ignored | ) | [static] |
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.
o | A fully activated isoburn object. isoburn_start_emulation() was already called. |
Definition at line 406 of file isofs_wrap.c.
References isoburn::drive, isoburn_activate_session(), and isoburn::target_iso_head.
Referenced by isoburn_disc_erase().
{ /* * replace CD001 with CDXX1 in PVM. * I think this is enought for invalidating an iso image */ strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5); return isoburn_activate_session(o->drive); }
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.
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. |
Definition at line 112 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.
{ int ret, int_num, dummy; IsoReadOpts *ropts= NULL; IsoReadImageFeatures *features= NULL; uint32_t ms_block; char msg[160]; enum burn_disc_status status= BURN_DISC_BLANK; IsoDataSource *ds= NULL; struct isoburn *o= NULL; if(d != NULL) { ret = isoburn_find_emulator(&o, d, 0); if (ret < 0 || o == NULL) return 0; status = isoburn_disc_get_status(d); } if(read_opts==NULL) { isoburn_msgs_submit(o, 0x00060000, "Program error: isoburn_read_image: read_opts==NULL", 0, "FATAL", 0); return(-1); } if (d == NULL || status == BURN_DISC_BLANK || read_opts->pretend_blank) { create_blank_image:; /* * Blank disc, we create a new image without files. */ if (d == NULL) { /* New empty image without relation to a drive */ if (image==NULL) { isoburn_msgs_submit(o, 0x00060000, "Program error: isoburn_read_image: image==NULL", 0, "FATAL", 0); return -1; } /* create a new image */ ret = iso_image_new("ISOIMAGE", image); if (ret < 0) { isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0); return ret; } } else { /* Blank new image for the drive */ iso_image_unref(o->image); ret = iso_image_new("ISOIMAGE", &o->image); if (ret < 0) { isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0); return ret; } if (image) { *image = o->image; iso_image_ref(*image); /*protects object from premature free*/ } } iso_image_set_ignore_aclea(*image, (!!(read_opts->noacl)) | ((!!read_opts->noea) << 1) ); return 1; } if (status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL) { isoburn_msgs_submit(o, 0x00060000, "Program error: isoburn_read_image: incorrect disc status", 0, "FATAL", 0); return -4; } memset((char *) &ropts, 0, sizeof(ropts)); ret = isoburn_disc_get_msc1(d, &int_num); if (ret <= 0) return -2; ms_block= int_num; ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0); if (ret <= 0) { sprintf(msg, "No ISO 9660 image at LBA %d. Creating blank image.", int_num); isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); goto create_blank_image; } /* create the data source */ ret = iso_read_opts_new(&ropts, 0); if (ret < 0) { isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0); return ret; } /* Important: do not return until iso_read_opts_free() */ iso_read_opts_set_start_block(ropts, ms_block); iso_read_opts_set_no_rockridge(ropts, read_opts->norock); iso_read_opts_set_no_aaip(ropts, read_opts->noaaip); iso_read_opts_set_no_md5(ropts, read_opts->nomd5); iso_read_opts_set_new_inos(ropts, read_opts->noino); iso_read_opts_set_no_joliet(ropts, read_opts->nojoliet); iso_read_opts_set_no_iso1999(ropts, read_opts->noiso1999); iso_read_opts_set_preferjoliet(ropts, read_opts->preferjoliet); iso_read_opts_set_default_permissions(ropts, read_opts->mode, read_opts->dirmode); iso_read_opts_set_default_uid(ropts, read_opts->uid); iso_read_opts_set_default_gid(ropts, read_opts->gid); iso_read_opts_set_input_charset(ropts, read_opts->input_charset); iso_read_opts_auto_input_charset(ropts, read_opts->auto_input_charset); iso_read_opts_load_system_area(ropts, 1); ds = isoburn_data_source_new(d); if(o->iso_data_source!=NULL) iso_data_source_unref(o->iso_data_source); o->iso_data_source= ds; iso_image_attach_data(o->image, o->read_pacifier_handle, isoburn_idle_free_function); if(o->read_pacifier_handle==NULL) iso_tree_set_report_callback(o->image, NULL); else iso_tree_set_report_callback(o->image, o->read_pacifier); ret = iso_image_import(o->image, ds, ropts, &features); iso_tree_set_report_callback(o->image, NULL); iso_read_opts_free(ropts); if (ret < 0) { isoburn_report_iso_error(ret, "Cannot import image", 0, "FAILURE", 0); return ret; } /* Important: do not return until free(features) */ if (image!=NULL) { *image = o->image; iso_image_ref(*image); /*protects object from premature free*/ } read_opts->hasRR = iso_read_image_features_has_rockridge(features); read_opts->hasJoliet = iso_read_image_features_has_joliet(features); read_opts->hasIso1999 = iso_read_image_features_has_iso1999(features); read_opts->hasElTorito = iso_read_image_features_has_eltorito(features); read_opts->size = iso_read_image_features_get_size(features); iso_read_image_features_destroy(features); return 1; }
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.
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* |
Definition at line 418 of file isofs_wrap.c.
References isoburn_find_emulator(), isoburn::read_pacifier, and isoburn::read_pacifier_handle.
{ int ret; struct isoburn *o; ret = isoburn_find_emulator(&o, drive, 0); if(ret < 0 || o == NULL) return -1; o->read_pacifier_handle= read_handle; o->read_pacifier= read_pacifier; return(1); }
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.
o | A freshly created isoburn object. isoburn_create_data_source() was already called, nevertheless. |
Definition at line 310 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().
{ int ret, i, capacity = -1, role; off_t data_count, to_read; struct burn_drive *drive; struct ecma119_pri_vol_desc *pvm; if(o==NULL) { isoburn_msgs_submit(NULL, 0x00060000, "Program error: isoburn_start_emulation: o==NULL", 0, "FATAL", 0); return -1; } drive= o->drive; /* We can assume 0 as start block for image. The data there point to the most recent session. */ role = burn_drive_get_drive_role(drive); ret = burn_get_read_capacity(drive, &capacity, 0); if (ret <= 0) capacity = -1; if (capacity > 0 || role == 2) { /* Might be a block device on a system where libburn cannot determine its size. Try to read anyway. */ memset(o->target_iso_head, 0, Libisoburn_target_head_sizE); to_read = Libisoburn_target_head_sizE; if(capacity > 0 && (off_t) capacity * (off_t) 2048 < to_read) to_read = (off_t) capacity * (off_t) 2048; ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, to_read, &data_count, 2); if (ret <= 0) { /* an error means a disc with no ISO image */ if (capacity > 0) o->fabricated_disc_status= BURN_DISC_FULL; else o->fabricated_disc_status= BURN_DISC_BLANK; return 1; } } else { /* No read capacity means blank media */ o->fabricated_disc_status= BURN_DISC_BLANK; return 1; } /* check first 64K. If 0's, the disc is treated as a blank disc, and thus overwritten without extra check. */ i = Libisoburn_target_head_sizE; while (i && !o->target_iso_head[i-1]) --i; if (!i) { o->fabricated_disc_status= BURN_DISC_BLANK; return 1; } pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048); if (!strncmp((char*)pvm->std_identifier, "CD001", 5)) { off_t size; /* sanity check */ if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 || pvm->file_structure_version[0] != 1 ) { /* TODO for now I treat this as a full disc */ o->fabricated_disc_status= BURN_DISC_FULL; return 1; } /* ok, PVM found, set size */ size = (off_t) iso_read_lsb(pvm->vol_space_size, 4); size *= (off_t) 2048; /* block size in bytes */ isoburn_set_start_byte(o, size, 0); o->fabricated_disc_status= BURN_DISC_APPENDABLE; } else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) { /* empty image */ isoburn_set_start_byte(o, o->zero_nwa * 2048, 0); o->fabricated_disc_status= BURN_DISC_BLANK; } else { /* treat any disc in an unknown format as full */ o->fabricated_disc_status= BURN_DISC_FULL; } return 1; }