963 lines
23 KiB
C
963 lines
23 KiB
C
|
|
/*
|
|
cc -g -c isoburn.c
|
|
*/
|
|
|
|
/*
|
|
Class core of libisoburn.
|
|
|
|
Copyright 2007 - 2009 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
|
|
Thomas Schmitt <scdbackup@gmx.net>
|
|
*/
|
|
|
|
/* ( derived from stub generated by CgeN on Sat, 01 Sep 2007 12:04:36 GMT ) */
|
|
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
|
|
#ifndef Xorriso_standalonE
|
|
|
|
#include <libburn/libburn.h>
|
|
|
|
#include <libisofs/libisofs.h>
|
|
|
|
#else /* ! Xorriso_standalonE */
|
|
|
|
#include "../libisofs/libisofs.h"
|
|
#include "../libburn/libburn.h"
|
|
|
|
#endif /* Xorriso_standalonE */
|
|
|
|
|
|
#include "libisoburn.h"
|
|
|
|
#include "isoburn.h"
|
|
|
|
|
|
/* Default values for application provided msgs_submit methods.
|
|
To be attached to newly aquired drives.
|
|
*/
|
|
int (*libisoburn_default_msgs_submit)
|
|
(void *handle, int error_code, char msg_text[],
|
|
int os_errno, char severity[], int flag)= NULL;
|
|
void *libisoburn_default_msgs_submit_handle= NULL;
|
|
int libisoburn_default_msgs_submit_flag= 0;
|
|
|
|
|
|
/* ----------------------- isoburn_toc_entry ---------------------- */
|
|
|
|
|
|
int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt,
|
|
struct isoburn_toc_entry *boss, int flag)
|
|
{
|
|
struct isoburn_toc_entry *o, *s;
|
|
|
|
*objpt= o= (struct isoburn_toc_entry *)
|
|
malloc(sizeof(struct isoburn_toc_entry));
|
|
if(o==NULL) {
|
|
isoburn_msgs_submit(NULL, 0x00060000,
|
|
"Cannot allocate memory for isoburn toc entry",
|
|
0, "FATAL", 0);
|
|
return(-1);
|
|
}
|
|
o->session= 0;
|
|
o->track_no= 0;
|
|
o->start_lba= -1;
|
|
o->track_blocks= 0;
|
|
o->next= NULL;
|
|
if(boss!=NULL) {
|
|
for(s= boss; s->next!=NULL; s= s->next);
|
|
s->next= o;
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* @param flag bit0= delete all subordinates too
|
|
*/
|
|
int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag)
|
|
{
|
|
if(*o==NULL)
|
|
return(0);
|
|
if(flag&1)
|
|
isoburn_toc_entry_destroy(&((*o)->next), flag);
|
|
free((char *) (*o));
|
|
*o= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* --------------------- end isoburn_toc_entry -------------------- */
|
|
|
|
/* -------------------------- isoburn ----------------------- */
|
|
|
|
|
|
/* The global list of isoburn objects. Usually there is only one.
|
|
>>> we are not ready for multiple control threads yet. See >>> mutex .
|
|
Multiple burns under one control thread should work.
|
|
*/
|
|
struct isoburn *isoburn_list_start= NULL;
|
|
|
|
|
|
int isoburn_new(struct isoburn **objpt, int flag)
|
|
{
|
|
struct isoburn *o;
|
|
int i, ret;
|
|
|
|
*objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn));
|
|
if(o==NULL) {
|
|
isoburn_msgs_submit(NULL, 0x00060000,
|
|
"Cannot allocate memory for isoburn control object",
|
|
0, "FATAL", 0);
|
|
return(-1);
|
|
}
|
|
|
|
o->drive= NULL;
|
|
o->emulation_mode= 0;
|
|
o->fabricated_msc1= -1;
|
|
o->fabricated_msc2= -1;
|
|
o->zero_nwa= Libisoburn_overwriteable_starT;
|
|
o->min_start_byte= o->zero_nwa * 2048;
|
|
o->nwa= o->zero_nwa;
|
|
o->truncate= 0;
|
|
o->iso_source= NULL;
|
|
o->fabricated_disc_status= BURN_DISC_UNREADY;
|
|
o->toc= NULL;
|
|
o->wrote_well= -1;
|
|
for(i=0;i<Libisoburn_target_head_sizE;i++)
|
|
o->target_iso_head[i]= 0;
|
|
o->image= NULL;
|
|
o->iso_data_source= NULL;
|
|
o->read_pacifier= NULL;
|
|
o->read_pacifier_handle= NULL;
|
|
o->msgs_submit= NULL;
|
|
o->msgs_submit_handle= NULL;
|
|
o->msgs_submit_flag= 0;
|
|
o->prev= NULL;
|
|
o->next= NULL;
|
|
ret= iso_image_new("ISOIMAGE", &o->image);
|
|
if(ret<0) {
|
|
isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0);
|
|
goto failed;
|
|
}
|
|
isoburn_link(o, isoburn_list_start, 1);
|
|
return(1);
|
|
failed:;
|
|
isoburn_destroy(objpt, 0);
|
|
return(-1);
|
|
}
|
|
|
|
|
|
int isoburn_destroy(struct isoburn **objpt, int flag)
|
|
{
|
|
struct isoburn *o;
|
|
|
|
o= *objpt;
|
|
if(o==NULL)
|
|
return(0);
|
|
|
|
/* >>> mutex */
|
|
|
|
if(o==isoburn_list_start)
|
|
isoburn_list_start= o->next;
|
|
if(o->prev!=NULL)
|
|
o->prev->next= o->next;
|
|
if(o->next!=NULL)
|
|
o->next->prev= o->prev;
|
|
|
|
/* >>> end mutex */
|
|
|
|
if(o->image!=NULL)
|
|
iso_image_unref(o->image);
|
|
if(o->toc!=NULL)
|
|
isoburn_toc_entry_destroy(&(o->toc), 1); /* all */
|
|
if(o->iso_source!=NULL)
|
|
burn_source_free(o->iso_source);
|
|
if(o->iso_data_source!=NULL)
|
|
iso_data_source_unref(o->iso_data_source);
|
|
free((char *) o);
|
|
*objpt= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_destroy_all(struct isoburn **objpt, int flag)
|
|
{
|
|
struct isoburn *o,*n;
|
|
|
|
o= *objpt;
|
|
if(o==NULL)
|
|
return(0);
|
|
for(;o->prev!=NULL;o= o->prev);
|
|
for(;o!=NULL;o= n) {
|
|
n= o->next;
|
|
isoburn_destroy(&o,0);
|
|
}
|
|
*objpt= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag)
|
|
{
|
|
*pt= o->image;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag)
|
|
{
|
|
*pt= o->prev;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag)
|
|
{
|
|
*pt= o->next;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_link(struct isoburn *o, struct isoburn *link, int flag)
|
|
/*
|
|
bit0= insert as link->prev rather than as link->next
|
|
*/
|
|
{
|
|
|
|
/* >>> mutex */
|
|
|
|
if(isoburn_list_start==NULL ||
|
|
(isoburn_list_start==link && (flag&1)))
|
|
isoburn_list_start= o;
|
|
if(o->prev!=NULL)
|
|
o->prev->next= o->next;
|
|
if(o->next!=NULL)
|
|
o->next->prev= o->prev;
|
|
o->prev= o->next= NULL;
|
|
if(link==NULL)
|
|
return(1);
|
|
if(flag&1) {
|
|
o->next= link;
|
|
o->prev= link->prev;
|
|
if(o->prev!=NULL)
|
|
o->prev->next= o;
|
|
link->prev= o;
|
|
} else {
|
|
o->prev= link;
|
|
o->next= link->next;
|
|
if(o->next!=NULL)
|
|
o->next->prev= o;
|
|
link->next= o;
|
|
}
|
|
|
|
/* >>> end mutex */
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_count(struct isoburn *o, int flag)
|
|
/* flag: bit1= count from start of list */
|
|
{
|
|
int counter= 0;
|
|
|
|
if(flag&2)
|
|
for(;o->prev!=NULL;o= o->prev);
|
|
for(;o!=NULL;o= o->next)
|
|
counter++;
|
|
return(counter);
|
|
}
|
|
|
|
|
|
int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag)
|
|
/* flag: bit0= fetch first (idx<0) or last (idx>0) item in list
|
|
bit1= address from start of list */
|
|
{
|
|
int i,abs_idx;
|
|
struct isoburn *npt;
|
|
|
|
if(flag&2)
|
|
for(;o->prev!=NULL;o= o->prev);
|
|
abs_idx= (idx>0?idx:-idx);
|
|
*pt= o;
|
|
for(i= 0;(i<abs_idx || (flag&1)) && *pt!=NULL;i++) {
|
|
if(idx>0)
|
|
npt= o->next;
|
|
else
|
|
npt= o->prev;
|
|
if(npt==NULL && (flag&1))
|
|
break;
|
|
*pt= npt;
|
|
}
|
|
return(*pt!=NULL);
|
|
}
|
|
|
|
|
|
int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag)
|
|
{
|
|
struct isoburn *o;
|
|
|
|
*pt= NULL;
|
|
for(o= isoburn_list_start;o!=NULL;o= o->next)
|
|
if(o->drive==d) {
|
|
*pt= o;
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
int isoburn_msgs_submit(struct isoburn *o, int error_code, char msg_text[],
|
|
int os_errno, char severity[], int flag)
|
|
{
|
|
int ret, use_drive_method= 0;
|
|
|
|
if(o!=NULL)
|
|
if(o->msgs_submit!=NULL)
|
|
use_drive_method= 1;
|
|
if(use_drive_method) {
|
|
ret= o->msgs_submit(o->msgs_submit_handle, error_code, msg_text, os_errno,
|
|
severity, o->msgs_submit_flag);
|
|
return(ret);
|
|
}
|
|
if(libisoburn_default_msgs_submit != NULL) {
|
|
ret= libisoburn_default_msgs_submit(libisoburn_default_msgs_submit_handle,
|
|
error_code, msg_text, os_errno, severity,
|
|
libisoburn_default_msgs_submit_flag);
|
|
return(ret);
|
|
}
|
|
/* Fallback: use message queue of libburn */
|
|
burn_msgs_submit(error_code, msg_text, os_errno, severity, NULL);
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* @param flag bit0= modifying rather than growing
|
|
bit1= prepare for early release of input drive:
|
|
wait until input and then disable image data source
|
|
*/
|
|
static
|
|
int isoburn_prepare_disc_aux(struct burn_drive *in_d, struct burn_drive *out_d,
|
|
struct burn_disc **disc,
|
|
struct isoburn_imgen_opts *opts, int flag)
|
|
{
|
|
struct burn_source *wsrc;
|
|
struct burn_session *session;
|
|
struct burn_track *track;
|
|
struct isoburn *in_o, *out_o;
|
|
IsoWriteOpts *wopts= NULL;
|
|
enum burn_disc_status state;
|
|
int ret, fifo_chunks, lba, nwa, i, new_img, early_indev_release;
|
|
size_t buffer_size= 0, buffer_free= 0;
|
|
char msg[160];
|
|
|
|
new_img= flag&1;
|
|
early_indev_release= flag&2;
|
|
if(new_img && early_indev_release) {
|
|
isoburn_msgs_submit(in_o, 0x00060000,
|
|
"Programming error: Wrong session setup: new_img && early_indev_release",
|
|
0, "FATAL", 0);
|
|
{ret= -4; goto ex;}
|
|
}
|
|
|
|
ret= isoburn_find_emulator(&in_o, in_d, 0);
|
|
if(ret<0 || in_o==NULL)
|
|
{ret= -1; goto ex;}
|
|
ret= isoburn_find_emulator(&out_o, out_d, 0);
|
|
if(ret<0 || out_o==NULL)
|
|
{ret= -1; goto ex;}
|
|
/* early end will be registered as failure */
|
|
in_o->wrote_well= out_o->wrote_well= 0;
|
|
|
|
state = isoburn_disc_get_status(in_d);
|
|
if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE &&
|
|
state != BURN_DISC_FULL) {
|
|
isoburn_msgs_submit(in_o, 0x00060000, "Unsuitable source media state",
|
|
0, "FAILURE", 0);
|
|
{ret= -2; goto ex;}
|
|
}
|
|
state = isoburn_disc_get_status(out_d);
|
|
if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) {
|
|
isoburn_msgs_submit(out_o, 0x00060000, "Unsuitable target media state",
|
|
0, "FAILURE", 0);
|
|
{ret= -2; goto ex;}
|
|
}
|
|
|
|
fifo_chunks= 32;
|
|
if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){
|
|
fifo_chunks= opts->fifo_size/2048;
|
|
if(fifo_chunks*2048 < opts->fifo_size)
|
|
fifo_chunks++;
|
|
}
|
|
|
|
ret = iso_write_opts_new(&wopts, 0);
|
|
if (ret < 0) {
|
|
isoburn_report_iso_error(ret, "Cannot create iso_write_opts", 0, "FATAL",0);
|
|
goto ex;
|
|
}
|
|
iso_write_opts_set_iso_level(wopts, opts->level);
|
|
iso_write_opts_set_rockridge(wopts, opts->rockridge);
|
|
iso_write_opts_set_joliet(wopts, opts->joliet);
|
|
iso_write_opts_set_iso1999(wopts, opts->iso1999);
|
|
iso_write_opts_set_omit_version_numbers(wopts, opts->omit_version_numbers);
|
|
iso_write_opts_set_allow_deep_paths(wopts, opts->allow_deep_paths);
|
|
iso_write_opts_set_allow_longer_paths(wopts, opts->allow_longer_paths);
|
|
iso_write_opts_set_max_37_char_filenames(wopts, opts->max_37_char_filenames);
|
|
iso_write_opts_set_no_force_dots(wopts, opts->no_force_dots);
|
|
iso_write_opts_set_allow_lowercase(wopts, opts->allow_lowercase);
|
|
iso_write_opts_set_allow_full_ascii(wopts, opts->allow_full_ascii);
|
|
iso_write_opts_set_relaxed_vol_atts(wopts, 1);
|
|
iso_write_opts_set_joliet_longer_paths(wopts, opts->joliet_longer_paths);
|
|
iso_write_opts_set_always_gmt(wopts, opts->always_gmt);
|
|
iso_write_opts_set_rrip_version_1_10(wopts, opts->rrip_version_1_10);
|
|
iso_write_opts_set_dir_rec_mtime(wopts, opts->dir_rec_mtime);
|
|
iso_write_opts_set_sort_files(wopts, opts->sort_files);
|
|
iso_write_opts_set_replace_mode(wopts, opts->replace_dir_mode,
|
|
opts->replace_file_mode, opts->replace_uid, opts->replace_gid);
|
|
iso_write_opts_set_default_dir_mode(wopts, opts->dir_mode);
|
|
iso_write_opts_set_default_file_mode(wopts, opts->file_mode);
|
|
iso_write_opts_set_default_uid(wopts, opts->uid);
|
|
iso_write_opts_set_default_gid(wopts, opts->gid);
|
|
iso_write_opts_set_output_charset(wopts, opts->output_charset);
|
|
iso_write_opts_set_fifo_size(wopts, fifo_chunks);
|
|
|
|
ret = isoburn_disc_track_lba_nwa(out_d, NULL, 0, &lba, &nwa);
|
|
opts->effective_lba= nwa;
|
|
ret= isoburn_get_msc2(out_o, NULL, &nwa, 0);
|
|
if (ret != 1) {
|
|
isoburn_msgs_submit(out_o, 0x00060000,
|
|
"Cannot determine next writeable address", 0, "FAILURE", 0);
|
|
{ret= -3; goto ex;}
|
|
}
|
|
iso_write_opts_set_ms_block(wopts, nwa);
|
|
iso_write_opts_set_appendable(wopts, !new_img);
|
|
iso_write_opts_set_overwrite_buf(wopts,
|
|
nwa>0 ? out_o->target_iso_head : NULL);
|
|
|
|
ret = iso_image_create_burn_source(in_o->image, wopts, &wsrc);
|
|
if (ret < 0) {
|
|
isoburn_report_iso_error(ret, "Cannot create burn source", 0, "FAILURE", 0);
|
|
{ret= -1; goto ex;}
|
|
}
|
|
if (early_indev_release) {
|
|
for(i= 0; i<300; i++) {
|
|
|
|
/* <<< ??? */
|
|
if((i%30) == 0) {
|
|
sprintf(msg, "Waiting for data in fifo since %d seconds", i/30);
|
|
isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
|
|
}
|
|
|
|
usleep(100000);
|
|
ret= iso_ring_buffer_get_status(wsrc, &buffer_size, &buffer_free);
|
|
if(ret >0 && buffer_size != buffer_free)
|
|
break;
|
|
}
|
|
|
|
/* <<< ??? */
|
|
sprintf(msg,
|
|
"After %.1f seconds: %d bytes of output available (fifo state=%d)",
|
|
((double) i+1) / 10.0, (int) (buffer_size - buffer_free), ret);
|
|
isoburn_msgs_submit(in_o, 0x00060000, msg, 0, "DEBUG", 0);
|
|
|
|
if(in_o->iso_data_source!=NULL)
|
|
isoburn_data_source_shutdown(in_o->iso_data_source, 0);
|
|
}
|
|
|
|
/* TODO check return values for failure. propertly clean-up on error */
|
|
|
|
out_o->iso_source= wsrc;
|
|
|
|
*disc = burn_disc_create();
|
|
session = burn_session_create();
|
|
burn_disc_add_session(*disc, session, BURN_POS_END);
|
|
track = burn_track_create();
|
|
burn_track_set_source(track, out_o->iso_source);
|
|
burn_session_add_track(session, track, BURN_POS_END);
|
|
|
|
/* give up local references */
|
|
burn_track_free(track);
|
|
burn_session_free(session);
|
|
|
|
in_o->wrote_well= out_o->wrote_well= -1; /* neutral */
|
|
ret= 1;
|
|
ex:
|
|
if(wopts!=NULL)
|
|
{iso_write_opts_free(wopts); wopts= NULL;}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc,
|
|
struct isoburn_imgen_opts *opts)
|
|
{
|
|
return isoburn_prepare_disc_aux(d, d, disc, opts, 0);
|
|
}
|
|
|
|
|
|
int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc,
|
|
struct isoburn_imgen_opts *opts,
|
|
struct burn_drive *out_drive)
|
|
{
|
|
int ret;
|
|
|
|
ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 1);
|
|
if (ret<=0)
|
|
return ret;
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* API since 0.2.2 */
|
|
int isoburn_prepare_blind_grow(struct burn_drive *d, struct burn_disc **disc,
|
|
struct isoburn_imgen_opts *opts,
|
|
struct burn_drive *out_drive, int nwa)
|
|
{
|
|
int ret;
|
|
struct isoburn *o= NULL;
|
|
|
|
ret= isoburn_find_emulator(&o, out_drive, 0);
|
|
if(ret<0 || o==NULL)
|
|
return(-1);
|
|
if(nwa >= 0)
|
|
o->fabricated_msc2= nwa;
|
|
if(o->nwa == o->zero_nwa)
|
|
o->nwa= o->zero_nwa= 0;
|
|
else
|
|
o->zero_nwa= 0;
|
|
ret= isoburn_prepare_disc_aux(d, out_drive, disc, opts, 2);
|
|
if (ret<=0)
|
|
return ret;
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* API @since 0.1.0
|
|
@param flag bit0= this is a regular end, not an abort
|
|
give up source reference
|
|
*/
|
|
int isoburn_cancel_prepared_write(struct burn_drive *d,
|
|
struct burn_drive *output_drive, int flag)
|
|
{
|
|
int ret;
|
|
struct isoburn *o= NULL;
|
|
|
|
if(output_drive!=NULL) {
|
|
ret= isoburn_find_emulator(&o, output_drive, 0);
|
|
if(ret<0 || o==NULL)
|
|
o= NULL;
|
|
else if(o->iso_source==NULL)
|
|
o= NULL;
|
|
}
|
|
if(o==NULL) {
|
|
ret= isoburn_find_emulator(&o, d, 0);
|
|
if(ret<0)
|
|
return(-1);
|
|
if(o==NULL)
|
|
return(0);
|
|
if(o->iso_source==NULL)
|
|
return(0);
|
|
}
|
|
if(o->iso_source->read!=NULL)
|
|
return(0);
|
|
if(o->iso_source->version<1)
|
|
return(0);
|
|
o->iso_source->cancel(o->iso_source);
|
|
burn_source_free(o->iso_source);
|
|
o->iso_source= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* API @since 0.1.0 */
|
|
int isoburn_sync_after_write(struct burn_drive *d,
|
|
struct burn_drive *output_drive, int flag)
|
|
{
|
|
return isoburn_cancel_prepared_write(d, output_drive, 1);
|
|
}
|
|
|
|
|
|
void isoburn_version(int *major, int *minor, int *micro)
|
|
{
|
|
*major= isoburn_header_version_major;
|
|
*minor= isoburn_header_version_minor;
|
|
*micro= isoburn_header_version_micro;
|
|
|
|
/* No more: values from version.h generated from version.h.in and
|
|
macro values defined in configure.ac
|
|
|
|
*major = ISOBURN_MAJOR_VERSION;
|
|
*minor = ISOBURN_MINOR_VERSION;
|
|
*micro = ISOBURN_MICRO_VERSION;
|
|
*/
|
|
}
|
|
|
|
|
|
int isoburn_is_compatible(int major, int minor, int micro, int flag)
|
|
{
|
|
int own_major, own_minor, own_micro;
|
|
|
|
isoburn_version(&own_major, &own_minor, &own_micro);
|
|
return(own_major > major ||
|
|
(own_major == major && (own_minor > minor ||
|
|
(own_minor == minor && own_micro >= micro))));
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
/*
|
|
Options for image reading.
|
|
*/
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
|
|
int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag)
|
|
{
|
|
struct isoburn_read_opts *o;
|
|
|
|
o= (*new_o)= calloc(1, sizeof(struct isoburn_read_opts));
|
|
if(o==NULL) {
|
|
isoburn_msgs_submit(NULL, 0x00060000,
|
|
"Cannot allocate memory for read options", 0, "FATAL", 0);
|
|
return(-1);
|
|
}
|
|
o->norock= 0;
|
|
o->nojoliet= 0;
|
|
o->noiso1999= 1;
|
|
o->preferjoliet= 0;
|
|
o->uid= geteuid();
|
|
o->gid= getegid();
|
|
o->mode= 0444;
|
|
o->dirmode= 0555;
|
|
o->input_charset= NULL;
|
|
o->hasRR= 0;
|
|
o->hasJoliet= 0;
|
|
o->hasIso1999= 0;
|
|
o->hasElTorito= 0;
|
|
o->size= 0;
|
|
o->pretend_blank= 1;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_destroy(struct isoburn_read_opts **o, int flag)
|
|
{
|
|
if(*o==NULL)
|
|
return(0);
|
|
free(*o);
|
|
*o= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_set_extensions(struct isoburn_read_opts *o, int ext)
|
|
{
|
|
o->norock= !!(ext&1);
|
|
o->nojoliet= !!(ext&2);
|
|
o->noiso1999= !!(ext&4);
|
|
o->preferjoliet= !!(ext&8);
|
|
o->pretend_blank= !!(ext&16);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_get_extensions(struct isoburn_read_opts *o, int *ext)
|
|
{
|
|
*ext= (!!o->norock) | ((!!o->nojoliet)<<1) | ((!!o->noiso1999)<<2) |
|
|
((!!o->preferjoliet)<<3) | ((!!o->pretend_blank)<<4);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_set_default_perms(struct isoburn_read_opts *o,
|
|
uid_t uid, gid_t gid, mode_t mode)
|
|
{
|
|
mode_t dirmode;
|
|
|
|
o->uid= uid;
|
|
o->gid= gid;
|
|
o->mode= mode;
|
|
dirmode= mode;
|
|
if(dirmode & S_IRUSR)
|
|
dirmode|= S_IXUSR;
|
|
if(dirmode & S_IRGRP)
|
|
dirmode|= S_IXGRP;
|
|
if(dirmode & S_IROTH)
|
|
dirmode|= S_IXOTH;
|
|
o->dirmode= dirmode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_get_default_perms(struct isoburn_read_opts *o,
|
|
uid_t *uid, gid_t *gid, mode_t *mode)
|
|
{
|
|
*uid= o->uid;
|
|
*gid= o->gid;
|
|
*mode= o->mode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_set_default_dirperms(struct isoburn_read_opts *o,
|
|
mode_t mode)
|
|
{
|
|
o->dirmode= mode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o,
|
|
mode_t *mode)
|
|
{
|
|
*mode= o->dirmode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o,
|
|
char *input_charset)
|
|
{
|
|
o->input_charset= input_charset;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_in_charset(struct isoburn_read_opts *o,
|
|
char **input_charset)
|
|
{
|
|
*input_charset= o->input_charset;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
|
|
uint32_t *size, int *has_what)
|
|
{
|
|
*size= o->size;
|
|
*has_what= (!!o->hasRR) | ((!!o->hasJoliet)<<1) |
|
|
((!!o->hasIso1999)<<2) | ((!!o->hasElTorito)<<3);
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
/*
|
|
Options for image generation by libisofs and image transport to libburn.
|
|
*/
|
|
/* ----------------------------------------------------------------------- */
|
|
|
|
|
|
int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag)
|
|
{
|
|
struct isoburn_imgen_opts *o;
|
|
|
|
o= (*new_o)= calloc(1, sizeof(struct isoburn_imgen_opts));
|
|
if(o==NULL) {
|
|
isoburn_msgs_submit(NULL, 0x00060000,
|
|
"Cannot allocate memory for image generation options",
|
|
0, "FATAL", 0);
|
|
return(-1);
|
|
}
|
|
o->level= 2;
|
|
o->rockridge= 1;
|
|
o->joliet= 0;
|
|
o->iso1999= 0;
|
|
o->omit_version_numbers= 0;
|
|
o->allow_deep_paths= 1;
|
|
o->allow_longer_paths= 0;
|
|
o->max_37_char_filenames= 0;
|
|
o->no_force_dots= 0;
|
|
o->allow_lowercase= 0;
|
|
o->allow_full_ascii= 0;
|
|
o->joliet_longer_paths= 0;
|
|
o->always_gmt= 0;
|
|
o->rrip_version_1_10= 0;
|
|
o->dir_rec_mtime= 0;
|
|
o->sort_files= 0;
|
|
o->replace_dir_mode= 0;
|
|
o->replace_file_mode= 0;
|
|
o->replace_uid= 0;
|
|
o->replace_gid= 0;
|
|
o->dir_mode= 0555;
|
|
o->file_mode= 0444;
|
|
o->uid= 0;
|
|
o->gid= 0;
|
|
o->output_charset= NULL;
|
|
o->fifo_size= 4*1024*1024;
|
|
o->effective_lba= -1;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag)
|
|
{
|
|
if(*o==NULL)
|
|
return(0);
|
|
free(*o);
|
|
*o= NULL;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_level(struct isoburn_imgen_opts *o, int level)
|
|
{
|
|
o->level= level;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_level(struct isoburn_imgen_opts *o, int *level)
|
|
{
|
|
*level= o->level;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_extensions(struct isoburn_imgen_opts *o, int ext)
|
|
{
|
|
o->rockridge= !!(ext&1);
|
|
o->joliet= !!(ext&2);
|
|
o->iso1999= !!(ext&4);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext)
|
|
{
|
|
*ext= (!!o->rockridge) | ((!!o->joliet)<<1) | ((!!o->iso1999)<<2);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_relaxed(struct isoburn_imgen_opts *o, int relax)
|
|
{
|
|
o->omit_version_numbers= !!(relax&1);
|
|
o->allow_deep_paths= !!(relax&2);
|
|
o->allow_longer_paths= !!(relax&4);
|
|
o->max_37_char_filenames= !!(relax&8);
|
|
o->no_force_dots= !!(relax&16);
|
|
o->allow_lowercase= !!(relax&32);
|
|
o->allow_full_ascii= !!(relax&64);
|
|
o->joliet_longer_paths= !!(relax&128);
|
|
o->always_gmt= !!(relax & isoburn_igopt_always_gmt);
|
|
o->rrip_version_1_10= !!(relax & isoburn_igopt_rrip_version_1_10);
|
|
o->dir_rec_mtime= !!(relax & isoburn_igopt_dir_rec_mtime);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_relaxed(struct isoburn_imgen_opts *o, int *relax)
|
|
{
|
|
*relax= (!!o->omit_version_numbers) | ((!!o->allow_deep_paths)<<1) |
|
|
((!!o->allow_longer_paths)<<2) | ((!!o->max_37_char_filenames)<<3) |
|
|
((!!o->no_force_dots)<<4) | ((!!o->allow_lowercase)<<5) |
|
|
((!!o->allow_full_ascii)<<6) | ((!!o->joliet_longer_paths)<<7);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_sort_files(struct isoburn_imgen_opts *o, int value)
|
|
{
|
|
o->sort_files= !!(value&1);
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_sort_files(struct isoburn_imgen_opts *o, int *value)
|
|
{
|
|
*value= !!o->sort_files;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_over_mode(struct isoburn_imgen_opts *o,
|
|
int replace_dir_mode, int replace_file_mode,
|
|
mode_t dir_mode, mode_t file_mode)
|
|
{
|
|
o->replace_dir_mode= replace_dir_mode%3;
|
|
o->replace_file_mode= replace_file_mode%3;
|
|
o->dir_mode= dir_mode;
|
|
o->file_mode= file_mode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_over_mode(struct isoburn_imgen_opts *o,
|
|
int *replace_dir_mode, int *replace_file_mode,
|
|
mode_t *dir_mode, mode_t *file_mode)
|
|
{
|
|
*replace_dir_mode= o->replace_dir_mode%3;
|
|
*replace_file_mode= o->replace_file_mode%3;
|
|
*dir_mode= o->dir_mode;
|
|
*file_mode= o->file_mode;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_over_ugid(struct isoburn_imgen_opts *o,
|
|
int replace_uid, int replace_gid,
|
|
uid_t uid, gid_t gid)
|
|
{
|
|
o->replace_uid= replace_uid%3;
|
|
o->replace_gid= replace_gid%3;
|
|
o->uid= uid;
|
|
o->gid= gid;
|
|
return(1);
|
|
}
|
|
|
|
int isoburn_igopt_get_over_ugid(struct isoburn_imgen_opts *o,
|
|
int *replace_uid, int *replace_gid,
|
|
uid_t *uid, gid_t *gid)
|
|
{
|
|
*replace_uid= o->replace_uid%3;
|
|
*replace_gid= o->replace_gid%3;
|
|
*uid= o->uid;
|
|
*gid= o->gid;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_out_charset(struct isoburn_imgen_opts *o,
|
|
char *output_charset)
|
|
{
|
|
o->output_charset= output_charset;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_out_charset(struct isoburn_imgen_opts *o,
|
|
char **output_charset)
|
|
{
|
|
*output_charset= o->output_charset;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_set_fifo_size(struct isoburn_imgen_opts *o, int fifo_size)
|
|
{
|
|
o->fifo_size= fifo_size;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_fifo_size(struct isoburn_imgen_opts *o, int *fifo_size)
|
|
{
|
|
*fifo_size= o->fifo_size;
|
|
return(1);
|
|
}
|
|
|
|
|
|
int isoburn_igopt_get_effective_lba(struct isoburn_imgen_opts *o, int *lba)
|
|
{
|
|
*lba= o->effective_lba;
|
|
return(1);
|
|
}
|
|
|
|
|