Upload Tizen:Base source
[framework/base/util-linux-ng.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         close(fd);
164 }
165
166 int
167 main(int argc, char * argv[]) {
168         int j, ct;
169         char *p;
170
171         progname = argv[0];
172         if ((p = strrchr(progname, '/')) != NULL)
173                 progname = p+1;
174
175         setlocale(LC_ALL, "");
176         bindtextdomain(PACKAGE, LOCALEDIR);
177         textdomain(PACKAGE);
178
179         if (argc >= 2 &&
180             (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
181                 printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
182                 exit(0);
183         }
184
185         for (;;) {
186                 int opt;
187
188                 opt = getopt(argc, argv, "xd:");
189                 if (opt == -1)
190                         break;
191                 switch (opt) {
192                 case 'd':
193                         divisor = atoi(optarg);
194                         break;
195                 case 'x':
196                         xflag = 1;
197                         break;
198                 default:
199                         fprintf(stderr,
200                                 _("%s: option parse error\n"), progname);
201                         exit(1);
202                 }
203         }
204
205         ct = argc - optind;
206
207         if (ct <= 0) {
208                 fprintf(stderr, _("Usage: %s [-x] [-d <num>] iso9660-image\n"),
209                         progname);
210                 exit(1);
211         }
212
213         for (j = optind; j < argc; j++) {
214                 if (ct > 1)
215                         printf("%s: ", argv[j]);
216                 isosize(argv[j]);
217         }
218
219         return 0;
220 }