]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/isosize.c
lscpu: add --bytes
[thirdparty/util-linux.git] / disk-utils / isosize.c
CommitLineData
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"
66ee8158 32
c3801802
KZ
33#define ISOSIZE_EXIT_ALLFAILED 32
34#define ISOSIZE_EXIT_SOMEOK 64
35
bb2d1ea5
SK
36static int is_iso(int fd)
37{
38 char label[8];
1da83869 39
bb2d1ea5
SK
40 if (pread(fd, &label, 8, 0x8000) == -1)
41 return 1;
42 return memcmp(&label, &"\1CD001\1", 8);
43}
44
6f81751a
SK
45static int isonum_721(unsigned char *p)
46{
47 return ((p[0] & 0xff)
48 | ((p[1] & 0xff) << 8));
66ee8158
KZ
49}
50
6f81751a
SK
51static int isonum_722(unsigned char *p)
52{
53 return ((p[1] & 0xff)
54 | ((p[0] & 0xff) << 8));
66ee8158
KZ
55}
56
6f81751a
SK
57static int isonum_723(unsigned char *p, int xflag)
58{
59 int le = isonum_721(p);
60 int be = isonum_722(p + 2);
1da83869 61
6f81751a 62 if (xflag && le != be)
66ee8158 63 /* translation is useless */
6f81751a
SK
64 warnx("723error: le=%d be=%d", le, be);
65 return (le);
66ee8158
KZ
66}
67
6f81751a
SK
68static int isonum_731(unsigned char *p)
69{
70 return ((p[0] & 0xff)
71 | ((p[1] & 0xff) << 8)
72 | ((p[2] & 0xff) << 16)
73 | ((p[3] & 0xff) << 24));
66ee8158
KZ
74}
75
6f81751a
SK
76static int isonum_732(unsigned char *p)
77{
78 return ((p[3] & 0xff)
79 | ((p[2] & 0xff) << 8)
80 | ((p[1] & 0xff) << 16)
81 | ((p[0] & 0xff) << 24));
66ee8158
KZ
82}
83
6f81751a
SK
84static int isonum_733(unsigned char *p, int xflag)
85{
86 int le = isonum_731(p);
87 int be = isonum_732(p + 4);
1da83869 88
6f81751a
SK
89 if (xflag && le != be)
90 /* translation is useless */
5a2ed453 91 warnx("733error: le=%d be=%d", le, be);
6f81751a 92 return (le);
66ee8158
KZ
93}
94
c3801802 95static int isosize(int argc, char *filenamep, int xflag, long divisor)
6f81751a 96{
c3801802 97 int fd, nsecs, ssize, rc = -1;
e3e0054f
SK
98 unsigned char volume_space_size[8];
99 unsigned char logical_block_size[4];
66ee8158 100
c3801802
KZ
101 if ((fd = open(filenamep, O_RDONLY)) < 0) {
102 warn(_("cannot open %s"), filenamep);
103 goto done;
104 }
bb2d1ea5 105 if (is_iso(fd))
b548a8c9 106 warnx(_("%s: might not be an ISO filesystem"), filenamep);
73611843 107
c3801802
KZ
108 if (pread(fd, volume_space_size, sizeof(volume_space_size), 0x8050) != sizeof(volume_space_size) ||
109 pread(fd, logical_block_size, sizeof(logical_block_size), 0x8080) != sizeof(logical_block_size)) {
e3e0054f 110 if (errno)
c3801802
KZ
111 warn(_("read error on %s"), filenamep);
112 else
113 warnx(_("read error on %s"), filenamep);
114 goto done;
e3e0054f 115 }
66ee8158 116
e3e0054f 117 nsecs = isonum_733(volume_space_size, xflag);
6f81751a 118 /* isonum_723 returns nowadays always 2048 */
e3e0054f 119 ssize = isonum_723(logical_block_size, xflag);
66ee8158 120
799e5842
SK
121 if (1 < argc)
122 printf("%s: ", filenamep);
1da83869 123 if (xflag)
6f81751a 124 printf(_("sector count: %d, sector size: %d\n"), nsecs, ssize);
1da83869 125 else {
66ee8158
KZ
126 long long product = nsecs;
127
128 if (divisor == 0)
6f81751a 129 printf("%lld\n", product * ssize);
66ee8158 130 else if (divisor == ssize)
6f81751a 131 printf("%d\n", nsecs);
66ee8158 132 else
6f81751a 133 printf("%lld\n", (product * ssize) / divisor);
66ee8158 134 }
122db55d 135
c3801802
KZ
136 rc = 0;
137done:
138 if (fd >= 0)
139 close(fd);
140 return rc;
66ee8158
KZ
141}
142
6e1eda6f 143static void __attribute__((__noreturn__)) usage(void)
9404cc7f 144{
1da83869
KZ
145
146 fputs(USAGE_HEADER, stdout);
147 fprintf(stdout,
148 _(" %s [options] <iso9660_image_file> ...\n"),
9404cc7f 149 program_invocation_short_name);
451dbcfa 150
1da83869
KZ
151 fputs(USAGE_SEPARATOR, stdout);
152 fputs(_("Show the length of an ISO-9660 filesystem.\n"), stdout);
153
154 fputs(USAGE_OPTIONS, stdout);
155 fputs(_(" -d, --divisor=<number> divide the amount of bytes by <number>\n"), stdout);
156 fputs(_(" -x, --sectors show sector count and size\n"), stdout);
451dbcfa 157
f45f3ec3
RM
158 printf(USAGE_HELP_OPTIONS(25));
159 printf(USAGE_MAN_TAIL("isosize(8)"));
4eba43a7 160
6e1eda6f 161 exit(EXIT_SUCCESS);
9404cc7f
FC
162}
163
6f81751a
SK
164int main(int argc, char **argv)
165{
c3801802 166 int j, ct_err = 0, ct, opt, xflag = 0;
ab3a34ff 167 long divisor = 0;
66ee8158 168
4eba43a7 169 static const struct option longopts[] = {
87918040
SK
170 {"divisor", required_argument, NULL, 'd'},
171 {"sectors", no_argument, NULL, 'x'},
172 {"version", no_argument, NULL, 'V'},
173 {"help", no_argument, NULL, 'h'},
174 {NULL, 0, NULL, 0}
4eba43a7
SK
175 };
176
66ee8158
KZ
177 setlocale(LC_ALL, "");
178 bindtextdomain(PACKAGE, LOCALEDIR);
179 textdomain(PACKAGE);
45ca68ec 180 atexit(close_stdout);
66ee8158 181
1da83869 182 while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1) {
66ee8158
KZ
183 switch (opt) {
184 case 'd':
ab3a34ff
SK
185 divisor =
186 strtol_or_err(optarg,
187 _("invalid divisor argument"));
66ee8158
KZ
188 break;
189 case 'x':
190 xflag = 1;
191 break;
4eba43a7 192 case 'V':
bb7ea8d8 193 printf(UTIL_LINUX_VERSION);
4eba43a7
SK
194 return EXIT_SUCCESS;
195 case 'h':
6e1eda6f 196 usage();
66ee8158 197 default:
677ec86c 198 errtryhelp(EXIT_FAILURE);
66ee8158 199 }
1da83869 200 }
66ee8158
KZ
201
202 ct = argc - optind;
203
6e1eda6f
RM
204 if (ct <= 0) {
205 warnx(_("no device specified"));
206 errtryhelp(EXIT_FAILURE);
207 }
66ee8158 208
c3801802
KZ
209 for (j = optind; j < argc; j++) {
210 if (isosize(ct, argv[j], xflag, divisor) != 0)
211 ct_err++;
212 }
66ee8158 213
c3801802
KZ
214 return ct == ct_err ? ISOSIZE_EXIT_ALLFAILED : /* all failed */
215 ct_err ? ISOSIZE_EXIT_SOMEOK : /* some ok */
216 EXIT_SUCCESS; /* all success */
66ee8158 217}