2000-01-06 22:46:20 +00:00
|
|
|
/*-
|
2011-12-30 00:59:08 +00:00
|
|
|
* Copyright (c) 2000,2001,2002 Søren Schmidt <sos@freebsd.org>
|
2000-01-06 22:46:20 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer,
|
|
|
|
* without modification, immediately at the beginning of the file.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
2008-12-19 20:20:14 +00:00
|
|
|
#include <signal.h>
|
2002-12-29 22:28:51 +00:00
|
|
|
#include <stdint.h>
|
2000-01-06 22:46:20 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <err.h>
|
|
|
|
#include <sysexits.h>
|
|
|
|
#include <fcntl.h>
|
2000-12-26 11:56:15 +00:00
|
|
|
#include <sys/errno.h>
|
2000-01-06 22:46:20 +00:00
|
|
|
#include <sys/ioctl.h>
|
2000-01-17 01:43:25 +00:00
|
|
|
#include <sys/stat.h>
|
2000-01-06 22:46:20 +00:00
|
|
|
#include <sys/cdio.h>
|
|
|
|
#include <sys/cdrio.h>
|
2002-08-08 07:59:24 +00:00
|
|
|
#include <sys/dvdio.h>
|
2001-01-10 19:28:37 +00:00
|
|
|
#include <sys/param.h>
|
2002-03-04 20:50:16 +00:00
|
|
|
#include <arpa/inet.h>
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2000-01-17 01:43:25 +00:00
|
|
|
#define BLOCKS 16
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
struct track_info {
|
|
|
|
int file;
|
2003-05-04 10:03:15 +00:00
|
|
|
char file_name[MAXPATHLEN + 1];
|
2002-08-08 07:59:24 +00:00
|
|
|
off_t file_size;
|
2001-09-10 11:44:32 +00:00
|
|
|
int block_size;
|
|
|
|
int block_type;
|
2001-12-04 21:48:56 +00:00
|
|
|
int pregap;
|
2001-09-10 11:44:32 +00:00
|
|
|
int addr;
|
|
|
|
};
|
|
|
|
static struct track_info tracks[100];
|
2008-12-23 17:57:17 +00:00
|
|
|
static int quiet, verbose, saved_block_size, notracks;
|
2009-01-05 16:47:42 +00:00
|
|
|
static volatile sig_atomic_t global_fd_for_cleanup;
|
2001-09-10 11:44:32 +00:00
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
void add_track(char *, int, int, int);
|
2002-12-29 22:28:51 +00:00
|
|
|
void do_DAO(int fd, int, int);
|
|
|
|
void do_TAO(int fd, int, int, int);
|
2002-08-08 07:59:24 +00:00
|
|
|
void do_format(int, int, char *);
|
2002-12-29 22:28:51 +00:00
|
|
|
int write_file(int fd, struct track_info *);
|
2001-09-10 11:44:32 +00:00
|
|
|
int roundup_blocks(struct track_info *);
|
|
|
|
void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
|
2000-01-06 22:46:20 +00:00
|
|
|
void cleanup(int);
|
2008-12-19 20:20:14 +00:00
|
|
|
void cleanup_flush(void);
|
|
|
|
void cleanup_signal(int);
|
2001-09-11 11:52:49 +00:00
|
|
|
void usage(void);
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2000-01-06 22:46:20 +00:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
2002-12-29 22:28:51 +00:00
|
|
|
int arg, addr, ch, fd;
|
2001-09-10 11:44:32 +00:00
|
|
|
int dao = 0, eject = 0, fixate = 0, list = 0, multi = 0, preemp = 0;
|
2002-10-27 19:44:57 +00:00
|
|
|
int nogap = 0, speed = 4 * 177, test_write = 0, force = 0;
|
2002-08-08 07:59:24 +00:00
|
|
|
int block_size = 0, block_type = 0, cdopen = 0, dvdrw = 0;
|
2009-12-21 19:27:52 +00:00
|
|
|
const char *dev, *env_speed;
|
2003-05-04 10:09:57 +00:00
|
|
|
|
Add a "kern.features.ata_cam" sysctl in the kernel when the ATA_CAM kernel
option is defined. This sysctl can be queried by feature_present(3).
Query for this feature in /sbin/atacontrol and /usr/sbin/burncd.
If these utilities detect that ATA_CAM is enabled, then these utilities
will error out. These utilities are compatible with the old ATA
driver, but are incomptible with the new ATA_CAM driver. By erroring out,
we give end-users an idea as to what remedies to use, and reduce the need for them
to file PR's. For atacontrol, camcontrol must be used instead,
and for burncd, alternative utilties from the ports collection must be used
such as sysutils/cdrtools.
In future, maybe someone can re-write burncd to work with ATA_CAM,
but at least for now, we give a somewhat useful error message to end users.
PR: 160979
Reviewed by: jh, Arnaud Lacombe <lacombar at gmail dot com>
Reported by: Joe Barbish <fbsd8 at a1poweruser dot com>
MFC after: 3 days
2011-10-09 21:42:02 +00:00
|
|
|
if (feature_present("ata_cam")) {
|
|
|
|
errx(1, "\nATA_CAM option is enabled in kernel.\n"
|
|
|
|
"Install the sysutils/cdrtools port and use cdrecord instead.\n\n"
|
|
|
|
"Please refer to:\n"
|
|
|
|
"http://www.freebsd.org/doc/handbook/creating-cds.html#CDRECORD");
|
|
|
|
}
|
|
|
|
|
2003-05-04 10:09:57 +00:00
|
|
|
if ((dev = getenv("CDROM")) == NULL)
|
|
|
|
dev = "/dev/acd0";
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2009-12-21 19:27:52 +00:00
|
|
|
env_speed = getenv("BURNCD_SPEED");
|
|
|
|
|
2002-08-08 07:59:24 +00:00
|
|
|
while ((ch = getopt(argc, argv, "def:Flmnpqs:tv")) != -1) {
|
2000-01-06 22:46:20 +00:00
|
|
|
switch (ch) {
|
2001-09-10 11:44:32 +00:00
|
|
|
case 'd':
|
|
|
|
dao = 1;
|
|
|
|
break;
|
|
|
|
|
2000-01-06 22:46:20 +00:00
|
|
|
case 'e':
|
|
|
|
eject = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'f':
|
2001-12-24 03:20:10 +00:00
|
|
|
dev = optarg;
|
2000-01-06 22:46:20 +00:00
|
|
|
break;
|
2004-09-15 19:01:08 +00:00
|
|
|
|
2002-08-08 07:59:24 +00:00
|
|
|
case 'F':
|
|
|
|
force = 1;
|
|
|
|
break;
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
case 'l':
|
|
|
|
list = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'm':
|
|
|
|
multi = 1;
|
|
|
|
break;
|
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
case 'n':
|
|
|
|
nogap = 1;
|
|
|
|
break;
|
|
|
|
|
2000-01-06 22:46:20 +00:00
|
|
|
case 'p':
|
|
|
|
preemp = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'q':
|
|
|
|
quiet = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 's':
|
2009-12-21 19:27:52 +00:00
|
|
|
env_speed = optarg;
|
2000-01-06 22:46:20 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 't':
|
|
|
|
test_write = 1;
|
|
|
|
break;
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
case 'v':
|
|
|
|
verbose = 1;
|
|
|
|
break;
|
|
|
|
|
2004-09-15 19:01:08 +00:00
|
|
|
default:
|
2001-09-11 11:52:49 +00:00
|
|
|
usage();
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
2009-12-21 19:27:52 +00:00
|
|
|
if (env_speed == NULL)
|
|
|
|
;
|
|
|
|
else if (strcasecmp("max", env_speed) == 0)
|
|
|
|
speed = CDR_MAX_SPEED;
|
|
|
|
else
|
|
|
|
speed = atoi(env_speed) * 177;
|
|
|
|
if (speed <= 0)
|
2010-01-20 18:22:56 +00:00
|
|
|
errx(EX_USAGE, "Invalid speed: %s", env_speed);
|
2009-12-21 19:27:52 +00:00
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
if (argc == 0)
|
2001-09-11 11:52:49 +00:00
|
|
|
usage();
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2001-12-24 03:20:10 +00:00
|
|
|
if ((fd = open(dev, O_RDWR, 0)) < 0)
|
|
|
|
err(EX_NOINPUT, "open(%s)", dev);
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDRIOCGETBLOCKSIZE, &saved_block_size) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCGETBLOCKSIZE)");
|
2000-01-06 22:46:20 +00:00
|
|
|
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDRIOCWRITESPEED, &speed) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCWRITESPEED)");
|
2001-09-10 11:44:32 +00:00
|
|
|
|
2002-12-29 22:28:51 +00:00
|
|
|
global_fd_for_cleanup = fd;
|
2000-01-06 22:46:20 +00:00
|
|
|
err_set_exit(cleanup);
|
2008-12-19 20:20:14 +00:00
|
|
|
signal(SIGHUP, cleanup_signal);
|
|
|
|
signal(SIGINT, cleanup_signal);
|
|
|
|
signal(SIGTERM, cleanup_signal);
|
2000-01-06 22:46:20 +00:00
|
|
|
|
|
|
|
for (arg = 0; arg < argc; arg++) {
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "fixate")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
fixate = 1;
|
2004-12-21 14:49:10 +00:00
|
|
|
continue;
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|
2004-09-15 19:03:35 +00:00
|
|
|
if (!strcasecmp(argv[arg], "eject")) {
|
|
|
|
eject = 1;
|
|
|
|
break;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "msinfo")) {
|
2004-09-15 19:01:08 +00:00
|
|
|
struct ioc_read_toc_single_entry entry;
|
2001-12-27 10:10:56 +00:00
|
|
|
struct ioc_toc_header header;
|
2000-03-03 23:17:27 +00:00
|
|
|
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDIOREADTOCHEADER, &header) < 0)
|
2001-12-27 10:10:56 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDIOREADTOCHEADER)");
|
2000-03-03 23:17:27 +00:00
|
|
|
bzero(&entry, sizeof(struct ioc_read_toc_single_entry));
|
|
|
|
entry.address_format = CD_LBA_FORMAT;
|
2001-12-27 10:10:56 +00:00
|
|
|
entry.track = header.ending_track;
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDIOREADTOCENTRY, &entry) < 0)
|
2000-03-03 23:17:27 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDIOREADTOCENTRY)");
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
|
2000-03-03 23:17:27 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stdout, "%d,%d\n",
|
2001-01-10 19:28:37 +00:00
|
|
|
ntohl(entry.entry.addr.lba), addr);
|
|
|
|
|
2000-03-03 23:17:27 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-08-08 07:59:24 +00:00
|
|
|
if ((!strcasecmp(argv[arg], "erase") ||
|
|
|
|
!strcasecmp(argv[arg], "blank")) && !test_write) {
|
2004-09-15 19:01:08 +00:00
|
|
|
int blank, pct, last = 0;
|
2001-05-30 08:13:39 +00:00
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "erase"))
|
2001-01-10 19:28:37 +00:00
|
|
|
blank = CDR_B_ALL;
|
|
|
|
else
|
|
|
|
blank = CDR_B_MIN;
|
2001-05-30 08:13:39 +00:00
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "%sing CD, please wait..\r",
|
|
|
|
blank == CDR_B_ALL ? "eras" : "blank");
|
2001-01-10 19:28:37 +00:00
|
|
|
|
|
|
|
if (ioctl(fd, CDRIOCBLANK, &blank) < 0)
|
2004-09-15 19:01:08 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCBLANK)");
|
2000-12-26 11:56:15 +00:00
|
|
|
while (1) {
|
|
|
|
sleep(1);
|
2002-12-18 07:43:42 +00:00
|
|
|
if (ioctl(fd, CDRIOCGETPROGRESS, &pct) == -1)
|
|
|
|
err(EX_IOERR,"ioctl(CDRIOGETPROGRESS)");
|
|
|
|
if (pct > 0 && !quiet)
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stderr,
|
2001-05-30 08:13:39 +00:00
|
|
|
"%sing CD - %d %% done \r",
|
2004-09-15 19:01:08 +00:00
|
|
|
blank == CDR_B_ALL ?
|
2002-12-18 07:43:42 +00:00
|
|
|
"eras" : "blank", pct);
|
|
|
|
if (pct == 100 || (pct == 0 && last > 90))
|
2000-12-26 11:56:15 +00:00
|
|
|
break;
|
2002-12-18 07:43:42 +00:00
|
|
|
last = pct;
|
2000-12-26 11:56:15 +00:00
|
|
|
}
|
|
|
|
if (!quiet)
|
|
|
|
printf("\n");
|
2000-03-03 23:17:27 +00:00
|
|
|
continue;
|
|
|
|
}
|
2002-08-08 07:59:24 +00:00
|
|
|
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
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_NOINPUT, "format media type invalid");
|
2002-08-08 07:59:24 +00:00
|
|
|
arg++;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "audio") || !strcasecmp(argv[arg], "raw")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
block_type = CDR_DB_RAW;
|
2000-01-06 22:46:20 +00:00
|
|
|
block_size = 2352;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "data") || !strcasecmp(argv[arg], "mode1")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
block_type = CDR_DB_ROM_MODE1;
|
2000-01-06 22:46:20 +00:00
|
|
|
block_size = 2048;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "mode2")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
block_type = CDR_DB_ROM_MODE2;
|
2000-02-02 13:38:02 +00:00
|
|
|
block_size = 2336;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "xamode1")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
block_type = CDR_DB_XA_MODE1;
|
2000-02-02 13:38:02 +00:00
|
|
|
block_size = 2048;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "xamode2")) {
|
2001-09-10 11:44:32 +00:00
|
|
|
block_type = CDR_DB_XA_MODE2_F2;
|
|
|
|
block_size = 2324;
|
|
|
|
continue;
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
if (!strcasecmp(argv[arg], "vcd")) {
|
|
|
|
block_type = CDR_DB_XA_MODE2_F2;
|
|
|
|
block_size = 2352;
|
|
|
|
dao = 1;
|
|
|
|
nogap = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2002-08-08 07:59:24 +00:00
|
|
|
if (!strcasecmp(argv[arg], "dvdrw")) {
|
|
|
|
block_type = CDR_DB_ROM_MODE1;
|
|
|
|
block_size = 2048;
|
|
|
|
dvdrw = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-02-18 16:36:28 +00:00
|
|
|
if (!block_size)
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_NOINPUT, "no data format selected");
|
2001-01-10 19:28:37 +00:00
|
|
|
if (list) {
|
|
|
|
char file_buf[MAXPATHLEN + 1], *eol;
|
|
|
|
FILE *fp;
|
2000-02-18 16:36:28 +00:00
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
if ((fp = fopen(argv[arg], "r")) == NULL)
|
2004-09-15 19:01:08 +00:00
|
|
|
err(EX_NOINPUT, "fopen(%s)", argv[arg]);
|
2000-02-18 16:36:28 +00:00
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
while (fgets(file_buf, sizeof(file_buf), fp) != NULL) {
|
|
|
|
if (*file_buf == '#' || *file_buf == '\n')
|
|
|
|
continue;
|
2001-09-10 11:44:32 +00:00
|
|
|
if ((eol = strchr(file_buf, '\n')))
|
2004-03-05 08:10:19 +00:00
|
|
|
*eol = '\0';
|
2001-12-04 21:48:56 +00:00
|
|
|
add_track(file_buf, block_size, block_type, nogap);
|
2000-03-02 21:49:10 +00:00
|
|
|
}
|
2001-01-10 19:28:37 +00:00
|
|
|
if (feof(fp))
|
|
|
|
fclose(fp);
|
|
|
|
else
|
|
|
|
err(EX_IOERR, "fgets(%s)", file_buf);
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|
2001-01-10 19:28:37 +00:00
|
|
|
else
|
2001-12-04 21:48:56 +00:00
|
|
|
add_track(argv[arg], block_size, block_type, nogap);
|
2001-09-10 11:44:32 +00:00
|
|
|
}
|
|
|
|
if (notracks) {
|
2002-08-08 07:59:24 +00:00
|
|
|
if (dvdrw && notracks > 1)
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_USAGE, "DVD's only have 1 track");
|
2001-09-10 11:44:32 +00:00
|
|
|
if (ioctl(fd, CDIOCSTART, 0) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDIOCSTART)");
|
|
|
|
if (!cdopen) {
|
|
|
|
if (ioctl(fd, CDRIOCINITWRITER, &test_write) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCINITWRITER)");
|
|
|
|
cdopen = 1;
|
|
|
|
}
|
2004-09-15 19:01:08 +00:00
|
|
|
if (dao)
|
2002-12-29 22:28:51 +00:00
|
|
|
do_DAO(fd, test_write, multi);
|
2001-09-10 11:44:32 +00:00
|
|
|
else
|
2002-12-29 22:28:51 +00:00
|
|
|
do_TAO(fd, test_write, preemp, dvdrw);
|
2001-09-10 11:44:32 +00:00
|
|
|
}
|
2003-05-04 09:55:46 +00:00
|
|
|
if (!test_write && fixate && !dao && !dvdrw) {
|
2001-09-10 11:44:32 +00:00
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "fixating CD, please wait..\n");
|
|
|
|
if (ioctl(fd, CDRIOCFIXATE, &multi) < 0)
|
2004-09-15 19:01:08 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCFIXATE)");
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
if (ioctl(fd, CDRIOCSETBLOCKSIZE, &saved_block_size) < 0) {
|
|
|
|
err_set_exit(NULL);
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
|
|
|
|
}
|
2000-01-06 22:46:20 +00:00
|
|
|
|
|
|
|
if (eject)
|
|
|
|
if (ioctl(fd, CDIOCEJECT) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDIOCEJECT)");
|
2008-12-19 20:20:14 +00:00
|
|
|
|
|
|
|
signal(SIGHUP, SIG_DFL);
|
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
signal(SIGTERM, SIG_DFL);
|
2000-01-06 22:46:20 +00:00
|
|
|
close(fd);
|
2001-01-10 19:28:37 +00:00
|
|
|
exit(EX_OK);
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|
|
|
|
|
2001-01-10 19:28:37 +00:00
|
|
|
void
|
2001-12-04 21:48:56 +00:00
|
|
|
add_track(char *name, int block_size, int block_type, int nogap)
|
2001-01-10 19:28:37 +00:00
|
|
|
{
|
2001-12-24 03:20:10 +00:00
|
|
|
struct stat sb;
|
2001-09-10 11:44:32 +00:00
|
|
|
int file;
|
|
|
|
static int done_stdin = 0;
|
2001-01-10 19:28:37 +00:00
|
|
|
|
|
|
|
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);
|
2001-12-24 03:20:10 +00:00
|
|
|
if (fstat(file, &sb) < 0)
|
2001-09-10 11:44:32 +00:00
|
|
|
err(EX_IOERR, "fstat(%s)", name);
|
|
|
|
tracks[notracks].file = file;
|
2003-05-04 10:03:15 +00:00
|
|
|
strncpy(tracks[notracks].file_name, name, MAXPATHLEN);
|
2002-04-05 19:35:41 +00:00
|
|
|
if (file == STDIN_FILENO)
|
|
|
|
tracks[notracks].file_size = -1;
|
|
|
|
else
|
|
|
|
tracks[notracks].file_size = sb.st_size;
|
2001-09-10 11:44:32 +00:00
|
|
|
tracks[notracks].block_size = block_size;
|
|
|
|
tracks[notracks].block_type = block_type;
|
2001-12-04 21:48:56 +00:00
|
|
|
|
|
|
|
if (nogap && notracks)
|
|
|
|
tracks[notracks].pregap = 0;
|
|
|
|
else {
|
|
|
|
if (tracks[notracks - (notracks > 0)].block_type == block_type)
|
|
|
|
tracks[notracks].pregap = 150;
|
|
|
|
else
|
|
|
|
tracks[notracks].pregap = 255;
|
|
|
|
}
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
if (verbose) {
|
|
|
|
int pad = 0;
|
|
|
|
|
|
|
|
if (tracks[notracks].file_size / tracks[notracks].block_size !=
|
|
|
|
roundup_blocks(&tracks[notracks]))
|
|
|
|
pad = 1;
|
2003-12-28 13:32:49 +00:00
|
|
|
fprintf(stderr,
|
|
|
|
"adding type 0x%02x file %s size %jd KB %d blocks %s\n",
|
|
|
|
tracks[notracks].block_type, name,
|
|
|
|
(intmax_t)sb.st_size/1024,
|
2001-12-24 03:20:10 +00:00
|
|
|
roundup_blocks(&tracks[notracks]),
|
2001-09-10 11:44:32 +00:00
|
|
|
pad ? "(0 padded)" : "");
|
2001-01-10 19:28:37 +00:00
|
|
|
}
|
2001-09-10 11:44:32 +00:00
|
|
|
notracks++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-12-29 22:28:51 +00:00
|
|
|
do_DAO(int fd, int test_write, int multi)
|
2001-09-10 11:44:32 +00:00
|
|
|
{
|
|
|
|
struct cdr_cuesheet sheet;
|
|
|
|
struct cdr_cue_entry cue[100];
|
2001-12-04 21:48:56 +00:00
|
|
|
int format = CDR_SESS_CDROM;
|
2001-09-10 11:44:32 +00:00
|
|
|
int addr, i, j = 0;
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
int bt2ctl[16] = { 0x0, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, -1, -1 };
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
int bt2df[16] = { 0x0, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
0x10, 0x30, 0x20, -1, 0x21, -1, -1, -1 };
|
2004-09-15 19:01:08 +00:00
|
|
|
|
|
|
|
if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
|
2001-09-10 11:44:32 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
|
|
|
|
if (verbose)
|
|
|
|
fprintf(stderr, "next writeable LBA %d\n", addr);
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
cue_ent(&cue[j++], bt2ctl[tracks[0].block_type], 0x01, 0x00, 0x0,
|
2004-09-15 19:01:08 +00:00
|
|
|
(bt2df[tracks[0].block_type] & 0xf0) |
|
2001-09-10 11:44:32 +00:00
|
|
|
(tracks[0].block_type < 8 ? 0x01 : 0x04), 0x00, addr);
|
|
|
|
|
|
|
|
for (i = 0; i < notracks; i++) {
|
|
|
|
if (bt2ctl[tracks[i].block_type] < 0 ||
|
|
|
|
bt2df[tracks[i].block_type] < 0)
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_IOERR, "track type not supported in DAO mode");
|
2001-09-10 11:44:32 +00:00
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
if (tracks[i].block_type >= CDR_DB_XA_MODE1)
|
|
|
|
format = CDR_SESS_CDROM_XA;
|
2001-09-10 11:44:32 +00:00
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
if (i == 0) {
|
|
|
|
addr += tracks[i].pregap;
|
2001-09-10 11:44:32 +00:00
|
|
|
tracks[i].addr = addr;
|
|
|
|
|
2004-09-15 19:01:08 +00:00
|
|
|
cue_ent(&cue[j++], bt2ctl[tracks[i].block_type],
|
2001-09-10 11:44:32 +00:00
|
|
|
0x01, i+1, 0x1, bt2df[tracks[i].block_type],
|
|
|
|
0x00, addr);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
2001-12-04 21:48:56 +00:00
|
|
|
if (tracks[i].pregap) {
|
|
|
|
if (tracks[i].block_type > 0x7) {
|
2004-09-15 19:01:08 +00:00
|
|
|
cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
|
2001-12-04 21:48:56 +00:00
|
|
|
0x01, i+1, 0x0,
|
2004-09-15 19:01:08 +00:00
|
|
|
(bt2df[tracks[i].block_type] & 0xf0) |
|
2001-12-04 21:48:56 +00:00
|
|
|
(tracks[i].block_type < 8 ? 0x01 :0x04),
|
|
|
|
0x00, addr);
|
|
|
|
}
|
|
|
|
else
|
2004-09-15 19:01:08 +00:00
|
|
|
cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
|
2001-12-04 21:48:56 +00:00
|
|
|
0x01, i+1, 0x0,
|
|
|
|
bt2df[tracks[i].block_type],
|
|
|
|
0x00, addr);
|
2001-09-10 11:44:32 +00:00
|
|
|
}
|
|
|
|
tracks[i].addr = tracks[i - 1].addr +
|
|
|
|
roundup_blocks(&tracks[i - 1]);
|
|
|
|
|
|
|
|
cue_ent(&cue[j++], bt2ctl[tracks[i].block_type],
|
|
|
|
0x01, i+1, 0x1, bt2df[tracks[i].block_type],
|
2001-12-04 21:48:56 +00:00
|
|
|
0x00, addr + tracks[i].pregap);
|
2001-09-10 11:44:32 +00:00
|
|
|
|
|
|
|
if (tracks[i].block_type > 0x7)
|
2001-12-04 21:48:56 +00:00
|
|
|
addr += tracks[i].pregap;
|
2001-09-10 11:44:32 +00:00
|
|
|
}
|
|
|
|
addr += roundup_blocks(&tracks[i]);
|
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
cue_ent(&cue[j++], bt2ctl[tracks[i - 1].block_type], 0x01, 0xaa, 0x01,
|
2004-09-15 19:01:08 +00:00
|
|
|
(bt2df[tracks[i - 1].block_type] & 0xf0) |
|
2001-09-10 11:44:32 +00:00
|
|
|
(tracks[i - 1].block_type < 8 ? 0x01 : 0x04), 0x00, addr);
|
|
|
|
|
|
|
|
sheet.len = j * 8;
|
|
|
|
sheet.entries = cue;
|
2001-10-01 14:58:04 +00:00
|
|
|
sheet.test_write = test_write;
|
2001-12-04 21:48:56 +00:00
|
|
|
sheet.session_type = multi ? CDR_SESS_MULTI : CDR_SESS_NONE;
|
|
|
|
sheet.session_format = format;
|
2001-09-10 11:44:32 +00:00
|
|
|
if (verbose) {
|
|
|
|
u_int8_t *ptr = (u_int8_t *)sheet.entries;
|
2004-09-15 19:01:08 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
fprintf(stderr,"CUE sheet:");
|
|
|
|
for (i = 0; i < sheet.len; i++)
|
|
|
|
if (i % 8)
|
|
|
|
fprintf(stderr," %02x", ptr[i]);
|
|
|
|
else
|
|
|
|
fprintf(stderr,"\n%02x", ptr[i]);
|
|
|
|
fprintf(stderr,"\n");
|
|
|
|
}
|
2004-09-15 19:01:08 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
if (ioctl(fd, CDRIOCSENDCUE, &sheet) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");
|
2001-12-04 21:48:56 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
for (i = 0; i < notracks; i++) {
|
2008-12-19 20:20:14 +00:00
|
|
|
if (write_file(fd, &tracks[i])) {
|
|
|
|
cleanup_flush();
|
2001-09-10 11:44:32 +00:00
|
|
|
err(EX_IOERR, "write_file");
|
2008-12-19 20:20:14 +00:00
|
|
|
}
|
2001-09-10 11:44:32 +00:00
|
|
|
}
|
2001-12-04 21:48:56 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
ioctl(fd, CDRIOCFLUSH);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-12-29 22:28:51 +00:00
|
|
|
do_TAO(int fd, int test_write, int preemp, int dvdrw)
|
2001-09-10 11:44:32 +00:00
|
|
|
{
|
|
|
|
struct cdr_track track;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < notracks; i++) {
|
|
|
|
track.test_write = test_write;
|
|
|
|
track.datablock_type = tracks[i].block_type;
|
|
|
|
track.preemp = preemp;
|
|
|
|
if (ioctl(fd, CDRIOCINITTRACK, &track) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCINITTRACK)");
|
|
|
|
|
2002-08-08 07:59:24 +00:00
|
|
|
if (dvdrw)
|
|
|
|
tracks[i].addr = 0;
|
|
|
|
else
|
2004-09-15 19:01:08 +00:00
|
|
|
if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR,
|
2002-08-08 07:59:24 +00:00
|
|
|
&tracks[i].addr) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "next writeable LBA %d\n",
|
|
|
|
tracks[i].addr);
|
2008-12-19 20:20:14 +00:00
|
|
|
if (write_file(fd, &tracks[i])) {
|
|
|
|
cleanup_flush();
|
2001-09-10 11:44:32 +00:00
|
|
|
err(EX_IOERR, "write_file");
|
2008-12-19 20:20:14 +00:00
|
|
|
}
|
2001-09-10 11:44:32 +00:00
|
|
|
if (ioctl(fd, CDRIOCFLUSH) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-08 07:59:24 +00:00
|
|
|
#define NTOH3B(x) ((x&0x0000ff)<<16) | (x&0x00ff00) | ((x&0xff0000)>>16)
|
|
|
|
|
|
|
|
void
|
2002-12-30 10:57:41 +00:00
|
|
|
do_format(int the_fd, int force, char *type)
|
2002-08-08 07:59:24 +00:00
|
|
|
{
|
|
|
|
struct cdr_format_capacities capacities;
|
|
|
|
struct cdr_format_params format_params;
|
2002-12-18 07:43:42 +00:00
|
|
|
int count, i, pct, last = 0;
|
2002-08-08 07:59:24 +00:00
|
|
|
|
2002-12-30 10:57:41 +00:00
|
|
|
if (ioctl(the_fd, CDRIOCREADFORMATCAPS, &capacities) == -1)
|
2002-08-08 07:59:24 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCREADFORMATCAPS)");
|
|
|
|
|
|
|
|
if (verbose) {
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stderr, "format list entries=%zd\n",
|
2002-08-08 07:59:24 +00:00
|
|
|
capacities.length / sizeof(struct cdr_format_capacity));
|
|
|
|
fprintf(stderr, "current format: blocks=%u type=0x%x block_size=%u\n",
|
2004-09-15 19:01:08 +00:00
|
|
|
ntohl(capacities.blocks), capacities.type,
|
2002-08-08 07:59:24 +00:00
|
|
|
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)
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_IOERR, "could not find a valid format capacity");
|
2004-09-15 19:01:08 +00:00
|
|
|
|
2002-08-08 07:59:24 +00:00
|
|
|
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)
|
2004-12-17 13:24:22 +00:00
|
|
|
errx(EX_IOERR, "media already formatted (use -F to override)");
|
2002-08-08 07:59:24 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
|
2002-12-30 10:57:41 +00:00
|
|
|
if(ioctl(the_fd, CDRIOCFORMAT, &format_params) == -1)
|
2002-08-08 07:59:24 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCFORMAT)");
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
sleep(1);
|
2002-12-30 10:57:41 +00:00
|
|
|
if (ioctl(the_fd, CDRIOCGETPROGRESS, &pct) == -1)
|
2002-08-08 07:59:24 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOGETPROGRESS)");
|
2002-12-18 07:43:42 +00:00
|
|
|
if (pct > 0 && !quiet)
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stderr, "formatting DVD - %d %% done \r",
|
2002-12-18 07:43:42 +00:00
|
|
|
pct);
|
|
|
|
if (pct == 100 || (pct == 0 && last > 90))
|
2002-08-08 07:59:24 +00:00
|
|
|
break;
|
2002-12-18 07:43:42 +00:00
|
|
|
last = pct;
|
2002-08-08 07:59:24 +00:00
|
|
|
}
|
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
int
|
2002-12-29 22:28:51 +00:00
|
|
|
write_file(int fd, struct track_info *track_info)
|
2001-09-10 11:44:32 +00:00
|
|
|
{
|
2002-08-08 07:59:24 +00:00
|
|
|
off_t size, count, filesize;
|
2001-09-10 11:44:32 +00:00
|
|
|
char buf[2352*BLOCKS];
|
2002-08-08 07:59:24 +00:00
|
|
|
static off_t tot_size = 0;
|
2001-09-10 11:44:32 +00:00
|
|
|
|
|
|
|
filesize = track_info->file_size / 1024;
|
|
|
|
|
|
|
|
if (ioctl(fd, CDRIOCSETBLOCKSIZE, &track_info->block_size) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
|
|
|
|
|
|
|
|
if (track_info->addr >= 0)
|
|
|
|
lseek(fd, track_info->addr * track_info->block_size, SEEK_SET);
|
|
|
|
|
2001-12-04 21:48:56 +00:00
|
|
|
if (verbose)
|
2002-12-29 22:28:51 +00:00
|
|
|
fprintf(stderr, "addr = %d size = %jd blocks = %d\n",
|
|
|
|
track_info->addr, (intmax_t)track_info->file_size,
|
2001-12-04 21:48:56 +00:00
|
|
|
roundup_blocks(track_info));
|
2001-01-10 19:28:37 +00:00
|
|
|
|
|
|
|
if (!quiet) {
|
2001-09-10 11:44:32 +00:00
|
|
|
if (track_info->file == STDIN_FILENO)
|
2001-01-10 19:28:37 +00:00
|
|
|
fprintf(stderr, "writing from stdin\n");
|
|
|
|
else
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stderr,
|
2002-12-29 22:28:51 +00:00
|
|
|
"writing from file %s size %jd KB\n",
|
|
|
|
track_info->file_name, (intmax_t)filesize);
|
2001-01-10 19:28:37 +00:00
|
|
|
}
|
|
|
|
size = 0;
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
while ((count = read(track_info->file, buf,
|
2003-07-26 12:14:58 +00:00
|
|
|
track_info->file_size == -1
|
|
|
|
? track_info->block_size * BLOCKS
|
|
|
|
: MIN((track_info->file_size - size),
|
2004-09-15 19:01:08 +00:00
|
|
|
track_info->block_size * BLOCKS))) > 0) {
|
2001-01-10 19:28:37 +00:00
|
|
|
int res;
|
2001-09-10 11:44:32 +00:00
|
|
|
|
|
|
|
if (count % track_info->block_size) {
|
2001-01-10 19:28:37 +00:00
|
|
|
/* pad file to % block_size */
|
2001-09-10 11:44:32 +00:00
|
|
|
bzero(&buf[count],
|
|
|
|
(track_info->block_size * BLOCKS) - count);
|
|
|
|
count = ((count / track_info->block_size) + 1) *
|
|
|
|
track_info->block_size;
|
2001-01-10 19:28:37 +00:00
|
|
|
}
|
|
|
|
if ((res = write(fd, buf, count)) != count) {
|
2008-12-19 20:20:14 +00:00
|
|
|
if (res == -1) {
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
close(track_info->file);
|
|
|
|
return errno;
|
|
|
|
} else
|
2005-05-13 20:06:44 +00:00
|
|
|
fprintf(stderr, "\nonly wrote %d of %jd"
|
|
|
|
" bytes\n", res, (intmax_t)count);
|
2001-01-10 19:28:37 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
size += count;
|
|
|
|
tot_size += count;
|
|
|
|
if (!quiet) {
|
|
|
|
int pct;
|
|
|
|
|
2002-12-29 22:28:51 +00:00
|
|
|
fprintf(stderr, "written this track %jd KB",
|
|
|
|
(intmax_t)size/1024);
|
2002-03-04 20:50:16 +00:00
|
|
|
if (track_info->file != STDIN_FILENO && filesize) {
|
2001-01-10 19:28:37 +00:00
|
|
|
pct = (size / 1024) * 100 / filesize;
|
|
|
|
fprintf(stderr, " (%d%%)", pct);
|
|
|
|
}
|
2004-09-15 19:01:08 +00:00
|
|
|
fprintf(stderr, " total %jd KB\r",
|
2002-12-29 22:28:51 +00:00
|
|
|
(intmax_t)tot_size / 1024);
|
2001-01-10 19:28:37 +00:00
|
|
|
}
|
2003-07-26 12:14:58 +00:00
|
|
|
if (track_info->file_size != -1
|
|
|
|
&& size >= track_info->file_size)
|
2001-12-04 21:48:56 +00:00
|
|
|
break;
|
2001-01-10 19:28:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!quiet)
|
|
|
|
fprintf(stderr, "\n");
|
2001-09-10 11:44:32 +00:00
|
|
|
close(track_info->file);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
roundup_blocks(struct track_info *track)
|
|
|
|
{
|
|
|
|
return ((track->file_size + track->block_size - 1) / track->block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-27 10:10:56 +00:00
|
|
|
cue_ent(struct cdr_cue_entry *cue, int ctl, int adr, int track, int idx,
|
2001-09-10 11:44:32 +00:00
|
|
|
int dataform, int scms, int lba)
|
|
|
|
{
|
|
|
|
cue->adr = adr;
|
|
|
|
cue->ctl = ctl;
|
|
|
|
cue->track = track;
|
2001-12-27 10:10:56 +00:00
|
|
|
cue->index = idx;
|
2001-09-10 11:44:32 +00:00
|
|
|
cue->dataform = dataform;
|
|
|
|
cue->scms = scms;
|
|
|
|
lba += 150;
|
|
|
|
cue->min = lba / (60*75);
|
|
|
|
cue->sec = (lba % (60*75)) / 75;
|
|
|
|
cue->frame = (lba % (60*75)) % 75;
|
|
|
|
}
|
2001-01-10 19:28:37 +00:00
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
void
|
2001-12-24 03:20:10 +00:00
|
|
|
cleanup(int dummy __unused)
|
2001-09-10 11:44:32 +00:00
|
|
|
{
|
2002-12-29 22:28:51 +00:00
|
|
|
if (ioctl(global_fd_for_cleanup, CDRIOCSETBLOCKSIZE,
|
2004-09-15 19:01:08 +00:00
|
|
|
&saved_block_size) < 0)
|
2001-09-10 11:44:32 +00:00
|
|
|
err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
|
|
|
|
}
|
|
|
|
|
2008-12-19 20:20:14 +00:00
|
|
|
void
|
|
|
|
cleanup_flush(void)
|
|
|
|
{
|
|
|
|
if (ioctl(global_fd_for_cleanup, CDRIOCFLUSH) < 0)
|
|
|
|
err(EX_IOERR, "ioctl(CDRIOCFLUSH)");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-12-23 17:57:17 +00:00
|
|
|
cleanup_signal(int sig)
|
2008-12-19 20:20:14 +00:00
|
|
|
{
|
2008-12-23 17:57:17 +00:00
|
|
|
signal(sig, SIG_IGN);
|
|
|
|
ioctl(global_fd_for_cleanup, CDRIOCFLUSH);
|
|
|
|
write(STDERR_FILENO, "\nAborted\n", 10);
|
|
|
|
_exit(EXIT_FAILURE);
|
2008-12-19 20:20:14 +00:00
|
|
|
}
|
|
|
|
|
2001-09-10 11:44:32 +00:00
|
|
|
void
|
2001-09-11 11:52:49 +00:00
|
|
|
usage(void)
|
2001-09-10 11:44:32 +00:00
|
|
|
{
|
2001-09-11 11:52:49 +00:00
|
|
|
fprintf(stderr,
|
2004-12-21 14:53:44 +00:00
|
|
|
"usage: %s [-deFlmnpqtv] [-f device] [-s speed] [command]"
|
2001-09-11 12:14:20 +00:00
|
|
|
" [command file ...]\n", getprogname());
|
2001-09-10 11:44:32 +00:00
|
|
|
exit(EX_USAGE);
|
2000-01-06 22:46:20 +00:00
|
|
|
}
|