⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 path.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <libsec.h>#include "iso9660.h"/* * Add the requisite path tables to the CD image. * They get put on the end once everything else is done. * We use the path table itself as a queue in the breadth-first * traversal of the tree.   * * The only problem with this is that the path table does not * store the lengths of the directories.  So we keep an explicit * map in an array in memory. */enum {	Big,	Little};static voidCrdpath(Cdimg *cd, Cpath *p){	p->namelen = Cgetc(cd);	if(p->namelen == 0) {		Crseek(cd, (Croffset(cd)+Blocksize-1)/Blocksize * Blocksize);		p->namelen = Cgetc(cd);		assert(p->namelen != 0);	}	p->xlen = Cgetc(cd);	assert(p->xlen == 0);	/* sanity, might not be true if we start using the extended fields */	Cread(cd, p->dloc, 4);	Cread(cd, p->parent, 2);	p->name[0] = '\0';	Crseek(cd, Croffset(cd)+p->namelen+p->xlen+(p->namelen&1));	/* skip name, ext data */}static voidwritepath(Cdimg *cd, Cdir *c, int parent, int size){/*	DO NOT UNCOMMENT THIS CODE.	This commented-out code is here only so that no one comes	along and adds it later.	The ISO 9660 spec is silent about whether path table entries	need to be padded so that they never cross block boundaries.	It would be reasonable to assume that they are like every other	data structure in the bloody spec; this code pads them out.	Empirically, though, they're NOT padded.  Windows NT and	derivatives are the only known current operating systems	that actually read these things.	int l;	l = 1+1+4+2+c->namelen;	if(Cwoffset(cd)/Blocksize != (Cwoffset(cd)+l)/Blocksize)		Cpadblock(cd);*/	Cputc(cd, c->namelen);	Cputc(cd, 0);	Cwrite(cd, c->dloc + (size==Little ? 0 : 4), 4);	(size==Little ? Cputnl : Cputnm)(cd, parent, 2);	Cwrite(cd, c->name, c->namelen);	if(c->namelen & 1)		Cputc(cd, 0);}static ulong*addlength(ulong *a, ulong x, int n){	if(n%128==0)		a = erealloc(a, (n+128)*sizeof a[0]);	a[n] = x;	return a;}static ulongwritepathtable(Cdimg *cd, ulong vdblock, int size){	int rp, wp;	uchar buf[Blocksize];	ulong bk, end, i, *len, n, rdoff, start;	Cdir *c;	Cpath p;	Creadblock(cd, buf, vdblock, Blocksize);	c = (Cdir*)(buf+offsetof(Cvoldesc, rootdir[0]));	rp = 0;	wp = 0;	len = nil;	start = cd->nextblock*Blocksize;	Cwseek(cd, start);	Crseek(cd, start);	writepath(cd, c, 1, size);	len = addlength(len, little(c->dlen, 4), wp);	wp++;	while(rp < wp) {		Crdpath(cd, &p);		n = (len[rp]+Blocksize-1)/Blocksize;		rp++;		bk = (size==Big ? big : little)(p.dloc, 4);		rdoff = Croffset(cd);		for(i=0; i<n; i++) {			Creadblock(cd, buf, bk+i, Blocksize);			c = (Cdir*)buf;			if(i != 0 && c->namelen == 1 && c->name[0] == '\0')	/* hit another directory; stop */				break;			while(c->len && c->namelen && (uchar*)c+c->len < buf+Blocksize) {				if((c->flags & 0x02) && (c->namelen > 1 || c->name[0] > '\001')) {	/* directory */					writepath(cd, c, rp, size);					len = addlength(len, little(c->dlen, 4), wp);					wp++;				}				c = (Cdir*)((uchar*)c+c->len);			}		}		Crseek(cd, rdoff);	}	end = Cwoffset(cd);	Cpadblock(cd);	return end-start;}static voidwritepathtablepair(Cdimg *cd, ulong vdblock){	ulong bloc, lloc, sz, sz2;	lloc = cd->nextblock;	sz = writepathtable(cd, vdblock, Little);	bloc = cd->nextblock;	sz2 = writepathtable(cd, vdblock, Big);	assert(sz == sz2);	setpathtable(cd, vdblock, sz, lloc, bloc);}voidwritepathtables(Cdimg *cd){	cd->pathblock = cd->nextblock;	writepathtablepair(cd, cd->iso9660pvd);	if(cd->flags & CDjoliet)		writepathtablepair(cd, cd->jolietsvd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -