/*
 * Copyright (C) 1999 by Andries Brouwer
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
 * Copyright (C) 2001 by Andreas Dilger
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 *
 * Inspired also by libvolume_id by
 *     Kay Sievers <kay.sievers@vrfy.org>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>

#include "superblocks.h"

struct iso9660_date {
	unsigned char year[4];
	unsigned char month[2];
	unsigned char day[2];
	unsigned char hour[2];
	unsigned char minute[2];
	unsigned char second[2];
	unsigned char hundredth[2];
	unsigned char offset;
} __attribute__ ((packed));

/* PVD - Primary volume descriptor */
struct iso_volume_descriptor {
	unsigned char	vd_type;
	unsigned char	vd_id[5];
	unsigned char	vd_version;
	unsigned char	flags;
	unsigned char	system_id[32];
	unsigned char	volume_id[32];
	unsigned char	unused[8];
	unsigned char	space_size[8];
	unsigned char	escape_sequences[8];
	unsigned char  unused1[222];
	unsigned char  publisher_id[128];
	unsigned char  unused2[128];
	unsigned char  application_id[128];
	unsigned char  unused3[111];
	struct iso9660_date created;
	struct iso9660_date modified;
} __attribute__((packed));

/* Boot Record */
struct boot_record {
	unsigned char	vd_type;
	unsigned char	vd_id[5];
	unsigned char	vd_version;
	unsigned char	boot_system_id[32];
	unsigned char	boot_id[32];
	unsigned char	unused[1];
} __attribute__((packed));

#define ISO_SUPERBLOCK_OFFSET		0x8000
#define ISO_SECTOR_SIZE			0x800
#define ISO_VD_OFFSET			(ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
#define ISO_VD_BOOT_RECORD		0x0
#define ISO_VD_SUPPLEMENTARY		0x2
#define ISO_VD_END			0xff
#define ISO_VD_MAX			16

struct high_sierra_volume_descriptor {
	unsigned char	foo[8];
	unsigned char	type;
	unsigned char	id[5];
	unsigned char	version;
	unsigned char	unused1;
	unsigned char	system_id[32];
	unsigned char   volume_id[32];
} __attribute__((packed));

/* returns 1 if the begin of @ascii is equal to @utf16 string.
 */
static int ascii_eq_utf16be(unsigned char *ascii,
			unsigned char *utf16, size_t len)
{
	size_t a, u;

	for (a = 0, u = 0; u < len; a++, u += 2) {
		if (utf16[u] != 0x0 || ascii[a] != utf16[u + 1])
			return 0;
	}
	return 1;
}

/* old High Sierra format */
static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct high_sierra_volume_descriptor *iso;

	iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor);
	if (!iso)
		return errno ? -errno : 1;

	blkid_probe_set_version(pr, "High Sierra");
	blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id));
	return 0;
}

static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *date)
{
	unsigned char buffer[16];
	unsigned int i, zeros = 0;

	buffer[0] = date->year[0];
	buffer[1] = date->year[1];
	buffer[2] = date->year[2];
	buffer[3] = date->year[3];
	buffer[4] = date->month[0];
	buffer[5] = date->month[1];
	buffer[6] = date->day[0];
	buffer[7] = date->day[1];
	buffer[8] = date->hour[0];
	buffer[9] = date->hour[1];
	buffer[10] = date->minute[0];
	buffer[11] = date->minute[1];
	buffer[12] = date->second[0];
	buffer[13] = date->second[1];
	buffer[14] = date->hundredth[0];
	buffer[15] = date->hundredth[1];

	/* count the number of zeros ('0') in the date buffer */
	for (i = 0, zeros = 0; i < sizeof(buffer); i++)
		if (buffer[i] == '0')
			zeros++;

	/* due to the iso9660 standard if all date fields are '0' and offset is 0, the date is unset */
	if (zeros == sizeof(buffer) && date->offset == 0)
		return 0;

	/* generate an UUID using this date and return success */
	blkid_probe_sprintf_uuid (pr, buffer, sizeof(buffer),
		"%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c",
		buffer[0], buffer[1], buffer[2], buffer[3],
		buffer[4], buffer[5],
		buffer[6], buffer[7],
		buffer[8], buffer[9],
		buffer[10], buffer[11],
		buffer[12], buffer[13],
		buffer[14], buffer[15]);

	return 1;
}

static int is_str_empty(const unsigned char *str, size_t len)
{
	size_t i;

	if (!str || !*str)
		return 1;

	for (i = 0; i < len; i++)
		if (!isspace(str[i]))
			return 0;
	return 1;
}

/* iso9660 [+ Microsoft Joliet Extension] */
int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct iso_volume_descriptor *iso;
	unsigned char label[32];
	int i;
	int off;

	if (strcmp(mag->magic, "CDROM") == 0)
		return probe_iso9660_hsfs(pr, mag);

	iso = blkid_probe_get_sb(pr, mag, struct iso_volume_descriptor);
	if (!iso)
		return errno ? -errno : 1;

	memcpy(label, iso->volume_id, sizeof(label));

	if (!is_str_empty(iso->system_id, sizeof(iso->system_id)))
		blkid_probe_set_id_label(pr, "SYSTEM_ID",
				iso->system_id, sizeof(iso->system_id));

	if (!is_str_empty(iso->publisher_id, sizeof(iso->publisher_id)))
		blkid_probe_set_id_label(pr, "PUBLISHER_ID",
				iso->publisher_id, sizeof(iso->publisher_id));

	if (!is_str_empty(iso->application_id, sizeof(iso->application_id)))
		blkid_probe_set_id_label(pr, "APPLICATION_ID",
				iso->application_id, sizeof(iso->application_id));

	/* create an UUID using the modified/created date */
	if (! probe_iso9660_set_uuid(pr, &iso->modified))
		probe_iso9660_set_uuid(pr, &iso->created);

	/* Joliet Extension and Boot Record */
	off = ISO_VD_OFFSET;
	for (i = 0; i < ISO_VD_MAX; i++) {
		struct boot_record *boot= (struct boot_record *)
			blkid_probe_get_buffer(pr,
					off,
					max(sizeof(struct boot_record),
					    sizeof(struct iso_volume_descriptor)));

		if (boot == NULL || boot->vd_type == ISO_VD_END)
			break;

		if (boot->vd_type == ISO_VD_BOOT_RECORD) {
			if (!is_str_empty(boot->boot_system_id,
					  sizeof(boot->boot_system_id)))
				blkid_probe_set_id_label(pr, "BOOT_SYSTEM_ID",
							boot->boot_system_id,
							sizeof(boot->boot_system_id));
			off += ISO_SECTOR_SIZE;
			continue;
		}

		/* Not a Boot record, lets see if its supplemntary volume descriptor */
		iso = (struct iso_volume_descriptor *) boot;

		if (iso->vd_type != ISO_VD_SUPPLEMENTARY) {
			off += ISO_SECTOR_SIZE;
			continue;
		}

		if (memcmp(iso->escape_sequences, "%/@", 3) == 0 ||
		    memcmp(iso->escape_sequences, "%/C", 3) == 0 ||
		    memcmp(iso->escape_sequences, "%/E", 3) == 0) {

			blkid_probe_set_version(pr, "Joliet Extension");

			/* Is the Joliet (UTF16BE) label equal to the label in
			 * the PVD? If yes, use PVD label.  The Jolied version
			 * of the label could be trimed (because UTF16..).
			 */
			if (ascii_eq_utf16be(label, iso->volume_id, 32))
				break;

			blkid_probe_set_utf8label(pr,
					iso->volume_id,
					sizeof(iso->volume_id),
					BLKID_ENC_UTF16BE);
			goto has_label;
		}
		off += ISO_SECTOR_SIZE;
	}

	/* Joliet not found, let use standard iso label */
	blkid_probe_set_label(pr, label, sizeof(label));

has_label:
	return 0;
}

const struct blkid_idinfo iso9660_idinfo =
{
	.name		= "iso9660",
	.usage		= BLKID_USAGE_FILESYSTEM,
	.probefunc	= probe_iso9660,
	.flags		= BLKID_IDINFO_TOLERANT,
	.magics		=
	{
		{ .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 },
		{ .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9 },
		{ NULL }
	}
};

