#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 | 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 BP | ( | a, | |||
b | ) | [(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.
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.
d | The output drive to which the session was written |
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.
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 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.
d | The drive to inquire |
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] |
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 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.
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 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.
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 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.
o | A freshly created isoburn object. isoburn_create_data_source() was already called, nevertheless. |
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 }