]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/isosize.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[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"
1f10f4af 32#include "iso9660.h"
66ee8158 33
c3801802
KZ
34#define ISOSIZE_EXIT_ALLFAILED 32
35#define ISOSIZE_EXIT_SOMEOK 64
36
bb2d1ea5
SK
37static 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 46static 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;
88done:
89 if (fd >= 0)
90 close(fd);
91 return rc;
66ee8158
KZ
92}
93
6e1eda6f 94static 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
115int 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}