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

📄 dump9660.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <disk.h>#include <libsec.h>#include "iso9660.h"ulong now;int chatty;int doabort;int docolon;int mk9660;int dataoffset;int blocksize;Conform *map;static void addprotofile(char *new, char *old, Dir *d, void *a);void usage(void);char *argv0;voidusage(void){	if(mk9660)		fprint(2, "usage: disk/mk9660 [-D:] [-9cjr] [-b bootfile] [-o offset blocksize] [-p proto] [-s src] cdimage\n");	else		fprint(2, "usage: disk/dump9660 [-D:] [-9cjr] [-m maxsize] [-n now] [-p proto] [-s src] cdimage\n");	exits("usage");}intmain(int argc, char **argv){	int fix;	char buf[256], *dumpname, *proto, *s, *src, *status;	ulong block, length, newnull, cblock, clength, maxsize;	Cdimg *cd;	Cdinfo info;	XDir dir;	Direc *iconform, idumproot, iroot, *jconform, jdumproot, jroot, *r;	Dump *dump;	fix = 0;	status = nil;	memset(&info, 0, sizeof info);	proto = "/sys/lib/sysconfig/proto/allproto";	src = "./";	info.volumename = atom("9CD");	info.volumeset = atom("9VolumeSet");	info.publisher = atom("9Publisher");	info.preparer = atom("dump9660");	info.application = atom("dump9660");	info.flags = CDdump;	maxsize = 0;	mk9660 = 0;	fmtinstall('H', encodefmt);	ARGBEGIN{	case 'D':		chatty++;		break;	case 'M':		mk9660 = 1;		argv0 = "disk/mk9660";		info.flags &= ~CDdump;		break;	case '9':		info.flags |= CDplan9;		break;	case ':':		docolon = 1;		break;	case 'a':		doabort = 1;		break;	case 'b':		if(!mk9660)			usage();		info.flags |= CDbootable;		info.bootimage = EARGF(usage());		break;	case 'c':		info.flags |= CDconform;		break;	case 'f':		fix = 1;		break;	case 'j':		info.flags |= CDjoliet;		break;	case 'n':		now = atoi(EARGF(usage()));		break;	case 'm':		maxsize = strtoul(EARGF(usage()), 0, 0);		break;	case 'o':		dataoffset = atoi(EARGF(usage()));		blocksize = atoi(EARGF(usage()));		if(blocksize%Blocksize)			sysfatal("bad block size %d -- must be multiple of 2048", blocksize);		blocksize /= Blocksize;		break;	case 'p':		proto = EARGF(usage());		break;	case 'r':		info.flags |= CDrockridge;		break;	case 's':		src = EARGF(usage());		break;	case 'v':		info.volumename = atom(EARGF(usage()));		break;	default:		usage();	}ARGEND	if(mk9660 && (fix || now || maxsize))		usage();	if(argc != 1)		usage();	if(now == 0)		now = (ulong)time(0);	if(mk9660){		if((cd = createcd(argv[0], info)) == nil)			sysfatal("cannot create '%s': %r", argv[0]);	}else{		if((cd = opencd(argv[0], info)) == nil)			sysfatal("cannot open '%s': %r", argv[0]);		if(!(cd->flags & CDdump))			sysfatal("not a dump cd");	}	/* create ISO9660/Plan 9 tree in memory */	memset(&dir, 0, sizeof dir);	dir.name = atom("");	dir.uid = atom("sys");	dir.gid = atom("sys");	dir.uidno = 0;	dir.gidno = 0;	dir.mode = DMDIR | 0755;	dir.mtime = now;	dir.atime = now;	dir.ctime = now;	mkdirec(&iroot, &dir);	iroot.srcfile = src;	/*	 * Read new files into memory	 */	if(rdproto(proto, src, addprotofile, nil, &iroot) < 0)		sysfatal("rdproto: %r");	if(mk9660){		dump = emalloc(sizeof *dump);		dumpname = nil;	}else{		/*		 * Read current dump tree and _conform.map.		 */		idumproot = readdumpdirs(cd, &dir, isostring);		readdumpconform(cd);		if(cd->flags & CDjoliet)			jdumproot = readdumpdirs(cd, &dir, jolietstring);		if(fix){			dumpname = nil;			cd->nextblock = cd->nulldump+1;			cd->nulldump = 0;			Cwseek(cd, cd->nextblock*Blocksize);			goto Dofix;		}			dumpname = adddumpdir(&idumproot, now, &dir);		/* note that we assume all names are conforming and thus sorted */		if(cd->flags & CDjoliet) {			s = adddumpdir(&jdumproot, now, &dir);			if(s != dumpname)				sysfatal("dumpnames don't match %s %s\n", dumpname, s);		}		dump = dumpcd(cd, &idumproot);		cd->nextblock = cd->nulldump+1;	}	/*	 * Write new files, starting where the dump tree was. 	 * Must be done before creation of the Joliet tree so that 	 * blocks and lengths are correct.	 */	if(dataoffset > cd->nextblock*Blocksize)		cd->nextblock = (dataoffset+Blocksize-1)/Blocksize;	Cwseek(cd, cd->nextblock*Blocksize);	writefiles(dump, cd, &iroot);	if(cd->bootimage){		findbootimage(cd, &iroot);		Cupdatebootcat(cd);	}			/* create Joliet tree */	if(cd->flags & CDjoliet)		copydirec(&jroot, &iroot);	if(info.flags & CDconform) {		checknames(&iroot, isbadiso9660);		convertnames(&iroot, struprcpy);	} else		convertnames(&iroot, (void *) strcpy);//	isoabstract = findconform(&iroot, abstract);//	isobiblio = findconform(&iroot, biblio);//	isonotice = findconform(&iroot, notice);	dsort(&iroot, isocmp);	if(cd->flags & CDjoliet) {	//	jabstract = findconform(&jroot, abstract);	//	jbiblio = findconform(&jroot, biblio);	//	jnotice = findconform(&jroot, notice);		checknames(&jroot, isbadjoliet);		convertnames(&jroot, (void *) strcpy);		dsort(&jroot, jolietcmp);	}	/*	 * Write directories.	 */	writedirs(cd, &iroot, Cputisodir);	if(cd->flags & CDjoliet)		writedirs(cd, &jroot, Cputjolietdir);	if(mk9660){		cblock = 0;		clength = 0;		newnull = 0;	}else{		/*		 * Write incremental _conform.map block.		 */		wrconform(cd, cd->nconform, &cblock, &clength);			/* jump here if we're just fixing up the cd */Dofix:		/*		 * Write null dump header block; everything after this will be 		 * overwritten at the next dump.  Because of this, it needs to be		 * reconstructable.  We reconstruct the _conform.map and dump trees		 * from the header blocks in dump.c, and we reconstruct the path 		 * tables by walking the cd.		 */		newnull = Cputdumpblock(cd);	}	/*	 * Write _conform.map.	 */	dir.mode = 0444;	if(cd->flags & (CDconform|CDjoliet)) {		if(!mk9660 && cd->nconform == 0){			block = cblock;				length = clength;		}else			wrconform(cd, 0, &block, &length);		if(mk9660) {			idumproot = iroot;			jdumproot = jroot;		}		if(length) {			/* The ISO9660 name will get turned into uppercase when written. */			if((iconform = walkdirec(&idumproot, "_conform.map")) == nil)				iconform = adddirec(&idumproot, "_conform.map", &dir);			jconform = nil;			if(cd->flags & CDjoliet) {				if((jconform = walkdirec(&jdumproot, "_conform.map")) == nil)					jconform = adddirec(&jdumproot, "_conform.map", &dir);			}			iconform->block = block;			iconform->length = length;			if(cd->flags & CDjoliet) {				jconform->block = block;				jconform->length = length;			}		}		if(mk9660) {			iroot = idumproot;			jroot = jdumproot;		}	}	if(mk9660){		/*		 * Patch in root directories.		 */		setroot(cd, cd->iso9660pvd, iroot.block, iroot.length);		setvolsize(cd, cd->iso9660pvd, cd->nextblock*Blocksize);		if(cd->flags & CDjoliet){			setroot(cd, cd->jolietsvd, jroot.block, jroot.length);			setvolsize(cd, cd->jolietsvd, cd->nextblock*Blocksize);		}	}else{		/*		 * Write dump tree at end.  We assume the name characters		 * are all conforming, so everything is already sorted properly.		 */		convertnames(&idumproot, (info.flags & CDconform) ? (void *) struprcpy : (void *) strcpy);		if(cd->nulldump) {			r = walkdirec(&idumproot, dumpname);			assert(r != nil);			copybutname(r, &iroot);		}		if(cd->flags & CDjoliet) {			convertnames(&jdumproot, (void *) strcpy);			if(cd->nulldump) {				r = walkdirec(&jdumproot, dumpname);				assert(r != nil);				copybutname(r, &jroot);			}		}			writedumpdirs(cd, &idumproot, Cputisodir);		if(cd->flags & CDjoliet)			writedumpdirs(cd, &jdumproot, Cputjolietdir);			/*		 * Patch in new root directory entry.		 */		setroot(cd, cd->iso9660pvd, idumproot.block, idumproot.length);		setvolsize(cd, cd->iso9660pvd, cd->nextblock*Blocksize);		if(cd->flags & CDjoliet){			setroot(cd, cd->jolietsvd, jdumproot.block, jdumproot.length);			setvolsize(cd, cd->jolietsvd, cd->nextblock*Blocksize);		}	}	writepathtables(cd);		if(!mk9660){		/*		 * If we've gotten too big, truncate back to what we started with,		 * fix up the cd, and exit with a non-zero status.		 */		Cwflush(cd);		if(cd->nulldump && maxsize && Cwoffset(cd) > maxsize){			fprint(2, "too big; writing old tree back\n");			status = "cd too big; aborted";				rmdumpdir(&idumproot, dumpname);			rmdumpdir(&jdumproot, dumpname);				cd->nextblock = cd->nulldump+1;			cd->nulldump = 0;			Cwseek(cd, cd->nextblock*Blocksize);			goto Dofix;		}			/*		 * Write old null header block; this commits all our changes.		 */		if(cd->nulldump){			Cwseek(cd, cd->nulldump*Blocksize);			sprint(buf, "plan 9 dump cd\n");			sprint(buf+strlen(buf), "%s %lud %lud %lud %lud %lud %lud",				dumpname, now, newnull, cblock, clength, iroot.block,				iroot.length);			if(cd->flags & CDjoliet)				sprint(buf+strlen(buf), " %lud %lud",					jroot.block, jroot.length);			strcat(buf, "\n");			Cwrite(cd, buf, strlen(buf));			Cpadblock(cd);			Cwflush(cd);		}	}	fdtruncate(cd->fd, cd->nextblock*Blocksize);	exits(status);	return 0;}static voidaddprotofile(char *new, char *old, Dir *d, void *a){	char *name, *p;	Direc *direc;	XDir xd;	dirtoxdir(&xd, d);	name = nil;	if(docolon && strchr(new, ':')) {		name = emalloc(strlen(new)+1);		strcpy(name, new);		while((p=strchr(name, ':')))			*p=' ';		new = name;	}	if((direc = adddirec((Direc*)a, new, &xd))) {		direc->srcfile = atom(old);		// BUG: abstract, biblio, notice	}	if(name)		free(name);}

⌨️ 快捷键说明

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