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

📄 fdisk.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		return n<4;	}	/* 	 * secondary partitions can be inserted between two primary	 * partitions only if there is an empty primary slot.	 * otherwise, we can put a new secondary partition next	 * to a secondary partition no problem.	 */	n = 0;	for(i=0; i<edit->npart; i++){		p = (Dospart*)edit->part[i];		if(p->primary)			n++;		pend = p->end;		if(i+1<edit->npart){			q = (Dospart*)edit->part[i+1];			qstart = q->start;		}else{			qstart = edit->end;			q = nil;		}		if(start < pend || start >= qstart)			continue;		/* we go between these two */		if(p->primary==0 || (q && q->primary==0))			return 1;	}	/* not next to a secondary, need a new primary */	return n<4;}static voidautopart(Edit *edit){	char *err;	int active, i;	vlong bigstart, bigsize, start;	Dospart *p;	for(i=0; i<edit->npart; i++)		if(((Dospart*)edit->part[i])->type == Type9)			return;	/* look for the biggest gap in which we can put a primary partition */	start = 0;	bigsize = 0;	SET(bigstart);	for(i=0; i<edit->npart; i++) {		p = (Dospart*)edit->part[i];		if(p->start > start && p->start - start > bigsize && haveroom(edit, 1, start)) {			bigsize = p->start - start;			bigstart = start;		}		start = p->end;	}	if(edit->end - start > bigsize && haveroom(edit, 1, start)) {		bigsize = edit->end - start;		bigstart = start;	}	if(bigsize < 1) {		fprint(2, "couldn't find space or partition slot for plan 9 partition\n");		return;	}	/* set new partition active only if no others are */	active = Active;		for(i=0; i<edit->npart; i++)		if(((Dospart*)edit->part[i])->primary && (((Dospart*)edit->part[i])->active & Active))			active = 0;	/* add new plan 9 partition */	bigsize *= sec2cyl;	bigstart *= sec2cyl;	if(bigstart == 0) {		bigstart += edit->disk->s;		bigsize -= edit->disk->s;	}	p = mkpart(nil, 1, bigstart, bigsize, nil);	p->active = active;	p->changed = 1;	p->type = Type9;	edit->changed = 1;	if(err = addpart(edit, p)) {		fprint(2, "error adding plan9 partition: %s\n", err);		return;	}}typedef struct Name Name;struct Name {	char *name;	Name *link;};Name *namelist;static voidplan9print(Dospart *part, int fd){	int i, ok;	char *name, *vname;	Name *n;	vlong start, end;	char *sep;	vname = types[part->type].name;	if(vname==nil || strcmp(vname, "")==0) {		part->ctlname = "";		return;	}	start = mbroffset+part->lba;	end = start+part->size;	/* avoid names like plan90 */	i = strlen(vname) - 1;	if(vname[i] >= '0' && vname[i] <= '9')		sep = ".";	else		sep = "";	i = 0;	name = emalloc(strlen(vname)+10);	sprint(name, "%s", vname);	do {		ok = 1;		for(n=namelist; n; n=n->link) {			if(strcmp(name, n->name) == 0) {				i++;				sprint(name, "%s%s%d", vname, sep, i);				ok = 0;			}		}	} while(ok == 0);	n = emalloc(sizeof(*n));	n->name = name;	n->link = namelist;	namelist = n;	part->ctlname = name;	if(fd >= 0)		print("part %s %lld %lld\n", name, start, end);}static voidfreenamelist(void){	Name *n, *next;	for(n=namelist; n; n=next) {		next = n->link;		free(n);	}	namelist = nil;}static voidcmdprintctl(Edit *edit, int ctlfd){	int i;	freenamelist();	for(i=0; i<edit->npart; i++)		plan9print((Dospart*)edit->part[i], -1);	ctldiff(edit, ctlfd);}static char*cmdokname(Edit*, char *name){	char *q;	if(name[0] != 'p' && name[0] != 's')		return "name must be pN or sN";	strtol(name+1, &q, 10);	if(*q != '\0')		return "name must be pN or sN";	return nil;}#define GB (1024*1024*1024)#define MB (1024*1024)#define KB (1024)static voidcmdsum(Edit *edit, Part *vp, vlong a, vlong b){	char *name, *ty;	char buf[3];	char *suf;	Dospart *p;	vlong sz, div;	p = (Dospart*)vp;	buf[0] = p && p->changed ? '\'' : ' ';	buf[1] = p && (p->active & Active) ? '*' : ' ';	buf[2] = '\0';	name = p ? p->name : "empty";	ty = p ? typestr0(p->type) : "";	sz = (b-a)*edit->disk->secsize*sec2cyl;	if(sz >= 1*GB){		suf = "GB";		div = GB;	}else if(sz >= 1*MB){		suf = "MB";		div = MB;	}else if(sz >= 1*KB){		suf = "KB";		div = KB;	}else{		suf = "B ";		div = 1;	}	if(div == 1)		print("%s %-12s %*lld %-*lld (%lld cylinders, %lld %s) %s\n", buf, name,			edit->disk->width, a, edit->disk->width, b, b-a, sz, suf, ty);	else		print("%s %-12s %*lld %-*lld (%lld cylinders, %lld.%.2d %s) %s\n", buf, name,			edit->disk->width, a, edit->disk->width, b,  b-a,			sz/div, (int)(((sz%div)*100)/div), suf, ty);}static char*cmdadd(Edit *edit, char *name, vlong start, vlong end){	Dospart *p;	if(!haveroom(edit, name[0]=='p', start))		return "no room for partition";	start *= sec2cyl;	end *= sec2cyl;	if(start == 0 || name[0] != 'p')		start += edit->disk->s;	p = mkpart(name, name[0]=='p', start, end-start, nil);	p->changed = 1;	p->type = Type9;	return addpart(edit, p);}static char*cmddel(Edit *edit, Part *p){	return delpart(edit, p);}static char*cmdwrite(Edit *edit){	wrpart(edit);	return nil;}static char *help = 	"A name - set partition active\n"	"P - print table in ctl format\n"	"R - restore disk back to initial configuration and exit\n"	"e - show empty dos partitions\n"	"t name [type] - set partition type\n";static char*cmdhelp(Edit*){	print("%s\n", help);	return nil;}static char*cmdactive(Edit *edit, int nf, char **f){	int i;	Dospart *p, *ip;	if(nf != 2)		return "args";	if(f[1][0] != 'p')		return "cannot set secondary partition active";	if((p = (Dospart*)findpart(edit, f[1])) == nil)		return "unknown partition";	for(i=0; i<edit->npart; i++) {		ip = (Dospart*)edit->part[i];		if(ip->active & Active) {			ip->active &= ~Active;			ip->changed = 1;			edit->changed = 1;		}	}	if((p->active & Active) == 0) {		p->active |= Active;		p->changed = 1;		edit->changed = 1;	}	return nil;}static char*strupr(char *s){	char *p;	for(p=s; *p; p++)		*p = toupper(*p);	return s;}static voiddumplist(void){	int i, n;	n = 0;	for(i=0; i<256; i++) {		if(types[i].desc) {			print("%-16s", types[i].desc);			if(n++%4 == 3)				print("\n");		}	}	if(n%4)		print("\n");}static char*cmdtype(Edit *edit, int nf, char **f){	char *q;	Dospart *p;	int i;	if(nf < 2)		return "args";	if((p = (Dospart*)findpart(edit, f[1])) == nil)		return "unknown partition";	if(nf == 2) {		for(;;) {			fprint(2, "new partition type [? for list]: ");			q = getline(edit);			if(q[0] == '?')				dumplist();			else				break;		}	} else		q = f[2];	strupr(q);	for(i=0; i<256; i++)		if(types[i].desc && strcmp(types[i].desc, q) == 0)			break;	if(i < 256 && p->type != i) {		p->type = i;		p->changed = 1;		edit->changed = 1;	}	return nil;}static char*cmdext(Edit *edit, int nf, char **f){	switch(f[0][0]) {	case 'A':		return cmdactive(edit, nf, f);	case 't':		return cmdtype(edit, nf, f);	case 'R':		recover(edit);		return nil;	default:		return "unknown command";	}}static intDfmt(Fmt *f){	char buf[60];	uchar *p;	int c, h, s;	p = va_arg(f->args, uchar*);	h = p[0];	c = p[2];	c |= (p[1]&0xC0)<<2;	s = (p[1] & 0x3F);	sprint(buf, "%d/%d/%d", c, h, s);	return fmtstrcpy(f, buf);}static voidwritechs(Disk *disk, uchar *p, vlong lba){	int c, h, s;	s = lba % disk->s;	h = (lba / disk->s) % disk->h;	c = lba / (disk->s * disk->h);	if(c >= 1024) {		c = 1023;		h = disk->h - 1;		s = disk->s - 1;	}	p[0] = h;	p[1] = ((s+1) & 0x3F) | ((c>>2) & 0xC0);	p[2] = c;}static voidwrtentry(Disk *disk, Tentry *tp, int type, u32int xbase, u32int lba, u32int end){	tp->type = type;	writechs(disk, &tp->starth, lba);	writechs(disk, &tp->endh, end-1);	putle32(tp->xlba, lba-xbase);	putle32(tp->xsize, end-lba);}static intwrextend(Edit *edit, int i, vlong xbase, vlong startlba, vlong *endlba){	int ni;	Table table;	Tentry *tp, *ep;	Dospart *p;	Disk *disk;	if(i == edit->npart){		*endlba = edit->disk->secs;	Finish:		if(startlba < *endlba){			disk = edit->disk;			diskread(disk, &table, sizeof table, mbroffset+startlba, Toffset);			tp = table.entry;			ep = tp+NTentry;			for(; tp<ep; tp++)				memset(tp, 0, sizeof *tp);			table.magic[0] = Magic0;			table.magic[1] = Magic1;			if(diskwrite(edit->disk, &table, sizeof table, mbroffset+startlba, Toffset) < 0)				recover(edit);		}		return i;	}	p = (Dospart*)edit->part[i];	if(p->primary){		*endlba = (vlong)p->start*sec2cyl;		goto Finish;	}	disk = edit->disk;	diskread(disk, &table, sizeof table, mbroffset+startlba, Toffset);	tp = table.entry;	ep = tp+NTentry;	ni = wrextend(edit, i+1, xbase, p->end*sec2cyl, endlba);	*tp = p->Tentry;	wrtentry(disk, tp, p->type, startlba, startlba+disk->s, p->end*sec2cyl);	tp++;	if(p->end*sec2cyl != *endlba){		memset(tp, 0, sizeof *tp);		wrtentry(disk, tp, TypeEXTENDED, xbase, p->end*sec2cyl, *endlba);		tp++;	}	for(; tp<ep; tp++)		memset(tp, 0, sizeof *tp);	table.magic[0] = Magic0;	table.magic[1] = Magic1;	if(diskwrite(edit->disk, &table, sizeof table, mbroffset+startlba, Toffset) < 0)		recover(edit);	return ni;}	static voidwrpart(Edit *edit){		int i, ni, t;	Table table;	Tentry *tp, *ep;	Disk *disk;	vlong s, endlba;	Dospart *p;	disk = edit->disk;	diskread(disk, &table, sizeof table, mbroffset, Toffset);	tp = table.entry;	ep = tp+NTentry;	for(i=0; i<edit->npart && tp<ep; ) {		p = (Dospart*)edit->part[i];		if(p->start == 0)			s = disk->s;		else			s = p->start*sec2cyl;		if(p->primary) {			*tp = p->Tentry;			wrtentry(disk, tp, p->type, 0, s, p->end*sec2cyl);			tp++;			i++;		} else {			ni = wrextend(edit, i, p->start*sec2cyl, p->start*sec2cyl, &endlba);			memset(tp, 0, sizeof *tp);			if(endlba >= 1024*sec2cyl)				t = TypeEXTHUGE;			else				t = TypeEXTENDED;			wrtentry(disk, tp, t, 0, s, endlba);			tp++;			i = ni;		}	}	for(; tp<ep; tp++)		memset(tp, 0, sizeof(*tp));			if(i != edit->npart)		sysfatal("cannot happen #1");	if(diskwrite(disk, &table, sizeof table, mbroffset, Toffset) < 0)		recover(edit);	/* bring parts up to date */	freenamelist();	for(i=0; i<edit->npart; i++)		plan9print((Dospart*)edit->part[i], -1);	if(ctldiff(edit, disk->ctlfd) < 0)		fprint(2, "?warning: partitions could not be updated in devsd\n");}

⌨️ 快捷键说明

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