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

📄 copy.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "stdinc.h"#include "dat.h"#include "fns.h"static int fast;static int quiet;VtSession *zsrc, *zdst;voidusage(void){	fprint(2, "usage: copy [-fq] src-host dst-host score [type]\n");	exits("usage");}intparseScore(uchar *score, char *buf, int n){	int i, c;	memset(score, 0, VtScoreSize);	if(n < VtScoreSize*2)		return 0;	for(i=0; i<VtScoreSize*2; i++) {		if(buf[i] >= '0' && buf[i] <= '9')			c = buf[i] - '0';		else if(buf[i] >= 'a' && buf[i] <= 'f')			c = buf[i] - 'a' + 10;		else if(buf[i] >= 'A' && buf[i] <= 'F')			c = buf[i] - 'A' + 10;		else {			return 0;		}		if((i & 1) == 0)			c <<= 4;		score[i>>1] |= c;	}	return 1;}voidwalk(uchar score[VtScoreSize], uint type, int base){	int i, n, sub;	uchar *buf;	VtEntry e;	VtRoot root;	if(memcmp(score, vtZeroScore, VtScoreSize) == 0)		return;	buf = vtMemAllocZ(VtMaxLumpSize);	if(fast && vtRead(zdst, score, type, buf, VtMaxLumpSize) >= 0){		if(!quiet)			fprint(2, "%V already exists on dst server; skipping.\n", score);		free(buf);		return;	}	n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);	/*	 * we usually see this at the end of a venti/copy of a vac tree:	 * warning: could not read block \	 * 0000000000000000000000000000000000000000 1: \	 * no block with that score exists	 * maybe it's harmless.	 */	if(n < 0){		fprint(2, "warning: could not read block %V %d: %R\n",			score, type);		return;	}	switch(type){	case VtRootType:		if(!vtRootUnpack(&root, buf)){			fprint(2, "warning: could not unpack root in %V %d\n", score, type);			break;		}		walk(root.score, VtDirType, 0);		walk(root.prev, VtRootType, 0);		break;	case VtDirType:		for(i=0; i<n/VtEntrySize; i++){			if(!vtEntryUnpack(&e, buf, i)){				fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);				continue;			}			if(!(e.flags & VtEntryActive))				continue;			if(e.flags&VtEntryDir)				base = VtDirType;			else				base = VtDataType;			if(e.depth == 0)				sub = base;			else				sub = VtPointerType0+e.depth-1;			walk(e.score, sub, base);		}		break;	case VtDataType:		break;	default:	/* pointers */		if(type == VtPointerType0)			sub = base;		else			sub = type-1;		for(i=0; i<n; i+=VtScoreSize)			if(memcmp(buf+i, vtZeroScore, VtScoreSize) != 0)				walk(buf+i, sub, base);		break;	}	if(!vtWrite(zdst, score, type, buf, n))		fprint(2, "warning: could not write block %V %d: %R\n", score, type);	free(buf);}voidmain(int argc, char *argv[]){	int type, n;	uchar score[VtScoreSize];	uchar *buf;	ARGBEGIN{	case 'f':		fast = 1;		break;	case 'q':		quiet = 1;		break;	default:		usage();		break;	}ARGEND	if(argc != 3 && argc != 4)		usage();	vtAttach();	fmtinstall('V', vtScoreFmt);	fmtinstall('R', vtErrFmt);	if(!parseScore(score, argv[2], strlen(argv[2])))		vtFatal("could not parse score: %s", vtGetError());	buf = vtMemAllocZ(VtMaxLumpSize);	zsrc = vtDial(argv[0], 0);	if(zsrc == nil)		vtFatal("could not dial src server: %R");	if(!vtConnect(zsrc, 0))		sysfatal("vtConnect src: %r");	zdst = vtDial(argv[1], 0);	if(zdst == nil)		vtFatal("could not dial dst server: %R");	if(!vtConnect(zdst, 0))		sysfatal("vtConnect dst: %r");	if(argc == 4){		type = atoi(argv[3]);		n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);		if(n < 0)			vtFatal("could not read block: %R");	}else{		for(type=0; type<VtMaxType; type++){			n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);			if(n >= 0)				break;		}		if(type == VtMaxType)			vtFatal("could not find block %V of any type", score);	}	walk(score, type, VtDirType);	if(!vtSync(zdst))		vtFatal("could not sync dst server: %R");	vtDetach();	exits(0);}

⌨️ 快捷键说明

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