From 4b1bcb6a378eff050b8f6d064ec300fc2def100e Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Lopes Date: Sat, 22 Sep 2007 15:19:05 +0000 Subject: [PATCH] Add example test program and some changes to make it work --- Makefile.am | 7 +- src/burn_wrap.c | 4 +- src/data_source.c | 11 +-- src/isoburn.c | 36 +++++++-- src/isoburn.h | 7 +- src/isofs_wrap.c | 69 ++++++++--------- test/test.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 266 insertions(+), 55 deletions(-) create mode 100644 test/test.c diff --git a/Makefile.am b/Makefile.am index 9b25310c..337dd026 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,12 @@ libinclude_HEADERS = \ ## ========================================================================= ## ## Build test applications -noinst_PROGRAMS = +noinst_PROGRAMS = \ + test/test + +test_test_CPPFLAGS = -Ilibisofs -Ilibburn -Ilibisoburn +test_test_LDADD = $(src_libisoburn_la_OBJECTS) $(THREAD_LIBS) -lburn -lisofs +test_test_SOURCES = test/test.c bin_PROGRAMS = diff --git a/src/burn_wrap.c b/src/burn_wrap.c index 06d81a47..146ffc03 100644 --- a/src/burn_wrap.c +++ b/src/burn_wrap.c @@ -20,8 +20,8 @@ #include -#include -#include +#include +#include #include "libisoburn.h" #include "isoburn.h" diff --git a/src/data_source.c b/src/data_source.c index 79de91b3..0da3108f 100644 --- a/src/data_source.c +++ b/src/data_source.c @@ -7,8 +7,8 @@ #include #include -#include -#include +#include +#include #include "isoburn.h" struct disc_data_src { @@ -31,9 +31,10 @@ ds_read_block(struct data_source *src, int lba, unsigned char *buffer) * return BLOCK_OUT_OF_FILE; */ - ret = burn_read_data(data->d, (off_t) lba * (off_t) 2048, buffer, 2048, &count, 0); + ret = burn_read_data(data->d, (off_t) lba * (off_t) 2048, (char *) buffer, + 2048, &count, 0); if (ret <= 0 ) - return -1; //error + return -1; return 0; } @@ -55,7 +56,7 @@ ds_free_data(struct data_source *src) free(src->data); } -static struct data_source * +struct data_source * isoburn_data_source_new(struct burn_drive *d) { struct disc_data_src *data; diff --git a/src/isoburn.c b/src/isoburn.c index e09b23ad..5f24aef2 100644 --- a/src/isoburn.c +++ b/src/isoburn.c @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include #include "isoburn.h" @@ -39,7 +39,6 @@ int isoburn_new(struct isoburn **objpt, int flag) { struct isoburn *o; int i; - int isoburn_new_rwopts(struct isoburn *o); *objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn)); if(o==NULL) @@ -50,7 +49,7 @@ int isoburn_new(struct isoburn **objpt, int flag) o->min_start_byte= 0; o->nwa= 0; o->treatment= 1; - o->target_ropts= NULL; + o->src= NULL; o->new_wopts= NULL; o->fabricated_disc_status= BURN_DISC_UNREADY; for(i=0;i<65536;i++) @@ -227,7 +226,7 @@ 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->prev!=NULL;o= o->prev) + for(o= isoburn_list_start;o!=NULL;o= o->prev) if(o->drive==d) { *pt= o; return(1); @@ -235,3 +234,30 @@ int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag) return(0); } +int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc) +{ + struct burn_source *wsrc; + struct burn_session *session; + struct burn_track *track; + struct isoburn *o; + int ret; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return -1; + + *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!! + o->new_wopts->ms_block = o->nwa; + o->new_wopts->src = o->src; + wsrc = iso_source_new_ecma119(o->target_volset, o->new_wopts); + + track = burn_track_create(); + burn_track_set_source(track, wsrc); + burn_session_add_track(session, track, BURN_POS_END); + + return 1; +} diff --git a/src/isoburn.h b/src/isoburn.h index 2f72f50e..1f33cf9c 100644 --- a/src/isoburn.h +++ b/src/isoburn.h @@ -50,10 +50,9 @@ struct isoburn { /* Expansion treatment strategy: 1= grow, 2= modify, (any use for 0 ?) */ int treatment; - - /* The options for reading the old image. - target_ropts.size will contain the number of blocks of the image. */ - struct ecma119_read_opts *target_ropts; + + /* The data source for reading the old image */ + struct data_source *src; /* Buffered ISO head from media (should that become part of ecma119_read_opts ?) */ diff --git a/src/isofs_wrap.c b/src/isofs_wrap.c index 7add8fcf..614ce977 100644 --- a/src/isofs_wrap.c +++ b/src/isofs_wrap.c @@ -13,21 +13,10 @@ #include #include -#include -#include +#include +#include #include "isoburn.h" - -/* Vreixo: - - This is now all yours. My text here is only a snapshot - of what i think we discussed in the last days. - - If you change the prototypes of the functions listed - in this initial stub, then you have to change isoburn.h - and eventually libisoburn.h. And you have to tell me so - i can adjust burn_wrap.c . - -*/ +#include "libisoburn.h" #define BP(a,b) [(b) - (a) + 1] @@ -87,7 +76,6 @@ int isoburn_read_volset(struct burn_drive *d, struct isoburn_read_opts *read_opt { int ret; struct ecma119_read_opts ropts; - struct data_source *src; struct isoburn *o; assert(d && read_opts && volset); @@ -96,15 +84,19 @@ int isoburn_read_volset(struct burn_drive *d, struct isoburn_read_opts *read_opt if (ret < 0) return 0; + if (!o) { + return -1; + } + if (o->fabricated_disc_status == BURN_DISC_BLANK) { // FIXME construct an empty volset!! *volset = NULL; return 1; } - ret = isoburn_disc_get_msc1(d, &ropts.block); + ret = isoburn_disc_get_msc1(d, (int*) &ropts.block); if (ret < 0) - return -1; + return -2; ropts.norock = read_opts->norock; ropts.nojoliet = read_opts->nojoliet; @@ -113,13 +105,8 @@ int isoburn_read_volset(struct burn_drive *d, struct isoburn_read_opts *read_opt ropts.uid = read_opts->uid; ropts.gid = read_opts->gid; - src = isoburn_data_source_new(d); - if (!src) - return -2; - - *volset = iso_volset_read(src, &ropts); - - data_source_free(src); + assert(o->src); + *volset = iso_volset_read(o->src, &ropts); if (!(*volset)) return -3; @@ -146,7 +133,7 @@ int isoburn_activate_session(struct burn_drive *drive) if (o->emulation_mode != 1) return 1; /* don't need to activate session */ - ret = burn_random_access_write(drive, 0, o->target_iso_head, 64*2048, 0); + ret = burn_random_access_write(drive, 0, (char*)o->target_iso_head, 64*2048, 0); return ret; } @@ -161,13 +148,6 @@ int isoburn_new_rwopts(struct isoburn *o) { struct ecma119_source_opts *wopts; - /* create and initialize target_ropts read options */ - o->target_ropts = calloc(1, sizeof(struct ecma119_read_opts)); - if (!p->target_ropts) - return -1; - - /* TODO mmm, maybe we don't need struct ecma119_read_opts in libisoburn */ - /* create and initialize new_wopts write options for new image */ wopts = calloc(1, sizeof(struct ecma119_source_opts)); if (!wopts) @@ -188,7 +168,10 @@ int isoburn_new_rwopts(struct isoburn *o) */ int isoburn_free_rwopts(struct isoburn *o) { - free(o->target_ropts); + // FIXME I really don't like the data_source_free here. + // isoburn_drive_release() seems a better place + if (o->src) + data_source_free(o->src); free(o->new_wopts); return 1; } @@ -203,18 +186,28 @@ int isoburn_free_rwopts(struct isoburn *o) int isoburn_start_emulation(struct isoburn *o, int flag) { int ret, i; - off_t *data_count; + off_t data_count; struct burn_drive *drive; struct ecma119_pri_vol_desc *pvm; + + assert(o); drive= o->drive; /* we can assume 0 as start block for image */ // TODO what about ms? where we validate valid iso image in ms disc? - ret = burn_read_data(drive, (off_t) 0, o->target_iso_head, + ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, sizeof(o->target_iso_head), &data_count, 0); - // TODO mmm, can a read error mean an empty disc (e.g. CD-R)? - if (ret <= 0) + + /* an error means an empty disc */ + if (ret <= 0) { + o->fabricated_disc_status= BURN_DISC_BLANK; + return 1; + } + + /* create and initialize the data source */ + o->src = isoburn_data_source_new(o->drive); + if (!o->src) return -1; /* check first 64K. If 0's, the disc is treated as a blank disc, and thus @@ -273,7 +266,7 @@ int isoburn_invalidate_iso(struct isoburn *o, int flag) * replace CD001 with CDXX1 in PVM. * I think this is enought for invalidating an iso image */ - strncpy(o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5); + strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5); return isoburn_activate_session(o->drive); } diff --git a/test/test.c b/test/test.c new file mode 100644 index 00000000..596a346d --- /dev/null +++ b/test/test.c @@ -0,0 +1,187 @@ +/* + Little test program for libisoburn. + It grows an iso filesystem on a disc. + + Copyright 2007 Vreixo Formoso Lopes +*/ + + +#include +#include +#include +#include +#include + +#include +#include +#include "../src/libisoburn.h" + +const char * const optstring = "JRh"; +extern char *optarg; +extern int optind; + +static +void usage() +{ + printf("test [OPTIONS] DRIVE DIRECTORY\n"); +} + +static +void help() +{ + printf( +"Options:\n" +" -J Add Joliet support\n" +" -R Add Rock Ridge support\n" +" -h Print this message\n" +); +} + +int main(int argc, char **argv) +{ + struct burn_drive_info *drives; + struct iso_volset *volset; + struct burn_drive *drive; + struct iso_tree_node_dir *root; + struct burn_disc *disc; + enum burn_disc_status state; + struct isoburn_read_opts ropts; + int c; + struct iso_tree_radd_dir_behavior behav = {0,0,0}; + int flags=0; + int ret=0; + + while ((c = getopt(argc, argv, optstring)) != -1) { + switch(c) { + case 'h': + usage(); + help(); + exit(0); + break; + case 'J': + flags |= ECMA119_JOLIET; + break; + case 'R': + flags |= ECMA119_ROCKRIDGE; + break; + case '?': + usage(); + exit(1); + break; + } + } + + if (argc < optind + 1) { + printf("Please supply device name\n"); + usage(); + return 1; + } + if (argc < optind + 2) { + printf("Please supply directory to add to disc\n"); + usage(); + return 1; + } + + + if (!isoburn_initialize()) { + err(1, "Can't init libisoburn"); + } + + // TODO change this. maybe we can add wrapp in libisoburn + iso_msgs_set_severities("NEVER", "DEBUG", "libisofs : "); + burn_msgs_set_severities("NEVER", "DEBUG", "libburn : "); + + printf("Growing drive %s\n", argv[optind]); + + if (isoburn_drive_scan_and_grab(&drives, argv[optind], 0) <= 0) { + err(1, "Can't open device. Are you sure it is a valid drive?\n"); + } + drive = drives[0].drive; + + /* check for invalid state */ + state = isoburn_disc_get_status(drive); + if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { + printf("Unsuitable disc status"); + goto exit_cleanup; + } + + /* fill read opts */ + ropts.norock = 0; + ropts.nojoliet = 0; + ropts.preferjoliet = 0; + ropts.uid = 0; + ropts.gid = 0; + ropts.mode = 0555; + + if (isoburn_read_volset(drive, &ropts, &volset) <= 0) { + printf("Can't read volset\n"); + goto exit_cleanup; + } + printf("Volset read\n"); + fflush(stdout); + + if (!volset) { + // TODO this piece of code should be inside libisoburn + struct iso_volume *volume; + + root = iso_tree_new_root(); + volume = iso_volume_new_with_root("NEW DISC", "", "LIBISOBURN", root); + volset = iso_volset_new( volume, "VOLSETID" ); + } + root = iso_volume_get_root(iso_volset_get_volume(volset, 0)); + + /* add a new dir */ + iso_tree_radd_dir(root, argv[optind+1], &behav); + + if (isoburn_prepare_disc(drive, &disc) <= 0) { + printf("Can't prepare disc"); + goto volset_cleanup; + } + + /* a. write the new image */ + printf("Adding new data...\n"); + { + struct burn_write_opts *burn_options; + struct burn_progress progress; + char reasons[BURN_REASONS_LEN]; + + burn_options = burn_write_opts_new(drive); + burn_drive_set_speed(drive, 0, 0); + burn_write_opts_set_underrun_proof(burn_options, 1); + + if (burn_write_opts_auto_write_type(burn_options, disc, + reasons, 0) == BURN_WRITE_NONE) { + printf("Failed to find a suitable write mode:\n%s\n", reasons); + ret = 1; + goto volset_cleanup; + } + + /* ok, write the new track */ + isoburn_disc_write(burn_options, disc); + burn_write_opts_free(burn_options); + + while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) + usleep(1002); + + while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { + printf("Writing: sector %d of %d\n", progress.sector, progress.sectors); + sleep(1); + } + } + + /* b. write the new vol desc */ + printf("Writing the new vol desc...\n"); + if (isoburn_activate_session(drive) <= 0) { + printf("Ups, new vol desc write failed\n"); + } + +volset_cleanup:; + iso_volset_free(volset); + +exit_cleanup:; + isoburn_drive_release(drive, 0); + isoburn_finish(); + + exit(ret); +} +