]>
Commit | Line | Data |
---|---|---|
66ee8158 KZ |
1 | /* |
2 | * isosize.c - Andries Brouwer, 000608 | |
3 | * | |
4 | * use header info to find size of iso9660 file system | |
5 | * output a number - useful in scripts | |
6 | * | |
7 | * Synopsis: | |
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 | |
13 | * by <num> is given | |
14 | * | |
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] | |
19 | * | |
20 | */ | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <getopt.h> | |
24 | #include <fcntl.h> | |
25 | #include <unistd.h> | |
4c0ecdd4 | 26 | #include <errno.h> |
66ee8158 KZ |
27 | |
28 | #include "nls.h" | |
73611843 | 29 | #include "c.h" |
ab3a34ff | 30 | #include "strutils.h" |
45ca68ec | 31 | #include "closestream.h" |
1f10f4af | 32 | #include "iso9660.h" |
66ee8158 | 33 | |
c3801802 KZ |
34 | #define ISOSIZE_EXIT_ALLFAILED 32 |
35 | #define ISOSIZE_EXIT_SOMEOK 64 | |
36 | ||
bb2d1ea5 SK |
37 | static int is_iso(int fd) |
38 | { | |
39 | char label[8]; | |
1da83869 | 40 | |
bb2d1ea5 SK |
41 | if (pread(fd, &label, 8, 0x8000) == -1) |
42 | return 1; | |
43 | return memcmp(&label, &"\1CD001\1", 8); | |
44 | } | |
45 | ||
c3801802 | 46 | static int isosize(int argc, char *filenamep, int xflag, long divisor) |
6f81751a | 47 | { |
c3801802 | 48 | int fd, nsecs, ssize, rc = -1; |
e3e0054f SK |
49 | unsigned char volume_space_size[8]; |
50 | unsigned char logical_block_size[4]; | |
66ee8158 | 51 | |
c3801802 KZ |
52 | if ((fd = open(filenamep, O_RDONLY)) < 0) { |
53 | warn(_("cannot open %s"), filenamep); | |
54 | goto done; | |
55 | } | |
bb2d1ea5 | 56 | if (is_iso(fd)) |
b548a8c9 | 57 | warnx(_("%s: might not be an ISO filesystem"), filenamep); |
73611843 | 58 | |
c3801802 KZ |
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)) { | |
e3e0054f | 61 | if (errno) |
c3801802 KZ |
62 | warn(_("read error on %s"), filenamep); |
63 | else | |
64 | warnx(_("read error on %s"), filenamep); | |
65 | goto done; | |
e3e0054f | 66 | } |
66ee8158 | 67 | |
e3e0054f | 68 | nsecs = isonum_733(volume_space_size, xflag); |
6f81751a | 69 | /* isonum_723 returns nowadays always 2048 */ |
e3e0054f | 70 | ssize = isonum_723(logical_block_size, xflag); |
66ee8158 | 71 | |
799e5842 SK |
72 | if (1 < argc) |
73 | printf("%s: ", filenamep); | |
1da83869 | 74 | if (xflag) |
6f81751a | 75 | printf(_("sector count: %d, sector size: %d\n"), nsecs, ssize); |
1da83869 | 76 | else { |
66ee8158 KZ |
77 | long long product = nsecs; |
78 | ||
79 | if (divisor == 0) | |
6f81751a | 80 | printf("%lld\n", product * ssize); |
66ee8158 | 81 | else if (divisor == ssize) |
6f81751a | 82 | printf("%d\n", nsecs); |
66ee8158 | 83 | else |
6f81751a | 84 | printf("%lld\n", (product * ssize) / divisor); |
66ee8158 | 85 | } |
122db55d | 86 | |
c3801802 KZ |
87 | rc = 0; |
88 | done: | |
89 | if (fd >= 0) | |
90 | close(fd); | |
91 | return rc; | |
66ee8158 KZ |
92 | } |
93 | ||
6e1eda6f | 94 | static void __attribute__((__noreturn__)) usage(void) |
9404cc7f | 95 | { |
1da83869 KZ |
96 | |
97 | fputs(USAGE_HEADER, stdout); | |
98 | fprintf(stdout, | |
99 | _(" %s [options] <iso9660_image_file> ...\n"), | |
9404cc7f | 100 | program_invocation_short_name); |
451dbcfa | 101 | |
1da83869 KZ |
102 | fputs(USAGE_SEPARATOR, stdout); |
103 | fputs(_("Show the length of an ISO-9660 filesystem.\n"), stdout); | |
104 | ||
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); | |
451dbcfa | 108 | |
f45f3ec3 RM |
109 | printf(USAGE_HELP_OPTIONS(25)); |
110 | printf(USAGE_MAN_TAIL("isosize(8)")); | |
4eba43a7 | 111 | |
6e1eda6f | 112 | exit(EXIT_SUCCESS); |
9404cc7f FC |
113 | } |
114 | ||
6f81751a SK |
115 | int main(int argc, char **argv) |
116 | { | |
c3801802 | 117 | int j, ct_err = 0, ct, opt, xflag = 0; |
ab3a34ff | 118 | long divisor = 0; |
66ee8158 | 119 | |
4eba43a7 | 120 | static const struct option longopts[] = { |
87918040 SK |
121 | {"divisor", required_argument, NULL, 'd'}, |
122 | {"sectors", no_argument, NULL, 'x'}, | |
123 | {"version", no_argument, NULL, 'V'}, | |
124 | {"help", no_argument, NULL, 'h'}, | |
125 | {NULL, 0, NULL, 0} | |
4eba43a7 SK |
126 | }; |
127 | ||
66ee8158 KZ |
128 | setlocale(LC_ALL, ""); |
129 | bindtextdomain(PACKAGE, LOCALEDIR); | |
130 | textdomain(PACKAGE); | |
2c308875 | 131 | close_stdout_atexit(); |
66ee8158 | 132 | |
1da83869 | 133 | while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1) { |
66ee8158 KZ |
134 | switch (opt) { |
135 | case 'd': | |
ab3a34ff SK |
136 | divisor = |
137 | strtol_or_err(optarg, | |
138 | _("invalid divisor argument")); | |
66ee8158 KZ |
139 | break; |
140 | case 'x': | |
141 | xflag = 1; | |
142 | break; | |
4eba43a7 | 143 | case 'V': |
2c308875 | 144 | print_version(EXIT_SUCCESS); |
4eba43a7 | 145 | case 'h': |
6e1eda6f | 146 | usage(); |
66ee8158 | 147 | default: |
677ec86c | 148 | errtryhelp(EXIT_FAILURE); |
66ee8158 | 149 | } |
1da83869 | 150 | } |
66ee8158 KZ |
151 | |
152 | ct = argc - optind; | |
153 | ||
6e1eda6f RM |
154 | if (ct <= 0) { |
155 | warnx(_("no device specified")); | |
156 | errtryhelp(EXIT_FAILURE); | |
157 | } | |
66ee8158 | 158 | |
c3801802 KZ |
159 | for (j = optind; j < argc; j++) { |
160 | if (isosize(ct, argv[j], xflag, divisor) != 0) | |
161 | ct_err++; | |
162 | } | |
66ee8158 | 163 | |
c3801802 KZ |
164 | return ct == ct_err ? ISOSIZE_EXIT_ALLFAILED : /* all failed */ |
165 | ct_err ? ISOSIZE_EXIT_SOMEOK : /* some ok */ | |
166 | EXIT_SUCCESS; /* all success */ | |
66ee8158 | 167 | } |