Add example test program and some changes to make it work

This commit is contained in:
Vreixo Formoso Lopes 2007-09-22 15:19:05 +00:00
parent 2461231664
commit 4b1bcb6a37
7 changed files with 266 additions and 55 deletions

View File

@ -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 =

View File

@ -20,8 +20,8 @@
#include <fcntl.h>
#include <libburn.h>
#include <libisofs.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "libisoburn.h"
#include "isoburn.h"

View File

@ -7,8 +7,8 @@
#include <assert.h>
#include <stdlib.h>
#include <libburn.h>
#include <libisofs.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#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;

View File

@ -19,8 +19,8 @@
#include <errno.h>
#include <unistd.h>
#include <libburn.h>
#include <libisofs.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#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;
}

View File

@ -51,9 +51,8 @@ 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 ?) */

View File

@ -13,21 +13,10 @@
#include <string.h>
#include <assert.h>
#include <libburn.h>
#include <libisofs.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#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);
}

187
test/test.c Normal file
View File

@ -0,0 +1,187 @@
/*
Little test program for libisoburn.
It grows an iso filesystem on a disc.
Copyright 2007 Vreixo Formoso Lopes <metalpain2002@yahoo.es>
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <err.h>
#include <libisofs/libisofs.h>
#include <libburn/libburn.h>
#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);
}