/*
 * old (V6 and before) PDP-11 Unix filesystem
 */
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include "tapefs.h"

/*
 * v6 disk inode
 */
#define	V6NADDR	8
#define	V6FMT	0160000
#define	V6IFREG	0100000
#define	V6IFDIR	0140000
#define	V6IFCHR	0120000
#define	V6IFBLK	0160000
#define	V6MODE	0777
#define	V6LARGE	010000
#define	V6SUPERB	1
#define	V6ROOT		1	/* root inode */
#define	V6NAMELEN	14
#define	BLSIZE	512
#define	LINOPB	(BLSIZE/sizeof(struct v6dinode))
#define	LNINDIR	(BLSIZE/sizeof(unsigned short))

struct v6dinode {
	unsigned char flags[2];
	unsigned char nlinks;
	unsigned char uid;
	unsigned char gid;
	unsigned char hisize;
	unsigned char losize[2];
	unsigned char addr[V6NADDR][2];
	unsigned char atime[4];	/* pdp-11 order */
	unsigned char mtime[4];	/* pdp-11 order */
};

struct	v6dir {
	uchar	ino[2];
	char	name[V6NAMELEN];
};

int	tapefile;
Fileinf	iget(int ino);
long	bmap(Ram *r, long bno);
void	getblk(Ram *r, long bno, char *buf);

void
populate(char *name)
{
	Fileinf f;

	replete = 0;
	tapefile = open(name, OREAD);
	if (tapefile<0)
		error("Can't open argument file");
	f = iget(V6ROOT);
	ram->perm = f.mode;
	ram->mtime = f.mdate;
	ram->addr = f.addr;
	ram->data = f.data;
	ram->ndata = f.size;
}

void
popdir(Ram *r)
{
	int i, ino;
	char *cp;
	struct v6dir *dp;
	Fileinf f;
	char name[V6NAMELEN+1];

	cp = 0;
	for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
		if (i%BLSIZE==0)
			cp = doread(r, i, BLSIZE);
		dp = (struct v6dir *)(cp+i%BLSIZE);
		ino = dp->ino[0] + (dp->ino[1]<<8);
		if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
			continue;
		if (ino==0)
			continue;
		f = iget(ino);
		strncpy(name, dp->name, V6NAMELEN);
		name[V6NAMELEN] = '\0';
		f.name = name;
		popfile(r, f);
	}
	r->replete = 1;
}

void
dotrunc(Ram *r)
{
	USED(r);
}

void
docreate(Ram *r)
{
	USED(r);
}

char *
doread(Ram *r, vlong off, long cnt)
{
	static char buf[Maxbuf+BLSIZE];
	int bno, i;

	bno = off/BLSIZE;
	off -= bno*BLSIZE;
	if (cnt>Maxbuf)
		error("count too large");
	if (off)
		cnt += off;
	i = 0;
	while (cnt>0) {
		getblk(r, bno, &buf[i*BLSIZE]);
		cnt -= BLSIZE;
		bno++;
		i++;
	}
	return buf;
}

void
dowrite(Ram *r, char *buf, long off, long cnt)
{
	USED(r); USED(buf); USED(off); USED(cnt);
}

int
dopermw(Ram *r)
{
	USED(r);
	return 0;
}

/*
 * fetch an i-node
 * -- no sanity check for now
 * -- magic inode-to-disk-block stuff here
 */

Fileinf
iget(int ino)
{
	char buf[BLSIZE];
	struct v6dinode *dp;
	long flags, i;
	Fileinf f;

	memset(&f, 0, sizeof f);
	seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
	if (read(tapefile, buf, BLSIZE) != BLSIZE)
		error("Can't read inode");
	dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
	flags = (dp->flags[1]<<8) + dp->flags[0];
	f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
	if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
		f.size = 0;
	f.data = emalloc(V6NADDR*sizeof(ushort));
	for (i = 0; i < V6NADDR; i++)
		((ushort*)f.data)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
	f.mode = flags & V6MODE;
	if ((flags&V6FMT)==V6IFDIR)
		f.mode |= DMDIR;
	f.uid = dp->uid;
	f.gid = dp->gid;	
	f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
	     +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
	return f;
}

void
getblk(Ram *r, long bno, char *buf)
{
	long dbno;

	if ((dbno = bmap(r, bno)) == 0) {
		memset(buf, 0, BLSIZE);
		return;
	}
	seek(tapefile, dbno*BLSIZE, 0);
	if (read(tapefile, buf, BLSIZE) != BLSIZE)
		error("bad read");
}

/*
 * logical to physical block
 * only singly-indirect files for now
 */

long
bmap(Ram *r, long bno)
{
	unsigned char indbuf[LNINDIR][2];

	if (r->ndata <= V6NADDR*BLSIZE) {	/* assume size predicts largeness of file */
		if (bno < V6NADDR)
			return ((ushort*)r->data)[bno];
		return 0;
	}
	if (bno < V6NADDR*LNINDIR) {
		seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0);
		if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
			return 0;
		return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
	}
	return 0;
}
