libisoburn/src/isoburn.c

288 lines
5.5 KiB
C

/*
cc -g -c isoburn.c
*/
/*
Class core of libisoburn.
Copyright 2007 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
and 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>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "isoburn.h"
/* -------------------------- 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;
*objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn));
if(o==NULL)
return(-1);
o->drive= NULL;
o->emulation_mode= 0;
o->min_start_byte= 0;
o->nwa= 0;
o->src= NULL;
o->fabricated_disc_status= BURN_DISC_UNREADY;
for(i=0;i<65536;i++)
o->target_iso_head[i]= 0;
o->target_volset= NULL;
o->prev= NULL;
o->next= NULL;
isoburn_link(o, isoburn_list_start, 1);
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->target_volset!=NULL)
iso_volset_free(o->target_volset);
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_emulation_mode(struct isoburn *o, int *pt, int flag)
{
*pt= o->emulation_mode;
return(1);
}
int isoburn_get_target_volset(struct isoburn *o, struct iso_volset **pt,
int flag)
{
*pt= o->target_volset;
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->prev)
if(o->drive==d) {
*pt= o;
return(1);
}
return(0);
}
static
int isoburn_prepare_disc_aux(struct burn_drive *d, struct burn_disc **disc,
int new_img)
{
struct burn_source *wsrc;
struct burn_session *session;
struct burn_track *track;
struct isoburn *o;
struct ecma119_source_opts wopts;
int ret;
ret= isoburn_find_emulator(&o, d, 0);
if(ret<0)
return -1;
// TODO check return values for failure. propertly clean-up on error
*disc = burn_disc_create();
session = burn_session_create();
burn_disc_add_session(*disc, session, BURN_POS_END);
// FIXME we need a way to allow users to pass parameters to this!!
wopts.volnum = 0;
wopts.level = 2;
wopts.flags = 0;
wopts.relaxed_constraints = 0;
wopts.copy_eltorito = 0;
wopts.no_cache_inodes = 0;
wopts.sort_files = 1;
wopts.default_mode = 0;
wopts.replace_dir_mode = 0;
wopts.replace_file_mode = 0;
wopts.replace_uid = 0;
wopts.replace_gid = 0;
wopts.dir_mode = 0555;
wopts.file_mode = 0555;
wopts.gid = 0;
wopts.uid = 0;
wopts.input_charset = NULL;
wopts.ouput_charset = NULL;
wopts.ms_block = (new_img ? 0 : o->nwa);
wopts.src = o->src;
wopts.overwrite = (new_img ? NULL : o->target_iso_head);
wsrc = iso_source_new_ecma119(o->target_volset, &wopts);
track = burn_track_create();
burn_track_set_source(track, wsrc);
burn_session_add_track(session, track, BURN_POS_END);
return 1;
}
int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc)
{
return isoburn_prepare_disc_aux(d, disc, 0);
}
int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc)
{
return isoburn_prepare_disc_aux(d, disc, 1);
}