2 * isosize.c - Andries Brouwer, 000608
4 * use header info to find size of iso9660 file system
5 * output a number - useful in scripts
8 * isosize [-x] [-d <num>] <filename>
9 * where "-x" gives length in sectors and sector size while
10 * without this argument the size is given in bytes
11 * without "-x" gives length in bytes unless "-d <num>" is
12 * given. In the latter case the length in bytes divided
15 * Version 2.03 2000/12/21
16 * - add "-d <num>" option and use long long to fix things > 2 GB
17 * Version 2.02 2000/10/11
18 * - error messages on IO failures [D. Gilbert]
31 #include "closestream.h"
34 #define ISOSIZE_EXIT_ALLFAILED 32
35 #define ISOSIZE_EXIT_SOMEOK 64
37 static int is_iso(int fd
)
41 if (pread(fd
, &label
, 8, 0x8000) == -1)
43 return memcmp(&label
, &"\1CD001\1", 8);
46 static int isosize(int argc
, char *filenamep
, int xflag
, long divisor
)
48 int fd
, nsecs
, ssize
, rc
= -1;
49 unsigned char volume_space_size
[8];
50 unsigned char logical_block_size
[4];
52 if ((fd
= open(filenamep
, O_RDONLY
)) < 0) {
53 warn(_("cannot open %s"), filenamep
);
57 warnx(_("%s: might not be an ISO filesystem"), filenamep
);
59 if (pread(fd
, volume_space_size
, sizeof(volume_space_size
), 0x8050) != sizeof(volume_space_size
) ||
60 pread(fd
, logical_block_size
, sizeof(logical_block_size
), 0x8080) != sizeof(logical_block_size
)) {
62 warn(_("read error on %s"), filenamep
);
64 warnx(_("read error on %s"), filenamep
);
68 nsecs
= isonum_733(volume_space_size
, xflag
);
69 /* isonum_723 returns nowadays always 2048 */
70 ssize
= isonum_723(logical_block_size
, xflag
);
73 printf("%s: ", filenamep
);
75 printf(_("sector count: %d, sector size: %d\n"), nsecs
, ssize
);
77 long long product
= nsecs
;
80 printf("%lld\n", product
* ssize
);
81 else if (divisor
== ssize
)
82 printf("%d\n", nsecs
);
84 printf("%lld\n", (product
* ssize
) / divisor
);
94 static void __attribute__((__noreturn__
)) usage(void)
97 fputs(USAGE_HEADER
, stdout
);
99 _(" %s [options] <iso9660_image_file> ...\n"),
100 program_invocation_short_name
);
102 fputs(USAGE_SEPARATOR
, stdout
);
103 fputs(_("Show the length of an ISO-9660 filesystem.\n"), stdout
);
105 fputs(USAGE_OPTIONS
, stdout
);
106 fputs(_(" -d, --divisor=<number> divide the amount of bytes by <number>\n"), stdout
);
107 fputs(_(" -x, --sectors show sector count and size\n"), stdout
);
109 printf(USAGE_HELP_OPTIONS(25));
110 printf(USAGE_MAN_TAIL("isosize(8)"));
115 int main(int argc
, char **argv
)
117 int j
, ct_err
= 0, ct
, opt
, xflag
= 0;
120 static const struct option longopts
[] = {
121 {"divisor", required_argument
, NULL
, 'd'},
122 {"sectors", no_argument
, NULL
, 'x'},
123 {"version", no_argument
, NULL
, 'V'},
124 {"help", no_argument
, NULL
, 'h'},
128 setlocale(LC_ALL
, "");
129 bindtextdomain(PACKAGE
, LOCALEDIR
);
131 close_stdout_atexit();
133 while ((opt
= getopt_long(argc
, argv
, "d:xVh", longopts
, NULL
)) != -1) {
137 strtol_or_err(optarg
,
138 _("invalid divisor argument"));
144 print_version(EXIT_SUCCESS
);
148 errtryhelp(EXIT_FAILURE
);
155 warnx(_("no device specified"));
156 errtryhelp(EXIT_FAILURE
);
159 for (j
= optind
; j
< argc
; j
++) {
160 if (isosize(ct
, argv
[j
], xflag
, divisor
) != 0)
164 return ct
== ct_err
? ISOSIZE_EXIT_ALLFAILED
: /* all failed */
165 ct_err
? ISOSIZE_EXIT_SOMEOK
: /* some ok */
166 EXIT_SUCCESS
; /* all success */