#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 33 of file isofs_wrap.c.
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().
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 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.
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 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.
d | The drive to inquire |
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().
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 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.
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 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.
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 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.
o | A freshly created isoburn object. isoburn_create_data_source() was already called, nevertheless. |
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 }