|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
Copyright (C) 2004-2006, 2008, 2012-2014, 2017 Rocky Bernstein
|
|
Packit |
dd8086 |
<rocky@gnu.org>
|
|
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 |
ISO Info - prints various information about a ISO 9660 image.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
#include "getopt.h"
|
|
Packit |
dd8086 |
#include "util.h"
|
|
Packit |
dd8086 |
#undef err_exit
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define err_exit(fmt, args...) \
|
|
Packit |
dd8086 |
report (stderr, "%s: "fmt, program_name, ##args); \
|
|
Packit |
dd8086 |
iso9660_close(p_iso); \
|
|
Packit |
dd8086 |
if (NULL != program_name) free(program_name); \
|
|
Packit |
dd8086 |
if (NULL != source_name) free(source_name); \
|
|
Packit |
dd8086 |
return(EXIT_FAILURE);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_SYS_TYPES_H
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#include <cdio/types.h>
|
|
Packit |
dd8086 |
#include <cdio/bytesex.h>
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/ds.h>
|
|
Packit |
dd8086 |
#include <cdio/iso9660.h>
|
|
Packit |
dd8086 |
#include <cdio/udf.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STDIO_H
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_ERRNO_H
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STRING_H
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
dd8086 |
#include <unistd.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_ALLOCA_H
|
|
Packit |
dd8086 |
#include <alloca.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#if 0
|
|
Packit |
dd8086 |
#define STRONG "\033[1m"
|
|
Packit |
dd8086 |
#define NORMAL "\033[0m"
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
#define STRONG "__________________________________\n"
|
|
Packit |
dd8086 |
#define NORMAL ""
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* TODO: Find a better place from where cd-info can read it too. */
|
|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
ECMA-119 allows only a depth of 8 directories. Nobody obeys.
|
|
Packit |
dd8086 |
Rock Ridge allows path length 1023. This would be max depth 512.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
#define CDIO_MAX_DIR_RECURSION 512
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Used by `main' to communicate with `parse_opt'. And global options
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static struct arguments
|
|
Packit |
dd8086 |
{
|
|
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 print_udf;
|
|
Packit |
dd8086 |
int print_iso9660_short;
|
|
Packit |
dd8086 |
int64_t show_rock_ridge;
|
|
Packit |
dd8086 |
} opts;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Configuration option codes */
|
|
Packit |
dd8086 |
enum {
|
|
Packit |
dd8086 |
OP_HANDLED = 0,
|
|
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 a all options. */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
parse_options (int argc, char *argv[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int opt;
|
|
Packit |
dd8086 |
int rc = EXIT_FAILURE;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const char helpText[] =
|
|
Packit |
dd8086 |
"Usage: %s [OPTION...]\n"
|
|
Packit |
dd8086 |
" -d, --debug=UINT Set debugging to LEVEL\n"
|
|
Packit |
dd8086 |
" -i, --input[=FILE] Filename to read ISO-9960 image from\n"
|
|
Packit |
dd8086 |
" -f Generate output similar to 'find . -print'\n"
|
|
Packit |
dd8086 |
" -l, --iso9660 output similar to 'ls -lR' for an ISO 9660 fs\n"
|
|
Packit |
dd8086 |
" -U, --udf output similar to 'ls -lR' for a UDF fs\n"
|
|
Packit |
dd8086 |
" --no-header Don't display header and copyright (for regression\n"
|
|
Packit |
dd8086 |
#ifdef HAVE_JOLIET
|
|
Packit |
dd8086 |
" --no-joliet Don't use Joliet-extension information\n"
|
|
Packit |
dd8086 |
#endif /*HAVE_JOLIET*/
|
|
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 |
" -r --show-rock-ridge UINT Show if image uses Rock-Ridge extensions\n"
|
|
Packit |
dd8086 |
" A maximum of UINT files will be considered.\n"
|
|
Packit |
dd8086 |
" Use 0 for all files.\n"
|
|
Packit |
dd8086 |
" -q, --quiet Don't produce warning output\n"
|
|
Packit |
dd8086 |
" -V, --version display version and copyright information 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 [-i|--input FILE] [-f] [-l|--iso9660] [-U|--udf]\n"
|
|
Packit |
dd8086 |
" [--no-header] [--no-joliet] [--no-rock-ridge] [--show-rock-ridge] [--no-xa] [-q|--quiet]\n"
|
|
Packit |
dd8086 |
" [-d|--debug INT] [-V|--version] [-?|--help] [--usage]\n";
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const char optionsString[] = "d:i::flUqV?";
|
|
Packit |
dd8086 |
static const struct option optionsTable[] = {
|
|
Packit |
dd8086 |
{"debug", required_argument, NULL, 'd'},
|
|
Packit |
dd8086 |
{"input", optional_argument, NULL, 'i'},
|
|
Packit |
dd8086 |
{"iso9660", no_argument, NULL, 'l'},
|
|
Packit |
dd8086 |
{"udf", no_argument, NULL, 'U'},
|
|
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 |
{"show-rock-ridge", required_argument, NULL, 'r' },
|
|
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 |
{
|
|
Packit |
dd8086 |
case 'd': opts.debug_level = atoi(optarg); break;
|
|
Packit |
dd8086 |
case 'i': if (optarg != NULL) {
|
|
Packit |
dd8086 |
if (NULL != source_name) free(source_name);
|
|
Packit |
dd8086 |
source_name = strdup(optarg);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
case 'f': opts.print_iso9660_short = 1; break;
|
|
Packit |
dd8086 |
case 'l': opts.print_iso9660 = 1; break;
|
|
Packit |
dd8086 |
case 'U': opts.print_udf = 1; break;
|
|
Packit |
dd8086 |
case 'q': opts.silent = 1; break;
|
|
Packit |
dd8086 |
case 'r': opts.show_rock_ridge = atoll(optarg); 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 |
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 |
goto error_exit;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (NULL != source_name) free(source_name);
|
|
Packit |
dd8086 |
source_name = strdup(remaining_arg);
|
|
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 |
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 |
if (level == CDIO_LOG_ERROR) {
|
|
Packit |
dd8086 |
// print an error like default, but *don't* exit.
|
|
Packit |
dd8086 |
fprintf (stderr, "**ERROR: %s\n", message);
|
|
Packit |
dd8086 |
fflush (stderr);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
gl_default_cdio_log_handler (level, message);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_iso9660_recurse (iso9660_t *p_iso, const char psz_path[],
|
|
Packit |
dd8086 |
unsigned int rec_counter)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
CdioISO9660FileList_t *entlist;
|
|
Packit |
dd8086 |
CdioISO9660DirList_t *p_dirlist = iso9660_dirlist_new();
|
|
Packit |
dd8086 |
CdioListNode_t *entnode;
|
|
Packit |
dd8086 |
uint8_t i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
|
|
Packit |
dd8086 |
char *translated_name = (char *) alloca(4096);
|
|
Packit |
dd8086 |
size_t translated_name_size = 4096;
|
|
Packit |
dd8086 |
entlist = iso9660_ifs_readdir (p_iso, psz_path);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.print_iso9660) {
|
|
Packit |
dd8086 |
printf ("%s:\n", psz_path);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == entlist) {
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
report( stderr, "Error getting above directory information\n" );
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
rec_counter++;
|
|
Packit |
dd8086 |
if (rec_counter > CDIO_MAX_DIR_RECURSION) {
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
iso9660_filelist_free(entlist);
|
|
Packit |
dd8086 |
report( stderr,
|
|
Packit |
dd8086 |
"Directory recursion too deep. ISO most probably damaged.\n" );
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Iterate over files in this directory */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
_CDIO_LIST_FOREACH (entnode, 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 |
}
|
|
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 |
snprintf (_fullname, sizeof (_fullname), "%s%s", psz_path,
|
|
Packit |
dd8086 |
translated_name);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
snprintf (_fullname, sizeof (_fullname), "%s%s", psz_path,
|
|
Packit |
dd8086 |
psz_iso_name);
|
|
Packit |
dd8086 |
}
|
|
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 |
if (opts.print_iso9660) {
|
|
Packit |
dd8086 |
print_fs_attrs(p_statbuf,
|
|
Packit |
dd8086 |
0 == opts.no_rock_ridge,
|
|
Packit |
dd8086 |
iso9660_ifs_is_xa(p_iso) && 0 == opts.no_xa,
|
|
Packit |
dd8086 |
psz_iso_name, translated_name);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
if ( strcmp (psz_iso_name, ".") && strcmp (psz_iso_name, ".."))
|
|
Packit |
dd8086 |
printf("%9u %s%s\n", (unsigned int) p_statbuf->size, psz_path,
|
|
Packit |
dd8086 |
yep == p_statbuf->rr.b3_rock
|
|
Packit |
dd8086 |
? psz_iso_name : translated_name);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_filelist_free(entlist);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.print_iso9660) {
|
|
Packit |
dd8086 |
printf ("\n");
|
|
Packit |
dd8086 |
}
|
|
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_iso, _fullname, rec_counter);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_dirlist_free(p_dirlist);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_iso9660_fs (iso9660_t *iso)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
print_iso9660_recurse (iso, "/", 0);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_udf_file_info(const udf_dirent_t *p_udf_dirent,
|
|
Packit |
dd8086 |
const char* psz_dirname,
|
|
Packit |
dd8086 |
const char *psz_filename)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
time_t mod_time = udf_get_modification_time(p_udf_dirent);
|
|
Packit |
dd8086 |
char date_str[30];
|
|
Packit |
dd8086 |
char psz_mode[11]="invalid";
|
|
Packit |
dd8086 |
const char *psz_fname= psz_filename
|
|
Packit |
dd8086 |
? psz_filename : udf_get_filename(p_udf_dirent);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!opts.print_iso9660) {
|
|
Packit |
dd8086 |
if (strcmp(psz_dirname, ".") != 0) {
|
|
Packit |
dd8086 |
printf("%9lu ", (long unsigned int) udf_get_file_length(p_udf_dirent));
|
|
Packit |
dd8086 |
printf("/%s", psz_dirname);
|
|
Packit |
dd8086 |
printf("%s\n", *psz_fname ? psz_fname : "/");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
/* Print directory attributes*/
|
|
Packit |
dd8086 |
printf("%s ", udf_mode_string(udf_get_posix_filemode(p_udf_dirent),
|
|
Packit |
dd8086 |
psz_mode));
|
|
Packit |
dd8086 |
/* fake uid/gid */
|
|
Packit |
dd8086 |
printf("0 0 ");
|
|
Packit |
dd8086 |
printf("%3d ", udf_get_link_count(p_udf_dirent));
|
|
Packit |
dd8086 |
printf("%9lu ", (long unsigned int) udf_get_file_length(p_udf_dirent));
|
|
Packit |
dd8086 |
strftime(date_str, sizeof(date_str), "%b %d %Y %H:%M:%S ", localtime(&mod_time));
|
|
Packit |
dd8086 |
printf("%s %s", date_str, *psz_fname ? psz_fname : "/");
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
list_udf_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (!p_udf_dirent) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.print_iso9660) {
|
|
Packit |
dd8086 |
printf ("\n/%s:\n", psz_path);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
print_udf_file_info(p_udf_dirent, psz_path, ".");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
while (udf_readdir(p_udf_dirent)) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (udf_is_dir(p_udf_dirent)) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
udf_dirent_t *p_udf_dirent2 = udf_opendir(p_udf_dirent);
|
|
Packit |
dd8086 |
if (p_udf_dirent2) {
|
|
Packit |
dd8086 |
const char *psz_dirname = udf_get_filename(p_udf_dirent);
|
|
Packit |
dd8086 |
const unsigned int i_newlen=2 + strlen(psz_path) + strlen(psz_dirname);
|
|
Packit |
dd8086 |
char *psz_newpath = calloc(1, sizeof(char)*i_newlen);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
snprintf(psz_newpath, i_newlen, "%s%s/", psz_path, psz_dirname);
|
|
Packit |
dd8086 |
list_udf_files(p_udf, p_udf_dirent2, psz_newpath);
|
|
Packit |
dd8086 |
free(psz_newpath);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
print_udf_file_info(p_udf_dirent, psz_path, NULL);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static int
|
|
Packit |
dd8086 |
print_udf_fs (void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
udf_t *p_udf;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_udf = udf_open (source_name);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_udf) {
|
|
Packit |
dd8086 |
fprintf(stderr, "Sorry, couldn't open %s as something using UDF\n",
|
|
Packit |
dd8086 |
source_name);
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
udf_dirent_t *p_udf_root = udf_get_root(p_udf, true, 0);
|
|
Packit |
dd8086 |
if (NULL == p_udf_root) {
|
|
Packit |
dd8086 |
fprintf(stderr, "Sorry, couldn't find / in %s\n",
|
|
Packit |
dd8086 |
source_name);
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
list_udf_files(p_udf, p_udf_root, "");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
udf_close(p_udf);
|
|
Packit |
dd8086 |
return 0;
|
|
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 |
|
|
Packit |
dd8086 |
/* Default option values. */
|
|
Packit |
dd8086 |
opts.silent = 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.debug_level = 0;
|
|
Packit |
dd8086 |
opts.print_iso9660 = 0;
|
|
Packit |
dd8086 |
opts.print_iso9660_short = 0;
|
|
Packit |
dd8086 |
opts.show_rock_ridge = -1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define print_vd_info(title, fn) \
|
|
Packit |
dd8086 |
if (fn(p_iso, &psz_str)) { \
|
|
Packit |
dd8086 |
printf(title ": %s\n", psz_str); \
|
|
Packit |
dd8086 |
} \
|
|
Packit |
dd8086 |
free(psz_str); \
|
|
Packit |
dd8086 |
psz_str = NULL;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, char *argv[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_t *p_iso=NULL;
|
|
Packit |
dd8086 |
iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;
|
|
Packit |
dd8086 |
|
|
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 |
} else if (opts.debug_level >= 4) {
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_DEBUG;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (source_name==NULL) {
|
|
Packit |
dd8086 |
err_exit("No input device given/found%s\n", "");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.no_joliet) {
|
|
Packit |
dd8086 |
iso_extension_mask &= ~ISO_EXTENSION_JOLIET;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_iso = iso9660_open_ext (source_name, iso_extension_mask);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_iso==NULL) {
|
|
Packit |
dd8086 |
err_exit("Error in opening ISO-9660 image%s\n", "");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.silent == 0) {
|
|
Packit |
dd8086 |
char *psz_str = NULL;
|
|
Packit |
dd8086 |
uint8_t u_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf(STRONG "ISO 9660 image: %s\n", source_name);
|
|
Packit |
dd8086 |
print_vd_info("Application ", iso9660_ifs_get_application_id);
|
|
Packit |
dd8086 |
print_vd_info("Preparer ", iso9660_ifs_get_preparer_id);
|
|
Packit |
dd8086 |
print_vd_info("Publisher ", iso9660_ifs_get_publisher_id);
|
|
Packit |
dd8086 |
print_vd_info("System ", iso9660_ifs_get_system_id);
|
|
Packit |
dd8086 |
print_vd_info("Volume ", iso9660_ifs_get_volume_id);
|
|
Packit |
dd8086 |
print_vd_info("Volume Set ", iso9660_ifs_get_volumeset_id);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.show_rock_ridge >= 0) {
|
|
Packit |
dd8086 |
switch (iso9660_have_rr(p_iso, (uint64_t) opts.show_rock_ridge)) {
|
|
Packit |
dd8086 |
case yep:
|
|
Packit |
dd8086 |
printf("Rock Ridge : yes\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case nope:
|
|
Packit |
dd8086 |
printf("Rock Ridge : no\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case dunno:
|
|
Packit |
dd8086 |
printf("Rock Ridge : possibly not\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (u_joliet_level == 0) {
|
|
Packit |
dd8086 |
printf("No Joliet extensions\n");
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
printf("Joliet Level: %u\n", u_joliet_level);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (opts.print_iso9660 || opts.print_iso9660_short) {
|
|
Packit |
dd8086 |
printf(STRONG "ISO-9660 Information\n" NORMAL);
|
|
Packit |
dd8086 |
if (opts.print_iso9660 && opts.print_iso9660_short) {
|
|
Packit |
dd8086 |
printf("Note: both -f and -l options given -- "
|
|
Packit |
dd8086 |
"-l (long listing) takes precidence\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
print_iso9660_fs(p_iso);
|
|
Packit |
dd8086 |
} else if (opts.print_udf) {
|
|
Packit |
dd8086 |
print_udf_fs();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
free(source_name);
|
|
Packit |
dd8086 |
iso9660_close(p_iso);
|
|
Packit |
dd8086 |
/* Not reached:*/
|
|
Packit |
dd8086 |
free(program_name);
|
|
Packit |
dd8086 |
return(EXIT_SUCCESS);
|
|
Packit |
dd8086 |
}
|