23
23
#include <getopt.h>
25
25
#include <unistd.h>
30
32
#define ISODCL(from, to) (to - from + 1)
35
isonum_721 (unsigned char * p) {
37
| ((p[1] & 0xff) << 8));
41
isonum_722 (unsigned char * p) {
43
| ((p[0] & 0xff) << 8));
47
isonum_723 (unsigned char * p) {
48
int le = isonum_721 (p);
49
int be = isonum_722 (p+2);
50
if (xflag && le != be)
51
/* translation is useless */
52
fprintf(stderr, "723error: le=%d be=%d\n", le, be);
57
isonum_731 (unsigned char * p) {
59
| ((p[1] & 0xff) << 8)
60
| ((p[2] & 0xff) << 16)
61
| ((p[3] & 0xff) << 24));
65
isonum_732 (unsigned char * p) {
67
| ((p[2] & 0xff) << 8)
68
| ((p[1] & 0xff) << 16)
69
| ((p[0] & 0xff) << 24));
74
isonum_733 (unsigned char * p) {
75
int le = isonum_731 (p);
76
int be = isonum_732 (p+4);
77
if (xflag && le != be)
78
/* translation is useless */
79
fprintf(stderr, "733error: le=%d be=%d\n", le, be);
83
struct iso_primary_descriptor {
84
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
85
unsigned char id [ISODCL ( 2, 6)];
86
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
87
unsigned char unused1 [ISODCL ( 8, 8)];
88
unsigned char system_id [ISODCL ( 9, 40)]; /* auchars */
89
unsigned char volume_id [ISODCL ( 41, 72)]; /* duchars */
90
unsigned char unused2 [ISODCL ( 73, 80)];
91
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
92
unsigned char unused3 [ISODCL ( 89, 120)];
93
unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
94
unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
95
unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
96
unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
97
unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
98
unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
99
unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
100
unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
101
unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
102
unsigned char volume_set_id [ISODCL (191, 318)]; /* duchars */
103
unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
104
unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
105
unsigned char application_id [ISODCL (575, 702)]; /* achars */
106
unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
107
unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
108
unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
109
unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
110
unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
111
unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
112
unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
113
unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
114
unsigned char unused4 [ISODCL (883, 883)];
115
unsigned char application_data [ISODCL (884, 1395)];
116
unsigned char unused5 [ISODCL (1396, 2048)];
34
static int isonum_721(unsigned char *p)
37
| ((p[1] & 0xff) << 8));
40
static int isonum_722(unsigned char *p)
43
| ((p[0] & 0xff) << 8));
46
static int isonum_723(unsigned char *p, int xflag)
48
int le = isonum_721(p);
49
int be = isonum_722(p + 2);
50
if (xflag && le != be)
51
/* translation is useless */
52
warnx("723error: le=%d be=%d", le, be);
56
static int isonum_731(unsigned char *p)
59
| ((p[1] & 0xff) << 8)
60
| ((p[2] & 0xff) << 16)
61
| ((p[3] & 0xff) << 24));
64
static int isonum_732(unsigned char *p)
67
| ((p[2] & 0xff) << 8)
68
| ((p[1] & 0xff) << 16)
69
| ((p[0] & 0xff) << 24));
72
static int isonum_733(unsigned char *p, int xflag)
74
int le = isonum_731(p);
75
int be = isonum_732(p + 4);
76
if (xflag && le != be)
77
/* translation is useless */
78
warn("733error: le=%d be=%d", le, be);
82
struct iso_primary_descriptor
84
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
85
unsigned char id [ISODCL ( 2, 6)];
86
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
87
unsigned char unused1 [ISODCL ( 8, 8)];
88
unsigned char system_id [ISODCL ( 9, 40)]; /* auchars */
89
unsigned char volume_id [ISODCL ( 41, 72)]; /* duchars */
90
unsigned char unused2 [ISODCL ( 73, 80)];
91
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
92
unsigned char unused3 [ISODCL ( 89, 120)];
93
unsigned char volume_set_size [ISODCL ( 121, 124)]; /* 723 */
94
unsigned char volume_sequence_number [ISODCL ( 125, 128)]; /* 723 */
95
unsigned char logical_block_size [ISODCL ( 129, 132)]; /* 723 */
96
unsigned char path_table_size [ISODCL ( 133, 140)]; /* 733 */
97
unsigned char type_l_path_table [ISODCL ( 141, 144)]; /* 731 */
98
unsigned char opt_type_l_path_table [ISODCL ( 145, 148)]; /* 731 */
99
unsigned char type_m_path_table [ISODCL ( 149, 152)]; /* 732 */
100
unsigned char opt_type_m_path_table [ISODCL ( 153, 156)]; /* 732 */
101
unsigned char root_directory_record [ISODCL ( 157, 190)]; /* 9.1 */
102
unsigned char volume_set_id [ISODCL ( 191, 318)]; /* duchars */
103
unsigned char publisher_id [ISODCL ( 319, 446)]; /* achars */
104
unsigned char preparer_id [ISODCL ( 447, 574)]; /* achars */
105
unsigned char application_id [ISODCL ( 575, 702)]; /* achars */
106
unsigned char copyright_file_id [ISODCL ( 703, 739)]; /* 7.5 dchars */
107
unsigned char abstract_file_id [ISODCL ( 740, 776)]; /* 7.5 dchars */
108
unsigned char bibliographic_file_id [ISODCL ( 777, 813)]; /* 7.5 dchars */
109
unsigned char creation_date [ISODCL ( 814, 830)]; /* 8.4.26.1 */
110
unsigned char modification_date [ISODCL ( 831, 847)]; /* 8.4.26.1 */
111
unsigned char expiration_date [ISODCL ( 848, 864)]; /* 8.4.26.1 */
112
unsigned char effective_date [ISODCL ( 865, 881)]; /* 8.4.26.1 */
113
unsigned char file_structure_version [ISODCL ( 882, 882)]; /* 711 */
114
unsigned char unused4 [ISODCL ( 883, 883)];
115
unsigned char application_data [ISODCL ( 884, 1395)];
116
unsigned char unused5 [ISODCL (1396, 2048)];
119
const char *progname;
123
isosize(char *filenamep) {
119
static void isosize(char *filenamep, int xflag, long divisor)
124
121
int fd, nsecs, ssize;
125
122
struct iso_primary_descriptor ipd;
127
if ((fd = open(filenamep, O_RDONLY)) < 0) {
129
fprintf(stderr, _("%s: failed to open: %s\n"),
130
progname, filenamep);
133
if (lseek(fd, 16 << 11, 0) == (off_t)-1) {
135
fprintf(stderr, _("%s: seek error on %s\n"),
136
progname, filenamep);
139
if (read(fd, &ipd, sizeof(ipd)) < 0) {
141
fprintf(stderr, _("%s: read error on %s\n"),
142
progname, filenamep);
146
nsecs = isonum_733(ipd.volume_space_size);
147
ssize = isonum_723(ipd.logical_block_size); /* nowadays always 2048 */
124
if ((fd = open(filenamep, O_RDONLY)) < 0)
125
err(EXIT_FAILURE, _("failed to open %s"), filenamep);
127
if (lseek(fd, 16 << 11, 0) == (off_t) - 1)
128
err(EXIT_FAILURE, _("seek error on %s"), filenamep);
130
if (read(fd, &ipd, sizeof(ipd)) < 0)
131
err(EXIT_FAILURE, _("read error on %s"), filenamep);
133
nsecs = isonum_733(ipd.volume_space_size, xflag);
134
/* isonum_723 returns nowadays always 2048 */
135
ssize = isonum_723(ipd.logical_block_size, xflag);
150
printf (_("sector count: %d, sector size: %d\n"),
138
printf(_("sector count: %d, sector size: %d\n"), nsecs, ssize);
153
140
long long product = nsecs;
155
142
if (divisor == 0)
156
printf ("%lld\n", product * ssize);
143
printf("%lld\n", product * ssize);
157
144
else if (divisor == ssize)
158
printf ("%d\n", nsecs);
145
printf("%d\n", nsecs);
160
printf ("%lld\n", (product * ssize) / divisor);
147
printf("%lld\n", (product * ssize) / divisor);
167
main(int argc, char * argv[]) {
172
if ((p = strrchr(progname, '/')) != NULL)
153
static void __attribute__((__noreturn__)) usage(FILE *out)
155
fprintf(out, _("\nUsage:\n"
156
" %s [options] iso9660_image_file\n"),
157
program_invocation_short_name);
159
fprintf(out, _("\nOptions:\n"
160
" -d, --divisor=NUM devide bytes NUM\n"
161
" -x, --sectors show sector count and size\n"
162
" -V, --version output version information and exit\n"
163
" -H, --help display this help and exit\n\n"));
165
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
168
int main(int argc, char **argv)
170
int j, ct, opt, xflag = 0;
173
static const struct option longopts[] = {
174
{"divisor", no_argument, 0, 'd'},
175
{"sectors", no_argument, 0, 'x'},
176
{"version", no_argument, 0, 'V'},
177
{"help", no_argument, 0, 'h'},
175
181
setlocale(LC_ALL, "");
176
182
bindtextdomain(PACKAGE, LOCALEDIR);
177
183
textdomain(PACKAGE);
180
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
181
printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
188
opt = getopt(argc, argv, "xd:");
185
while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1)
193
divisor = atoi(optarg);
189
strtol_or_err(optarg,
190
_("invalid divisor argument"));
196
printf(_("%s (%s)\n"), program_invocation_short_name,
200
_("%s: option parse error\n"), progname);
205
205
ct = argc - optind;
208
fprintf(stderr, _("Usage: %s [-x] [-d <num>] iso9660-image\n"),
213
210
for (j = optind; j < argc; j++) {
215
212
printf("%s: ", argv[j]);
213
isosize(argv[j], xflag, divisor);