summaryrefslogtreecommitdiffstats
path: root/usr.sbin/burncd
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2002-08-08 07:59:24 +0000
committersos <sos@FreeBSD.org>2002-08-08 07:59:24 +0000
commit12355fce849b88ec85106092c90e813493705508 (patch)
tree020fde6a5b99212c341268e55e3b6576b1a95553 /usr.sbin/burncd
parent77f180ef672e189c01b122b1bea1a933f7f8002b (diff)
downloadFreeBSD-src-12355fce849b88ec85106092c90e813493705508.zip
FreeBSD-src-12355fce849b88ec85106092c90e813493705508.tar.gz
Add DVD+RW support to the ATA driver and burncd. This also closes
PR40430 by "Peter Haight <peterh@sapros.com>" that has semilar patches included and which I merged with my own work. HW sponsored by: FreeBSD Foundation & FreeBSD Mall Inc Enjoy!
Diffstat (limited to 'usr.sbin/burncd')
-rw-r--r--usr.sbin/burncd/burncd.89
-rw-r--r--usr.sbin/burncd/burncd.c150
2 files changed, 140 insertions, 19 deletions
diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8
index c1c0bef..47dc84f 100644
--- a/usr.sbin/burncd/burncd.8
+++ b/usr.sbin/burncd/burncd.8
@@ -54,6 +54,8 @@ burn the CD-R/RW in DAO (disk at once) mode.
eject the media when done.
.It Fl f Ar device
set the device to use for the burning process.
+.It Fl F
+force operation regardless of warnings.
.It Fl l
read a list of image files from filename.
.It Fl m
@@ -91,6 +93,10 @@ only those areas that make the media appear blank for further usage are erased.
Erase a CD-RW medium.
This erases the entire media.
Can take up to 1 hour to finish.
+.It Cm format dwd+rw
+Formats a DVD+RW media to the default max size and 2048byte blocks. This
+operation can take a long time to finish. Progress reporting is done
+during the process.
.It Cm fixate
Fixate the medium so that the TOC is generated and the media can be used
in an ordinary CD drive.
@@ -129,6 +135,9 @@ and
.Dq "no gaps"
.Pq Fl n
modes.
+.It Cm dvdrw
+Set the write mode to write a DVD+RW from the follwing image. DVD's only
+have one track.
.It Ar file
All other arguments are treated as filenames of images to write to the media,
or in case the
diff --git a/usr.sbin/burncd/burncd.c b/usr.sbin/burncd/burncd.c
index 31e7d51..1d3d2fd 100644
--- a/usr.sbin/burncd/burncd.c
+++ b/usr.sbin/burncd/burncd.c
@@ -40,6 +40,7 @@
#include <sys/stat.h>
#include <sys/cdio.h>
#include <sys/cdrio.h>
+#include <sys/dvdio.h>
#include <sys/param.h>
#include <arpa/inet.h>
@@ -48,7 +49,7 @@
struct track_info {
int file;
char *file_name;
- u_int file_size;
+ off_t file_size;
int block_size;
int block_type;
int pregap;
@@ -59,7 +60,8 @@ static int fd, quiet, verbose, saved_block_size, notracks;
void add_track(char *, int, int, int);
void do_DAO(int, int);
-void do_TAO(int, int);
+void do_TAO(int, int, int);
+void do_format(int, int, char *);
int write_file(struct track_info *);
int roundup_blocks(struct track_info *);
void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
@@ -71,11 +73,11 @@ main(int argc, char **argv)
{
int ch, arg, addr;
int dao = 0, eject = 0, fixate = 0, list = 0, multi = 0, preemp = 0;
- int nogap = 0, speed = 4, test_write = 0;
- int block_size = 0, block_type = 0, cdopen = 0;
+ int nogap = 0, speed = 4, test_write = 0, force = 0;
+ int block_size = 0, block_type = 0, cdopen = 0, dvdrw = 0;
const char *dev = "/dev/acd0c";
- while ((ch = getopt(argc, argv, "def:lmnpqs:tv")) != -1) {
+ while ((ch = getopt(argc, argv, "def:Flmnpqs:tv")) != -1) {
switch (ch) {
case 'd':
dao = 1;
@@ -88,6 +90,10 @@ main(int argc, char **argv)
case 'f':
dev = optarg;
break;
+
+ case 'F':
+ force = 1;
+ break;
case 'l':
list = 1;
@@ -167,8 +173,9 @@ main(int argc, char **argv)
break;
}
- if (!strcasecmp(argv[arg], "erase") || !strcasecmp(argv[arg], "blank")){
- int error, blank, percent;
+ if ((!strcasecmp(argv[arg], "erase") ||
+ !strcasecmp(argv[arg], "blank")) && !test_write) {
+ int error, blank, percent, last = 0;
if (!strcasecmp(argv[arg], "erase"))
blank = CDR_B_ALL;
@@ -188,13 +195,25 @@ main(int argc, char **argv)
"%sing CD - %d %% done \r",
blank == CDR_B_ALL ?
"eras" : "blank", percent);
- if (error || percent == 100)
+ if (error || percent == 100 ||
+ (percent == 0 && last == 99))
break;
+ last = percent;
}
if (!quiet)
printf("\n");
continue;
}
+ if (!strcasecmp(argv[arg], "format") && !test_write) {
+ if (arg + 1 < argc &&
+ (!strcasecmp(argv[arg + 1], "dvd+rw") ||
+ !strcasecmp(argv[arg + 1], "dvd-rw")))
+ do_format(fd, force, argv[arg + 1]);
+ else
+ err(EX_NOINPUT, "format media type invalid");
+ arg++;
+ continue;
+ }
if (!strcasecmp(argv[arg], "audio") || !strcasecmp(argv[arg], "raw")) {
block_type = CDR_DB_RAW;
block_size = 2352;
@@ -227,6 +246,13 @@ main(int argc, char **argv)
nogap = 1;
continue;
}
+ if (!strcasecmp(argv[arg], "dvdrw")) {
+ block_type = CDR_DB_ROM_MODE1;
+ block_size = 2048;
+ dvdrw = 1;
+ continue;
+ }
+
if (!block_size)
err(EX_NOINPUT, "no data format selected");
if (list) {
@@ -252,6 +278,8 @@ main(int argc, char **argv)
add_track(argv[arg], block_size, block_type, nogap);
}
if (notracks) {
+ if (dvdrw && notracks > 1)
+ err(EX_USAGE, "DVD's only have 1 track");
if (ioctl(fd, CDIOCSTART, 0) < 0)
err(EX_IOERR, "ioctl(CDIOCSTART)");
if (!cdopen) {
@@ -262,7 +290,7 @@ main(int argc, char **argv)
if (dao)
do_DAO(test_write, multi);
else
- do_TAO(test_write, preemp);
+ do_TAO(test_write, preemp, dvdrw);
}
if (fixate && !dao) {
if (!quiet)
@@ -436,7 +464,7 @@ do_DAO(int test_write, int multi)
}
void
-do_TAO(int test_write, int preemp)
+do_TAO(int test_write, int preemp, int dvdrw)
{
struct cdr_track track;
int i;
@@ -448,8 +476,13 @@ do_TAO(int test_write, int preemp)
if (ioctl(fd, CDRIOCINITTRACK, &track) < 0)
err(EX_IOERR, "ioctl(CDRIOCINITTRACK)");
- if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &tracks[i].addr) < 0)
- err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
+ if (dvdrw)
+ tracks[i].addr = 0;
+ else
+ if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR,
+ &tracks[i].addr) < 0)
+ err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
+
if (!quiet)
fprintf(stderr, "next writeable LBA %d\n",
tracks[i].addr);
@@ -460,12 +493,91 @@ do_TAO(int test_write, int preemp)
}
}
+#define NTOH3B(x) ((x&0x0000ff)<<16) | (x&0x00ff00) | ((x&0xff0000)>>16)
+
+void
+do_format(int fd, int force, char *type)
+{
+ struct cdr_format_capacities capacities;
+ struct cdr_format_params format_params;
+ int count, i, percent, last = 0;
+
+ if (ioctl(fd, CDRIOCREADFORMATCAPS, &capacities) == -1)
+ err(EX_IOERR, "ioctl(CDRIOCREADFORMATCAPS)");
+
+ if (verbose) {
+ fprintf(stderr, "format list entries=%d\n",
+ capacities.length / sizeof(struct cdr_format_capacity));
+ fprintf(stderr, "current format: blocks=%u type=0x%x block_size=%u\n",
+ ntohl(capacities.blocks), capacities.type,
+ NTOH3B(capacities.block_size));
+ }
+
+ count = capacities.length / sizeof(struct cdr_format_capacity);
+ if (verbose) {
+ for (i = 0; i < count; ++i)
+ fprintf(stderr,
+ "format %d: blocks=%u type=0x%x param=%u\n",
+ i, ntohl(capacities.format[i].blocks),
+ capacities.format[i].type,
+ NTOH3B(capacities.format[i].param));
+ }
+
+ for (i = 0; i < count; ++i) {
+ if (!strcasecmp(type, "dvd+rw")) {
+ if (capacities.format[i].type == 0x26) {
+ break;
+ }
+ }
+ if (!strcasecmp(type, "dvd-rw")) {
+ if (capacities.format[i].type == 0x0) {
+ break;
+ }
+ }
+ }
+ if (i == count)
+ err(EX_IOERR, "could not find a valid format capacity");
+
+ if (!quiet)
+ fprintf(stderr,"formatting with blocks=%u type=0x%x param=%u\n",
+ ntohl(capacities.format[i].blocks),
+ capacities.format[i].type,
+ NTOH3B(capacities.format[i].param));
+
+ if (!force && capacities.type == 2)
+ err(EX_IOERR, "media already formatted (use -F to override)");
+
+ memset(&format_params, 0, sizeof(struct cdr_format_params));
+ format_params.fov = 1;
+ format_params.immed = 1;
+ format_params.length = ntohs(sizeof(struct cdr_format_capacity));
+ memcpy(&format_params.format, &capacities.format[i],
+ sizeof(struct cdr_format_capacity));
+
+ if(ioctl(fd, CDRIOCFORMAT, &format_params) == -1)
+ err(EX_IOERR, "ioctl(CDRIOCFORMAT)");
+
+ while (1) {
+ sleep(1);
+ if (ioctl(fd, CDRIOCGETPROGRESS, &percent) == -1)
+ err(EX_IOERR, "ioctl(CDRIOGETPROGRESS)");
+ if (percent > 0 && !quiet)
+ fprintf(stderr, "formatting DVD - %d %% done \r",
+ percent);
+ if (percent == 100 || (percent == 0 && last == 99))
+ break;
+ last = percent;
+ }
+ if (!quiet)
+ fprintf(stderr, "\n");
+}
+
int
write_file(struct track_info *track_info)
{
- int size, count, filesize;
+ off_t size, count, filesize;
char buf[2352*BLOCKS];
- static int tot_size = 0;
+ static off_t tot_size = 0;
filesize = track_info->file_size / 1024;
@@ -476,7 +588,7 @@ write_file(struct track_info *track_info)
lseek(fd, track_info->addr * track_info->block_size, SEEK_SET);
if (verbose)
- fprintf(stderr, "addr = %d size = %d blocks = %d\n",
+ fprintf(stderr, "addr = %d size = %qd blocks = %d\n",
track_info->addr, track_info->file_size,
roundup_blocks(track_info));
@@ -485,7 +597,7 @@ write_file(struct track_info *track_info)
fprintf(stderr, "writing from stdin\n");
else
fprintf(stderr,
- "writing from file %s size %d KB\n",
+ "writing from file %s size %qd KB\n",
track_info->file_name, filesize);
}
size = 0;
@@ -503,7 +615,7 @@ write_file(struct track_info *track_info)
track_info->block_size;
}
if ((res = write(fd, buf, count)) != count) {
- fprintf(stderr, "\nonly wrote %d of %d bytes err=%d\n",
+ fprintf(stderr, "\nonly wrote %d of %qd bytes err=%d\n",
res, count, errno);
break;
}
@@ -512,12 +624,12 @@ write_file(struct track_info *track_info)
if (!quiet) {
int pct;
- fprintf(stderr, "written this track %d KB", size/1024);
+ fprintf(stderr, "written this track %qd KB", size/1024);
if (track_info->file != STDIN_FILENO && filesize) {
pct = (size / 1024) * 100 / filesize;
fprintf(stderr, " (%d%%)", pct);
}
- fprintf(stderr, " total %d KB\r", tot_size/1024);
+ fprintf(stderr, " total %qd KB\r", tot_size/1024);
}
if (size >= track_info->file_size)
break;
OpenPOWER on IntegriCloud