2006-12-06 17:25:44 -06:00
|
|
|
/*
|
|
|
|
* isosize.c - Andries Brouwer, 000608
|
|
|
|
*
|
|
|
|
* use header info to find size of iso9660 file system
|
|
|
|
* output a number - useful in scripts
|
|
|
|
*
|
|
|
|
* Synopsis:
|
|
|
|
* isosize [-x] [-d <num>] <filename>
|
|
|
|
* where "-x" gives length in sectors and sector size while
|
|
|
|
* without this argument the size is given in bytes
|
|
|
|
* without "-x" gives length in bytes unless "-d <num>" is
|
|
|
|
* given. In the latter case the length in bytes divided
|
|
|
|
* by <num> is given
|
|
|
|
*
|
|
|
|
* Version 2.03 2000/12/21
|
|
|
|
* - add "-d <num>" option and use long long to fix things > 2 GB
|
|
|
|
* Version 2.02 2000/10/11
|
|
|
|
* - error messages on IO failures [D. Gilbert]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2011-04-08 08:51:49 -05:00
|
|
|
#include <errno.h>
|
2006-12-06 17:25:44 -06:00
|
|
|
|
|
|
|
#include "nls.h"
|
2011-04-08 08:51:48 -05:00
|
|
|
#include "c.h"
|
2011-06-30 14:27:42 -05:00
|
|
|
#include "strutils.h"
|
2012-04-04 13:04:39 -05:00
|
|
|
#include "closestream.h"
|
2006-12-06 17:25:44 -06:00
|
|
|
|
|
|
|
#define ISODCL(from, to) (to - from + 1)
|
|
|
|
|
2012-12-16 04:43:54 -06:00
|
|
|
static int is_iso(int fd)
|
|
|
|
{
|
|
|
|
char label[8];
|
|
|
|
if (pread(fd, &label, 8, 0x8000) == -1)
|
|
|
|
return 1;
|
|
|
|
return memcmp(&label, &"\1CD001\1", 8);
|
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_721(unsigned char *p)
|
|
|
|
{
|
|
|
|
return ((p[0] & 0xff)
|
|
|
|
| ((p[1] & 0xff) << 8));
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_722(unsigned char *p)
|
|
|
|
{
|
|
|
|
return ((p[1] & 0xff)
|
|
|
|
| ((p[0] & 0xff) << 8));
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_723(unsigned char *p, int xflag)
|
|
|
|
{
|
|
|
|
int le = isonum_721(p);
|
|
|
|
int be = isonum_722(p + 2);
|
|
|
|
if (xflag && le != be)
|
2006-12-06 17:25:44 -06:00
|
|
|
/* translation is useless */
|
2011-06-30 14:49:36 -05:00
|
|
|
warnx("723error: le=%d be=%d", le, be);
|
|
|
|
return (le);
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_731(unsigned char *p)
|
|
|
|
{
|
|
|
|
return ((p[0] & 0xff)
|
|
|
|
| ((p[1] & 0xff) << 8)
|
|
|
|
| ((p[2] & 0xff) << 16)
|
|
|
|
| ((p[3] & 0xff) << 24));
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_732(unsigned char *p)
|
|
|
|
{
|
|
|
|
return ((p[3] & 0xff)
|
|
|
|
| ((p[2] & 0xff) << 8)
|
|
|
|
| ((p[1] & 0xff) << 16)
|
|
|
|
| ((p[0] & 0xff) << 24));
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
static int isonum_733(unsigned char *p, int xflag)
|
|
|
|
{
|
|
|
|
int le = isonum_731(p);
|
|
|
|
int be = isonum_732(p + 4);
|
|
|
|
if (xflag && le != be)
|
|
|
|
/* translation is useless */
|
|
|
|
warn("733error: le=%d be=%d", le, be);
|
|
|
|
return (le);
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
struct iso_primary_descriptor
|
|
|
|
{
|
|
|
|
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
|
|
|
|
unsigned char id [ISODCL ( 2, 6)];
|
|
|
|
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
|
|
|
|
unsigned char unused1 [ISODCL ( 8, 8)];
|
|
|
|
unsigned char system_id [ISODCL ( 9, 40)]; /* auchars */
|
|
|
|
unsigned char volume_id [ISODCL ( 41, 72)]; /* duchars */
|
|
|
|
unsigned char unused2 [ISODCL ( 73, 80)];
|
|
|
|
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
|
|
|
unsigned char unused3 [ISODCL ( 89, 120)];
|
|
|
|
unsigned char volume_set_size [ISODCL ( 121, 124)]; /* 723 */
|
|
|
|
unsigned char volume_sequence_number [ISODCL ( 125, 128)]; /* 723 */
|
|
|
|
unsigned char logical_block_size [ISODCL ( 129, 132)]; /* 723 */
|
|
|
|
unsigned char path_table_size [ISODCL ( 133, 140)]; /* 733 */
|
|
|
|
unsigned char type_l_path_table [ISODCL ( 141, 144)]; /* 731 */
|
|
|
|
unsigned char opt_type_l_path_table [ISODCL ( 145, 148)]; /* 731 */
|
|
|
|
unsigned char type_m_path_table [ISODCL ( 149, 152)]; /* 732 */
|
|
|
|
unsigned char opt_type_m_path_table [ISODCL ( 153, 156)]; /* 732 */
|
|
|
|
unsigned char root_directory_record [ISODCL ( 157, 190)]; /* 9.1 */
|
|
|
|
unsigned char volume_set_id [ISODCL ( 191, 318)]; /* duchars */
|
|
|
|
unsigned char publisher_id [ISODCL ( 319, 446)]; /* achars */
|
|
|
|
unsigned char preparer_id [ISODCL ( 447, 574)]; /* achars */
|
|
|
|
unsigned char application_id [ISODCL ( 575, 702)]; /* achars */
|
|
|
|
unsigned char copyright_file_id [ISODCL ( 703, 739)]; /* 7.5 dchars */
|
|
|
|
unsigned char abstract_file_id [ISODCL ( 740, 776)]; /* 7.5 dchars */
|
|
|
|
unsigned char bibliographic_file_id [ISODCL ( 777, 813)]; /* 7.5 dchars */
|
|
|
|
unsigned char creation_date [ISODCL ( 814, 830)]; /* 8.4.26.1 */
|
|
|
|
unsigned char modification_date [ISODCL ( 831, 847)]; /* 8.4.26.1 */
|
|
|
|
unsigned char expiration_date [ISODCL ( 848, 864)]; /* 8.4.26.1 */
|
|
|
|
unsigned char effective_date [ISODCL ( 865, 881)]; /* 8.4.26.1 */
|
|
|
|
unsigned char file_structure_version [ISODCL ( 882, 882)]; /* 711 */
|
|
|
|
unsigned char unused4 [ISODCL ( 883, 883)];
|
|
|
|
unsigned char application_data [ISODCL ( 884, 1395)];
|
|
|
|
unsigned char unused5 [ISODCL (1396, 2048)];
|
2006-12-06 17:25:44 -06:00
|
|
|
};
|
|
|
|
|
2014-02-16 17:54:20 -06:00
|
|
|
static void isosize(int argc, char *filenamep, int xflag, long divisor)
|
2011-06-30 14:49:36 -05:00
|
|
|
{
|
2006-12-06 17:25:44 -06:00
|
|
|
int fd, nsecs, ssize;
|
|
|
|
struct iso_primary_descriptor ipd;
|
|
|
|
|
2011-04-08 08:51:48 -05:00
|
|
|
if ((fd = open(filenamep, O_RDONLY)) < 0)
|
2012-07-15 03:39:57 -05:00
|
|
|
err(EXIT_FAILURE, _("cannot open %s"), filenamep);
|
2012-12-16 04:43:54 -06:00
|
|
|
if (is_iso(fd))
|
2013-01-26 16:21:07 -06:00
|
|
|
warnx(_("%s: might not be an ISO filesystem"), filenamep);
|
2011-04-08 08:51:48 -05:00
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
if (lseek(fd, 16 << 11, 0) == (off_t) - 1)
|
2011-04-08 08:51:48 -05:00
|
|
|
err(EXIT_FAILURE, _("seek error on %s"), filenamep);
|
|
|
|
|
|
|
|
if (read(fd, &ipd, sizeof(ipd)) < 0)
|
|
|
|
err(EXIT_FAILURE, _("read error on %s"), filenamep);
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2011-06-30 13:30:24 -05:00
|
|
|
nsecs = isonum_733(ipd.volume_space_size, xflag);
|
2011-06-30 14:49:36 -05:00
|
|
|
/* isonum_723 returns nowadays always 2048 */
|
|
|
|
ssize = isonum_723(ipd.logical_block_size, xflag);
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2014-02-16 17:54:20 -06:00
|
|
|
if (1 < argc)
|
|
|
|
printf("%s: ", filenamep);
|
2006-12-06 17:25:44 -06:00
|
|
|
if (xflag) {
|
2011-06-30 14:49:36 -05:00
|
|
|
printf(_("sector count: %d, sector size: %d\n"), nsecs, ssize);
|
2006-12-06 17:25:44 -06:00
|
|
|
} else {
|
|
|
|
long long product = nsecs;
|
|
|
|
|
|
|
|
if (divisor == 0)
|
2011-06-30 14:49:36 -05:00
|
|
|
printf("%lld\n", product * ssize);
|
2006-12-06 17:25:44 -06:00
|
|
|
else if (divisor == ssize)
|
2011-06-30 14:49:36 -05:00
|
|
|
printf("%d\n", nsecs);
|
2006-12-06 17:25:44 -06:00
|
|
|
else
|
2011-06-30 14:49:36 -05:00
|
|
|
printf("%lld\n", (product * ssize) / divisor);
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
2007-10-21 22:26:27 -05:00
|
|
|
|
|
|
|
close(fd);
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
2011-04-08 08:51:50 -05:00
|
|
|
static void __attribute__((__noreturn__)) usage(FILE *out)
|
|
|
|
{
|
2012-12-16 04:43:53 -06:00
|
|
|
fputs(USAGE_HEADER, out);
|
|
|
|
fprintf(out,
|
2013-01-26 16:21:07 -06:00
|
|
|
_(" %s [options] <iso9660_image_file>\n"),
|
2011-04-08 08:51:50 -05:00
|
|
|
program_invocation_short_name);
|
2014-12-22 15:57:17 -06:00
|
|
|
|
|
|
|
fputs(USAGE_SEPARATOR, out);
|
|
|
|
fputs(_("Show the length of an ISO-9660 filesystem.\n"), out);
|
|
|
|
|
2012-12-16 04:43:53 -06:00
|
|
|
fputs(USAGE_OPTIONS, out);
|
2013-01-26 16:21:07 -06:00
|
|
|
fputs(_(" -d, --divisor=<number> divide the amount of bytes by <number>\n"), out);
|
|
|
|
fputs(_(" -x, --sectors show sector count and size\n"), out);
|
2012-12-16 04:43:53 -06:00
|
|
|
fputs(USAGE_SEPARATOR, out);
|
|
|
|
fputs(USAGE_HELP, out);
|
|
|
|
fputs(USAGE_VERSION, out);
|
|
|
|
fprintf(out, USAGE_MAN_TAIL("isosize(8)"));
|
2011-06-30 13:54:55 -05:00
|
|
|
|
2011-04-08 08:51:50 -05:00
|
|
|
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2011-06-30 13:54:55 -05:00
|
|
|
int j, ct, opt, xflag = 0;
|
2011-06-30 14:27:42 -05:00
|
|
|
long divisor = 0;
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2011-06-30 13:54:55 -05:00
|
|
|
static const struct option longopts[] = {
|
2014-02-16 17:54:22 -06:00
|
|
|
{"divisor", required_argument, 0, 'd'},
|
2011-06-30 13:54:55 -05:00
|
|
|
{"sectors", no_argument, 0, 'x'},
|
|
|
|
{"version", no_argument, 0, 'V'},
|
|
|
|
{"help", no_argument, 0, 'h'},
|
|
|
|
{NULL, 0, 0, 0}
|
|
|
|
};
|
|
|
|
|
2006-12-06 17:25:44 -06:00
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
|
|
textdomain(PACKAGE);
|
2012-04-04 13:04:39 -05:00
|
|
|
atexit(close_stdout);
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2011-06-30 13:54:55 -05:00
|
|
|
while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1)
|
2006-12-06 17:25:44 -06:00
|
|
|
switch (opt) {
|
|
|
|
case 'd':
|
2011-06-30 14:27:42 -05:00
|
|
|
divisor =
|
|
|
|
strtol_or_err(optarg,
|
|
|
|
_("invalid divisor argument"));
|
2006-12-06 17:25:44 -06:00
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
xflag = 1;
|
|
|
|
break;
|
2011-06-30 13:54:55 -05:00
|
|
|
case 'V':
|
2012-12-16 04:43:53 -06:00
|
|
|
printf(UTIL_LINUX_VERSION);
|
2011-06-30 13:54:55 -05:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
case 'h':
|
|
|
|
usage(stdout);
|
2006-12-06 17:25:44 -06:00
|
|
|
default:
|
2011-04-08 08:51:50 -05:00
|
|
|
usage(stderr);
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ct = argc - optind;
|
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
if (ct <= 0)
|
2011-04-08 08:51:50 -05:00
|
|
|
usage(stderr);
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2014-02-16 17:54:20 -06:00
|
|
|
for (j = optind; j < argc; j++)
|
|
|
|
isosize(ct, argv[j], xflag, divisor);
|
2006-12-06 17:25:44 -06:00
|
|
|
|
2011-06-30 14:49:36 -05:00
|
|
|
return EXIT_SUCCESS;
|
2006-12-06 17:25:44 -06:00
|
|
|
}
|