/*
 * 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+1] = '\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;
}
