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