]> git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/isosize.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / disk-utils / isosize.c
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>
26 #include <string.h>
27
28 #include "nls.h"
29
30 #define ISODCL(from, to) (to - from + 1)
31
32 int xflag;
33
34 static int
35 isonum_721 (unsigned char * p) {
36 return ((p[0] & 0xff)
37 | ((p[1] & 0xff) << 8));
38 }
39
40 static int
41 isonum_722 (unsigned char * p) {
42 return ((p[1] & 0xff)
43 | ((p[0] & 0xff) << 8));
44 }
45
46 static int
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);
53 return (le);
54 }
55
56 static int
57 isonum_731 (unsigned char * p) {
58 return ((p[0] & 0xff)
59 | ((p[1] & 0xff) << 8)
60 | ((p[2] & 0xff) << 16)
61 | ((p[3] & 0xff) << 24));
62 }
63
64 static int
65 isonum_732 (unsigned char * p) {
66 return ((p[3] & 0xff)
67 | ((p[2] & 0xff) << 8)
68 | ((p[1] & 0xff) << 16)
69 | ((p[0] & 0xff) << 24));
70 }
71
72
73 static int
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);
80 return (le);
81 }
82
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)];
117 };
118
119 const char *progname;
120 int divisor = 0;
121
122 static void
123 isosize(char *filenamep) {
124 int fd, nsecs, ssize;
125 struct iso_primary_descriptor ipd;
126
127 if ((fd = open(filenamep, O_RDONLY)) < 0) {
128 perror(filenamep);
129 fprintf(stderr, _("%s: failed to open: %s\n"),
130 progname, filenamep);
131 exit(1);
132 }
133 if (lseek(fd, 16 << 11, 0) == (off_t)-1) {
134 perror("lseek");
135 fprintf(stderr, _("%s: seek error on %s\n"),
136 progname, filenamep);
137 exit(1);
138 }
139 if (read(fd, &ipd, sizeof(ipd)) < 0) {
140 perror("read");
141 fprintf(stderr, _("%s: read error on %s\n"),
142 progname, filenamep);
143 exit(1);
144 }
145
146 nsecs = isonum_733(ipd.volume_space_size);
147 ssize = isonum_723(ipd.logical_block_size); /* nowadays always 2048 */
148
149 if (xflag) {
150 printf (_("sector count: %d, sector size: %d\n"),
151 nsecs, ssize);
152 } else {
153 long long product = nsecs;
154
155 if (divisor == 0)
156 printf ("%lld\n", product * ssize);
157 else if (divisor == ssize)
158 printf ("%d\n", nsecs);
159 else
160 printf ("%lld\n", (product * ssize) / divisor);
161 }
162 }
163
164 int
165 main(int argc, char * argv[]) {
166 int j, ct;
167 char *p;
168
169 progname = argv[0];
170 if ((p = strrchr(progname, '/')) != NULL)
171 progname = p+1;
172
173 setlocale(LC_ALL, "");
174 bindtextdomain(PACKAGE, LOCALEDIR);
175 textdomain(PACKAGE);
176
177 if (argc >= 2 &&
178 (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
179 printf(_("%s from %s\n"), progname, util_linux_version);
180 exit(0);
181 }
182
183 for (;;) {
184 int opt;
185
186 opt = getopt(argc, argv, "xd:");
187 if (opt < 0)
188 break;
189 switch (opt) {
190 case 'd':
191 divisor = atoi(optarg);
192 break;
193 case 'x':
194 xflag = 1;
195 break;
196 default:
197 fprintf(stderr,
198 _("%s: option parse error\n"), progname);
199 exit(1);
200 }
201 }
202
203 ct = argc - optind;
204
205 if (ct <= 0) {
206 fprintf(stderr, _("Usage: %s [-x] [-d <num>] iso9660-image\n"),
207 progname);
208 exit(1);
209 }
210
211 for (j = optind; j < argc; j++) {
212 if (ct > 1)
213 printf("%s: ", argv[j]);
214 isosize(argv[j]);
215 }
216
217 return 0;
218 }