summaryrefslogtreecommitdiffstats
path: root/usr.sbin/burncd
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2001-01-10 19:28:37 +0000
committersos <sos@FreeBSD.org>2001-01-10 19:28:37 +0000
commit6422e31b024e9e55827907ce4926bb5ac4b0d350 (patch)
tree08dc43c4728e1539e53c39b756f96c1653748b76 /usr.sbin/burncd
parentaf68207f908ac95ff866cbe7bb6dc1a02a0ddc53 (diff)
downloadFreeBSD-src-6422e31b024e9e55827907ce4926bb5ac4b0d350.zip
FreeBSD-src-6422e31b024e9e55827907ce4926bb5ac4b0d350.tar.gz
New option -m to select multisession mode.
WARNING: until now all disks was closed as multisession disks, this is no longer the case, if the -m option isn't used disks are closed as singlesession. The reason is that some drives wont close a disk with one large image on in multisession mode, probably because it "knows" that a new session wont fit on the media resonably. Also update burncd with new stuff from various places that I've collected and modified to my taste, its actually amasing how many thinks up the same enhancements (none mentioned none forgotten): Allow '-' to be used as filename for using stdin. Add 'l' option to take a list of image files from 'filename'
Diffstat (limited to 'usr.sbin/burncd')
-rw-r--r--usr.sbin/burncd/burncd.838
-rw-r--r--usr.sbin/burncd/burncd.c244
2 files changed, 190 insertions, 92 deletions
diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8
index ad86abf..24ba84f 100644
--- a/usr.sbin/burncd/burncd.8
+++ b/usr.sbin/burncd/burncd.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2000 Søren Schmidt
+.\" Copyright (c) 2000,2001 Søren Schmidt
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -38,8 +38,11 @@
.Op Fl f Ar device
.Op Fl s Ar speed
.Op Fl e
+.Op Fl l
+.Op Fl m
.Op Fl p
.Op Fl q
+.Op Fl t
.Ar [command]
.Ar [command filename...]
.Sh DESCRIPTION
@@ -53,9 +56,13 @@ Available options and operands:
.It Fl f Ar device
set the device to use for the burning process.
.It Fl s Ar speed
-set the speed of the burner device, typically 1, 2 or 4. Defaults to 1.
+set the speed of the burner device. Defaults to 1.
.It Fl e
-eject the CD-R/RW when done.
+eject the media when done.
+.It Fl l
+read a list of image files from filename.
+.It Fl m
+close disk in multisession mode (otherwise disk is closed as singlesession).
.It Fl p
use preemphasis on audio tracks.
.It Fl q
@@ -76,9 +83,12 @@ and the next writeable address on the media for use with the
switch when adding additional data to ISO filesystems with extra sessions.
.It Ar blank
Blank a CD-RW medium.
-This uses the fast blanking method, so data are not physically overwritten, only those areas that make the media appear blank for further usage.
+This uses the fast blanking method, so data are not physically overwritten, only those areas that make the media appear blank for further usage are erased.
+.It Ar erase
+Erase a CD-RW medium.
+This erases the entire media. Can take up to 1 hour to finish.
.It Ar fixate
-Fixate the medium so that the TOC is generated and the media can be used in an ordinary CD drive. The driver defaults to creating multisession media.
+Fixate the medium so that the TOC is generated and the media can be used in an ordinary CD drive. The driver defaults to creating singlesession media (see -m option).
Should be the last command to
.Nm
as the program exits when this has been done.
@@ -94,10 +104,11 @@ on the command line.
Set the write mode to produce data (XAmode1) tracks for the following image
files on the command line.
.It Ar filename
-All other arguments are treated as filenames of images to write to the media.
+All other arguments are treated as filenames of images to write to the media, or
+in case the -l option is used as files containing lists of images.
.El
.Pp
-Files whose length are not a multiple of the current media blocksize are quietly zero padded to fit the blocksize requirement.
+Files whose length are not a multiple of the current media blocksize are quietly zero padded to fit the blocksize requirement. The conventional filename "-" refers to stdin, and can only be used once.
.Pp
.Sh EXAMPLES
The typical usage for burning a data CD-R:
@@ -112,16 +123,19 @@ The typical usage for burning a mixed mode CD-R:
.Bd -literal
# burncd -f /dev/acd0c data file1 audio file2 file3 fixate
.Pp
+The typical usage for burning from a compressed image file on stdin:
+.Bd -literal
+# gunzip -c file.iso.gz | burncd -f /dev/acd0c data - fixate
+.Pp
.Sh BUGS
Probably, please report when found.
.Sh HISTORY
-.Nm
-is currently under development.
The
.Nm
command appeared in
.Fx 4.0 .
.Sh AUTHORS
-The program has been contributed by
-.An S\(/oren Schmidt ,
-Denmark.
+The
+.Nm
+command and this manpage was contributed by
+.An S\(/oren Schmidt, Denmark (sos@freebsd.org).
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index e60c21a..40938ff 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 Søren Schmidt
+ * Copyright (c) 2000,2001 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,24 +40,27 @@
#include <sys/stat.h>
#include <sys/cdio.h>
#include <sys/cdrio.h>
+#include <sys/param.h>
#define BLOCKS 16
-static int fd, saved_block_size;
void cleanup(int);
+void write_file(const char *, int);
+void usage(const char *);
+
+static int fd, quiet, saved_block_size;
+static struct cdr_track track;
int
main(int argc, char **argv)
{
- int ch, speed = 1, preemp = 0, test_write = 0, eject = 0, quiet = 0;
- char *devname = "/dev/acd0c";
- char buf[2352*BLOCKS];
- int arg, file, addr, count, filesize;
- int block_size = 0, cdopen = 0, size, tot_size = 0;
- struct cdr_track track;
- struct stat stat;
+ int ch, arg, addr;
+ int eject=0, list=0, multi=0, preemp=0, speed=1, test_write=0;
+ char *devname = "/dev/acd0c", *prog_name;
+ int block_size = 0;
- while ((ch = getopt(argc, argv, "ef:pqs:t")) != -1) {
+ prog_name = argv[0];
+ while ((ch = getopt(argc, argv, "ef:lmpqs:t")) != -1) {
switch (ch) {
case 'e':
eject = 1;
@@ -67,6 +70,14 @@ main(int argc, char **argv)
devname = optarg;
break;
+ case 'l':
+ list = 1;
+ break;
+
+ case 'm':
+ multi = 1;
+ break;
+
case 'p':
preemp = 1;
break;
@@ -77,6 +88,8 @@ main(int argc, char **argv)
case 's':
speed = atoi(optarg);
+ if (speed <= 0)
+ errx(EX_USAGE, "Invalid speed: %s", optarg);
break;
case 't':
@@ -84,12 +97,15 @@ main(int argc, char **argv)
break;
default:
- exit(EX_USAGE);
+ usage(prog_name);
}
}
argc -= optind;
argv += optind;
+ if (argc == 0)
+ usage(prog_name);
+
if ((fd = open(devname, O_RDWR, 0)) < 0)
err(EX_NOINPUT, "open(%s)", devname);
@@ -105,7 +121,7 @@ main(int argc, char **argv)
if (!strcmp(argv[arg], "fixate")) {
if (!quiet)
fprintf(stderr, "fixating CD, please wait..\n");
- if (ioctl(fd, CDRIOCCLOSEDISK) < 0)
+ if (ioctl(fd, CDRIOCCLOSEDISK, &multi) < 0)
err(EX_IOERR, "ioctl(CDRIOCCLOSEDISK)");
break;
}
@@ -118,23 +134,31 @@ main(int argc, char **argv)
err(EX_IOERR, "ioctl(CDIOREADTOCENTRY)");
if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
- fprintf(stderr, "%d, %d\n", entry.entry.addr.lba, addr);
+ fprintf(stderr, "%d, %d\n",
+ ntohl(entry.entry.addr.lba), addr);
+
break;
}
- if (!strcmp(argv[arg], "blank")) {
- int error, percent;
+ if (!strcmp(argv[arg], "erase") || !strcmp(argv[arg], "blank")){
+ int error, blank, percent;
if (!quiet)
- fprintf(stderr, "blanking CD, please wait..\r");
- if (ioctl(fd, CDRIOCBLANK) < 0)
+ fprintf(stderr, "%sing CD, please wait..\r",
+ argv[arg]);
+ if (!strcmp(argv[arg], "erase"))
+ blank = CDR_B_ALL;
+ else
+ blank = CDR_B_MIN;
+
+ if (ioctl(fd, CDRIOCBLANK, &blank) < 0)
err(EX_IOERR, "ioctl(CDRIOCBLANK)");
while (1) {
sleep(1);
error = ioctl(fd, CDRIOCGETPROGRESS, &percent);
if (percent > 0 && !quiet)
fprintf(stderr,
- "blanking CD - %d %% done"
+ "%sing CD - %d %% done"
" \r",
- percent);
+ argv[arg], percent);
if (error || percent == 100)
break;
}
@@ -144,104 +168,164 @@ main(int argc, char **argv)
}
if (!strcmp(argv[arg], "audio") || !strcmp(argv[arg], "raw")) {
track.test_write = test_write;
- track.track_type = CDR_DB_RAW;
+ track.datablock_type = CDR_DB_RAW;
track.preemp = preemp;
block_size = 2352;
continue;
}
if (!strcmp(argv[arg], "data") || !strcmp(argv[arg], "mode1")) {
track.test_write = test_write;
- track.track_type = CDR_DB_ROM_MODE1;
+ track.datablock_type = CDR_DB_ROM_MODE1;
track.preemp = 0;
block_size = 2048;
continue;
}
if (!strcmp(argv[arg], "mode2")) {
track.test_write = test_write;
- track.track_type = CDR_DB_ROM_MODE2;
+ track.datablock_type = CDR_DB_ROM_MODE2;
track.preemp = 0;
block_size = 2336;
continue;
}
if (!strcmp(argv[arg], "XAmode1")) {
track.test_write = test_write;
- track.track_type = CDR_DB_XA_MODE1;
+ track.datablock_type = CDR_DB_XA_MODE1;
track.preemp = 0;
block_size = 2048;
continue;
}
if (!block_size)
err(EX_NOINPUT, "no data format selected");
+ if (list) {
+ char file_buf[MAXPATHLEN + 1], *eol;
+ FILE *fp;
- if ((file = open(argv[arg], O_RDONLY, 0)) < 0)
- err(EX_NOINPUT, "open(%s)", argv[arg]);
+ if ((fp = fopen(argv[arg], "r")) == NULL)
+ err(EX_NOINPUT, "fopen(%s)", argv[arg]);
- if (!cdopen) {
- if (ioctl(fd, CDRIOCOPENDISK) < 0)
- err(EX_IOERR, "ioctl(CDRIOCOPENDISK)");
- cdopen = 1;
- }
- if (ioctl(fd, CDRIOCOPENTRACK, &track) < 0)
- err(EX_IOERR, "ioctl(CDRIOCOPENTRACK)");
-
- if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
- err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
-
- if (fstat(file, &stat) < 0)
- err(EX_IOERR, "fstat(%s)", argv[arg]);
- filesize = stat.st_size / 1024;
- if (!quiet) {
- fprintf(stderr, "next writeable LBA %d\n", addr);
- fprintf(stderr, "writing from file %s size %d KB\n",
- argv[arg], filesize);
- }
- lseek(fd, addr * block_size, SEEK_SET);
- size = 0;
- if (filesize == 0)
- filesize++; /* cheat, avoid divide by zero */
-
- while ((count = read(file, buf, block_size * BLOCKS)) > 0) {
- int res;
- if (count % block_size) {
- /* pad file to % block_size */
- bzero(&buf[count], block_size * BLOCKS - count);
- count = ((count / block_size) + 1) * block_size;
- }
- if ((res = write(fd, buf, count)) != count) {
-
- fprintf(stderr, "\nonly wrote %d of %d bytes\n",
- res, count);
- break;
- }
- size += count;
- tot_size += count;
- if (!quiet) {
- int pct;
-
- pct = (size / 1024) * 100 / filesize;
- fprintf(stderr, "written this track %d KB"
- " (%d%%) total %d KB\r",
- size/1024, pct, tot_size/1024);
+ while (fgets(file_buf, sizeof(file_buf), fp) != NULL) {
+ if (*file_buf == '#' || *file_buf == '\n')
+ continue;
+ if (eol = strchr(file_buf, '\n'))
+ *eol = NULL;
+ write_file(file_buf, block_size);
}
+ if (feof(fp))
+ fclose(fp);
+ else
+ err(EX_IOERR, "fgets(%s)", file_buf);
}
- if (!quiet)
- fprintf(stderr, "\n");
- close(file);
- if (ioctl(fd, CDRIOCCLOSETRACK) < 0)
- err(EX_IOERR, "ioctl(CDRIOCCLOSETRACK)");
+ else
+ write_file(argv[arg], block_size);
}
- if (ioctl(fd, CDRIOCSETBLOCKSIZE, &saved_block_size) < 0)
- err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
+ if (ioctl(fd, CDRIOCSETBLOCKSIZE, &saved_block_size) < 0) {
+ err_set_exit(NULL);
+ err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
+ }
if (eject)
if (ioctl(fd, CDIOCEJECT) < 0)
err(EX_IOERR, "ioctl(CDIOCEJECT)");
close(fd);
+ exit(EX_OK);
}
-void cleanup(int dummy)
+void
+cleanup(int dummy)
{
if (ioctl(fd, CDRIOCSETBLOCKSIZE, &saved_block_size) < 0)
- err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
+ err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
+}
+
+void
+usage(const char *prog_name)
+{
+ fprintf(stderr, "Usage: %s [-f device] [-s speed] [-e] [-l] [-m] [-p]\n"
+ "\t[-q] [command] [command filename...]\n", prog_name);
+ exit(EX_USAGE);
+}
+
+void
+write_file(const char *name, int block_size)
+{
+ int addr, count, file, filesize, size;
+ char buf[2352*BLOCKS];
+ struct stat stat;
+ static int cdopen, done_stdin, tot_size = 0;
+
+ if (!strcmp(name, "-")) {
+ if (done_stdin) {
+ warn("skipping multiple usages of stdin");
+ return;
+ }
+ file = STDIN_FILENO;
+ done_stdin = 1;
+ }
+ else if ((file = open(name, O_RDONLY, 0)) < 0)
+ err(EX_NOINPUT, "open(%s)", name);
+
+ if (!cdopen) {
+ if (ioctl(fd, CDRIOCOPENDISK) < 0)
+ err(EX_IOERR, "ioctl(CDRIOCOPENDISK)");
+ cdopen = 1;
+ }
+
+ if (ioctl(fd, CDRIOCOPENTRACK, &track) < 0)
+ err(EX_IOERR, "ioctl(CDRIOCOPENTRACK)");
+
+ if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
+ err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
+
+ if (fstat(file, &stat) < 0)
+ err(EX_IOERR, "fstat(%s)", name);
+ filesize = stat.st_size / 1024;
+
+ if (!quiet) {
+ fprintf(stderr, "next writeable LBA %d\n", addr);
+ if (file == STDIN_FILENO)
+ fprintf(stderr, "writing from stdin\n");
+ else
+ fprintf(stderr,
+ "writing from file %s size %d KB\n",
+ name, filesize);
+ }
+
+ lseek(fd, addr * block_size, SEEK_SET);
+ size = 0;
+ if (filesize == 0)
+ filesize++; /* cheat, avoid divide by zero */
+
+ while ((count = read(file, buf, block_size * BLOCKS)) > 0) {
+ int res;
+ if (count % block_size) {
+ /* pad file to % block_size */
+ bzero(&buf[count], block_size * BLOCKS - count);
+ count = ((count / block_size) + 1) * block_size;
+ }
+ if ((res = write(fd, buf, count)) != count) {
+ fprintf(stderr, "\nonly wrote %d of %d bytes\n",
+ res, count);
+ break;
+ }
+ size += count;
+ tot_size += count;
+ if (!quiet) {
+ int pct;
+
+ fprintf(stderr, "written this track %d KB", size/1024);
+ if (file != STDIN_FILENO) {
+ pct = (size / 1024) * 100 / filesize;
+ fprintf(stderr, " (%d%%)", pct);
+ }
+ fprintf(stderr, " total %d KB\r", tot_size/1024);
+ }
+ }
+
+ if (!quiet)
+ fprintf(stderr, "\n");
+
+ close(file);
+ if (ioctl(fd, CDRIOCCLOSETRACK) < 0)
+ err(EX_IOERR, "ioctl(CDRIOCCLOSETRACK)");
}
OpenPOWER on IntegriCloud