/*
 * Initialize a fossil file system from an ISO9660 image already in the
 * file system.  This is a fairly bizarre thing to do, but it lets us generate
 * installation CDs that double as valid Plan 9 disk partitions.  
 * People having trouble booting the CD can just copy it into a disk
 * partition and you've got a working Plan 9 system.
 *
 * I've tried hard to keep all the associated cruft in this file.
 * If you deleted this file and cut out the three calls into it from flfmt.c,
 * no traces would remain.
 */

#include "stdinc.h"
#include "dat.h"
#include "fns.h"
#include "flfmt9660.h"
#include <bio.h>
#include <ctype.h>

static Biobuf *b;

enum{
	Tag = 0x96609660,
	Blocksize = 2048,
};

#pragma varargck type "s" uchar*
#pragma varargck type "L" uchar*
#pragma varargck type "B" uchar*
#pragma varargck type "N" uchar*
#pragma varargck type "C" uchar*
#pragma varargck type "D" uchar*

typedef struct Voldesc Voldesc;
struct Voldesc {
	uchar	magic[8];	/* 0x01, "CD001", 0x01, 0x00 */
	uchar	systemid[32];	/* system identifier */
	uchar	volumeid[32];	/* volume identifier */
	uchar	unused[8];	/* character set in secondary desc */
	uchar	volsize[8];	/* volume size */
	uchar	charset[32];
	uchar	volsetsize[4];	/* volume set size = 1 */
	uchar	volseqnum[4];	/* volume sequence number = 1 */
	uchar	blocksize[4];	/* logical block size */
	uchar	pathsize[8];	/* path table size */
	uchar	lpathloc[4];	/* Lpath */
	uchar	olpathloc[4];	/* optional Lpath */
	uchar	mpathloc[4];	/* Mpath */
	uchar	ompathloc[4];	/* optional Mpath */
	uchar	rootdir[34];	/* root directory */
	uchar	volsetid[128];	/* volume set identifier */
	uchar	publisher[128];
	uchar	prepid[128];	/* data preparer identifier */
	uchar	applid[128];	/* application identifier */
	uchar	notice[37];	/* copyright notice file */
	uchar	abstract[37];	/* abstract file */
	uchar	biblio[37];	/* bibliographic file */
	uchar	cdate[17];	/* creation date */
	uchar	mdate[17];	/* modification date */
	uchar	xdate[17];	/* expiration date */
	uchar	edate[17];	/* effective date */
	uchar	fsvers;		/* file system version = 1 */
};

typedef struct Cdir Cdir;
struct Cdir {
	uchar	len;
	uchar	xlen;
	uchar	dloc[8];
	uchar	dlen[8];
	uchar	date[7];
	uchar	flags;
	uchar	unitsize;
	uchar	gapsize;
	uchar	volseqnum[4];
	uchar	namelen;
	uchar	name[1];	/* chumminess */
};
#pragma varargck type "D" Cdir*

static int
Dfmt(Fmt *fmt)
{
	char buf[128];
	Cdir *c;

	c = va_arg(fmt->args, Cdir*);
	if(c->namelen == 1 && c->name[0] == '\0' || c->name[0] == '\001') {
		snprint(buf, sizeof buf, ".%s dloc %.4N dlen %.4N",
			c->name[0] ? "." : "", c->dloc, c->dlen);
	} else {
		snprint(buf, sizeof buf, "%.*C dloc %.4N dlen %.4N", c->namelen, c->name,
			c->dloc, c->dlen);
	}
	fmtstrcpy(fmt, buf);
	return 0;
}

static ulong
big(void *a, int n)
{
	uchar *p;
	ulong v;
	int i;

	p = a;
	v = 0;
	for(i=0; i<n; i++)
		v = (v<<8) | *p++;
	return v;
}

static ulong
little(void *a, int n)
{
	uchar *p;
	ulong v;
	int i;

	p = a;
	v = 0;
	for(i=0; i<n; i++)
		v |= (*p++<<(i*8));
	return v;
}

/* numbers in big or little endian. */
static int
BLfmt(Fmt *fmt)
{
	ulong v;
	uchar *p;
	char buf[20];

	p = va_arg(fmt->args, uchar*);

	if(!(fmt->flags&FmtPrec)) {
		fmtstrcpy(fmt, "*BL*");
		return 0;
	}

	if(fmt->r == 'B')
		v = big(p, fmt->prec);
	else
		v = little(p, fmt->prec);

	sprint(buf, "0x%.*lux", fmt->prec*2, v);
	fmt->flags &= ~FmtPrec;
	fmtstrcpy(fmt, buf);
	return 0;
}

/* numbers in both little and big endian */
static int
Nfmt(Fmt *fmt)
{
	char buf[100];
	uchar *p;

	p = va_arg(fmt->args, uchar*);

	sprint(buf, "%.*L %.*B", fmt->prec, p, fmt->prec, p+fmt->prec);
	fmt->flags &= ~FmtPrec;
	fmtstrcpy(fmt, buf);
	return 0;
}

static int
asciiTfmt(Fmt *fmt)
{
	char *p, buf[256];
	int i;

	p = va_arg(fmt->args, char*);
	for(i=0; i<fmt->prec; i++)
		buf[i] = *p++;
	buf[i] = '\0';
	for(p=buf+strlen(buf); p>buf && p[-1]==' '; p--)
		;
	p[0] = '\0';
	fmt->flags &= ~FmtPrec;
	fmtstrcpy(fmt, buf);
	return 0;
}

static void
ascii(void)
{
	fmtinstall('C', asciiTfmt);
}

static void
getsect(uchar *buf, int n)
{
	if(Bseek(b, n*2048, 0) != n*2048 || Bread(b, buf, 2048) != 2048)
{
abort();
		sysfatal("reading block at %,d: %r", n*2048);
}
}

static Header *h;
static int fd;
static char *file9660;
static int off9660;
static ulong startoff;
static ulong endoff;
static ulong fsoff;
static uchar root[2048];
static Voldesc *v;
static ulong iso9660start(Cdir*);
static void iso9660copydir(Fs*, File*, Cdir*);
static void iso9660copyfile(Fs*, File*, Cdir*);

void
iso9660init(int xfd, Header *xh, char *xfile9660, int xoff9660)
{
	uchar sect[2048], sect2[2048];

	fmtinstall('L', BLfmt);
	fmtinstall('B', BLfmt);
	fmtinstall('N', Nfmt);
	fmtinstall('D', Dfmt);

	fd = xfd;
	h = xh;
	file9660 = xfile9660;
	off9660 = xoff9660;

	if((b = Bopen(file9660, OREAD)) == nil)
		sysfatal("Bopen %s: %r", file9660);

	getsect(root, 16);
	ascii();

	v = (Voldesc*)root;
	if(memcmp(v->magic, "\x01CD001\x01\x00", 8) != 0)
		sysfatal("%s not a cd image", file9660);

	startoff = iso9660start((Cdir*)v->rootdir)*Blocksize;
	endoff = little(v->volsize, 4);	/* already in bytes */

	fsoff = off9660 + h->data*h->blockSize;
	if(fsoff > startoff)
		sysfatal("fossil data starts after cd data");
	if(off9660 + (vlong)h->end*h->blockSize < endoff)
		sysfatal("fossil data ends before cd data");
	if(fsoff%h->blockSize)
		sysfatal("cd offset not a multiple of fossil block size");

	/* Read "same" block via CD image and via Fossil image */
	getsect(sect, startoff/Blocksize);
	if(seek(fd, startoff-off9660, 0) < 0)
		sysfatal("cannot seek to first data sector on cd via fossil");
fprint(2, "look for %lud at %lud\n", startoff, startoff-off9660);
	if(readn(fd, sect2, Blocksize) != Blocksize)
		sysfatal("cannot read first data sector on cd via fossil");
	if(memcmp(sect, sect2, Blocksize) != 0)
		sysfatal("iso9660 offset is a lie %08lux %08lux", *(long*)sect, *(long*)sect2);
}

void
iso9660labels(Disk *disk, uchar *buf, void (*write)(int, u32int))
{
	ulong sb, eb, bn, lb, llb;
	Label l;
	int lpb;
	uchar sect[Blocksize];

	if(!diskReadRaw(disk, PartData, (startoff-fsoff)/h->blockSize, buf))
		sysfatal("disk read failed: %r");
	getsect(sect, startoff/Blocksize);
	if(memcmp(buf, sect, Blocksize) != 0)
		sysfatal("fsoff is wrong");

	sb = (startoff-fsoff)/h->blockSize;
	eb = (endoff-fsoff+h->blockSize-1)/h->blockSize;

	lpb = h->blockSize/LabelSize;

	/* for each reserved block, mark label */
	llb = ~0;
	l.type = BtData;
	l.state = BsAlloc;
	l.tag = Tag;
	l.epoch = 1;
	l.epochClose = ~(u32int)0;
	for(bn=sb; bn<eb; bn++){
		lb = bn/lpb;
		if(lb != llb){
			if(llb != ~0)
				(*write)(PartLabel, llb);
			memset(buf, 0, h->blockSize);
		}
		llb = lb;
		labelPack(&l, buf, bn%lpb);
	}
	if(llb != ~0)
		(*write)(PartLabel, llb);
}

void
iso9660copy(Fs *fs)
{
	File *root;

	root = fileOpen(fs, "/active");
	iso9660copydir(fs, root, (Cdir*)v->rootdir);
	fileDecRef(root);
	runlock(&fs->elk);
	if(!fsSnapshot(fs, nil, nil, 0))
		sysfatal("snapshot failed: %r");
	rlock(&fs->elk);
}

/*
 * The first block used is the first data block of the leftmost file in the tree.
 * (Just an artifact of how mk9660 works.)
 */
static ulong
iso9660start(Cdir *c)
{
	uchar sect[Blocksize];

	while(c->flags&2){
		getsect(sect, little(c->dloc, 4));
		c = (Cdir*)sect;
		c = (Cdir*)((uchar*)c+c->len);	/* skip dot */
		c = (Cdir*)((uchar*)c+c->len);	/* skip dotdot */
		/* oops: might happen if leftmost directory is empty or leftmost file is zero length! */
		if(little(c->dloc, 4) == 0)
			sysfatal("error parsing cd image or unfortunate cd image");	
	}
	return little(c->dloc, 4);
}

static void
iso9660copydir(Fs *fs, File *dir, Cdir *cd)
{
	ulong off, end, len;
	uchar sect[Blocksize], *esect, *p;
	Cdir *c;

	len = little(cd->dlen, 4);
	off = little(cd->dloc, 4)*Blocksize;
	end = off+len;
	esect = sect+Blocksize;

	for(; off<end; off+=Blocksize){
		getsect(sect, off/Blocksize);
		p = sect;
		while(p < esect){
			c = (Cdir*)p;
			if(c->len <= 0)
				break;
			if(c->namelen!=1 || c->name[0]>1)
				iso9660copyfile(fs, dir, c);
			p += c->len;
		}
	}
}

static char*
getname(uchar **pp)
{
	uchar *p;
	int l;

	p = *pp;
	l = *p;
	*pp = p+1+l;
	if(l == 0)
		return "";
	memmove(p, p+1, l);
	p[l] = 0;
	return (char*)p;
}

static char*
getcname(Cdir *c)
{
	uchar *up;
	char *p, *q;

	up = &c->namelen;
	p = getname(&up);
	for(q=p; *q; q++)
		*q = tolower(*q);
	return p;
}

static char
dmsize[12] =
{
	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
};

static ulong
getcdate(uchar *p)	/* yMdhmsz */
{
	Tm tm;
	int y, M, d, h, m, s, tz;

	y=p[0]; M=p[1]; d=p[2];
	h=p[3]; m=p[4]; s=p[5]; tz=p[6];
	USED(tz);
	if (y < 70)
		return 0;
	if (M < 1 || M > 12)
		return 0;
	if (d < 1 || d > dmsize[M-1])
		return 0;
	if (h > 23)
		return 0;
	if (m > 59)
		return 0;
	if (s > 59)
		return 0;

	memset(&tm, 0, sizeof tm);
	tm.sec = s;
	tm.min = m;
	tm.hour = h;
	tm.mday = d;
	tm.mon = M-1;
	tm.year = 1900+y;
	tm.zone[0] = 0;
	return tm2sec(&tm);
}

static int ind;

static void
iso9660copyfile(Fs *fs, File *dir, Cdir *c)
{
	Dir d;
	DirEntry de;
	int sysl;
	uchar score[VtScoreSize];
	ulong off, foff, len, mode;
	uchar *p;
	File *f;

	ind++;
	memset(&d, 0, sizeof d);
	p = c->name + c->namelen;
	if(((uintptr)p) & 1)
		p++;
	sysl = (uchar*)c + c->len - p;
	if(sysl <= 0)
		sysfatal("missing plan9 directory entry on %d/%d/%.*s", c->namelen, c->name[0], c->namelen, c->name);
	d.name = getname(&p);
	d.uid = getname(&p);
	d.gid = getname(&p);
	if((uintptr)p & 1)
		p++;
	d.mode = little(p, 4);
	if(d.name[0] == 0)
		d.name = getcname(c);
	d.mtime = getcdate(c->date);
	d.atime = d.mtime;

if(d.mode&DMDIR)	print("%*scopy %s %s %s %luo\n", ind*2, "", d.name, d.uid, d.gid, d.mode);

	mode = d.mode&0777;
	if(d.mode&DMDIR)
		mode |= ModeDir;
	if((f = fileCreate(dir, d.name, mode, d.uid)) == nil)
		sysfatal("could not create file '%s': %r", d.name);
	if(d.mode&DMDIR)
		iso9660copydir(fs, f, c);
	else{
		len = little(c->dlen, 4);
		off = little(c->dloc, 4)*Blocksize;
		for(foff=0; foff<len; foff+=h->blockSize){
			localToGlobal((off+foff-fsoff)/h->blockSize, score);
			if(!fileMapBlock(f, foff/h->blockSize, score, Tag))
				sysfatal("fileMapBlock: %r");
		}
		if(!fileSetSize(f, len))
			sysfatal("fileSetSize: %r");
	}
	if(!fileGetDir(f, &de))
		sysfatal("fileGetDir: %r");
	de.uid = d.uid;
	de.gid = d.gid;
	de.mtime = d.mtime;
	de.atime = d.atime;
	de.mode = d.mode&0777;
	if(!fileSetDir(f, &de, "sys"))
		sysfatal("fileSetDir: %r");
	fileDecRef(f);
	ind--;
}
