/* system/core/gpttool/gpttool.c
**
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

#include <zlib.h>

#include <linux/fs.h>

#include <sys/stat.h>

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;

const u8 partition_type_uuid[16] = {
	0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
	0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7,
};


#define EFI_VERSION 0x00010000
#define EFI_MAGIC "EFI PART"
#define EFI_ENTRIES 128
#define EFI_NAMELEN 36

struct efi_header {
	u8 magic[8];

	u32 version;
	u32 header_sz;

	u32 crc32;
	u32 reserved;

	u64 header_lba;
	u64 backup_lba;
	u64 first_lba;
	u64 last_lba;

	u8 volume_uuid[16];

	u64 entries_lba;

	u32 entries_count;
	u32 entries_size;
	u32 entries_crc32;
} __attribute__((packed));

struct efi_entry {
	u8 type_uuid[16];
	u8 uniq_uuid[16];
	u64 first_lba;
	u64 last_lba;
	u64 attr;
	u16 name[EFI_NAMELEN];
};

struct ptable {
	u8 mbr[512];
	union {
		struct efi_header header;
		u8 block[512];
	};
	struct efi_entry entry[EFI_ENTRIES];	
};

void get_uuid(u8 *uuid)
{
	int fd;
	fd = open("/dev/urandom", O_RDONLY);
	read(fd, uuid, 16);
	close(fd);
}

void init_mbr(u8 *mbr, u32 blocks)
{
	mbr[0x1be] = 0x00; // nonbootable
	mbr[0x1bf] = 0xFF; // bogus CHS
	mbr[0x1c0] = 0xFF;
	mbr[0x1c1] = 0xFF;

	mbr[0x1c2] = 0xEE; // GPT partition
	mbr[0x1c3] = 0xFF; // bogus CHS
	mbr[0x1c4] = 0xFF;
	mbr[0x1c5] = 0xFF;

	mbr[0x1c6] = 0x01; // start
	mbr[0x1c7] = 0x00;
	mbr[0x1c8] = 0x00;
	mbr[0x1c9] = 0x00;

	memcpy(mbr + 0x1ca, &blocks, sizeof(u32));

	mbr[0x1fe] = 0x55;
	mbr[0x1ff] = 0xaa;
}

int add_ptn(struct ptable *ptbl, u64 first, u64 last, const char *name)
{
	struct efi_header *hdr = &ptbl->header;
	struct efi_entry *entry = ptbl->entry;
	unsigned n;

	if (first < 34) {
		fprintf(stderr,"partition '%s' overlaps partition table\n", name);
		return -1;
	}

	if (last > hdr->last_lba) {
		fprintf(stderr,"partition '%s' does not fit on disk\n", name);
		return -1;
	}
	for (n = 0; n < EFI_ENTRIES; n++, entry++) {
		if (entry->type_uuid[0])
			continue;
		memcpy(entry->type_uuid, partition_type_uuid, 16);
		get_uuid(entry->uniq_uuid);
		entry->first_lba = first;
		entry->last_lba = last;
		for (n = 0; (n < EFI_NAMELEN) && *name; n++)
			entry->name[n] = *name++;
		return 0;
	}
	fprintf(stderr,"out of partition table entries\n");
	return -1;
}

int usage(void)
{
	fprintf(stderr,
		"usage: gpttool write <disk> [ <partition> ]*\n"
		"       gpttool read <disk>\n"
		"       gpttool test [ <partition> ]*\n"
		"\n"
		"partition:  [<name>]:<size>[kmg] | @<file-of-partitions>\n"
		);
	return 0;
}

void show(struct ptable *ptbl)
{
	struct efi_entry *entry = ptbl->entry;
	unsigned n, m;
	char name[EFI_NAMELEN + 1];

	fprintf(stderr,"ptn  start block   end block     name\n");
	fprintf(stderr,"---- ------------- ------------- --------------------\n");

	for (n = 0; n < EFI_ENTRIES; n++, entry++) {
		if (entry->type_uuid[0] == 0)
			break;
		for (m = 0; m < EFI_NAMELEN; m++) {
			name[m] = entry->name[m] & 127;
		}
		name[m] = 0;
		fprintf(stderr,"#%03d %13lld %13lld %s\n",
			n + 1, entry->first_lba, entry->last_lba, name);
	}
}

u64 find_next_lba(struct ptable *ptbl)
{
	struct efi_entry *entry = ptbl->entry;
	unsigned n;
	u64 a = 0;
	for (n = 0; n < EFI_ENTRIES; n++, entry++) {
		if ((entry->last_lba + 1) > a)
			a = entry->last_lba + 1;
	}
	return a;
}

u64 next_lba = 0;

u64 parse_size(char *sz)
{
	int l = strlen(sz);
	u64 n = strtoull(sz, 0, 10);
	if (l) {
		switch(sz[l-1]){
		case 'k':
		case 'K':
			n *= 1024;
			break;
		case 'm':
		case 'M':
			n *= (1024 * 1024);
			break;
		case 'g':
		case 'G':
			n *= (1024 * 1024 * 1024);
			break;
		}
	}
	return n;
}

int parse_ptn(struct ptable *ptbl, char *x)
{
	char *y = strchr(x, ':');
	u64 sz;

	if (!y) {
		fprintf(stderr,"invalid partition entry: %s\n", x);
		return -1;
	}
	*y++ = 0;

	if (*y == 0) {
		sz = ptbl->header.last_lba - next_lba;
	} else {
		sz = parse_size(y);
		if (sz & 511) {
			fprintf(stderr,"partition size must be multiple of 512\n");
			return -1;
		}
		sz /= 512;
	}

	if (sz == 0) {
		fprintf(stderr,"zero size partitions not allowed\n");
		return -1;
	}

	if (x[0] && add_ptn(ptbl, next_lba, next_lba + sz - 1, x))
		return -1;

	next_lba = next_lba + sz;
	return 0;
}

int main(int argc, char **argv)
{
	struct ptable ptbl;
	struct efi_entry *entry;
	struct efi_header *hdr = &ptbl.header;
	struct stat s;
	u32 n;
	u64 sz, blk;
	int fd;
	const char *device;
	int real_disk = 0;

	if (argc < 2)
		return usage();

	if (!strcmp(argv[1], "write")) {
		if (argc < 3)
			return usage();
		device = argv[2];
		argc -= 2;
		argv += 2;
		real_disk = 1;
	} else if (!strcmp(argv[1], "test")) {
		argc -= 1;
		argv += 1;
		real_disk = 0;
		sz = 2097152 * 16;
		fprintf(stderr,"< simulating 16GB disk >\n\n");
	} else {
		return usage();
	}

	if (real_disk) {
		if (!strcmp(device, "/dev/sda") || 
		    !strcmp(device, "/dev/sdb")) {
			fprintf(stderr,"error: refusing to partition sda or sdb\n");
			return -1;
		}
		
		fd = open(device, O_RDWR);
		if (fd < 0) {
			fprintf(stderr,"error: cannot open '%s'\n", device);
			return -1;
		}
		if (ioctl(fd, BLKGETSIZE64, &sz)) {
			fprintf(stderr,"error: cannot query block device size\n");
			return -1;
		}
		sz /= 512;
		fprintf(stderr,"blocks %lld\n", sz);
	}

	memset(&ptbl, 0, sizeof(ptbl));

	init_mbr(ptbl.mbr, sz - 1);

	memcpy(hdr->magic, EFI_MAGIC, sizeof(hdr->magic));
	hdr->version = EFI_VERSION;
	hdr->header_sz = sizeof(struct efi_header);
	hdr->header_lba = 1;
	hdr->backup_lba = sz - 1;
	hdr->first_lba = 34;
	hdr->last_lba = sz - 1;
	get_uuid(hdr->volume_uuid);
	hdr->entries_lba = 2;
	hdr->entries_count = 128;
	hdr->entries_size = sizeof(struct efi_entry);

	while (argc > 1) {
		if (argv[1][0] == '@') {
			char line[256], *p;
			FILE *f;
			f = fopen(argv[1] + 1, "r");
			if (!f) {
				fprintf(stderr,"cannot read partitions from '%s\n", argv[1]);
				return -1;
			}
			while (fgets(line, sizeof(line), f)) {
				p = line + strlen(line);
				while (p > line) {
					p--;
					if (*p > ' ')
						break;
					*p = 0;
				}
				p = line;
				while (*p && (*p <= ' '))
					p++;
				if (*p == '#')
					continue;
				if (*p == 0)
					continue;
				if (parse_ptn(&ptbl, p))
					return -1;
			}
			fclose(f);
		} else {	
			if (parse_ptn(&ptbl, argv[1]))
				return -1;
		}
		argc--;
		argv++;
	}

	n = crc32(0, Z_NULL, 0);
	n = crc32(n, (void*) ptbl.entry, sizeof(ptbl.entry));
	hdr->entries_crc32 = n;

	n = crc32(0, Z_NULL, 0);
	n = crc32(n, (void*) &ptbl.header, sizeof(ptbl.header));
	hdr->crc32 = n;

	show(&ptbl);

	if (real_disk) {
  		write(fd, &ptbl, sizeof(ptbl));
		fsync(fd);

		if (ioctl(fd, BLKRRPART, 0)) {
			fprintf(stderr,"could not re-read partition table\n");
		}
		close(fd);
	}
	return 0;
}
