|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
Copyright (C) 2003-2005, 2007-2008, 2011-2012, 2014, 2017
|
|
Packit |
dd8086 |
Rocky Bernstein <rocky@gnu.org>
|
|
Packit |
dd8086 |
Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org>
|
|
Packit |
dd8086 |
and Heiko Eißfeldt <heiko@hexco.de>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
dd8086 |
it under the terms of the GNU General Public License as published by
|
|
Packit |
dd8086 |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
dd8086 |
(at your option) any later version.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
dd8086 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
dd8086 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
dd8086 |
GNU General Public License for more details.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
You should have received a copy of the GNU General Public License
|
|
Packit |
dd8086 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
CD Info - prints various information about a CD, and detects the type of
|
|
Packit |
dd8086 |
the CD.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include "util.h"
|
|
Packit |
dd8086 |
#include "getopt.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STDARG_H
|
|
Packit |
dd8086 |
#include <stdarg.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STRINGS_H
|
|
Packit |
dd8086 |
#include <strings.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
#include <cddb/cddb.h>
|
|
Packit |
dd8086 |
#include "cddb.h"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
#include <libvcd/logging.h>
|
|
Packit |
dd8086 |
#include <libvcd/files.h>
|
|
Packit |
dd8086 |
#include <libvcd/info.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <cdio/bytesex.h>
|
|
Packit |
dd8086 |
#include <cdio/ds.h>
|
|
Packit |
dd8086 |
#include <cdio/util.h>
|
|
Packit |
dd8086 |
#include <cdio/cd_types.h>
|
|
Packit |
dd8086 |
#include <cdio/cdtext.h>
|
|
Packit |
dd8086 |
#include <cdio/iso9660.h>
|
|
Packit |
dd8086 |
#include <cdio/mmc.h>
|
|
Packit |
dd8086 |
#include <cdio/audio.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include "cdio_assert.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_FCNTL_H
|
|
Packit |
dd8086 |
#include <fcntl.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef __linux__
|
|
Packit |
dd8086 |
# include <linux/version.h>
|
|
Packit |
dd8086 |
# include <linux/cdrom.h>
|
|
Packit |
dd8086 |
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,50)
|
|
Packit |
dd8086 |
# include <linux/ucdrom.h>
|
|
Packit |
dd8086 |
# endif
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_ERRNO_H
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_ALLOCA_H
|
|
Packit |
dd8086 |
#include <alloca.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define STRONG "__________________________________\n"
|
|
Packit |
dd8086 |
#define NORMAL ""
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define CDIO_IOCTL_FINISHED 0
|
|
Packit |
dd8086 |
#if CDIO_IOCTL_FINISHED
|
|
Packit |
dd8086 |
static struct cdrom_multisession ms;
|
|
Packit |
dd8086 |
static struct cdrom_subchnl sub;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Used by `main' to communicate with `parse_opt'. And global options
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static struct opts_s
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int no_tracks;
|
|
Packit |
dd8086 |
int no_ioctl;
|
|
Packit |
dd8086 |
int no_analysis;
|
|
Packit |
dd8086 |
char *access_mode; /* Access method driver should use for control */
|
|
Packit |
dd8086 |
int no_cddb; /* If set the below are meaningless. */
|
|
Packit |
dd8086 |
int no_vcd;
|
|
Packit |
dd8086 |
int show_dvd;
|
|
Packit |
dd8086 |
int no_device;
|
|
Packit |
dd8086 |
int no_disc_mode;
|
|
Packit |
dd8086 |
uint32_t debug_level;
|
|
Packit |
dd8086 |
int version_only;
|
|
Packit |
dd8086 |
int silent;
|
|
Packit |
dd8086 |
int no_header;
|
|
Packit |
dd8086 |
int no_joliet;
|
|
Packit |
dd8086 |
int no_xa;
|
|
Packit |
dd8086 |
int no_rock_ridge;
|
|
Packit |
dd8086 |
int print_iso9660;
|
|
Packit |
dd8086 |
int list_drives;
|
|
Packit |
dd8086 |
source_image_t source_image;
|
|
Packit |
dd8086 |
} opts;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Configuration option codes */
|
|
Packit |
dd8086 |
enum {
|
|
Packit |
dd8086 |
OP_HANDLED = 0,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
OP_SOURCE_UNDEF,
|
|
Packit |
dd8086 |
OP_SOURCE_AUTO,
|
|
Packit |
dd8086 |
OP_SOURCE_BIN,
|
|
Packit |
dd8086 |
OP_SOURCE_CUE,
|
|
Packit |
dd8086 |
OP_SOURCE_CDRDAO,
|
|
Packit |
dd8086 |
OP_SOURCE_NRG ,
|
|
Packit |
dd8086 |
OP_SOURCE_DEVICE,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
OP_CDDB_SERVER,
|
|
Packit |
dd8086 |
OP_CDDB_CACHE,
|
|
Packit |
dd8086 |
OP_CDDB_EMAIL,
|
|
Packit |
dd8086 |
OP_CDDB_NOCACHE,
|
|
Packit |
dd8086 |
OP_CDDB_TIMEOUT,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
OP_USAGE,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* These are the remaining configuration options */
|
|
Packit |
dd8086 |
OP_VERSION,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
};
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Parse source options. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
parse_source(int opt)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
/* NOTE: The libpopt version made use of an extra temporary
|
|
Packit |
dd8086 |
variable (psz_my_source) for all sources _except_ devices.
|
|
Packit |
dd8086 |
This distinction seemed to serve no purpose.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.source_image != INPUT_UNKNOWN) {
|
|
Packit |
dd8086 |
report(stderr, "%s: another source type option given before.\n",
|
|
Packit |
dd8086 |
program_name);
|
|
Packit |
dd8086 |
report(stderr, "%s: give only one source type option.\n",
|
|
Packit |
dd8086 |
program_name);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* For all input sources which are not a DEVICE, we need to make
|
|
Packit |
dd8086 |
a copy of the string; for a DEVICE the fill-out routine makes
|
|
Packit |
dd8086 |
the copy.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
if (OP_SOURCE_DEVICE != opt)
|
|
Packit |
dd8086 |
if (optarg != NULL) source_name = strdup(optarg);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch (opt) {
|
|
Packit |
dd8086 |
case OP_SOURCE_BIN:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_BIN;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case OP_SOURCE_CUE:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_CUE;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case OP_SOURCE_CDRDAO:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_CDRDAO;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case OP_SOURCE_NRG:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_NRG;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case OP_SOURCE_AUTO:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_AUTO;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case OP_SOURCE_DEVICE:
|
|
Packit |
dd8086 |
opts.source_image = INPUT_DEVICE;
|
|
Packit |
dd8086 |
if (optarg != NULL) source_name = fillout_device_name(optarg);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Parse all options. */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
parse_options (int argc, char *argv[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int opt; /* used for argument parsing */
|
|
Packit |
dd8086 |
int rc = EXIT_FAILURE;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const char helpText[] =
|
|
Packit |
dd8086 |
"Usage: %s [OPTION...]\n"
|
|
Packit |
dd8086 |
" -a, --access-mode=STRING Set CD access method\n"
|
|
Packit |
dd8086 |
" -d, --debug=INT Set debugging to LEVEL\n"
|
|
Packit |
dd8086 |
" -T, --no-tracks Don't show track information\n"
|
|
Packit |
dd8086 |
" -A, --no-analyze Don't show filesystem analysis\n"
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
" --no-cddb Don't look up audio CDDB information\n"
|
|
Packit |
dd8086 |
" or print it\n"
|
|
Packit |
dd8086 |
" -P, --cddb-port=INT CDDB port number to use (default 8880)\n"
|
|
Packit |
dd8086 |
" -H, --cddb-http Lookup CDDB via HTTP proxy (default no\n"
|
|
Packit |
dd8086 |
" proxy)\n"
|
|
Packit |
dd8086 |
" --cddb-server=STRING CDDB server to contact for information\n"
|
|
Packit |
dd8086 |
" (default: freedb.freedb.org)\n"
|
|
Packit |
dd8086 |
" --cddb-cache=STRING Location of CDDB cache directory\n"
|
|
Packit |
dd8086 |
" (default ~/.cddbclient)\n"
|
|
Packit |
dd8086 |
" --cddb-email=STRING Email address to give CDDB server\n"
|
|
Packit |
dd8086 |
" (default me@home)\n"
|
|
Packit |
dd8086 |
" --no-cddb-cache Disable caching of CDDB entries\n"
|
|
Packit |
dd8086 |
" locally (default caches)\n"
|
|
Packit |
dd8086 |
" --cddb-timeout=INT CDDB timeout value in seconds\n"
|
|
Packit |
dd8086 |
" (default 10 seconds)\n"
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
" --no-cddb Does nothing since this program is not\n"
|
|
Packit |
dd8086 |
" -P, --cddb-port=INT CDDB-enabled\n"
|
|
Packit |
dd8086 |
" -H, --cddb-http\n"
|
|
Packit |
dd8086 |
" --cddb-server=STRING\n"
|
|
Packit |
dd8086 |
" --cddb-cache=STRING\n"
|
|
Packit |
dd8086 |
" --cddb-email=STRING\n"
|
|
Packit |
dd8086 |
" --no-cddb-cache\n"
|
|
Packit |
dd8086 |
" --cddb-timeout=INT\n"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
" --no-device-info Don't show device info, just CD info\n"
|
|
Packit |
dd8086 |
" --no-disc-mode Don't show disc-mode info\n"
|
|
Packit |
dd8086 |
" --dvd Attempt to give DVD information if a DVD is\n"
|
|
Packit |
dd8086 |
" found.\n"
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
" -v, --no-vcd Don't look up Video CD information\n"
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
" -v, --no-vcd Don't look up Video CD information - for\n"
|
|
Packit |
dd8086 |
" this build, this is always set\n"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
" -I, --no-ioctl Don't show ioctl() information\n"
|
|
Packit |
dd8086 |
" -b, --bin-file[=FILE] set \"bin\" CD-ROM disk image file as source\n"
|
|
Packit |
dd8086 |
" -c, --cue-file[=FILE] set \"cue\" CD-ROM disk image file as source\n"
|
|
Packit |
dd8086 |
" -N, --nrg-file[=FILE] set Nero CD-ROM disk image file as source\n"
|
|
Packit |
dd8086 |
" -t, --toc-file[=FILE] set cdrdao CD-ROM disk image file as source\n"
|
|
Packit |
dd8086 |
" -i, --input[=FILE] set source and determine if \"bin\" image or\n"
|
|
Packit |
dd8086 |
" device\n"
|
|
Packit |
dd8086 |
" --iso9660 print directory contents of any ISO-9660\n"
|
|
Packit |
dd8086 |
" filesystems\n"
|
|
Packit |
dd8086 |
" -C, --cdrom-device[=DEVICE] set CD-ROM device as source\n"
|
|
Packit |
dd8086 |
" -l, --list-drives Give a list of CD-drives\n"
|
|
Packit |
dd8086 |
" --no-header Don't display header and copyright (for\n"
|
|
Packit |
dd8086 |
" regression testing)\n"
|
|
Packit |
dd8086 |
#ifdef HAVE_JOLIET
|
|
Packit |
dd8086 |
" --no-joliet Don't use Joliet extensions\n"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
" --no-rock-ridge Don't use Rock-Ridge-extension information\n"
|
|
Packit |
dd8086 |
" --no-xa Don't use XA-extension information\n"
|
|
Packit |
dd8086 |
" -q, --quiet Don't produce warning output\n"
|
|
Packit |
dd8086 |
" -V, --version display version and copyright information\n"
|
|
Packit |
dd8086 |
" and exit\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"Help options:\n"
|
|
Packit |
dd8086 |
" -?, --help Show this help message\n"
|
|
Packit |
dd8086 |
" --usage Display brief usage message\n";
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const char usageText[] =
|
|
Packit |
dd8086 |
"Usage: %s [-a|--access-mode STRING] [-d|--debug INT] [-T|--no-tracks]\n"
|
|
Packit |
dd8086 |
" [-A|--no-analyze] [--no-cddb] [-P|--cddb-port INT] [-H|--cddb-http]\n"
|
|
Packit |
dd8086 |
" [--cddb-server=STRING] [--cddb-cache=STRING] [--cddb-email=STRING]\n"
|
|
Packit |
dd8086 |
" [--no-cddb-cache] [--cddb-timeout=INT] [--no-device-info]\n"
|
|
Packit |
dd8086 |
" [--no-disc-mode] [--dvd] [-v|--no-vcd] [-I|--no-ioctl]\n"
|
|
Packit |
dd8086 |
" [-b|--bin-file FILE] [-c|--cue-file FILE] [-N|--nrg-file FILE]\n"
|
|
Packit |
dd8086 |
" [-t|--toc-file FILE] [-i|--input FILE] [--iso9660]\n"
|
|
Packit |
dd8086 |
" [-C|--cdrom-device DEVICE] [-l|--list-drives] [--no-header]\n"
|
|
Packit |
dd8086 |
" [--no-joliet] [--no-rock-ridge] [--no-xa] [-q|--quiet] [-V|--version]\n"
|
|
Packit |
dd8086 |
" [-?|--help] [--usage]\n";
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const char optionsString[] = "a:d:TAP:HvIb::c::N::t::i::C::lqV?";
|
|
Packit |
dd8086 |
static const struct option optionsTable[] = {
|
|
Packit |
dd8086 |
{"access-mode", required_argument, NULL, 'a'},
|
|
Packit |
dd8086 |
{"debug", required_argument, NULL, 'd' },
|
|
Packit |
dd8086 |
{"no-tracks", no_argument, NULL, 'T' },
|
|
Packit |
dd8086 |
{"no-analyze", no_argument, NULL, 'A' },
|
|
Packit |
dd8086 |
{"no-cddb", no_argument, &opts.no_cddb, 1 },
|
|
Packit |
dd8086 |
{"cddb-port", required_argument, NULL, 'P' },
|
|
Packit |
dd8086 |
{"cddb-http", no_argument, NULL, 'H' },
|
|
Packit |
dd8086 |
{"cddb-server", required_argument, NULL, OP_CDDB_SERVER },
|
|
Packit |
dd8086 |
{"cddb-cache", required_argument, NULL, OP_CDDB_CACHE },
|
|
Packit |
dd8086 |
{"cddb-email", required_argument, NULL, OP_CDDB_EMAIL },
|
|
Packit |
dd8086 |
{"no-cddb-cache", no_argument, NULL, OP_CDDB_NOCACHE },
|
|
Packit |
dd8086 |
{"cddb-timeout", required_argument, NULL, OP_CDDB_TIMEOUT },
|
|
Packit |
dd8086 |
{"no-device-info", no_argument, &opts.no_device, 1 },
|
|
Packit |
dd8086 |
{"no-disc-mode", no_argument, &opts.no_disc_mode, 1 },
|
|
Packit |
dd8086 |
{"dvd", no_argument, &opts.show_dvd, 1 },
|
|
Packit |
dd8086 |
{"no-vcd", no_argument, NULL, 'v' },
|
|
Packit |
dd8086 |
{"no-ioctl", no_argument, NULL, 'I' },
|
|
Packit |
dd8086 |
{"bin-file", optional_argument, NULL, 'b' },
|
|
Packit |
dd8086 |
{"cue-file", optional_argument, NULL, 'c' },
|
|
Packit |
dd8086 |
{"nrg-file", optional_argument, NULL, 'N' },
|
|
Packit |
dd8086 |
{"toc-file", optional_argument, NULL, 't' },
|
|
Packit |
dd8086 |
{"input", optional_argument, NULL, 'i' },
|
|
Packit |
dd8086 |
{"iso9660", no_argument, &opts.print_iso9660, 1 },
|
|
Packit |
dd8086 |
{"cdrom-device", optional_argument, NULL, 'C' },
|
|
Packit |
dd8086 |
{"list-drives", no_argument, NULL, 'l' },
|
|
Packit |
dd8086 |
{"no-header", no_argument, &opts.no_header, 1 },
|
|
Packit |
dd8086 |
#ifdef HAVE_JOLIET
|
|
Packit |
dd8086 |
{"no-joliet", no_argument, &opts.no_joliet, 1 },
|
|
Packit |
dd8086 |
#endif /*HAVE_JOLIET*/
|
|
Packit |
dd8086 |
{"no-rock-ridge", no_argument, &opts.no_rock_ridge, 1 },
|
|
Packit |
dd8086 |
{"no-xa", no_argument, &opts.no_xa, 1 },
|
|
Packit |
dd8086 |
{"quiet", no_argument, NULL, 'q' },
|
|
Packit |
dd8086 |
{"version", no_argument, NULL, 'V' },
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
{"help", no_argument, NULL, '?' },
|
|
Packit |
dd8086 |
{"usage", no_argument, NULL, OP_USAGE },
|
|
Packit |
dd8086 |
{ NULL, 0, NULL, 0 }
|
|
Packit |
dd8086 |
};
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
program_name = strrchr(argv[0],'/');
|
|
Packit |
dd8086 |
program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0) {
|
|
Packit |
dd8086 |
switch (opt) {
|
|
Packit |
dd8086 |
case 'a': opts.access_mode = strdup(optarg); break;
|
|
Packit |
dd8086 |
case 'd': opts.debug_level = atoi(optarg); break;
|
|
Packit |
dd8086 |
case 'T': opts.no_tracks = 1; break;
|
|
Packit |
dd8086 |
case 'A': opts.no_analysis = 1; break;
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
case 'P': cddb_opts.port = atoi(optarg); break;
|
|
Packit |
dd8086 |
case 'H': cddb_opts.http = 1; break;
|
|
Packit |
dd8086 |
case OP_CDDB_SERVER: cddb_opts.server = strdup(optarg); break;
|
|
Packit |
dd8086 |
case OP_CDDB_CACHE: cddb_opts.cachedir = strdup(optarg); break;
|
|
Packit |
dd8086 |
case OP_CDDB_EMAIL: cddb_opts.email = strdup(optarg); break;
|
|
Packit |
dd8086 |
case OP_CDDB_NOCACHE: cddb_opts.disable_cache = 1; break;
|
|
Packit |
dd8086 |
case OP_CDDB_TIMEOUT: cddb_opts.timeout = atoi(optarg); break;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
case 'v': opts.no_vcd = 1; break;
|
|
Packit |
dd8086 |
case 'I': opts.no_ioctl = 1; break;
|
|
Packit |
dd8086 |
case 'b': parse_source(OP_SOURCE_BIN); break;
|
|
Packit |
dd8086 |
case 'c': parse_source(OP_SOURCE_CUE); break;
|
|
Packit |
dd8086 |
case 'N': parse_source(OP_SOURCE_NRG); break;
|
|
Packit |
dd8086 |
case 't': parse_source(OP_SOURCE_CDRDAO); break;
|
|
Packit |
dd8086 |
case 'i': parse_source(OP_SOURCE_AUTO); break;
|
|
Packit |
dd8086 |
case 'C': parse_source(OP_SOURCE_DEVICE); break;
|
|
Packit |
dd8086 |
case 'l': opts.list_drives = 1; break;
|
|
Packit |
dd8086 |
case 'q': opts.silent = 1; break;
|
|
Packit |
dd8086 |
case 'V': opts.version_only = 1; break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case '?':
|
|
Packit |
dd8086 |
fprintf(stdout, helpText, program_name);
|
|
Packit |
dd8086 |
rc = EXIT_INFO;
|
|
Packit |
dd8086 |
goto error_exit;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case OP_USAGE:
|
|
Packit |
dd8086 |
fprintf(stderr, usageText, program_name);
|
|
Packit |
dd8086 |
rc = EXIT_INFO;
|
|
Packit |
dd8086 |
goto error_exit;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case OP_HANDLED:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (optind < argc) {
|
|
Packit |
dd8086 |
const char *remaining_arg = argv[optind++];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (source_name != NULL) {
|
|
Packit |
dd8086 |
report(stderr, "%s: Source '%s' given as an argument of an option and as "
|
|
Packit |
dd8086 |
"unnamed option '%s'\n",
|
|
Packit |
dd8086 |
program_name, source_name, remaining_arg);
|
|
Packit |
dd8086 |
goto error_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.source_image == INPUT_DEVICE)
|
|
Packit |
dd8086 |
source_name = fillout_device_name(remaining_arg);
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
source_name = strdup(remaining_arg);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (optind < argc) {
|
|
Packit |
dd8086 |
report(stderr, "%s: Source specified in previously %s and %s\n",
|
|
Packit |
dd8086 |
program_name, source_name, remaining_arg);
|
|
Packit |
dd8086 |
free(source_name);
|
|
Packit |
dd8086 |
goto error_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return true;
|
|
Packit |
dd8086 |
error_exit:
|
|
Packit |
dd8086 |
free(program_name);
|
|
Packit |
dd8086 |
exit(rc);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* CDIO logging routines */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
static cddb_log_handler_t gl_default_cddb_log_handler = NULL;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
static vcd_log_handler_t gl_default_vcd_log_handler = NULL;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
_log_handler (cdio_log_level_t level, const char message[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (level == CDIO_LOG_DEBUG && opts.debug_level < 2)
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (level == CDIO_LOG_INFO && opts.debug_level < 1)
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (level == CDIO_LOG_WARN && opts.silent)
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
gl_default_cdio_log_handler (level, message);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
_cddb_log_handler (cddb_log_level_t level, const char message[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
/* CDDB errors should not be considered fatal. */
|
|
Packit |
dd8086 |
if (level == (cddb_log_level_t) CDDB_LOG_ERROR)
|
|
Packit |
dd8086 |
level = (cddb_log_level_t) CDIO_LOG_WARN;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Might consider doing some sort of CDDB to cdio to log level conversion,
|
|
Packit |
dd8086 |
but right now it's a no op. */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_log_handler((cdio_log_level_t) level, message);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_cdtext_track_info(cdtext_t *p_cdtext, track_t i_track, const char *psz_msg) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != p_cdtext) {
|
|
Packit |
dd8086 |
cdtext_field_t i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("%s\n", psz_msg);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
|
|
Packit |
dd8086 |
if (cdtext_get_const(p_cdtext, i, i_track)) {
|
|
Packit |
dd8086 |
printf("\t%s: %s\n", cdtext_field2str(i), cdtext_get_const(p_cdtext, i, i_track));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_cdtext_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) {
|
|
Packit |
dd8086 |
track_t i_last_track = i_first_track+i_tracks;
|
|
Packit |
dd8086 |
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
|
|
Packit |
dd8086 |
cdtext_lang_t *languages;
|
|
Packit |
dd8086 |
cdtext_genre_t genre;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int i, j;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if(NULL == p_cdtext) {
|
|
Packit |
dd8086 |
printf("No CD-TEXT on Disc.\n");
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
languages = cdtext_list_languages(p_cdtext);
|
|
Packit |
dd8086 |
for(i=0; i<8; i++)
|
|
Packit |
dd8086 |
if ( CDTEXT_LANGUAGE_UNKNOWN != languages[i]
|
|
Packit |
dd8086 |
&& cdtext_select_language(p_cdtext, languages[i]))
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
printf("\nLanguage %d '%s':\n", i, cdtext_lang2str(languages[i]));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_cdtext_track_info(p_cdtext, 0, "CD-TEXT for Disc:");
|
|
Packit |
dd8086 |
genre = cdtext_get_genre(p_cdtext);
|
|
Packit |
dd8086 |
if ( CDTEXT_GENRE_UNUSED != genre)
|
|
Packit |
dd8086 |
printf("\tGENRE_CODE: %d (%s)\n", genre, cdtext_genre2str(genre));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for ( j = i_first_track ; j < i_last_track; j++ ) {
|
|
Packit |
dd8086 |
char msg[50];
|
|
Packit |
dd8086 |
sprintf(msg, "CD-TEXT for Track %2d:", j);
|
|
Packit |
dd8086 |
print_cdtext_track_info(p_cdtext, j, msg);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
cddb_errmsg(const char *msg)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
report(stderr, "%s: %s\n", program_name, msg);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_cddb_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int i, i_cddb_matches = 0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cddb_conn_t *p_conn = NULL;
|
|
Packit |
dd8086 |
cddb_disc_t *p_cddb_disc = NULL;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( init_cddb(p_cdio, &p_conn, &p_cddb_disc, cddb_errmsg, i_first_track,
|
|
Packit |
dd8086 |
i_tracks, &i_cddb_matches) ) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (-1 == i_cddb_matches)
|
|
Packit |
dd8086 |
printf("%s: %s\n", program_name, cddb_error_str(cddb_errno(p_conn)));
|
|
Packit |
dd8086 |
else {
|
|
Packit |
dd8086 |
printf("%s: Found %d matches in CDDB\n", program_name, i_cddb_matches);
|
|
Packit |
dd8086 |
for (i=1; i<=i_cddb_matches; i++) {
|
|
Packit |
dd8086 |
cddb_disc_print(p_cddb_disc);
|
|
Packit |
dd8086 |
cddb_query_next(p_conn, p_cddb_disc);
|
|
Packit |
dd8086 |
if (i != i_cddb_matches) cddb_read(p_conn, p_cddb_disc);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cddb_disc_destroy(p_cddb_disc);
|
|
Packit |
dd8086 |
cddb_destroy(p_conn);
|
|
Packit |
dd8086 |
libcddb_shutdown();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_vcd_info(driver_id_t driver) {
|
|
Packit |
dd8086 |
vcdinfo_open_return_t open_rc;
|
|
Packit |
dd8086 |
vcdinfo_obj_t *p_vcd = NULL;
|
|
Packit |
dd8086 |
open_rc = vcdinfo_open(&p_vcd, &source_name, driver, NULL);
|
|
Packit |
dd8086 |
switch (open_rc) {
|
|
Packit |
dd8086 |
case VCDINFO_OPEN_VCD:
|
|
Packit |
dd8086 |
if (vcdinfo_get_format_version (p_vcd) == VCD_TYPE_INVALID) {
|
|
Packit |
dd8086 |
report(stderr, "VCD format detection failed");
|
|
Packit |
dd8086 |
vcdinfo_close(p_vcd);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
report (stdout, "Format : %s\n",
|
|
Packit |
dd8086 |
vcdinfo_get_format_version_str(p_vcd));
|
|
Packit |
dd8086 |
report (stdout, "Album : `%.16s'\n", vcdinfo_get_album_id(p_vcd));
|
|
Packit |
dd8086 |
report (stdout, "Volume count : %d\n", vcdinfo_get_volume_count(p_vcd));
|
|
Packit |
dd8086 |
report (stdout, "volume number: %d\n", vcdinfo_get_volume_num(p_vcd));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case VCDINFO_OPEN_ERROR:
|
|
Packit |
dd8086 |
report( stderr, "Error in Video CD opening of %s\n", source_name );
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case VCDINFO_OPEN_OTHER:
|
|
Packit |
dd8086 |
report( stderr, "Even though we thought this was a Video CD, "
|
|
Packit |
dd8086 |
" further inspection says it is not.\n" );
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (p_vcd) vcdinfo_close(p_vcd);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_iso9660_recurse (CdIo_t *p_cdio, const char pathname[],
|
|
Packit |
dd8086 |
cdio_fs_anal_t fs)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
CdioISO9660FileList_t *p_entlist;
|
|
Packit |
dd8086 |
CdioISO9660DirList_t *p_dirlist = iso9660_dirlist_new();
|
|
Packit |
dd8086 |
CdioListNode_t *entnode;
|
|
Packit |
dd8086 |
uint8_t i_joliet_level;
|
|
Packit |
dd8086 |
char *translated_name = (char *) alloca(4096);
|
|
Packit |
dd8086 |
size_t translated_name_size = 4096;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_joliet_level = (opts.no_joliet)
|
|
Packit |
dd8086 |
? 0
|
|
Packit |
dd8086 |
: cdio_get_joliet_level(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_entlist = iso9660_fs_readdir(p_cdio, pathname);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf ("%s:\n", pathname);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_entlist) {
|
|
Packit |
dd8086 |
report( stderr, "Error getting above directory information\n" );
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Iterate over files in this directory */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_CDIO_LIST_FOREACH (entnode, p_entlist)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
iso9660_stat_t *p_statbuf = _cdio_list_node_data (entnode);
|
|
Packit |
dd8086 |
char *psz_iso_name = p_statbuf->filename;
|
|
Packit |
dd8086 |
char _fullname[4096] = { 0, };
|
|
Packit |
dd8086 |
if (strlen(psz_iso_name) >= translated_name_size) {
|
|
Packit |
dd8086 |
translated_name_size = strlen(psz_iso_name)+1;
|
|
Packit |
dd8086 |
if (!translated_name) {
|
|
Packit |
dd8086 |
report( stderr, "Error allocating memory\n" );
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (yep != p_statbuf->rr.b3_rock || 1 == opts.no_rock_ridge) {
|
|
Packit |
dd8086 |
iso9660_name_translate_ext(psz_iso_name, translated_name,
|
|
Packit |
dd8086 |
i_joliet_level);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
snprintf (_fullname, sizeof (_fullname), "%s%s", pathname,
|
|
Packit |
dd8086 |
psz_iso_name);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
strncat (_fullname, "/", sizeof(_fullname) - strlen(_fullname) - 1);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_statbuf->type == _STAT_DIR
|
|
Packit |
dd8086 |
&& strcmp (psz_iso_name, ".")
|
|
Packit |
dd8086 |
&& strcmp (psz_iso_name, ".."))
|
|
Packit |
dd8086 |
_cdio_list_append (p_dirlist, strdup (_fullname));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_fs_attrs(p_statbuf, 0 == opts.no_rock_ridge, fs & CDIO_FS_ANAL_XA,
|
|
Packit |
dd8086 |
psz_iso_name, translated_name);
|
|
Packit |
dd8086 |
if (p_statbuf->rr.i_symlink) {
|
|
Packit |
dd8086 |
free(p_statbuf->rr.psz_symlink);
|
|
Packit |
dd8086 |
p_statbuf->rr.i_symlink = 0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_filelist_free(p_entlist);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf ("\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Now recurse over the directories. */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_CDIO_LIST_FOREACH (entnode, p_dirlist)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char *_fullname = _cdio_list_node_data (entnode);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_iso9660_recurse (p_cdio, _fullname, fs);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_iso9660_fs (CdIo_t *p_cdio, cdio_fs_anal_t fs,
|
|
Packit |
dd8086 |
track_format_t track_format)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.no_joliet) {
|
|
Packit |
dd8086 |
iso_extension_mask &= ~ISO_EXTENSION_JOLIET;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( !iso9660_fs_read_superblock(p_cdio, iso_extension_mask) )
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf ("ISO9660 filesystem\n");
|
|
Packit |
dd8086 |
print_iso9660_recurse (p_cdio, "/", fs);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define print_vd_info(title, fn) \
|
|
Packit |
dd8086 |
psz_str = fn(&pvd); \
|
|
Packit |
dd8086 |
if (psz_str) { \
|
|
Packit |
dd8086 |
report(stdout, title ": %s\n", psz_str); \
|
|
Packit |
dd8086 |
free(psz_str); \
|
|
Packit |
dd8086 |
psz_str = NULL; \
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_analysis(int ms_offset, cdio_iso_analysis_t cdio_iso_analysis,
|
|
Packit |
dd8086 |
cdio_fs_anal_t fs, int first_data, unsigned int num_audio,
|
|
Packit |
dd8086 |
track_t i_tracks, track_t i_first_track,
|
|
Packit |
dd8086 |
track_format_t track_format, CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int need_lf;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch(CDIO_FSTYPE(fs)) {
|
|
Packit |
dd8086 |
case CDIO_FS_AUDIO:
|
|
Packit |
dd8086 |
if (num_audio > 0) {
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
if (!opts.no_cddb) {
|
|
Packit |
dd8086 |
printf("Audio CD, CDDB disc ID is %08x\n",
|
|
Packit |
dd8086 |
cddb_discid(p_cdio, i_tracks));
|
|
Packit |
dd8086 |
print_cddb_info(p_cdio, i_tracks, i_first_track);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
print_cdtext_info(p_cdio, i_tracks, i_first_track);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660:
|
|
Packit |
dd8086 |
printf("CD-ROM with ISO 9660 filesystem");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_JOLIET) {
|
|
Packit |
dd8086 |
printf(" and joliet extension level %d", cdio_iso_analysis.joliet_level);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_ROCKRIDGE)
|
|
Packit |
dd8086 |
printf(" and rockridge extensions");
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660_INTERACTIVE:
|
|
Packit |
dd8086 |
printf("CD-ROM with CD-RTOS and ISO 9660 filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_HIGH_SIERRA:
|
|
Packit |
dd8086 |
printf("CD-ROM with High Sierra filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_INTERACTIVE:
|
|
Packit |
dd8086 |
printf("CD-Interactive%s\n", num_audio > 0 ? "/Ready" : "");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_HFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with Macintosh HFS\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_HFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with both Macintosh HFS and ISO 9660 filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_UFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with Unix UFS\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_EXT2:
|
|
Packit |
dd8086 |
printf("CD-ROM with GNU/Linux EXT2 (native) filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_3DO:
|
|
Packit |
dd8086 |
printf("CD-ROM with Panasonic 3DO filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_UDFX:
|
|
Packit |
dd8086 |
printf("CD-ROM with UDFX filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_UNKNOWN:
|
|
Packit |
dd8086 |
printf("CD-ROM with unknown filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_XISO:
|
|
Packit |
dd8086 |
printf("CD-ROM with Microsoft X-BOX XISO filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
switch(CDIO_FSTYPE(fs)) {
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660_INTERACTIVE:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_HFS:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_UDF:
|
|
Packit |
dd8086 |
printf("ISO 9660: %i blocks, label `%.32s'\n",
|
|
Packit |
dd8086 |
cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
iso9660_pvd_t pvd;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( iso9660_fs_read_pvd(p_cdio, &pvd) ) {
|
|
Packit |
dd8086 |
char *psz_str;
|
|
Packit |
dd8086 |
print_vd_info("Application", iso9660_get_application_id);
|
|
Packit |
dd8086 |
print_vd_info("Preparer ", iso9660_get_preparer_id);
|
|
Packit |
dd8086 |
print_vd_info("Publisher ", iso9660_get_publisher_id);
|
|
Packit |
dd8086 |
print_vd_info("System ", iso9660_get_system_id);
|
|
Packit |
dd8086 |
print_vd_info("Volume ", iso9660_get_volume_id);
|
|
Packit |
dd8086 |
print_vd_info("Volume Set ", iso9660_get_volumeset_id);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.print_iso9660)
|
|
Packit |
dd8086 |
print_iso9660_fs(p_cdio, fs, track_format);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch(CDIO_FSTYPE(fs)) {
|
|
Packit |
dd8086 |
case CDIO_FS_UDF:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_UDF:
|
|
Packit |
dd8086 |
report(stdout, "UDF: version %x.%2.2x\n",
|
|
Packit |
dd8086 |
cdio_iso_analysis.UDFVerMajor, cdio_iso_analysis.UDFVerMinor);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default: ;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
need_lf = 0;
|
|
Packit |
dd8086 |
if (first_data == 1 && num_audio > 0)
|
|
Packit |
dd8086 |
need_lf += printf("mixed mode CD ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_XA)
|
|
Packit |
dd8086 |
need_lf += printf("XA sectors ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_MULTISESSION)
|
|
Packit |
dd8086 |
need_lf += printf("Multisession, offset = %i ", ms_offset);
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_HIDDEN_TRACK)
|
|
Packit |
dd8086 |
need_lf += printf("Hidden Track ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_PHOTO_CD)
|
|
Packit |
dd8086 |
need_lf += printf("%sPhoto CD ",
|
|
Packit |
dd8086 |
num_audio > 0 ? " Portfolio " : "");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_CDTV)
|
|
Packit |
dd8086 |
need_lf += printf("Commodore CDTV ");
|
|
Packit |
dd8086 |
if (first_data > 1)
|
|
Packit |
dd8086 |
need_lf += printf("CD-Plus/Extra ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_BOOTABLE)
|
|
Packit |
dd8086 |
need_lf += printf("bootable CD ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_VIDEOCD && num_audio == 0) {
|
|
Packit |
dd8086 |
need_lf += printf("Video CD ");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_SVCD)
|
|
Packit |
dd8086 |
need_lf += printf("Super Video CD (SVCD) or Chaoji Video CD (CVD)");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_CVD)
|
|
Packit |
dd8086 |
need_lf += printf("Chaoji Video CD (CVD)");
|
|
Packit |
dd8086 |
if (need_lf) printf("\n");
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
if (fs & (CDIO_FS_ANAL_VIDEOCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_SVCD))
|
|
Packit |
dd8086 |
if (!opts.no_vcd) {
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
print_vcd_info(cdio_get_driver_id(p_cdio));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Initialize global variables. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
init(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
gl_default_cdio_log_handler = cdio_log_set_handler (_log_handler);
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
gl_default_cddb_log_handler =
|
|
Packit |
dd8086 |
cddb_log_set_handler ((cddb_log_handler_t) _cddb_log_handler);
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
gl_default_vcd_log_handler =
|
|
Packit |
dd8086 |
vcd_log_set_handler ((vcd_log_handler_t) _log_handler);
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Default option values. */
|
|
Packit |
dd8086 |
opts.silent = false;
|
|
Packit |
dd8086 |
opts.list_drives = false;
|
|
Packit |
dd8086 |
opts.no_header = false;
|
|
Packit |
dd8086 |
opts.no_joliet = 0;
|
|
Packit |
dd8086 |
opts.no_rock_ridge = 0;
|
|
Packit |
dd8086 |
opts.no_xa = 0;
|
|
Packit |
dd8086 |
opts.no_device = 0;
|
|
Packit |
dd8086 |
opts.no_disc_mode = 0;
|
|
Packit |
dd8086 |
opts.debug_level = 0;
|
|
Packit |
dd8086 |
opts.no_tracks = 0;
|
|
Packit |
dd8086 |
opts.print_iso9660 = 0;
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
opts.no_cddb = 0;
|
|
Packit |
dd8086 |
cddb_opts.port = 8880;
|
|
Packit |
dd8086 |
cddb_opts.http = 0;
|
|
Packit |
dd8086 |
cddb_opts.cachedir = NULL;
|
|
Packit |
dd8086 |
cddb_opts.server = NULL;
|
|
Packit |
dd8086 |
cddb_opts.timeout = -1;
|
|
Packit |
dd8086 |
cddb_opts.disable_cache = false;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
opts.no_vcd = 0;
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
opts.no_vcd = 1;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
opts.no_ioctl = 0;
|
|
Packit |
dd8086 |
opts.no_analysis = 0;
|
|
Packit |
dd8086 |
opts.source_image = INPUT_UNKNOWN;
|
|
Packit |
dd8086 |
opts.access_mode = NULL;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, char *argv[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
CdIo_t *p_cdio=NULL;
|
|
Packit |
dd8086 |
cdio_fs_anal_t fs = CDIO_FS_AUDIO;
|
|
Packit |
dd8086 |
int i;
|
|
Packit |
dd8086 |
lsn_t start_track_lsn; /* lsn of first track */
|
|
Packit |
dd8086 |
lsn_t data_start = 0; /* start of data area */
|
|
Packit |
dd8086 |
int ms_offset = 0;
|
|
Packit |
dd8086 |
track_t i_tracks = 0;
|
|
Packit |
dd8086 |
track_t i_first_track = 0;
|
|
Packit |
dd8086 |
unsigned int num_audio = 0; /* # of audio tracks */
|
|
Packit |
dd8086 |
unsigned int num_data = 0; /* # of data tracks */
|
|
Packit |
dd8086 |
int first_data = -1; /* # of first data track */
|
|
Packit |
dd8086 |
int first_audio = -1; /* # of first audio track */
|
|
Packit |
dd8086 |
bool b_playing_audio = false; /* currently playing a
|
|
Packit |
dd8086 |
CD-DA */
|
|
Packit |
dd8086 |
cdio_iso_analysis_t cdio_iso_analysis;
|
|
Packit |
dd8086 |
char *media_catalog_number;
|
|
Packit |
dd8086 |
char *isrc;
|
|
Packit |
dd8086 |
discmode_t discmode = CDIO_DISC_MODE_NO_INFO;
|
|
Packit |
dd8086 |
cdio_drive_read_cap_t i_read_cap = 0;
|
|
Packit |
dd8086 |
cdio_drive_write_cap_t i_write_cap;
|
|
Packit |
dd8086 |
cdio_drive_misc_cap_t i_misc_cap;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset(&cdio_iso_analysis, 0, sizeof(cdio_iso_analysis));
|
|
Packit |
dd8086 |
init();
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Parse our arguments; every option seen by `parse_opt' will
|
|
Packit |
dd8086 |
be reflected in `arguments'. */
|
|
Packit |
dd8086 |
parse_options(argc, argv);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_version(program_name, CDIO_VERSION, opts.no_header, opts.version_only);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.debug_level == 3) {
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_INFO;
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
vcd_loglevel_default = VCD_LOG_INFO;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
} else if (opts.debug_level >= 4) {
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_DEBUG;
|
|
Packit |
dd8086 |
#ifdef HAVE_VCDINFO
|
|
Packit |
dd8086 |
vcd_loglevel_default = VCD_LOG_DEBUG;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_cdio = open_input(source_name, opts.source_image, opts.access_mode);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_cdio==NULL) {
|
|
Packit |
dd8086 |
if (source_name) {
|
|
Packit |
dd8086 |
err_exit("%s: Error in opening device driver for input %s.\n",
|
|
Packit |
dd8086 |
program_name, source_name);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
err_exit("%s: Error in opening device driver for unspecified input.\n",
|
|
Packit |
dd8086 |
program_name);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (source_name==NULL) {
|
|
Packit |
dd8086 |
source_name=strdup(cdio_get_arg(p_cdio, "source"));
|
|
Packit |
dd8086 |
if (NULL == source_name) {
|
|
Packit |
dd8086 |
err_exit("%s: No input device given/found\n", program_name);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (0 == opts.silent) {
|
|
Packit |
dd8086 |
printf("CD location : %s\n", source_name);
|
|
Packit |
dd8086 |
printf("CD driver name: %s\n", cdio_get_driver_name(p_cdio));
|
|
Packit |
dd8086 |
printf(" access mode: %s\n\n", cdio_get_arg(p_cdio, "access-mode"));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_get_drive_cap(p_cdio, &i_read_cap, &i_write_cap, &i_misc_cap);
|
|
Packit |
dd8086 |
if (0 == opts.no_device) {
|
|
Packit |
dd8086 |
cdio_hwinfo_t hwinfo;
|
|
Packit |
dd8086 |
if (cdio_get_hwinfo(p_cdio, &hwinfo)) {
|
|
Packit |
dd8086 |
printf("%-28s: %s\n%-28s: %s\n%-28s: %s\n",
|
|
Packit |
dd8086 |
"Vendor" , hwinfo.psz_vendor,
|
|
Packit |
dd8086 |
"Model" , hwinfo.psz_model,
|
|
Packit |
dd8086 |
"Revision", hwinfo.psz_revision);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
print_drive_capabilities(i_read_cap, i_write_cap, i_misc_cap);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.list_drives) {
|
|
Packit |
dd8086 |
driver_id_t driver_id = DRIVER_DEVICE;
|
|
Packit |
dd8086 |
char ** device_list = cdio_get_devices_ret(&driver_id);
|
|
Packit |
dd8086 |
char ** d = device_list;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("list of devices found:\n");
|
|
Packit |
dd8086 |
if (NULL != d) {
|
|
Packit |
dd8086 |
for ( ; *d != NULL ; d++ ) {
|
|
Packit |
dd8086 |
CdIo_t *p_cdio_d = cdio_open(*d, driver_id);
|
|
Packit |
dd8086 |
cdio_hwinfo_t hwinfo;
|
|
Packit |
dd8086 |
printf("Drive %s\n", *d);
|
|
Packit |
dd8086 |
if (mmc_get_hwinfo(p_cdio_d, &hwinfo)) {
|
|
Packit |
dd8086 |
printf("%-8s: %s\n%-8s: %s\n%-8s: %s\n",
|
|
Packit |
dd8086 |
"Vendor" , hwinfo.psz_vendor,
|
|
Packit |
dd8086 |
"Model" , hwinfo.psz_model,
|
|
Packit |
dd8086 |
"Revision", hwinfo.psz_revision);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (p_cdio_d) cdio_destroy(p_cdio_d);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
cdio_free_device_list(device_list);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
report(stdout, STRONG "\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
discmode = cdio_get_discmode(p_cdio);
|
|
Packit |
dd8086 |
if ( 0 == opts.no_disc_mode ) {
|
|
Packit |
dd8086 |
printf("Disc mode is listed as: %s\n",
|
|
Packit |
dd8086 |
discmode2str[discmode]);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (cdio_is_discmode_dvd(discmode) && !opts.show_dvd) {
|
|
Packit |
dd8086 |
printf("No further information currently given for DVDs.\n");
|
|
Packit |
dd8086 |
printf("Use --dvd to override.\n");
|
|
Packit |
dd8086 |
myexit(p_cdio, EXIT_SUCCESS);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_first_track = cdio_get_first_track_num(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (CDIO_INVALID_TRACK == i_first_track) {
|
|
Packit |
dd8086 |
err_exit("Can't get first track number. I give up%s.\n", "");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_tracks = cdio_get_num_tracks(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (CDIO_INVALID_TRACK == i_tracks) {
|
|
Packit |
dd8086 |
err_exit("Can't get number of tracks. I give up.%s\n", "");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!opts.no_tracks) {
|
|
Packit |
dd8086 |
printf("CD-ROM Track List (%i - %i)\n" NORMAL,
|
|
Packit |
dd8086 |
i_first_track, i_tracks);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf(" #: MSF LSN Type Green? Copy?");
|
|
Packit |
dd8086 |
if ( CDIO_DISC_MODE_CD_DA == discmode
|
|
Packit |
dd8086 |
|| CDIO_DISC_MODE_CD_MIXED == discmode )
|
|
Packit |
dd8086 |
printf(" Channels Premphasis?");
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
start_track_lsn = cdio_get_track_lsn(p_cdio, i_first_track);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Read and possibly print track information. */
|
|
Packit |
dd8086 |
for (i = i_first_track; i <= CDIO_CDROM_LEADOUT_TRACK; i++) {
|
|
Packit |
dd8086 |
msf_t msf;
|
|
Packit |
dd8086 |
char *psz_msf;
|
|
Packit |
dd8086 |
track_format_t track_format;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!cdio_get_track_msf(p_cdio, i, &msf)) {
|
|
Packit |
dd8086 |
err_exit("cdio_track_msf for track %i failed, I give up.\n", i);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
track_format = cdio_get_track_format(p_cdio, i);
|
|
Packit |
dd8086 |
psz_msf = cdio_msf_to_str(&msf;;
|
|
Packit |
dd8086 |
if (i == CDIO_CDROM_LEADOUT_TRACK) {
|
|
Packit |
dd8086 |
if (!opts.no_tracks) {
|
|
Packit |
dd8086 |
lsn_t lsn= cdio_msf_to_lsn(&msf;;
|
|
Packit |
dd8086 |
long unsigned int i_bytes_raw = lsn * CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
long unsigned int i_bytes_formatted = lsn - start_track_lsn;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf( "%3d: %8s %06lu leadout ", (int) i, psz_msf,
|
|
Packit |
dd8086 |
(long unsigned int) lsn );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch (discmode) {
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_ROM:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_RAM:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_R:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_RW:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_PR:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_PRW:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_DVD_OTHER:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DATA:
|
|
Packit |
dd8086 |
i_bytes_formatted *= CDIO_CD_FRAMESIZE;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_DA:
|
|
Packit |
dd8086 |
i_bytes_formatted *= CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_XA:
|
|
Packit |
dd8086 |
case CDIO_DISC_MODE_CD_MIXED:
|
|
Packit |
dd8086 |
i_bytes_formatted *= CDIO_CD_FRAMESIZE_RAW0;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
i_bytes_formatted *= CDIO_CD_FRAMESIZE_RAW;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_bytes_raw < 1024)
|
|
Packit |
dd8086 |
printf( "(%lu bytes", i_bytes_raw );
|
|
Packit |
dd8086 |
if (i_bytes_raw < 1024 * 1024)
|
|
Packit |
dd8086 |
printf( "(%lu KB", i_bytes_raw / 1024 );
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
printf( "(%lu MB", i_bytes_raw / (1024 * 1024) );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf(" raw, ");
|
|
Packit |
dd8086 |
if (i_bytes_formatted < 1024)
|
|
Packit |
dd8086 |
printf( "%lu bytes", i_bytes_formatted );
|
|
Packit |
dd8086 |
if (i_bytes_formatted < 1024 * 1024)
|
|
Packit |
dd8086 |
printf( "%lu KB", i_bytes_formatted / 1024 );
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
printf( "%lu MB", i_bytes_formatted / (1024 * 1024) );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf(" formatted)\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
free(psz_msf);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
} else if (!opts.no_tracks) {
|
|
Packit |
dd8086 |
const char *psz;
|
|
Packit |
dd8086 |
printf( "%3d: %8s %06lu %-6s %-5s ", (int) i, psz_msf,
|
|
Packit |
dd8086 |
(long unsigned int) cdio_msf_to_lsn(&msf),
|
|
Packit |
dd8086 |
track_format2str[track_format],
|
|
Packit |
dd8086 |
cdio_get_track_green(p_cdio, i)? "true " : "false");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch (cdio_get_track_copy_permit(p_cdio, i)) {
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_FALSE:
|
|
Packit |
dd8086 |
psz="no";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_TRUE:
|
|
Packit |
dd8086 |
psz="yes";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_UNKNOWN:
|
|
Packit |
dd8086 |
psz="?";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_ERROR:
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
psz="error";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
printf("%-5s", psz);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (TRACK_FORMAT_AUDIO == track_format) {
|
|
Packit |
dd8086 |
const int i_channels = cdio_get_track_channels(p_cdio, i);
|
|
Packit |
dd8086 |
switch (cdio_get_track_preemphasis(p_cdio, i)) {
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_FALSE:
|
|
Packit |
dd8086 |
psz="no";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_TRUE:
|
|
Packit |
dd8086 |
psz="yes";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_UNKNOWN:
|
|
Packit |
dd8086 |
psz="?";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_TRACK_FLAG_ERROR:
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
psz="error";
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (i_channels == -2)
|
|
Packit |
dd8086 |
printf(" %-8s", "unknown");
|
|
Packit |
dd8086 |
else if (i_channels == -1)
|
|
Packit |
dd8086 |
printf(" %-8s", "error");
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
printf(" %-8d", i_channels);
|
|
Packit |
dd8086 |
printf( " %s", psz);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf( "\n" );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
free(psz_msf);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (TRACK_FORMAT_AUDIO == track_format) {
|
|
Packit |
dd8086 |
num_audio++;
|
|
Packit |
dd8086 |
if (-1 == first_audio) first_audio = i;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
num_data++;
|
|
Packit |
dd8086 |
if (-1 == first_data) first_data = i;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
/* skip to leadout? */
|
|
Packit |
dd8086 |
if (i == i_tracks) i = CDIO_CDROM_LEADOUT_TRACK-1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (cdio_is_discmode_cdrom(discmode)) {
|
|
Packit |
dd8086 |
/* get and print MCN */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
report(stdout, "Media Catalog Number (MCN): "); fflush(stdout);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
media_catalog_number = cdio_get_mcn(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == media_catalog_number) {
|
|
Packit |
dd8086 |
if (i_read_cap & CDIO_DRIVE_CAP_READ_MCN)
|
|
Packit |
dd8086 |
report(stdout, "not available\n");
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
report(stdout, "not supported by drive/driver\n");
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
report(stdout, "%s\n", media_catalog_number);
|
|
Packit |
dd8086 |
cdio_free(media_catalog_number);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* get and print track ISRCs */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i_read_cap & CDIO_DRIVE_CAP_READ_ISRC) {
|
|
Packit |
dd8086 |
for (i = first_audio; i < first_audio + num_audio; i++) {
|
|
Packit |
dd8086 |
isrc = cdio_get_track_isrc(p_cdio, i);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != isrc) {
|
|
Packit |
dd8086 |
report(stdout, "TRACK %2d ISRC: %s\n", i, isrc); fflush(stdout);
|
|
Packit |
dd8086 |
cdio_free(isrc);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* List number of sessions */
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
lsn_t i_last_session;
|
|
Packit |
dd8086 |
report(stdout, "Last CD Session LSN: "); fflush(stdout);
|
|
Packit |
dd8086 |
if (DRIVER_OP_SUCCESS == cdio_get_last_session(p_cdio, &i_last_session))
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
report(stdout, "%d\n", i_last_session);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
if (i_misc_cap & CDIO_DRIVE_CAP_MISC_MULTI_SESSION)
|
|
Packit |
dd8086 |
report(stdout, "failed\n");
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
report(stdout, "not supported by drive/driver\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* get audio status from subchannel */
|
|
Packit |
dd8086 |
if ( CDIO_DISC_MODE_CD_DA == discmode ||
|
|
Packit |
dd8086 |
CDIO_DISC_MODE_CD_MIXED == discmode ) {
|
|
Packit |
dd8086 |
cdio_subchannel_t subchannel;
|
|
Packit |
dd8086 |
driver_return_code_t rc;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset(&subchannel, 0, sizeof(subchannel));
|
|
Packit |
dd8086 |
report( stdout, "audio status: "); fflush(stdout);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
rc = cdio_audio_read_subchannel(p_cdio, &subchannel);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (DRIVER_OP_SUCCESS == rc) {
|
|
Packit |
dd8086 |
bool b_volume = false;
|
|
Packit |
dd8086 |
bool b_position = false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
report ( stdout, "%s\n",
|
|
Packit |
dd8086 |
mmc_audio_state2str(subchannel.audio_status) );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch (subchannel.audio_status) {
|
|
Packit |
dd8086 |
case CDIO_MMC_READ_SUB_ST_PLAY:
|
|
Packit |
dd8086 |
b_playing_audio = true;
|
|
Packit |
dd8086 |
/* Fall through to next case. */
|
|
Packit |
dd8086 |
case CDIO_MMC_READ_SUB_ST_PAUSED:
|
|
Packit |
dd8086 |
b_position = true;
|
|
Packit |
dd8086 |
/* Fall through to next case. */
|
|
Packit |
dd8086 |
case CDIO_MMC_READ_SUB_ST_NO_STATUS:
|
|
Packit |
dd8086 |
b_volume = true;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_position)
|
|
Packit |
dd8086 |
report( stdout, " at: %02d:%02d abs / %02d:%02d track %d\n",
|
|
Packit |
dd8086 |
subchannel.abs_addr.m,
|
|
Packit |
dd8086 |
subchannel.abs_addr.s,
|
|
Packit |
dd8086 |
subchannel.rel_addr.m,
|
|
Packit |
dd8086 |
subchannel.rel_addr.s,
|
|
Packit |
dd8086 |
subchannel.track );
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_volume) {
|
|
Packit |
dd8086 |
cdio_audio_volume_t volume;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (DRIVER_OP_SUCCESS == cdio_audio_get_volume (p_cdio, &volume)) {
|
|
Packit |
dd8086 |
uint8_t j=0;
|
|
Packit |
dd8086 |
for (j=0; j<4; j++) {
|
|
Packit |
dd8086 |
uint8_t i_level = volume.level[j];
|
|
Packit |
dd8086 |
report( stdout,
|
|
Packit |
dd8086 |
"volume level port %d: %3d (0..255) %3d (0..100)\n",
|
|
Packit |
dd8086 |
j, i_level, (i_level*100+128) / 256 );
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else
|
|
Packit |
dd8086 |
report( stdout, " can't get volume levels\n" );
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else if (DRIVER_OP_UNSUPPORTED == rc) {
|
|
Packit |
dd8086 |
report( stdout, "not implemented\n" );
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
report( stdout, "FAILED\n" );
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!opts.no_analysis) {
|
|
Packit |
dd8086 |
if (b_playing_audio) {
|
|
Packit |
dd8086 |
/* Running a CD Analysis would mess up audio playback.*/
|
|
Packit |
dd8086 |
report(stdout,
|
|
Packit |
dd8086 |
"CD Analysis Report omitted because audio is currently "
|
|
Packit |
dd8086 |
"playing.\n");
|
|
Packit |
dd8086 |
myexit(p_cdio, EXIT_SUCCESS);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
report(stdout, STRONG "CD Analysis Report\n" NORMAL);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* try to find out what sort of CD we have */
|
|
Packit |
dd8086 |
if (num_audio > 0) {
|
|
Packit |
dd8086 |
/* may be a "real" audio CD or hidden track CD */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
msf_t msf;
|
|
Packit |
dd8086 |
cdio_get_track_msf(p_cdio, i_first_track, &msf;;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* CD-I/Ready says start_track_lsn <= 30*75 then CDDA */
|
|
Packit |
dd8086 |
if (start_track_lsn > 100 /* 100 is just a guess */) {
|
|
Packit |
dd8086 |
fs = cdio_guess_cd_type(p_cdio, 0, 1, &cdio_iso_analysis);
|
|
Packit |
dd8086 |
if ((CDIO_FSTYPE(fs)) != CDIO_FS_UNKNOWN)
|
|
Packit |
dd8086 |
fs |= CDIO_FS_ANAL_HIDDEN_TRACK;
|
|
Packit |
dd8086 |
else {
|
|
Packit |
dd8086 |
fs &= ~CDIO_FS_MASK; /* del filesystem info */
|
|
Packit |
dd8086 |
report( stdout, "Oops: %lu unused sectors at start, "
|
|
Packit |
dd8086 |
"but hidden track check failed.\n",
|
|
Packit |
dd8086 |
(long unsigned int) start_track_lsn);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
print_analysis(ms_offset, cdio_iso_analysis, fs, first_data, num_audio,
|
|
Packit |
dd8086 |
i_tracks, i_first_track,
|
|
Packit |
dd8086 |
cdio_get_track_format(p_cdio, 1), p_cdio);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (num_data > 0) {
|
|
Packit |
dd8086 |
/* we have data track(s) */
|
|
Packit |
dd8086 |
int j;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (j = 2, i = first_data; i <= i_tracks; i++) {
|
|
Packit |
dd8086 |
msf_t msf;
|
|
Packit |
dd8086 |
track_format_t track_format = cdio_get_track_format(p_cdio, i);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_get_track_msf(p_cdio, i, &msf;;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch ( track_format ) {
|
|
Packit |
dd8086 |
case TRACK_FORMAT_AUDIO:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_ERROR:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case TRACK_FORMAT_CDI:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_XA:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_DATA:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_PSX:
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
start_track_lsn = (i == 1) ? 0 : cdio_msf_to_lsn(&msf;;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* save the start of the data area */
|
|
Packit |
dd8086 |
if (i == first_data)
|
|
Packit |
dd8086 |
data_start = start_track_lsn;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* skip tracks which belong to the current walked session */
|
|
Packit |
dd8086 |
if (start_track_lsn < data_start + cdio_iso_analysis.isofs_size)
|
|
Packit |
dd8086 |
continue;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fs = cdio_guess_cd_type(p_cdio, start_track_lsn, i,
|
|
Packit |
dd8086 |
&cdio_iso_analysis);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i > 1) {
|
|
Packit |
dd8086 |
/* track is beyond last session -> new session found */
|
|
Packit |
dd8086 |
ms_offset = start_track_lsn;
|
|
Packit |
dd8086 |
report( stdout, "session #%d starts at track %2i, LSN: %lu,"
|
|
Packit |
dd8086 |
" ISO 9660 blocks: %6i\n",
|
|
Packit |
dd8086 |
j++, i, (unsigned long int) start_track_lsn,
|
|
Packit |
dd8086 |
cdio_iso_analysis.isofs_size);
|
|
Packit |
dd8086 |
report( stdout, "ISO 9660: %i blocks, label `%.32s'\n",
|
|
Packit |
dd8086 |
cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
|
|
Packit |
dd8086 |
fs |= CDIO_FS_ANAL_MULTISESSION;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
print_analysis(ms_offset, cdio_iso_analysis, fs, first_data,
|
|
Packit |
dd8086 |
num_audio, i_tracks, i_first_track,
|
|
Packit |
dd8086 |
track_format, p_cdio);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( !(CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660 ||
|
|
Packit |
dd8086 |
CDIO_FSTYPE(fs) == CDIO_FS_ISO_HFS ||
|
|
Packit |
dd8086 |
/* CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE)
|
|
Packit |
dd8086 |
&& (fs & XA))) */
|
|
Packit |
dd8086 |
CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE) )
|
|
Packit |
dd8086 |
/* no method for non-ISO9660 multisessions */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
myexit(p_cdio, EXIT_SUCCESS);
|
|
Packit |
dd8086 |
/* Not reached:*/
|
|
Packit |
dd8086 |
return(EXIT_SUCCESS);
|
|
Packit |
dd8086 |
}
|