2003-03-24 19:01:09 +00:00
|
|
|
|
/*
|
2004-08-30 01:14:14 +00:00
|
|
|
|
$Id: cd-info.c,v 1.87 2004/08/30 01:14:14 rocky Exp $
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2004-02-07 02:40:20 +00:00
|
|
|
|
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
|
|
|
|
|
Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org>
|
|
|
|
|
|
and Heiko Ei<EFBFBD>feldt <heiko@hexco.de>
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
|
|
|
|
CD Info - prints various information about a CD, and detects the type of
|
|
|
|
|
|
the CD.
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2003-09-21 04:21:39 +00:00
|
|
|
|
#include "util.h"
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2003-04-14 04:58:49 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
|
|
|
|
|
#include <cddb/cddb.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-04-26 14:24:44 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
2003-08-13 12:18:49 +00:00
|
|
|
|
#include <libvcd/logging.h>
|
2003-04-26 14:24:44 +00:00
|
|
|
|
#include <libvcd/files.h>
|
|
|
|
|
|
#include <libvcd/info.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-04-22 12:09:08 +00:00
|
|
|
|
#include <cdio/util.h>
|
2003-08-16 15:34:58 +00:00
|
|
|
|
#include <cdio/cd_types.h>
|
2004-07-16 21:29:24 +00:00
|
|
|
|
#include <cdio/cdtext.h>
|
2003-08-31 06:59:23 +00:00
|
|
|
|
#include <cdio/iso9660.h>
|
2004-07-31 07:43:26 +00:00
|
|
|
|
#include <cdio/scsi_mmc.h>
|
2003-04-14 04:58:49 +00:00
|
|
|
|
|
2003-08-31 08:32:40 +00:00
|
|
|
|
#include "cdio_assert.h"
|
|
|
|
|
|
#include "bytesex.h"
|
2003-08-31 02:51:41 +00:00
|
|
|
|
#include "ds.h"
|
2003-08-31 04:02:05 +00:00
|
|
|
|
#include "iso9660_private.h"
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
|
# include <linux/version.h>
|
|
|
|
|
|
# include <linux/cdrom.h>
|
|
|
|
|
|
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,50)
|
|
|
|
|
|
# include <linux/ucdrom.h>
|
|
|
|
|
|
# endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
2003-03-24 21:01:40 +00:00
|
|
|
|
#if 0
|
|
|
|
|
|
#define STRONG "\033[1m"
|
|
|
|
|
|
#define NORMAL "\033[0m"
|
|
|
|
|
|
#else
|
|
|
|
|
|
#define STRONG "__________________________________\n"
|
|
|
|
|
|
#define NORMAL ""
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
#if CDIO_IOCTL_FINISHED
|
|
|
|
|
|
struct cdrom_multisession ms;
|
|
|
|
|
|
struct cdrom_subchnl sub;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* Used by `main' to communicate with `parse_opt'. And global options
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct arguments
|
|
|
|
|
|
{
|
2003-06-01 21:05:45 +00:00
|
|
|
|
int no_tracks;
|
|
|
|
|
|
int no_ioctl;
|
|
|
|
|
|
int no_analysis;
|
2003-09-27 23:29:29 +00:00
|
|
|
|
char *access_mode; /* Access method driver should use for control */
|
2004-07-24 14:23:37 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2004-07-25 11:32:33 +00:00
|
|
|
|
int no_cddb; /* If set the below are meaningless. */
|
2003-06-01 21:05:45 +00:00
|
|
|
|
char *cddb_email; /* email to report to CDDB server. */
|
|
|
|
|
|
char *cddb_server; /* CDDB server to contact */
|
|
|
|
|
|
int cddb_port; /* port number to contact CDDB server. */
|
|
|
|
|
|
int cddb_http; /* 1 if use http proxy */
|
|
|
|
|
|
int cddb_timeout;
|
|
|
|
|
|
bool cddb_disable_cache; /* If set the below is meaningless. */
|
|
|
|
|
|
char *cddb_cachedir;
|
2003-04-26 14:24:44 +00:00
|
|
|
|
#endif
|
2003-06-01 21:05:45 +00:00
|
|
|
|
int no_vcd;
|
2004-08-30 00:26:59 +00:00
|
|
|
|
int show_dvd;
|
2004-07-24 14:23:37 +00:00
|
|
|
|
int no_device;
|
|
|
|
|
|
int no_disc_mode;
|
2003-06-01 21:05:45 +00:00
|
|
|
|
uint32_t debug_level;
|
2003-06-07 20:40:47 +00:00
|
|
|
|
int version_only;
|
2003-10-06 04:04:05 +00:00
|
|
|
|
int silent;
|
2003-06-07 20:40:47 +00:00
|
|
|
|
int no_header;
|
2003-08-31 06:59:23 +00:00
|
|
|
|
int print_iso9660;
|
2004-02-21 13:09:12 +00:00
|
|
|
|
int list_drives;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
source_image_t source_image;
|
|
|
|
|
|
} opts;
|
|
|
|
|
|
|
|
|
|
|
|
/* Configuration option codes */
|
|
|
|
|
|
enum {
|
|
|
|
|
|
|
|
|
|
|
|
OP_SOURCE_UNDEF,
|
|
|
|
|
|
OP_SOURCE_AUTO,
|
|
|
|
|
|
OP_SOURCE_BIN,
|
|
|
|
|
|
OP_SOURCE_CUE,
|
2004-05-04 02:06:48 +00:00
|
|
|
|
OP_SOURCE_CDRDAO,
|
2003-03-24 19:01:09 +00:00
|
|
|
|
OP_SOURCE_NRG ,
|
|
|
|
|
|
OP_SOURCE_DEVICE,
|
|
|
|
|
|
|
|
|
|
|
|
/* These are the remaining configuration options */
|
2003-04-14 10:01:03 +00:00
|
|
|
|
OP_VERSION,
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
char *temp_str;
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-09-21 03:35:39 +00:00
|
|
|
|
/* Parse a all options. */
|
2003-03-24 19:01:09 +00:00
|
|
|
|
static bool
|
2003-09-21 03:35:39 +00:00
|
|
|
|
parse_options (int argc, const char *argv[])
|
2003-03-24 19:01:09 +00:00
|
|
|
|
{
|
|
|
|
|
|
int opt;
|
2004-05-31 04:00:54 +00:00
|
|
|
|
char *psz_my_source;
|
|
|
|
|
|
|
2003-09-21 03:35:39 +00:00
|
|
|
|
struct poptOption optionsTable[] = {
|
2003-09-27 23:29:29 +00:00
|
|
|
|
{"access-mode", 'a', POPT_ARG_STRING, &opts.access_mode, 0,
|
|
|
|
|
|
"Set CD access methed"},
|
|
|
|
|
|
|
2003-09-21 03:35:39 +00:00
|
|
|
|
{"debug", 'd', POPT_ARG_INT, &opts.debug_level, 0,
|
|
|
|
|
|
"Set debugging to LEVEL"},
|
|
|
|
|
|
|
|
|
|
|
|
{"no-tracks", 'T', POPT_ARG_NONE, &opts.no_tracks, 0,
|
|
|
|
|
|
"Don't show track information"},
|
|
|
|
|
|
|
|
|
|
|
|
{"no-analyze", 'A', POPT_ARG_NONE, &opts.no_analysis, 0,
|
|
|
|
|
|
"Don't filesystem analysis"},
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CDDB
|
2004-04-21 09:23:38 +00:00
|
|
|
|
{"no-cddb", '\0', POPT_ARG_NONE, &opts.no_cddb, 0,
|
|
|
|
|
|
"Don't look up audio CDDB information or print that"},
|
2003-09-21 03:35:39 +00:00
|
|
|
|
|
2003-10-06 04:04:05 +00:00
|
|
|
|
{"cddb-port", 'P', POPT_ARG_INT, &opts.cddb_port, 8880,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
"CDDB port number to use (default 8880)"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cddb-http", 'H', POPT_ARG_NONE, &opts.cddb_http, 0,
|
|
|
|
|
|
"Lookup CDDB via HTTP proxy (default no proxy)"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cddb-server", '\0', POPT_ARG_STRING, &opts.cddb_server, 0,
|
|
|
|
|
|
"CDDB server to contact for information (default: freedb.freedb.org)"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cddb-cache", '\0', POPT_ARG_STRING, &opts.cddb_cachedir, 0,
|
|
|
|
|
|
"Location of CDDB cache directory (default ~/.cddbclient)"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cddb-email", '\0', POPT_ARG_STRING, &opts.cddb_email, 0,
|
|
|
|
|
|
"Email address to give CDDB server (default me@home"},
|
|
|
|
|
|
|
|
|
|
|
|
{"no-cddb-cache", '\0', POPT_ARG_NONE, &opts.cddb_disable_cache, 0,
|
|
|
|
|
|
"Lookup CDDB via HTTP proxy (default no proxy)"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cddb-timeout", '\0', POPT_ARG_INT, &opts.cddb_timeout, 0,
|
|
|
|
|
|
"CDDB timeout value in seconds (default 10 seconds)"},
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2004-07-24 14:23:37 +00:00
|
|
|
|
{"no-device-info", '\0', POPT_ARG_NONE, &opts.no_device, 0,
|
|
|
|
|
|
"Don't show device info, just CD info"},
|
|
|
|
|
|
|
|
|
|
|
|
{"no-disc-mode", '\0', POPT_ARG_NONE, &opts.no_disc_mode, 0,
|
|
|
|
|
|
"Don't show disc-mode info"},
|
|
|
|
|
|
|
2004-08-30 00:26:59 +00:00
|
|
|
|
{"dvd", '\0', POPT_ARG_NONE, &opts.show_dvd, 0,
|
|
|
|
|
|
"Attempt to give DVD information if a DVD is found."},
|
|
|
|
|
|
|
2003-09-21 03:35:39 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
{"no-vcd", 'v', POPT_ARG_NONE, &opts.no_vcd, 0,
|
|
|
|
|
|
"Don't look up Video CD information"},
|
|
|
|
|
|
#else
|
2003-09-28 14:16:01 +00:00
|
|
|
|
{"no-vcd", 'v', POPT_ARG_NONE, &opts.no_vcd, 1,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
"Don't look up Video CD information - for this build, this is always set"},
|
|
|
|
|
|
#endif
|
|
|
|
|
|
{"no-ioctl", 'I', POPT_ARG_NONE, &opts.no_ioctl, 0,
|
|
|
|
|
|
"Don't show ioctl() information"},
|
|
|
|
|
|
|
2004-05-31 04:00:54 +00:00
|
|
|
|
{"bin-file", 'b', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
OP_SOURCE_BIN, "set \"bin\" CD-ROM disk image file as source", "FILE"},
|
|
|
|
|
|
|
2004-05-31 04:00:54 +00:00
|
|
|
|
{"cue-file", 'c', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
OP_SOURCE_CUE, "set \"cue\" CD-ROM disk image file as source", "FILE"},
|
|
|
|
|
|
|
2004-05-31 04:00:54 +00:00
|
|
|
|
{"input", 'i', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
OP_SOURCE_AUTO,
|
|
|
|
|
|
"set source and determine if \"bin\" image or device", "FILE"},
|
|
|
|
|
|
|
|
|
|
|
|
{"iso9660", '\0', POPT_ARG_NONE, &opts.print_iso9660, 0,
|
|
|
|
|
|
"print directory contents of any ISO-9660 filesystems"},
|
|
|
|
|
|
|
|
|
|
|
|
{"cdrom-device", 'C', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &source_name,
|
|
|
|
|
|
OP_SOURCE_DEVICE,
|
|
|
|
|
|
"set CD-ROM device as source", "DEVICE"},
|
|
|
|
|
|
|
2004-02-21 13:09:12 +00:00
|
|
|
|
{"list-drives", 'l', POPT_ARG_NONE, &opts.list_drives, 0,
|
|
|
|
|
|
"Give a list of CD-drives" },
|
|
|
|
|
|
|
2003-09-21 03:35:39 +00:00
|
|
|
|
{"no-header", '\0', POPT_ARG_NONE, &opts.no_header,
|
|
|
|
|
|
0, "Don't display header and copyright (for regression testing)"},
|
|
|
|
|
|
|
2004-05-31 04:00:54 +00:00
|
|
|
|
{"nrg-file", 'N', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source,
|
2003-09-21 03:35:39 +00:00
|
|
|
|
OP_SOURCE_NRG, "set Nero CD-ROM disk image file as source", "FILE"},
|
|
|
|
|
|
|
2004-05-31 04:00:54 +00:00
|
|
|
|
{"toc-file", 't', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &psz_my_source,
|
2004-05-04 02:06:48 +00:00
|
|
|
|
OP_SOURCE_CDRDAO, "set cdrdao CD-ROM disk image file as source", "FILE"},
|
|
|
|
|
|
|
2003-10-06 04:04:05 +00:00
|
|
|
|
{"quiet", 'q', POPT_ARG_NONE, &opts.silent, 0,
|
|
|
|
|
|
"Don't produce warning output" },
|
2003-09-21 03:35:39 +00:00
|
|
|
|
|
|
|
|
|
|
{"version", 'V', POPT_ARG_NONE, &opts.version_only, 0,
|
|
|
|
|
|
"display version and copyright information and exit"},
|
|
|
|
|
|
POPT_AUTOHELP {NULL, 0, 0, NULL, 0}
|
|
|
|
|
|
};
|
|
|
|
|
|
poptContext optCon = poptGetContext (NULL, argc, argv, optionsTable, 0);
|
|
|
|
|
|
|
2003-09-21 04:36:41 +00:00
|
|
|
|
program_name = strrchr(argv[0],'/');
|
2004-02-07 02:40:20 +00:00
|
|
|
|
program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);
|
2003-09-21 04:36:41 +00:00
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
while ((opt = poptGetNextOpt (optCon)) != -1) {
|
|
|
|
|
|
switch (opt) {
|
|
|
|
|
|
|
|
|
|
|
|
case OP_SOURCE_AUTO:
|
|
|
|
|
|
case OP_SOURCE_BIN:
|
|
|
|
|
|
case OP_SOURCE_CUE:
|
2004-05-04 02:06:48 +00:00
|
|
|
|
case OP_SOURCE_CDRDAO:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
case OP_SOURCE_NRG:
|
|
|
|
|
|
case OP_SOURCE_DEVICE:
|
|
|
|
|
|
if (opts.source_image != IMAGE_UNKNOWN) {
|
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
|
"%s: another source type option given before.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
fprintf(stderr, "%s: give only one source type option.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2004-05-31 04:00:54 +00:00
|
|
|
|
|
|
|
|
|
|
/* For all input sources which are not a DEVICE, we need to make
|
|
|
|
|
|
a copy of the string; for a DEVICE the fill-out routine makes
|
|
|
|
|
|
the copy.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (OP_SOURCE_DEVICE != opt)
|
|
|
|
|
|
source_name = strdup(psz_my_source);
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
switch (opt) {
|
|
|
|
|
|
case OP_SOURCE_BIN:
|
|
|
|
|
|
opts.source_image = IMAGE_BIN;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case OP_SOURCE_CUE:
|
|
|
|
|
|
opts.source_image = IMAGE_CUE;
|
|
|
|
|
|
break;
|
2004-05-04 02:06:48 +00:00
|
|
|
|
case OP_SOURCE_CDRDAO:
|
|
|
|
|
|
opts.source_image = IMAGE_CDRDAO;
|
|
|
|
|
|
break;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
case OP_SOURCE_NRG:
|
|
|
|
|
|
opts.source_image = IMAGE_NRG;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case OP_SOURCE_AUTO:
|
|
|
|
|
|
opts.source_image = IMAGE_AUTO;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case OP_SOURCE_DEVICE:
|
|
|
|
|
|
opts.source_image = IMAGE_DEVICE;
|
|
|
|
|
|
source_name = fillout_device_name(source_name);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
2004-02-07 02:40:20 +00:00
|
|
|
|
poptFreeContext(optCon);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
const char *remaining_arg = poptGetArg(optCon);
|
|
|
|
|
|
if ( remaining_arg != NULL) {
|
|
|
|
|
|
if (opts.source_image != IMAGE_UNKNOWN) {
|
|
|
|
|
|
fprintf (stderr,
|
2004-05-04 02:06:48 +00:00
|
|
|
|
"%s: Source '%s' given as an argument of an option and as "
|
|
|
|
|
|
"unnamed option '%s'\n",
|
2004-05-31 04:00:54 +00:00
|
|
|
|
program_name, psz_my_source, remaining_arg);
|
2004-02-07 02:40:20 +00:00
|
|
|
|
poptFreeContext(optCon);
|
|
|
|
|
|
free(program_name);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
exit (EXIT_FAILURE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-11-09 15:51:43 +00:00
|
|
|
|
if (opts.source_image == IMAGE_DEVICE)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
source_name = fillout_device_name(remaining_arg);
|
2003-11-09 15:51:43 +00:00
|
|
|
|
else
|
|
|
|
|
|
source_name = strdup(remaining_arg);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
if ( (poptGetArgs(optCon)) != NULL) {
|
|
|
|
|
|
fprintf (stderr,
|
|
|
|
|
|
"%s: Source specified in previously %s and %s\n",
|
2004-05-31 04:00:54 +00:00
|
|
|
|
program_name, psz_my_source, remaining_arg);
|
2004-02-07 02:40:20 +00:00
|
|
|
|
poptFreeContext(optCon);
|
|
|
|
|
|
free(program_name);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
exit (EXIT_FAILURE);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2004-02-07 02:40:20 +00:00
|
|
|
|
poptFreeContext(optCon);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2003-06-07 01:20:40 +00:00
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
/* CDDB */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Returns the sum of the decimal digits in a number. Eg. 1955 = 20
|
|
|
|
|
|
*/
|
|
|
|
|
|
static int
|
|
|
|
|
|
cddb_dec_digit_sum(int n)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ret=0;
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
ret += n%10;
|
|
|
|
|
|
n = n/10;
|
|
|
|
|
|
if (!n)
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Return the number of seconds (discarding frame portion) of an MSF */
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
msf_seconds(msf_t *msf)
|
|
|
|
|
|
{
|
|
|
|
|
|
return from_bcd8(msf->m)*60 + from_bcd8(msf->s);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Compute the CDDB disk ID for an Audio disk. This is a funny checksum
|
|
|
|
|
|
consisting of the concatenation of 3 things:
|
|
|
|
|
|
the sum of the decimal digits of sizes of all tracks,
|
|
|
|
|
|
the total length of the disk, and
|
|
|
|
|
|
the number of tracks.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static unsigned long
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cddb_discid(CdIo *p_cdio, int i_tracks)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
{
|
|
|
|
|
|
int i,t,n=0;
|
|
|
|
|
|
msf_t start_msf;
|
|
|
|
|
|
msf_t msf;
|
|
|
|
|
|
|
2004-07-17 02:18:26 +00:00
|
|
|
|
for (i = 1; i <= i_tracks; i++) {
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_msf(p_cdio, i, &msf);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
n += cddb_dec_digit_sum(msf_seconds(&msf));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_msf(p_cdio, 1, &start_msf);
|
|
|
|
|
|
cdio_get_track_msf(p_cdio, CDIO_CDROM_LEADOUT_TRACK, &msf);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
t = msf_seconds(&msf) - msf_seconds(&start_msf);
|
|
|
|
|
|
|
2004-07-17 02:18:26 +00:00
|
|
|
|
return ((n % 0xff) << 24 | t << 8 | i_tracks);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* CDIO logging routines */
|
|
|
|
|
|
|
2003-06-01 21:05:45 +00:00
|
|
|
|
static cdio_log_handler_t gl_default_cdio_log_handler = NULL;
|
2003-06-07 01:20:40 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2003-06-01 21:05:45 +00:00
|
|
|
|
static cddb_log_handler_t gl_default_cddb_log_handler = NULL;
|
2003-06-07 01:20:40 +00:00
|
|
|
|
#endif
|
2003-08-13 12:18:49 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
static vcd_log_handler_t gl_default_vcd_log_handler = NULL;
|
|
|
|
|
|
#endif
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
_log_handler (cdio_log_level_t level, const char message[])
|
|
|
|
|
|
{
|
|
|
|
|
|
if (level == CDIO_LOG_DEBUG && opts.debug_level < 2)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (level == CDIO_LOG_INFO && opts.debug_level < 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (level == CDIO_LOG_WARN && opts.silent)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2003-06-01 21:05:45 +00:00
|
|
|
|
gl_default_cdio_log_handler (level, message);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-16 21:29:24 +00:00
|
|
|
|
static void
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_cdtext_track_info(CdIo *p_cdio, track_t i_track, const char *message) {
|
|
|
|
|
|
const cdtext_t *cdtext = cdio_get_cdtext(p_cdio, 0);
|
2004-07-16 21:29:24 +00:00
|
|
|
|
|
2004-07-17 02:18:26 +00:00
|
|
|
|
if (NULL != cdtext) {
|
|
|
|
|
|
cdtext_field_t i;
|
|
|
|
|
|
|
|
|
|
|
|
printf("%s\n", message);
|
|
|
|
|
|
|
|
|
|
|
|
for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
|
|
|
|
|
|
if (cdtext->field[i]) {
|
|
|
|
|
|
printf("\t%s: %s\n", cdtext_field2str(i), cdtext->field[i]);
|
2004-07-16 21:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2004-07-17 02:18:26 +00:00
|
|
|
|
}
|
2004-07-16 21:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-17 02:18:26 +00:00
|
|
|
|
static void
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_cdtext_info(CdIo *p_cdio, track_t i_tracks, track_t i_first_track) {
|
2004-07-17 02:18:26 +00:00
|
|
|
|
track_t i_last_track = i_first_track+i_tracks;
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_cdtext_track_info(p_cdio, 0, "\nCD-TEXT for Disc:");
|
2004-07-17 02:18:26 +00:00
|
|
|
|
for ( ; i_first_track < i_last_track; i_first_track++ ) {
|
|
|
|
|
|
char msg[50];
|
|
|
|
|
|
sprintf(msg, "CD-TEXT for Track %d:", i_first_track);
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_cdtext_track_info(p_cdio, i_first_track, msg);
|
2004-07-17 02:18:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-04-14 04:26:17 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2003-04-19 00:53:27 +00:00
|
|
|
|
static void
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_cddb_info(CdIo *p_cdio, track_t i_tracks, track_t i_first_track) {
|
2003-04-19 00:53:27 +00:00
|
|
|
|
int i, matches;
|
|
|
|
|
|
|
|
|
|
|
|
cddb_conn_t *conn = cddb_new();
|
2003-04-14 04:26:17 +00:00
|
|
|
|
cddb_disc_t *disc = NULL;
|
|
|
|
|
|
|
2003-04-19 00:53:27 +00:00
|
|
|
|
if (!conn) {
|
2003-04-14 04:26:17 +00:00
|
|
|
|
fprintf(stderr, "%s: unable to initialize libcddb\n", program_name);
|
|
|
|
|
|
goto cddb_destroy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-06-01 21:05:45 +00:00
|
|
|
|
if (NULL == opts.cddb_email)
|
|
|
|
|
|
cddb_set_email_address(conn, "me@home");
|
|
|
|
|
|
else
|
|
|
|
|
|
cddb_set_email_address(conn, opts.cddb_email);
|
|
|
|
|
|
|
|
|
|
|
|
if (NULL == opts.cddb_server)
|
|
|
|
|
|
cddb_set_server_name(conn, "freedb.freedb.org");
|
|
|
|
|
|
else
|
|
|
|
|
|
cddb_set_server_name(conn, opts.cddb_server);
|
|
|
|
|
|
|
|
|
|
|
|
if (opts.cddb_timeout >= 0)
|
|
|
|
|
|
cddb_set_timeout(conn, opts.cddb_timeout);
|
|
|
|
|
|
|
2003-04-20 17:24:48 +00:00
|
|
|
|
cddb_set_server_port(conn, opts.cddb_port);
|
2003-06-01 21:05:45 +00:00
|
|
|
|
|
2003-04-20 17:24:48 +00:00
|
|
|
|
if (opts.cddb_http)
|
|
|
|
|
|
cddb_http_enable(conn);
|
|
|
|
|
|
else
|
|
|
|
|
|
cddb_http_disable(conn);
|
2003-06-01 21:05:45 +00:00
|
|
|
|
|
|
|
|
|
|
if (NULL != opts.cddb_cachedir)
|
|
|
|
|
|
cddb_cache_set_dir(conn, opts.cddb_cachedir);
|
|
|
|
|
|
|
|
|
|
|
|
if (opts.cddb_disable_cache)
|
|
|
|
|
|
cddb_cache_disable(conn);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
|
|
|
|
|
|
disc = cddb_disc_new();
|
|
|
|
|
|
if (!disc) {
|
2003-04-19 08:29:13 +00:00
|
|
|
|
fprintf(stderr, "%s: unable to create CDDB disc structure", program_name);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
goto cddb_destroy;
|
|
|
|
|
|
}
|
2004-07-17 02:18:26 +00:00
|
|
|
|
for(i = 0; i < i_tracks; i++) {
|
2003-04-14 04:26:17 +00:00
|
|
|
|
cddb_track_t *t = cddb_track_new();
|
2004-07-31 07:43:26 +00:00
|
|
|
|
t->frame_offset = cdio_get_track_lba(p_cdio, i+i_first_track);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
cddb_disc_add_track(disc, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
disc->length =
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
|
2003-04-14 04:26:17 +00:00
|
|
|
|
/ CDIO_CD_FRAMES_PER_SEC;
|
|
|
|
|
|
|
|
|
|
|
|
if (!cddb_disc_calc_discid(disc)) {
|
|
|
|
|
|
fprintf(stderr, "%s: libcddb calc discid failed.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
goto cddb_destroy;
|
|
|
|
|
|
}
|
2003-04-19 00:53:27 +00:00
|
|
|
|
|
|
|
|
|
|
matches = cddb_query(conn, disc);
|
|
|
|
|
|
|
2003-04-20 17:24:48 +00:00
|
|
|
|
if (-1 == matches)
|
2004-04-21 09:23:38 +00:00
|
|
|
|
printf("%s: %s\n", program_name, cddb_error_str(cddb_errno(conn)));
|
2003-04-20 17:24:48 +00:00
|
|
|
|
else {
|
|
|
|
|
|
printf("%s: Found %d matches in CDDB\n", program_name, matches);
|
|
|
|
|
|
for (i=1; i<=matches; i++) {
|
|
|
|
|
|
cddb_read(conn, disc);
|
|
|
|
|
|
cddb_disc_print(disc);
|
|
|
|
|
|
cddb_query_next(conn, disc);
|
|
|
|
|
|
}
|
2003-04-19 00:53:27 +00:00
|
|
|
|
}
|
2003-04-20 17:24:48 +00:00
|
|
|
|
|
2003-04-14 04:26:17 +00:00
|
|
|
|
cddb_disc_destroy(disc);
|
|
|
|
|
|
cddb_destroy:
|
2003-04-19 00:53:27 +00:00
|
|
|
|
cddb_destroy(conn);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-04-26 14:24:44 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
static void
|
2004-05-04 02:06:48 +00:00
|
|
|
|
print_vcd_info(driver_id_t driver) {
|
2003-04-26 14:24:44 +00:00
|
|
|
|
vcdinfo_open_return_t open_rc;
|
2003-08-10 02:27:49 +00:00
|
|
|
|
vcdinfo_obj_t *obj;
|
2004-05-04 02:06:48 +00:00
|
|
|
|
open_rc = vcdinfo_open(&obj, &source_name, driver, NULL);
|
2003-04-26 14:24:44 +00:00
|
|
|
|
switch (open_rc) {
|
|
|
|
|
|
case VCDINFO_OPEN_VCD:
|
2003-08-10 02:27:49 +00:00
|
|
|
|
if (vcdinfo_get_format_version (obj) == VCD_TYPE_INVALID) {
|
2003-04-26 14:24:44 +00:00
|
|
|
|
fprintf(stderr, "VCD format detection failed");
|
2003-08-10 02:27:49 +00:00
|
|
|
|
vcdinfo_close(obj);
|
2003-04-26 14:24:44 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2004-06-19 10:38:07 +00:00
|
|
|
|
fprintf (stdout, "Format : %s\n",
|
|
|
|
|
|
vcdinfo_get_format_version_str(obj));
|
|
|
|
|
|
fprintf (stdout, "Album : `%.16s'\n", vcdinfo_get_album_id(obj));
|
|
|
|
|
|
fprintf (stdout, "Volume count: %d\n", vcdinfo_get_volume_count(obj));
|
2003-08-16 15:34:58 +00:00
|
|
|
|
fprintf (stdout, "volume number: %d\n", vcdinfo_get_volume_num(obj));
|
2003-04-26 14:24:44 +00:00
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VCDINFO_OPEN_ERROR:
|
|
|
|
|
|
fprintf (stderr, "Error in Video CD opening of %s\n", source_name);
|
|
|
|
|
|
return;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VCDINFO_OPEN_OTHER:
|
|
|
|
|
|
fprintf (stderr, "Even though we thought this was a Video CD, "
|
|
|
|
|
|
" further inspection says it is not.\n");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2003-08-10 02:27:49 +00:00
|
|
|
|
vcdinfo_close(obj);
|
2003-04-26 14:24:44 +00:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-08-31 02:51:41 +00:00
|
|
|
|
static void
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_iso9660_recurse (const CdIo *p_cdio, const char pathname[],
|
2004-06-19 10:38:07 +00:00
|
|
|
|
cdio_fs_anal_t fs,
|
|
|
|
|
|
bool b_mode2)
|
2003-08-31 02:51:41 +00:00
|
|
|
|
{
|
|
|
|
|
|
CdioList *entlist;
|
|
|
|
|
|
CdioList *dirlist = _cdio_list_new ();
|
|
|
|
|
|
CdioListNode *entnode;
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
entlist = iso9660_fs_readdir (p_cdio, pathname, b_mode2);
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
|
|
|
|
|
printf ("%s:\n", pathname);
|
|
|
|
|
|
|
2003-10-15 01:59:51 +00:00
|
|
|
|
if (NULL == entlist) {
|
|
|
|
|
|
fprintf (stderr, "Error getting above directory information\n");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
2003-09-06 14:50:50 +00:00
|
|
|
|
/* Iterate over files in this directory */
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
|
|
|
|
|
_CDIO_LIST_FOREACH (entnode, entlist)
|
|
|
|
|
|
{
|
2003-11-16 19:30:45 +00:00
|
|
|
|
iso9660_stat_t *statbuf = _cdio_list_node_data (entnode);
|
|
|
|
|
|
char *iso_name = statbuf->filename;
|
2003-08-31 02:51:41 +00:00
|
|
|
|
char _fullname[4096] = { 0, };
|
2003-09-06 14:50:50 +00:00
|
|
|
|
char translated_name[MAX_ISONAME+1];
|
2003-09-07 18:12:30 +00:00
|
|
|
|
#define DATESTR_SIZE 30
|
|
|
|
|
|
char date_str[DATESTR_SIZE];
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
2003-09-06 14:50:50 +00:00
|
|
|
|
iso9660_name_translate(iso_name, translated_name);
|
|
|
|
|
|
|
|
|
|
|
|
snprintf (_fullname, sizeof (_fullname), "%s%s", pathname,
|
|
|
|
|
|
iso_name);
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
|
|
|
|
|
strncat (_fullname, "/", sizeof (_fullname));
|
|
|
|
|
|
|
2003-11-16 19:30:45 +00:00
|
|
|
|
if (statbuf->type == _STAT_DIR
|
2003-09-06 14:50:50 +00:00
|
|
|
|
&& strcmp (iso_name, ".")
|
|
|
|
|
|
&& strcmp (iso_name, ".."))
|
2003-08-31 02:51:41 +00:00
|
|
|
|
_cdio_list_append (dirlist, strdup (_fullname));
|
|
|
|
|
|
|
2003-08-31 06:59:23 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_XA) {
|
2003-09-14 09:34:17 +00:00
|
|
|
|
printf ( " %c %s %d %d [fn %.2d] [LSN %6lu] ",
|
2003-11-16 19:30:45 +00:00
|
|
|
|
(statbuf->type == _STAT_DIR) ? 'd' : '-',
|
|
|
|
|
|
iso9660_get_xa_attr_str (statbuf->xa.attributes),
|
|
|
|
|
|
uint16_from_be (statbuf->xa.user_id),
|
|
|
|
|
|
uint16_from_be (statbuf->xa.group_id),
|
|
|
|
|
|
statbuf->xa.filenum,
|
|
|
|
|
|
(long unsigned int) statbuf->lsn);
|
2003-08-31 06:59:23 +00:00
|
|
|
|
|
2003-11-16 19:30:45 +00:00
|
|
|
|
if (uint16_from_be(statbuf->xa.attributes) & XA_ATTR_MODE2FORM2) {
|
2003-09-14 09:34:17 +00:00
|
|
|
|
printf ("%9u (%9u)",
|
2003-11-16 19:30:45 +00:00
|
|
|
|
(unsigned int) statbuf->secsize * M2F2_SECTOR_SIZE,
|
|
|
|
|
|
(unsigned int) statbuf->size);
|
2003-08-31 06:59:23 +00:00
|
|
|
|
} else {
|
2003-11-16 19:30:45 +00:00
|
|
|
|
printf ("%9u", (unsigned int) statbuf->size);
|
2003-08-31 06:59:23 +00:00
|
|
|
|
}
|
2003-08-31 02:51:41 +00:00
|
|
|
|
}
|
2004-03-24 11:24:44 +00:00
|
|
|
|
strftime(date_str, DATESTR_SIZE, "%b %d %Y %H:%M ", &statbuf->tm);
|
2003-09-07 18:12:30 +00:00
|
|
|
|
printf (" %s %s\n", date_str, translated_name);
|
2003-08-31 02:51:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_cdio_list_free (entlist, true);
|
|
|
|
|
|
|
|
|
|
|
|
printf ("\n");
|
|
|
|
|
|
|
2003-10-15 01:59:51 +00:00
|
|
|
|
/* Now recurse over the directories. */
|
2003-08-31 02:51:41 +00:00
|
|
|
|
|
|
|
|
|
|
_CDIO_LIST_FOREACH (entnode, dirlist)
|
|
|
|
|
|
{
|
|
|
|
|
|
char *_fullname = _cdio_list_node_data (entnode);
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
print_iso9660_recurse (p_cdio, _fullname, fs, b_mode2);
|
2003-08-31 02:51:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_cdio_list_free (dirlist, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2004-06-19 10:38:07 +00:00
|
|
|
|
static bool
|
|
|
|
|
|
read_iso9660_pvd(const CdIo *p_cdio, track_format_t track_format, /*out*/
|
|
|
|
|
|
iso9660_pvd_t *p_pvd) {
|
|
|
|
|
|
|
2003-08-31 14:26:06 +00:00
|
|
|
|
switch (track_format) {
|
|
|
|
|
|
case TRACK_FORMAT_CDI:
|
|
|
|
|
|
case TRACK_FORMAT_XA:
|
2004-06-19 10:38:07 +00:00
|
|
|
|
if (0 != cdio_read_mode2_sector (p_cdio, p_pvd, ISO_PVD_SECTOR, false))
|
|
|
|
|
|
return false;
|
2003-08-31 14:26:06 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case TRACK_FORMAT_DATA:
|
2004-06-19 10:38:07 +00:00
|
|
|
|
if (0 != cdio_read_mode1_sector (p_cdio, p_pvd, ISO_PVD_SECTOR, false))
|
|
|
|
|
|
return false;
|
2003-09-01 02:04:33 +00:00
|
|
|
|
break;
|
2003-08-31 20:56:14 +00:00
|
|
|
|
case TRACK_FORMAT_AUDIO:
|
|
|
|
|
|
case TRACK_FORMAT_PSX:
|
|
|
|
|
|
case TRACK_FORMAT_ERROR:
|
|
|
|
|
|
default:
|
2004-06-19 10:38:07 +00:00
|
|
|
|
return false;
|
2003-08-31 14:26:06 +00:00
|
|
|
|
}
|
2004-06-19 10:38:07 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
print_iso9660_fs (const CdIo *p_cdio, cdio_fs_anal_t fs,
|
|
|
|
|
|
track_format_t track_format)
|
|
|
|
|
|
{
|
|
|
|
|
|
iso9660_pvd_t pvd;
|
|
|
|
|
|
bool b_mode2 = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (fs & CDIO_FS_ANAL_XA) track_format = TRACK_FORMAT_XA;
|
|
|
|
|
|
|
|
|
|
|
|
if ( !read_iso9660_pvd(p_cdio, track_format, &pvd) )
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
b_mode2 = ( TRACK_FORMAT_CDI == track_format
|
|
|
|
|
|
|| TRACK_FORMAT_XA == track_format );
|
2003-08-31 14:26:06 +00:00
|
|
|
|
|
|
|
|
|
|
{
|
2003-08-31 04:02:05 +00:00
|
|
|
|
const lsn_t extent = iso9660_get_root_lsn(&pvd);
|
2003-08-31 14:26:06 +00:00
|
|
|
|
|
2003-08-31 04:02:05 +00:00
|
|
|
|
printf ("ISO9660 filesystem\n");
|
2003-09-14 09:34:17 +00:00
|
|
|
|
printf (" root dir in PVD set to lsn %lu\n\n", (long unsigned) extent);
|
2003-08-31 04:02:05 +00:00
|
|
|
|
|
2004-06-19 10:38:07 +00:00
|
|
|
|
print_iso9660_recurse (p_cdio, "/", fs, b_mode2);
|
2003-08-31 04:02:05 +00:00
|
|
|
|
}
|
2003-08-31 02:51:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
static void
|
2003-11-05 04:12:57 +00:00
|
|
|
|
print_analysis(int ms_offset, cdio_iso_analysis_t cdio_iso_analysis,
|
2003-08-16 17:31:40 +00:00
|
|
|
|
cdio_fs_anal_t fs, int first_data, unsigned int num_audio,
|
2004-07-17 02:18:26 +00:00
|
|
|
|
track_t i_tracks, track_t i_first_track,
|
2004-06-19 10:38:07 +00:00
|
|
|
|
track_format_t track_format, CdIo *p_cdio)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
{
|
|
|
|
|
|
int need_lf;
|
|
|
|
|
|
|
2003-08-16 15:34:58 +00:00
|
|
|
|
switch(CDIO_FSTYPE(fs)) {
|
2003-09-28 17:14:20 +00:00
|
|
|
|
case CDIO_FS_AUDIO:
|
2003-04-14 04:26:17 +00:00
|
|
|
|
if (num_audio > 0) {
|
2003-08-14 13:41:26 +00:00
|
|
|
|
printf("Audio CD, CDDB disc ID is %08lx\n",
|
2004-07-17 02:18:26 +00:00
|
|
|
|
cddb_discid(p_cdio, i_tracks));
|
2003-04-14 04:26:17 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2004-07-17 02:18:26 +00:00
|
|
|
|
if (!opts.no_cddb) print_cddb_info(p_cdio, i_tracks, i_first_track);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
#endif
|
2004-07-17 02:18:26 +00:00
|
|
|
|
print_cdtext_info(p_cdio, i_tracks, i_first_track);
|
2003-04-14 04:26:17 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_ISO_9660:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with ISO 9660 filesystem");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_JOLIET) {
|
2003-11-05 04:12:57 +00:00
|
|
|
|
printf(" and joliet extension level %d", cdio_iso_analysis.joliet_level);
|
2003-04-19 00:53:27 +00:00
|
|
|
|
}
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_ROCKRIDGE)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf(" and rockridge extensions");
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_ISO_9660_INTERACTIVE:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with CD-RTOS and ISO 9660 filesystem\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_HIGH_SIERRA:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with High Sierra filesystem\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_INTERACTIVE:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-Interactive%s\n", num_audio > 0 ? "/Ready" : "");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_HFS:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with Macintosh HFS\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_ISO_HFS:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with both Macintosh HFS and ISO 9660 filesystem\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_UFS:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with Unix UFS\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_EXT2:
|
2004-06-19 19:15:15 +00:00
|
|
|
|
printf("CD-ROM with GNU/Linux EXT2 (native) filesystem\n");
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_3DO:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with Panasonic 3DO filesystem\n");
|
|
|
|
|
|
break;
|
2004-06-23 03:56:25 +00:00
|
|
|
|
case CDIO_FS_UDFX:
|
|
|
|
|
|
printf("CD-ROM with UDFX filesystem\n");
|
|
|
|
|
|
break;
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_UNKNOWN:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("CD-ROM with unknown filesystem\n");
|
|
|
|
|
|
break;
|
2004-06-19 19:15:15 +00:00
|
|
|
|
case CDIO_FS_XISO:
|
|
|
|
|
|
printf("CD-ROM with Microsoft X-BOX XISO filesystem\n");
|
|
|
|
|
|
break;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
2003-08-16 15:34:58 +00:00
|
|
|
|
switch(CDIO_FSTYPE(fs)) {
|
2003-08-16 12:59:03 +00:00
|
|
|
|
case CDIO_FS_ISO_9660:
|
|
|
|
|
|
case CDIO_FS_ISO_9660_INTERACTIVE:
|
|
|
|
|
|
case CDIO_FS_ISO_HFS:
|
2004-06-23 03:56:25 +00:00
|
|
|
|
case CDIO_FS_ISO_UDF:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("ISO 9660: %i blocks, label `%.32s'\n",
|
2003-11-05 04:12:57 +00:00
|
|
|
|
cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
|
2004-06-19 10:38:07 +00:00
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
iso9660_pvd_t pvd;
|
|
|
|
|
|
|
|
|
|
|
|
if ( read_iso9660_pvd(p_cdio, track_format, &pvd) ) {
|
|
|
|
|
|
fprintf(stdout, "Application: %s\n",
|
|
|
|
|
|
iso9660_get_application_id(&pvd));
|
|
|
|
|
|
fprintf(stdout, "Preparer : %s\n", iso9660_get_preparer_id(&pvd));
|
|
|
|
|
|
fprintf(stdout, "Publisher : %s\n", iso9660_get_publisher_id(&pvd));
|
|
|
|
|
|
fprintf(stdout, "System : %s\n", iso9660_get_system_id(&pvd));
|
|
|
|
|
|
fprintf(stdout, "Volume : %s\n", iso9660_get_volume_id(&pvd));
|
|
|
|
|
|
fprintf(stdout, "Volume Set : %s\n", iso9660_get_volumeset_id(&pvd));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-08-31 06:59:23 +00:00
|
|
|
|
if (opts.print_iso9660)
|
2004-06-19 10:38:07 +00:00
|
|
|
|
print_iso9660_fs(p_cdio, fs, track_format);
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2004-06-23 09:28:02 +00:00
|
|
|
|
|
|
|
|
|
|
switch(CDIO_FSTYPE(fs)) {
|
|
|
|
|
|
case CDIO_FS_UDF:
|
|
|
|
|
|
case CDIO_FS_ISO_UDF:
|
|
|
|
|
|
fprintf(stdout, "UDF: version %x.%2.2x\n",
|
|
|
|
|
|
cdio_iso_analysis.UDFVerMajor, cdio_iso_analysis.UDFVerMinor);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default: ;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf = 0;
|
|
|
|
|
|
if (first_data == 1 && num_audio > 0)
|
|
|
|
|
|
need_lf += printf("mixed mode CD ");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_XA)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf += printf("XA sectors ");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_MULTISESSION)
|
2003-08-14 13:41:26 +00:00
|
|
|
|
need_lf += printf("Multisession, offset = %i ", ms_offset);
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_HIDDEN_TRACK)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf += printf("Hidden Track ");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_PHOTO_CD)
|
2003-08-14 13:41:26 +00:00
|
|
|
|
need_lf += printf("%sPhoto CD ",
|
|
|
|
|
|
num_audio > 0 ? " Portfolio " : "");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_CDTV)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf += printf("Commodore CDTV ");
|
|
|
|
|
|
if (first_data > 1)
|
|
|
|
|
|
need_lf += printf("CD-Plus/Extra ");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_BOOTABLE)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf += printf("bootable CD ");
|
2003-09-28 17:14:20 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_VIDEOCD && num_audio == 0) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
need_lf += printf("Video CD ");
|
2003-04-26 14:24:44 +00:00
|
|
|
|
}
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_SVCD)
|
2003-08-13 12:33:59 +00:00
|
|
|
|
need_lf += printf("Super Video CD (SVCD) or Chaoji Video CD (CVD)");
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if (fs & CDIO_FS_ANAL_CVD)
|
2003-08-16 12:59:03 +00:00
|
|
|
|
need_lf += printf("Chaoji Video CD (CVD)");
|
2003-08-13 12:33:59 +00:00
|
|
|
|
if (need_lf) printf("\n");
|
2003-09-28 14:16:01 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
2003-09-28 17:14:20 +00:00
|
|
|
|
if (fs & (CDIO_FS_ANAL_VIDEOCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_SVCD))
|
2003-09-28 14:16:01 +00:00
|
|
|
|
if (!opts.no_vcd) {
|
|
|
|
|
|
printf("\n");
|
2004-06-19 10:38:07 +00:00
|
|
|
|
print_vcd_info(cdio_get_driver_id(p_cdio));
|
2003-09-28 14:16:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2003-09-21 04:36:41 +00:00
|
|
|
|
/* Initialize global variables. */
|
|
|
|
|
|
static void
|
|
|
|
|
|
init(void)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
{
|
2003-06-01 21:05:45 +00:00
|
|
|
|
gl_default_cdio_log_handler = cdio_log_set_handler (_log_handler);
|
2003-06-07 01:20:40 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2003-06-01 21:05:45 +00:00
|
|
|
|
gl_default_cddb_log_handler = cddb_log_set_handler (_log_handler);
|
2003-06-07 01:20:40 +00:00
|
|
|
|
#endif
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2003-08-13 12:18:49 +00:00
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
gl_default_vcd_log_handler = vcd_log_set_handler (_log_handler);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
/* Default option values. */
|
2003-06-01 21:05:45 +00:00
|
|
|
|
opts.silent = false;
|
2004-02-21 13:09:12 +00:00
|
|
|
|
opts.list_drives = false;
|
2003-06-07 20:40:47 +00:00
|
|
|
|
opts.no_header = false;
|
2004-07-24 14:23:37 +00:00
|
|
|
|
opts.no_device = 0;
|
|
|
|
|
|
opts.no_disc_mode = 0;
|
2003-06-01 21:05:45 +00:00
|
|
|
|
opts.debug_level = 0;
|
|
|
|
|
|
opts.no_tracks = 0;
|
2003-08-31 06:59:23 +00:00
|
|
|
|
opts.print_iso9660 = 0;
|
2003-04-14 10:01:03 +00:00
|
|
|
|
#ifdef HAVE_CDDB
|
2003-06-01 21:05:45 +00:00
|
|
|
|
opts.no_cddb = 0;
|
|
|
|
|
|
opts.cddb_port = 8880;
|
|
|
|
|
|
opts.cddb_http = 0;
|
|
|
|
|
|
opts.cddb_cachedir = NULL;
|
|
|
|
|
|
opts.cddb_server = NULL;
|
|
|
|
|
|
opts.cddb_timeout = -1;
|
|
|
|
|
|
opts.cddb_disable_cache = false;
|
2004-07-24 14:23:37 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
opts.no_vcd = 0;
|
|
|
|
|
|
#else
|
|
|
|
|
|
opts.no_vcd = 1;
|
2003-04-14 10:01:03 +00:00
|
|
|
|
#endif
|
2003-06-01 21:05:45 +00:00
|
|
|
|
opts.no_ioctl = 0;
|
|
|
|
|
|
opts.no_analysis = 0;
|
|
|
|
|
|
opts.source_image = IMAGE_UNKNOWN;
|
2004-05-13 01:50:10 +00:00
|
|
|
|
opts.access_mode = NULL;
|
2003-09-21 04:36:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
main(int argc, const char *argv[])
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
CdIo *p_cdio=NULL;
|
2003-11-05 04:12:57 +00:00
|
|
|
|
cdio_fs_anal_t fs=CDIO_FS_AUDIO;
|
2003-09-21 04:36:41 +00:00
|
|
|
|
int i;
|
2003-11-05 04:12:57 +00:00
|
|
|
|
lsn_t start_track_lsn; /* lsn of first track */
|
2004-07-17 02:18:26 +00:00
|
|
|
|
lsn_t data_start = 0; /* start of data area */
|
|
|
|
|
|
int ms_offset = 0;
|
|
|
|
|
|
track_t i_tracks = 0;
|
|
|
|
|
|
track_t i_first_track = 0;
|
|
|
|
|
|
unsigned int num_audio = 0; /* # of audio tracks */
|
|
|
|
|
|
unsigned int num_data = 0; /* # of data tracks */
|
|
|
|
|
|
int first_data = -1; /* # of first data track */
|
|
|
|
|
|
int first_audio = -1; /* # of first audio track */
|
2003-11-05 04:12:57 +00:00
|
|
|
|
cdio_iso_analysis_t cdio_iso_analysis;
|
|
|
|
|
|
char *media_catalog_number;
|
2004-07-25 18:37:09 +00:00
|
|
|
|
discmode_t discmode = CDIO_DISC_MODE_NO_INFO;
|
2003-09-21 04:36:41 +00:00
|
|
|
|
|
2003-11-05 04:12:57 +00:00
|
|
|
|
memset(&cdio_iso_analysis, 0, sizeof(cdio_iso_analysis));
|
2003-09-21 04:36:41 +00:00
|
|
|
|
init();
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
/* Parse our arguments; every option seen by `parse_opt' will
|
|
|
|
|
|
be reflected in `arguments'. */
|
2003-09-21 03:35:39 +00:00
|
|
|
|
parse_options(argc, argv);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2003-09-21 04:21:39 +00:00
|
|
|
|
print_version(program_name, VERSION, opts.no_header, opts.version_only);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2003-11-09 13:57:51 +00:00
|
|
|
|
if (opts.debug_level == 3) {
|
|
|
|
|
|
cdio_loglevel_default = CDIO_LOG_INFO;
|
|
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
vcd_loglevel_default = VCD_LOG_INFO;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
} else if (opts.debug_level >= 4) {
|
|
|
|
|
|
cdio_loglevel_default = CDIO_LOG_DEBUG;
|
|
|
|
|
|
#ifdef HAVE_VCDINFO
|
|
|
|
|
|
vcd_loglevel_default = VCD_LOG_DEBUG;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
switch (opts.source_image) {
|
|
|
|
|
|
case IMAGE_UNKNOWN:
|
|
|
|
|
|
case IMAGE_AUTO:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_am (source_name, DRIVER_UNKNOWN, opts.access_mode);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in automatically selecting driver for input %s.\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in automatically selecting driver.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
2003-06-12 04:46:27 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case IMAGE_DEVICE:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_am (source_name, DRIVER_DEVICE, opts.access_mode);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in automatically selecting CD-image driver for input %s\n",
|
2004-04-25 00:46:34 +00:00
|
|
|
|
program_name, source_name);
|
2004-05-31 12:19:35 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in automatically selecting CD-image driver.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
2003-06-12 04:46:27 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case IMAGE_BIN:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_am (source_name, DRIVER_BINCUE, opts.access_mode);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in opening bin/cue for input %s\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in opening bin/cue for unspecified input.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
2003-06-12 04:46:27 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case IMAGE_CUE:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_cue(source_name);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in opening cue/bin with input %s\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in opening cue/bin for unspeicified input.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
2003-06-12 04:46:27 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case IMAGE_NRG:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_am (source_name, DRIVER_NRG, opts.access_mode);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in opening NRG with input %s\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in opening NRG for unspecified input.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
2003-06-12 04:46:27 +00:00
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
2004-05-04 02:06:48 +00:00
|
|
|
|
|
|
|
|
|
|
case IMAGE_CDRDAO:
|
2004-07-31 07:43:26 +00:00
|
|
|
|
p_cdio = cdio_open_am (source_name, DRIVER_CDRDAO, opts.access_mode);
|
|
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in opening TOC with input %s.\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in opening TOC for unspecified input.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2004-05-04 02:06:48 +00:00
|
|
|
|
break;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
if (p_cdio==NULL) {
|
2004-05-31 12:19:35 +00:00
|
|
|
|
if (source_name) {
|
|
|
|
|
|
err_exit("%s: Error in opening device driver for input %s.\n",
|
|
|
|
|
|
program_name, source_name);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
err_exit("%s: Error in opening device driver for unspecified input.\n",
|
|
|
|
|
|
program_name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-04-14 04:26:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
if (source_name==NULL) {
|
2004-07-31 07:43:26 +00:00
|
|
|
|
source_name=strdup(cdio_get_arg(p_cdio, "source"));
|
2003-06-12 04:46:27 +00:00
|
|
|
|
if (NULL == source_name) {
|
|
|
|
|
|
err_exit("%s: No input device given/found\n", program_name);
|
|
|
|
|
|
}
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-24 14:23:37 +00:00
|
|
|
|
if (0 == opts.silent) {
|
2004-05-13 01:50:10 +00:00
|
|
|
|
printf("CD location : %s\n", source_name);
|
2004-07-31 07:43:26 +00:00
|
|
|
|
printf("CD driver name: %s\n", cdio_get_driver_name(p_cdio));
|
|
|
|
|
|
printf(" access mode: %s\n\n", cdio_get_arg(p_cdio, "access-mode"));
|
2004-05-13 01:50:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-24 14:23:37 +00:00
|
|
|
|
if (0 == opts.no_device) {
|
2004-07-17 22:16:46 +00:00
|
|
|
|
cdio_drive_read_cap_t i_read_cap;
|
|
|
|
|
|
cdio_drive_write_cap_t i_write_cap;
|
|
|
|
|
|
cdio_drive_misc_cap_t i_misc_cap;
|
2004-08-27 02:50:13 +00:00
|
|
|
|
cdio_hwinfo_t hwinfo;
|
|
|
|
|
|
if (cdio_get_hwinfo(p_cdio, &hwinfo)) {
|
2004-07-31 07:43:26 +00:00
|
|
|
|
printf("%-28s: %s\n%-28s: %s\n%-28s: %s\n",
|
2004-08-27 11:53:38 +00:00
|
|
|
|
"Vendor" , hwinfo.psz_vendor,
|
|
|
|
|
|
"Model" , hwinfo.psz_model,
|
|
|
|
|
|
"Revision", hwinfo.psz_revision);
|
2004-07-31 07:43:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
cdio_get_drive_cap(p_cdio, &i_read_cap, &i_write_cap, &i_misc_cap);
|
2004-07-17 22:16:46 +00:00
|
|
|
|
print_drive_capabilities(i_read_cap, i_write_cap, i_misc_cap);
|
2004-04-23 01:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-02-21 13:09:12 +00:00
|
|
|
|
if (opts.list_drives) {
|
2004-08-27 04:17:08 +00:00
|
|
|
|
driver_id_t driver_id = DRIVER_DEVICE;
|
|
|
|
|
|
char ** device_list = cdio_get_devices_ret(&driver_id);
|
2004-02-21 13:09:12 +00:00
|
|
|
|
char ** d = device_list;
|
|
|
|
|
|
|
|
|
|
|
|
printf("list of devices found:\n");
|
|
|
|
|
|
if (NULL != d) {
|
|
|
|
|
|
for ( ; *d != NULL ; d++ ) {
|
2004-08-27 04:17:08 +00:00
|
|
|
|
CdIo *p_cdio = cdio_open(source_name, driver_id);
|
2004-08-27 02:50:13 +00:00
|
|
|
|
cdio_hwinfo_t hwinfo;
|
2004-07-31 07:43:26 +00:00
|
|
|
|
printf("Drive %s\n", *d);
|
2004-08-27 02:50:13 +00:00
|
|
|
|
if (scsi_mmc_get_hwinfo(p_cdio, &hwinfo)) {
|
2004-07-31 07:43:26 +00:00
|
|
|
|
printf("%-8s: %s\n%-8s: %s\n%-8s: %s\n",
|
2004-08-27 11:53:38 +00:00
|
|
|
|
"Vendor" , hwinfo.psz_vendor,
|
|
|
|
|
|
"Model" , hwinfo.psz_model,
|
|
|
|
|
|
"Revision", hwinfo.psz_revision);
|
2004-07-31 07:43:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
if (p_cdio) cdio_destroy(p_cdio);
|
2004-02-21 13:09:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
cdio_free_device_list(device_list);
|
2004-05-24 23:28:05 +00:00
|
|
|
|
if (device_list) free(device_list);
|
2004-02-21 13:09:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-24 14:23:37 +00:00
|
|
|
|
printf(STRONG "\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
2004-08-06 00:53:58 +00:00
|
|
|
|
discmode = cdio_get_discmode(p_cdio);
|
2004-07-24 14:23:37 +00:00
|
|
|
|
if ( 0 == opts.no_disc_mode ) {
|
2004-07-28 22:03:35 +00:00
|
|
|
|
printf("Disc mode is listed as: %s\n",
|
2004-08-06 00:53:58 +00:00
|
|
|
|
discmode2str[discmode]);
|
2004-07-24 14:23:37 +00:00
|
|
|
|
}
|
2004-08-30 00:26:59 +00:00
|
|
|
|
|
2004-08-30 01:01:14 +00:00
|
|
|
|
if (discmode_is_dvd(discmode) && !opts.show_dvd) {
|
2004-08-30 00:26:59 +00:00
|
|
|
|
printf("No further information currently given for DVDs.\n");
|
|
|
|
|
|
printf("Use --dvd to override.\n");
|
|
|
|
|
|
myexit(p_cdio, EXIT_SUCCESS);
|
|
|
|
|
|
}
|
2004-07-24 14:23:37 +00:00
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
i_first_track = cdio_get_first_track_num(p_cdio);
|
2004-08-30 01:14:14 +00:00
|
|
|
|
|
|
|
|
|
|
if (CDIO_INVALID_TRACK == i_first_track) {
|
|
|
|
|
|
err_exit("Can't number of tracks, I give up.\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
i_tracks = cdio_get_num_tracks(p_cdio);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
if (!opts.no_tracks) {
|
2004-07-24 14:23:37 +00:00
|
|
|
|
printf("CD-ROM Track List (%i - %i)\n" NORMAL,
|
2004-07-17 02:18:26 +00:00
|
|
|
|
i_first_track, i_tracks);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2004-06-12 17:30:03 +00:00
|
|
|
|
printf(" #: MSF LSN Type Green?\n");
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
2004-07-24 14:23:37 +00:00
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
/* Read and possibly print track information. */
|
2004-07-17 02:18:26 +00:00
|
|
|
|
for (i = i_first_track; i <= CDIO_CDROM_LEADOUT_TRACK; i++) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
msf_t msf;
|
2004-05-09 17:05:34 +00:00
|
|
|
|
char *psz_msf;
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
if (!cdio_get_track_msf(p_cdio, i, &msf)) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
err_exit("cdio_track_msf for track %i failed, I give up.\n", i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2004-05-09 17:05:34 +00:00
|
|
|
|
psz_msf = cdio_msf_to_str(&msf);
|
2003-04-06 17:57:20 +00:00
|
|
|
|
if (i == CDIO_CDROM_LEADOUT_TRACK) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
if (!opts.no_tracks)
|
2004-06-12 17:30:03 +00:00
|
|
|
|
printf("%3d: %8s %06lu leadout\n", (int) i, psz_msf,
|
2003-09-14 09:34:17 +00:00
|
|
|
|
(long unsigned int) cdio_msf_to_lsn(&msf));
|
2003-03-24 19:01:09 +00:00
|
|
|
|
break;
|
|
|
|
|
|
} else if (!opts.no_tracks) {
|
2004-06-12 17:30:03 +00:00
|
|
|
|
printf("%3d: %8s %06lu %-5s %s\n", (int) i, psz_msf,
|
2003-09-14 09:34:17 +00:00
|
|
|
|
(long unsigned int) cdio_msf_to_lsn(&msf),
|
2004-07-31 07:43:26 +00:00
|
|
|
|
track_format2str[cdio_get_track_format(p_cdio, i)],
|
|
|
|
|
|
cdio_get_track_green(p_cdio, i)? "true" : "false");
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
if (TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i)) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
num_audio++;
|
2003-08-16 17:31:40 +00:00
|
|
|
|
if (-1 == first_audio) first_audio = i;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
num_data++;
|
2003-08-16 17:31:40 +00:00
|
|
|
|
if (-1 == first_data) first_data = i;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
/* skip to leadout? */
|
2004-07-17 02:18:26 +00:00
|
|
|
|
if (i == i_tracks) i = CDIO_CDROM_LEADOUT_TRACK-1;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-25 18:37:09 +00:00
|
|
|
|
if (cdio_is_discmode_cdrom(discmode)) {
|
|
|
|
|
|
/* get and print MCN */
|
2004-07-31 07:43:26 +00:00
|
|
|
|
media_catalog_number = cdio_get_mcn(p_cdio);
|
2004-07-25 18:37:09 +00:00
|
|
|
|
|
|
|
|
|
|
printf("Media Catalog Number (MCN): "); fflush(stdout);
|
|
|
|
|
|
if (NULL == media_catalog_number)
|
|
|
|
|
|
printf("not available\n");
|
|
|
|
|
|
else {
|
2003-09-25 09:38:15 +00:00
|
|
|
|
printf("%s\n", media_catalog_number);
|
|
|
|
|
|
free(media_catalog_number);
|
2004-07-25 18:37:09 +00:00
|
|
|
|
}
|
2003-09-25 09:38:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2004-07-25 18:37:09 +00:00
|
|
|
|
|
2003-09-25 09:38:15 +00:00
|
|
|
|
|
2003-03-24 19:01:09 +00:00
|
|
|
|
#if CDIO_IOCTL_FINISHED
|
|
|
|
|
|
if (!opts.no_ioctl) {
|
|
|
|
|
|
printf(STRONG "What ioctl's report...\n" NORMAL);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CDROMMULTISESSION
|
|
|
|
|
|
/* get multisession */
|
|
|
|
|
|
printf("multisession: "); fflush(stdout);
|
|
|
|
|
|
ms.addr_format = CDROM_LBA;
|
|
|
|
|
|
if (ioctl(filehandle,CDROMMULTISESSION,&ms))
|
|
|
|
|
|
printf("FAILED\n");
|
|
|
|
|
|
else
|
|
|
|
|
|
printf("%d%s\n",ms.addr.lba,ms.xa_flag?" XA":"");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CDROMSUBCHNL
|
|
|
|
|
|
/* get audio status from subchnl */
|
|
|
|
|
|
printf("audio status: "); fflush(stdout);
|
|
|
|
|
|
sub.cdsc_format = CDROM_MSF;
|
|
|
|
|
|
if (ioctl(filehandle,CDROMSUBCHNL,&sub))
|
|
|
|
|
|
printf("FAILED\n");
|
|
|
|
|
|
else {
|
|
|
|
|
|
switch (sub.cdsc_audiostatus) {
|
|
|
|
|
|
case CDROM_AUDIO_INVALID: printf("invalid\n"); break;
|
|
|
|
|
|
case CDROM_AUDIO_PLAY: printf("playing"); break;
|
|
|
|
|
|
case CDROM_AUDIO_PAUSED: printf("paused"); break;
|
|
|
|
|
|
case CDROM_AUDIO_COMPLETED: printf("completed\n"); break;
|
|
|
|
|
|
case CDROM_AUDIO_ERROR: printf("error\n"); break;
|
|
|
|
|
|
case CDROM_AUDIO_NO_STATUS: printf("no status\n"); break;
|
|
|
|
|
|
default: printf("Oops: unknown\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (sub.cdsc_audiostatus == CDROM_AUDIO_PLAY ||
|
|
|
|
|
|
sub.cdsc_audiostatus == CDROM_AUDIO_PAUSED) {
|
|
|
|
|
|
printf(" at: %02d:%02d abs / %02d:%02d track %d\n",
|
|
|
|
|
|
sub.cdsc_absaddr.msf.minute,
|
|
|
|
|
|
sub.cdsc_absaddr.msf.second,
|
|
|
|
|
|
sub.cdsc_reladdr.msf.minute,
|
|
|
|
|
|
sub.cdsc_reladdr.msf.second,
|
|
|
|
|
|
sub.cdsc_trk);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif /* CDROMSUBCHNL */
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif /*CDIO_IOCTL_FINISHED*/
|
|
|
|
|
|
|
|
|
|
|
|
if (!opts.no_analysis) {
|
2003-04-26 14:24:44 +00:00
|
|
|
|
printf(STRONG "CD Analysis Report\n" NORMAL);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
/* try to find out what sort of CD we have */
|
|
|
|
|
|
if (0 == num_data) {
|
|
|
|
|
|
/* no data track, may be a "real" audio CD or hidden track CD */
|
|
|
|
|
|
|
|
|
|
|
|
msf_t msf;
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_msf(p_cdio, 1, &msf);
|
2003-09-14 09:34:17 +00:00
|
|
|
|
start_track_lsn = cdio_msf_to_lsn(&msf);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2003-09-14 09:34:17 +00:00
|
|
|
|
/* CD-I/Ready says start_track_lsn <= 30*75 then CDDA */
|
|
|
|
|
|
if (start_track_lsn > 100 /* 100 is just a guess */) {
|
2004-07-31 07:43:26 +00:00
|
|
|
|
fs = cdio_guess_cd_type(p_cdio, 0, 1, &cdio_iso_analysis);
|
2003-08-16 15:34:58 +00:00
|
|
|
|
if ((CDIO_FSTYPE(fs)) != CDIO_FS_UNKNOWN)
|
|
|
|
|
|
fs |= CDIO_FS_ANAL_HIDDEN_TRACK;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
else {
|
2003-08-16 12:59:03 +00:00
|
|
|
|
fs &= ~CDIO_FS_MASK; /* del filesystem info */
|
2003-09-14 09:34:17 +00:00
|
|
|
|
printf("Oops: %lu unused sectors at start, "
|
2003-03-29 17:32:00 +00:00
|
|
|
|
"but hidden track check failed.\n",
|
2003-09-14 09:34:17 +00:00
|
|
|
|
(long unsigned int) start_track_lsn);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2003-11-05 04:12:57 +00:00
|
|
|
|
print_analysis(ms_offset, cdio_iso_analysis, fs, first_data, num_audio,
|
2004-07-17 02:18:26 +00:00
|
|
|
|
i_tracks, i_first_track,
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_format(p_cdio, 1), p_cdio);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
/* we have data track(s) */
|
2003-08-14 13:41:26 +00:00
|
|
|
|
int j;
|
2003-08-16 17:31:40 +00:00
|
|
|
|
|
2004-07-17 02:18:26 +00:00
|
|
|
|
for (j = 2, i = first_data; i <= i_tracks; i++) {
|
2003-03-24 19:01:09 +00:00
|
|
|
|
msf_t msf;
|
2004-07-31 07:43:26 +00:00
|
|
|
|
track_format_t track_format = cdio_get_track_format(p_cdio, i);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
cdio_get_track_msf(p_cdio, i, &msf);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
switch ( track_format ) {
|
|
|
|
|
|
case TRACK_FORMAT_AUDIO:
|
|
|
|
|
|
case TRACK_FORMAT_ERROR:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case TRACK_FORMAT_CDI:
|
|
|
|
|
|
case TRACK_FORMAT_XA:
|
|
|
|
|
|
case TRACK_FORMAT_DATA:
|
2003-04-06 06:46:06 +00:00
|
|
|
|
case TRACK_FORMAT_PSX:
|
2003-03-24 19:01:09 +00:00
|
|
|
|
;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2003-09-14 09:34:17 +00:00
|
|
|
|
start_track_lsn = (i == 1) ? 0 : cdio_msf_to_lsn(&msf);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
/* save the start of the data area */
|
|
|
|
|
|
if (i == first_data)
|
2003-09-14 09:34:17 +00:00
|
|
|
|
data_start = start_track_lsn;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
/* skip tracks which belong to the current walked session */
|
2003-11-05 04:12:57 +00:00
|
|
|
|
if (start_track_lsn < data_start + cdio_iso_analysis.isofs_size)
|
2003-03-24 19:01:09 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
fs = cdio_guess_cd_type(p_cdio, start_track_lsn, i,
|
|
|
|
|
|
&cdio_iso_analysis);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
|
|
|
|
|
|
if (i > 1) {
|
|
|
|
|
|
/* track is beyond last session -> new session found */
|
2003-09-14 09:34:17 +00:00
|
|
|
|
ms_offset = start_track_lsn;
|
|
|
|
|
|
printf("session #%d starts at track %2i, LSN: %lu,"
|
2003-03-24 19:01:09 +00:00
|
|
|
|
" ISO 9660 blocks: %6i\n",
|
2003-09-14 09:34:17 +00:00
|
|
|
|
j++, i, (unsigned long int) start_track_lsn,
|
2003-11-05 04:12:57 +00:00
|
|
|
|
cdio_iso_analysis.isofs_size);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
printf("ISO 9660: %i blocks, label `%.32s'\n",
|
2003-11-05 04:12:57 +00:00
|
|
|
|
cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
|
2003-08-16 15:34:58 +00:00
|
|
|
|
fs |= CDIO_FS_ANAL_MULTISESSION;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
} else {
|
2003-11-05 04:12:57 +00:00
|
|
|
|
print_analysis(ms_offset, cdio_iso_analysis, fs, first_data,
|
2004-07-17 02:18:26 +00:00
|
|
|
|
num_audio, i_tracks, i_first_track,
|
2004-07-31 07:43:26 +00:00
|
|
|
|
track_format, p_cdio);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
2003-08-16 15:34:58 +00:00
|
|
|
|
|
|
|
|
|
|
if ( !(CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660 ||
|
|
|
|
|
|
CDIO_FSTYPE(fs) == CDIO_FS_ISO_HFS ||
|
|
|
|
|
|
/* CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE)
|
2003-08-16 12:59:03 +00:00
|
|
|
|
&& (fs & XA))) */
|
2003-08-16 15:34:58 +00:00
|
|
|
|
CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE) )
|
|
|
|
|
|
/* no method for non-ISO9660 multisessions */
|
|
|
|
|
|
break;
|
2003-03-24 19:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2003-08-14 13:41:26 +00:00
|
|
|
|
|
2004-07-31 07:43:26 +00:00
|
|
|
|
myexit(p_cdio, EXIT_SUCCESS);
|
2003-03-24 19:01:09 +00:00
|
|
|
|
/* Not reached:*/
|
|
|
|
|
|
return(EXIT_SUCCESS);
|
|
|
|
|
|
}
|