[Libburn] Re: How to pipe stdin to CD-RW ?

scdbackup at gmx.net scdbackup at gmx.net
Fri Dec 2 04:26:33 PST 2005


Hi,

Derek, by some reason i do not get your replies via mail
but can only see them in the archives.
My own postings do reach me.
Any idea why this happens ?


>> Currently i could need help with
>> - the stdin problem
>
> Wow, that's a pretty bizarre request.  The whole idea behind libburn was 
> that you'd have a C api instead of wrappers on shell scripts.

My project works with the tools as they exist. (shrug)
I presume you are familiar with the situation about
ISO-9660, CD, DVD on Linux systems since the end-90s.

I employ a volume planner which produces a backup plan
(actually a shell script) which then starts volume
production pipelines :
  formatter | checksummer | writer

As formatter i currently offer mkisofs, afio, star.
Writers are avalable on base of cdrecord(-ProDVD),
growisofs, disk file, pipe, SSH, /dev/null (very fast).

The checksummer is my own produce. It appends a
checksum tag to the end of the stream which can
be used to verify the written image without refering
to its inner format or to lowlevel media checksums.

By this design, my bizarre wish becomes quite natural.


So, why don't i just use cdrecord ?
Well, i do and i got no problems with it.
But Joerg got problems with Linux. 
The need for a second CD burning tool is evident.
Just in case.

I notice the existence of libburn when i researched
about the spectrum of cdrecord clones. My project is
up since december 1999 and yours since december 2003.
It is about time that i make some use of your work.


>> - finding the specs about the system requirements of libburn
> Should work with most mmc compliant burners.  Never really thought about 
> the requirements.  It's only really been tested on ia32, and it should 
> work with 2.4 and 2.6 linux kernels.  Maybe 2.2 as well.

This matches with my own project's range.
There are users on other Unixes but my declared goal
is to provide backup for Linux.


>>        int (*get_size)(struct burn_source *);
> iirc, we need that information to tell us when to start messing
> with the p subchannel.

Bear with me. My closest encounter with CD entrails
is a C2-scan by Joerg's readcd. I've also read something
about grooves and 1 error per million (ouch !).

My CD usage is restricted to 
- media recognition
- blanking
- writing a single track and closing the disk


>> libburn doesn't do tao (yet.  when I finally write that,
>> I'll make the next libburn release...)

The advantage for backup purposes would be substantial.
A buffer file not only eats disk space which might be
in short supply, it also opens a whole world of security
threats.
Besides the license issues i prefer growisofs over 
cdrecord-ProDVD because it does not ask for any size.
This is very helpful with compressed archives where
the size is only known after they are finished.

The padding trick for sao has the disadvantage to need the
writing time for a full CD regardless of the payload size.


My current weird idea is to start with test/burniso.c and
to enhance it to a writer which is usable for scdbackup.
That would be in fact the beginning of a cdrecord skin
for libburn. 
I myself, nevertheless, will _at most_ be able to implement
those cdrecord data features which i use and know.
  dev= -scanbus -atip blank= -sao -tao tsize= -eject
  -help -v padsize=300k fs=8m driveropts=burnfree -data
  (probably some more)
  source file address or "-"
All the audio stuff, multi session, helping the ISO formatter,
piping multi-volume star backups, ... would have to be done
by others who know what it is supposed to do. (If libburn supports it.)

Let me state that this effort is not directed against cdrecord
or Joerg Schilling. I myself will not strive to achieve the
versatility of cdrecord. It is just for creating an alternative
tool for CD data burning on Linux.
(I do not consider the cdrecord forks as such alternatives.)


Questions : 

What mode did i get with  libburn-0.2/test/burniso  ?
Should i add some burn_* call to choose a mode that is better
suited for data backups ?

Should i issue a call to close the disk ?
My burner makes three moaning sounds when it is beginning
to read or blank the libburn-CDs. With cdrecord-CDs it doesn't.


> Always interested in new functionality.
> a diff -pRuN would be great, thanks

In all those years of C programming i never submitted
a patch or used cvs. 
The follwing diff is run versus the current libburn-0.2.tar.gz.

The output of 
  diff -pruN libburn-0.2 libburn-0.2.ts
was a bit overwhelming because of configure's work.
(If you want it, just ask me.)

I therefore ran :
  for d in libburn test
  do
    cd "$base"/libburn-0.2/"$d"
    for i in *.[ch]  
    do
      diff -puN "$i" ../../libburn-0.2.ts/"$d"/"$i" 
    done
  done
 
The function name  burn_file_source_new3  might be
used as the final one (i am not familiar with your
naming scheme).
It could be wrapped around  burn_file_source_new
if this function would support "-" as address of
stdin or if we would abandon that feature and rely
on /dev/fd/0 or /proc/self/fd/0.
  struct burn_source *burn_file_source_new3(...) 
  { struct burn_source *src;
    src= burn_file_source_new(...);
    if(retd!=NULL)
      src->fixed_size= fixed_size; 
    return(src); 
  }
For now it is a modified full copy of burn_file_source_new.

The names  burn_iso3  and  parse_args4  in test/burniso.c
are just to keep the functions distinct from the originals
during experimentation. They are intended as replacements
of burn_iso and parse_args, though.
  

--- file.c	2004-02-25 04:58:18.000000000 +0100
+++ ../../libburn-0.2.ts/libburn/file.c	2005-12-01 22:15:38.000000000 +0100
@@ -79,3 +79,45 @@ struct burn_source *burn_file_source_new
 	src->data = fs;
 	return src;
 }
+
+/* scdbackup at gmx.net , experimental A51201 */
+struct burn_source *burn_file_source_new3(const char *path, 
+					  const char *subpath,
+                                          int fixed_size)
+{
+	struct burn_source_file *fs;
+	struct burn_source *src;
+	int fd1, fd2 = 0;
+
+	if (!path)
+		return NULL;
+	if (path[0]=='-' && path[1]==0)
+		fd1 = 0;
+	else
+		fd1 = open(path, O_RDONLY);
+	if (fd1 == -1)
+		return NULL;
+	if (subpath) {
+		fd2 = open(subpath, O_RDONLY);
+		if (fd2 == -1) {
+			close(fd1);
+			return NULL;
+		}
+	}
+	fs = malloc(sizeof(struct burn_source_file));
+	fs->datafd = fd1;
+
+	if (subpath)
+		fs->subfd = fd2;
+
+	src = burn_source_new();
+	src->read = file_read;
+	if (subpath)
+		src->read_sub = file_read_sub;
+
+	src->get_size = file_size;
+	src->fixed_size = fixed_size;
+	src->free_data = file_free;
+	src->data = fs;
+	return src;
+}
--- libburn.h	2004-02-25 03:00:57.000000000 +0100
+++ ../../libburn-0.2.ts/libburn/libburn.h	2005-12-01 22:26:16.000000000 +0100
@@ -280,6 +280,9 @@ struct burn_source {
 	/** Get the size of the source's data */
 	int (*get_size)(struct burn_source *);
 
+	/* scdbackup at gmx.net , experimental A51201 */
+	int fixed_size; 
+
 	/** Clean up the source specific data */
 	void (*free_data)(struct burn_source *);
 
@@ -707,6 +710,10 @@ void burn_source_free(struct burn_source
 /** Creates a data source for an image file (and maybe subcode file) */
 struct burn_source *burn_file_source_new(const char *path,
                                                const char *subpath);
+/* scdbackup at gmx.net , experimental A51201 */
+struct burn_source *burn_file_source_new3(const char *path,
+                                               const char *subpath,
+                                               int fixed_size);
 /** Tells how long a track will be on disc */
 int burn_track_get_sectors(struct burn_track *);
 
--- source.c	2004-02-25 04:55:32.000000000 +0100
+++ ../../libburn-0.2.ts/libburn/source.c	2005-12-01 21:57:16.000000000 +0100
@@ -33,3 +33,12 @@ struct burn_source *burn_source_new(void
 	out->refcount = 1;
 	return out;
 }
+
+/* scdbackup at gmx.net , experimental A51201 */
+int burn_source_get_size(struct burn_source *src)
+{
+	if(src->fixed_size>0)
+		return(src->fixed_size);
+	return(src->get_size(src));
+}
+
--- structure.c	2004-02-24 19:43:04.000000000 +0100
+++ ../../libburn-0.2.ts/libburn/structure.c	2005-12-01 22:00:27.000000000 +0100
@@ -227,7 +227,12 @@ int burn_track_get_sectors(struct burn_t
 	int sectors, seclen;
 
 	seclen = burn_sector_length(t->mode);
+
+/* scdbackup at gmx.net , experimental A51201
 	size = t->offset + t->source->get_size(t->source) + t->tail;
+*/
+	size = t->offset + burn_source_get_size(t->source) + t->tail;
+
 	sectors = size / seclen;
 	if (size % seclen)
 		sectors++;
@@ -241,7 +246,12 @@ int burn_track_get_shortage(struct burn_
 	int seclen;
 
 	seclen = burn_sector_length(t->mode);
+
+/* scdbackup at gmx.net , experimental A51201
 	size = t->offset + t->source->get_size(t->source) + t->tail;
+*/
+	size = t->offset + burn_source_get_size(t->source) + t->tail;
+
 	if (size % seclen)
 		return seclen - size % seclen;
 	return 0;

--- burniso.c	2004-02-24 19:43:04.000000000 +0100
+++ ../../libburn-0.2.ts/test/burniso.c	2005-12-01 22:21:57.000000000 +0100
@@ -14,7 +14,7 @@
 static struct burn_drive_info *drives;
 static unsigned int n_drives;
 
-void burn_iso(struct burn_drive *drive, const char *path)
+void burn_iso3(struct burn_drive *drive, const char *path, int fixed_size)
 {
 	struct burn_source *src;
 	struct burn_disc *disc;
@@ -29,7 +29,7 @@ void burn_iso(struct burn_drive *drive, 
 	burn_disc_add_session(disc, session, BURN_POS_END);
 	tr = burn_track_create();
 	burn_track_define_data(tr, 0, 0, 0, BURN_MODE1);
-	src = burn_file_source_new(path, NULL);
+	src = burn_file_source_new3(path, NULL, fixed_size);
 	assert(src);
 
 	if (burn_track_set_source(tr, src) != BURN_SOURCE_OK) {
@@ -79,7 +79,8 @@ void burn_iso(struct burn_drive *drive, 
 	burn_disc_free(disc);
 }
 
-void parse_args(int argc, char **argv, int *drive, char **iso)
+void parse_args4(int argc, char **argv, int *drive, char **iso,
+		 int *fixed_size)
 {
 	int i;
 	int help = 0;
@@ -91,6 +92,12 @@ void parse_args(int argc, char **argv, i
 				printf("--drive requires an argument\n");
 			else
 				*drive = atoi(argv[i]);
+		} else if (!strcmp(argv[i], "--fixed_size")) {
+			++i;
+			if (i >= argc)
+				printf("--fixed_size requires an argument\n");
+			else
+				*fixed_size = atoi(argv[i]);
 		} else if (!strcmp(argv[i], "--verbose")) {
 			++i;
 			if (i >= argc)
@@ -103,7 +110,7 @@ void parse_args(int argc, char **argv, i
 			*iso = argv[i];
 	}
 	if (help || !*iso) {
-		printf("Usage: %s [--drive <num>] [--verbose <level>] isofile\n", argv[0]);
+		printf("Usage: %s [--drive <num>] [--verbose <level>] [--fixed_size <num>] isofile\n", argv[0]);
 		exit(EXIT_FAILURE);
 	}
 }
@@ -112,8 +119,9 @@ int main(int argc, char **argv)
 {
 	int drive = 0;
 	char *iso = NULL;
+	int fixed_size = 0;
 
-	parse_args(argc, argv, &drive, &iso);
+	parse_args4(argc, argv, &drive, &iso, &fixed_size);
 
 	printf("Initializing library...");
 	if (burn_initialize())
@@ -127,7 +135,7 @@ int main(int argc, char **argv)
 	while (!burn_drive_scan(&drives, &n_drives)) ;
 	printf("Done\n");
 
-	burn_iso(drives[drive].drive, iso);
+	burn_iso3(drives[drive].drive, iso, fixed_size);
 
 	burn_drive_info_free(drives);
 	burn_finish();



Have a nice day :)

Thomas



More information about the libburn mailing list