/*
 * isosize.c - Andries Brouwer, 000608
 *
 * use header info to find size of iso9660 file system
 * output a number - useful in scripts
 *
 * Synopsis:
 *    isosize [-x] [-d <num>] <filename>
 *        where "-x" gives length in sectors and sector size while
 *              without this argument the size is given in bytes
 *        without "-x" gives length in bytes unless "-d <num>" is
 *		given. In the latter case the length in bytes divided
 *		by <num> is given
 *
 *  Version 2.03 2000/12/21
 *     - add "-d <num>" option and use long long to fix things > 2 GB
 *  Version 2.02 2000/10/11
 *     - error messages on IO failures [D. Gilbert]
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "nls.h"
#include "c.h"
#include "strutils.h"
#include "closestream.h"

#define ISODCL(from, to) (to - from + 1)

static int is_iso(int fd)
{
	char label[8];
	if (pread(fd, &label, 8, 0x8000) == -1)
		return 1;
	return memcmp(&label, &"\1CD001\1", 8);
}

static int isonum_721(unsigned char *p)
{
	return ((p[0] & 0xff)
		| ((p[1] & 0xff) << 8));
}

static int isonum_722(unsigned char *p)
{
	return ((p[1] & 0xff)
		| ((p[0] & 0xff) << 8));
}

static int isonum_723(unsigned char *p, int xflag)
{
	int le = isonum_721(p);
	int be = isonum_722(p + 2);
	if (xflag && le != be)
		/* translation is useless */
		warnx("723error: le=%d be=%d", le, be);
	return (le);
}

static int isonum_731(unsigned char *p)
{
	return ((p[0] & 0xff)
		| ((p[1] & 0xff) << 8)
		| ((p[2] & 0xff) << 16)
		| ((p[3] & 0xff) << 24));
}

static int isonum_732(unsigned char *p)
{
	return ((p[3] & 0xff)
		| ((p[2] & 0xff) << 8)
		| ((p[1] & 0xff) << 16)
		| ((p[0] & 0xff) << 24));
}

static int isonum_733(unsigned char *p, int xflag)
{
	int le = isonum_731(p);
	int be = isonum_732(p + 4);
	if (xflag && le != be)
		/* translation is useless */
		warn("733error: le=%d be=%d", le, be);
	return (le);
}

struct iso_primary_descriptor
{
	unsigned char type			[ISODCL (   1,	  1)]; /* 711 */
	unsigned char id			[ISODCL (   2,	  6)];
	unsigned char version			[ISODCL (   7,	  7)]; /* 711 */
	unsigned char unused1			[ISODCL (   8,	  8)];
	unsigned char system_id			[ISODCL (   9,	 40)]; /* auchars */
	unsigned char volume_id			[ISODCL (  41,	 72)]; /* duchars */
	unsigned char unused2			[ISODCL (  73,	 80)];
	unsigned char volume_space_size		[ISODCL (  81,	 88)]; /* 733 */
	unsigned char unused3			[ISODCL (  89,	120)];
	unsigned char volume_set_size		[ISODCL ( 121,	124)]; /* 723 */
	unsigned char volume_sequence_number	[ISODCL ( 125,	128)]; /* 723 */
	unsigned char logical_block_size	[ISODCL ( 129,	132)]; /* 723 */
	unsigned char path_table_size		[ISODCL ( 133,	140)]; /* 733 */
	unsigned char type_l_path_table		[ISODCL ( 141,	144)]; /* 731 */
	unsigned char opt_type_l_path_table	[ISODCL ( 145,	148)]; /* 731 */
	unsigned char type_m_path_table		[ISODCL ( 149,	152)]; /* 732 */
	unsigned char opt_type_m_path_table	[ISODCL ( 153,	156)]; /* 732 */
	unsigned char root_directory_record	[ISODCL ( 157,	190)]; /* 9.1 */
	unsigned char volume_set_id		[ISODCL ( 191,	318)]; /* duchars */
	unsigned char publisher_id		[ISODCL ( 319,	446)]; /* achars */
	unsigned char preparer_id		[ISODCL ( 447,	574)]; /* achars */
	unsigned char application_id		[ISODCL ( 575,	702)]; /* achars */
	unsigned char copyright_file_id		[ISODCL ( 703,	739)]; /* 7.5 dchars */
	unsigned char abstract_file_id		[ISODCL ( 740,	776)]; /* 7.5 dchars */
	unsigned char bibliographic_file_id	[ISODCL ( 777,	813)]; /* 7.5 dchars */
	unsigned char creation_date		[ISODCL ( 814,	830)]; /* 8.4.26.1 */
	unsigned char modification_date		[ISODCL ( 831,	847)]; /* 8.4.26.1 */
	unsigned char expiration_date		[ISODCL ( 848,	864)]; /* 8.4.26.1 */
	unsigned char effective_date		[ISODCL ( 865,	881)]; /* 8.4.26.1 */
	unsigned char file_structure_version	[ISODCL ( 882,	882)]; /* 711 */
	unsigned char unused4			[ISODCL ( 883,	883)];
	unsigned char application_data		[ISODCL ( 884, 1395)];
	unsigned char unused5			[ISODCL (1396, 2048)];
};

static void isosize(int argc, char *filenamep, int xflag, long divisor)
{
	int fd, nsecs, ssize;
	struct iso_primary_descriptor ipd;

	if ((fd = open(filenamep, O_RDONLY)) < 0)
		err(EXIT_FAILURE, _("cannot open %s"), filenamep);
	if (is_iso(fd))
		warnx(_("%s: might not be an ISO filesystem"), filenamep);

	if (lseek(fd, 16 << 11, 0) == (off_t) - 1)
		err(EXIT_FAILURE, _("seek error on %s"), filenamep);

	if (read(fd, &ipd, sizeof(ipd)) < 0)
		err(EXIT_FAILURE, _("read error on %s"), filenamep);

	nsecs = isonum_733(ipd.volume_space_size, xflag);
	/* isonum_723 returns nowadays always 2048 */
	ssize = isonum_723(ipd.logical_block_size, xflag);

	if (1 < argc)
		printf("%s: ", filenamep);
	if (xflag) {
		printf(_("sector count: %d, sector size: %d\n"), nsecs, ssize);
	} else {
		long long product = nsecs;

		if (divisor == 0)
			printf("%lld\n", product * ssize);
		else if (divisor == ssize)
			printf("%d\n", nsecs);
		else
			printf("%lld\n", (product * ssize) / divisor);
	}

	close(fd);
}

static void __attribute__((__noreturn__)) usage(FILE *out)
{
	fputs(USAGE_HEADER, out);
	fprintf(out,
		_(" %s [options] <iso9660_image_file>\n"),
		program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Show the length of an ISO-9660 filesystem.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -d, --divisor=<number>  divide the amount of bytes by <number>\n"), out);
	fputs(_(" -x, --sectors           show sector count and size\n"), out);
	fputs(USAGE_SEPARATOR, out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);
	fprintf(out, USAGE_MAN_TAIL("isosize(8)"));

	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
	int j, ct, opt, xflag = 0;
	long divisor = 0;

	static const struct option longopts[] = {
		{"divisor", required_argument, 0, 'd'},
		{"sectors", no_argument, 0, 'x'},
		{"version", no_argument, 0, 'V'},
		{"help", no_argument, 0, 'h'},
		{NULL, 0, 0, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((opt = getopt_long(argc, argv, "d:xVh", longopts, NULL)) != -1)
		switch (opt) {
		case 'd':
			divisor =
			    strtol_or_err(optarg,
					  _("invalid divisor argument"));
			break;
		case 'x':
			xflag = 1;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}

	ct = argc - optind;

	if (ct <= 0)
		usage(stderr);

	for (j = optind; j < argc; j++)
		isosize(ct, argv[j], xflag, divisor);

	return EXIT_SUCCESS;
}
