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

📄 part.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			sectors= geometry.sectors;			precise= 1;		}	} else {		err= ENODEV;	}	if (err != 0) {		/* Getting the geometry from the driver failed, so use the		 * alternate geometry.		 */		if (alt_heads == 0) {			alt_cyls= table[0].size / (64 * 32);			alt_heads= 64;			alt_secs= 32;		}		cylinders= alt_cyls;		heads= alt_heads;		sectors= alt_secs;		stat_start(1);		printf("Failure to get the geometry of %s: %s", curdev->name,			errno == ENOTTY ? "No driver support" : strerror(err));		stat_end(5);		stat_start(0);		printf("The geometry has been guessed as %ux%ux%u",						cylinders, heads, sectors);		stat_end(5);	} else {		if (alt_heads == 0) {			alt_cyls= cylinders;			alt_heads= heads;			alt_secs= sectors;		}		if (heads != alt_heads || sectors != alt_secs) {			stat_start(1);			printf("WARNING:");			stat_end(10);			stat_start(0);			printf("The %ux%ux%u geometry obtained from the device driver does not match",				cylinders, heads, sectors);			stat_end(10);			stat_start(0);			printf("the %ux%ux%u geometry implied by the partition table.  Hit 'X' to switch",				alt_cyls, alt_heads, alt_secs);			stat_end(10);			stat_start(0);			printf("between the two geometries to see what is best.  Note that the geometry");			stat_end(10);			stat_start(0);			printf("must be correct when the table is written or the system may not boot!");			stat_end(10);		}	}	/* Show the base and size of the device instead of the whole drive.	 * This makes sense for subpartitioning primary partitions.	 */	if (precise && ioctl(device, DIOCGETP, &geometry) >= 0) {		table[0].lowsec= div64u(geometry.base, SECTOR_SIZE);		table[0].size= div64u(geometry.size, SECTOR_SIZE);	} else {		precise= 0;	}	recompute0();	sort();}typedef struct indicators {	/* Partition type to partition name. */	unsigned char	ind;	char		name[10];} indicators_t;indicators_t ind_table[]= {	{ NO_PART,	"None"		},	{ 0x01,		"DOS-12"	},	{ 0x02,		"XENIX /"	},	{ 0x03,		"XENIX usr"	},	{ 0x04,		"DOS-16"	},	{ 0x05,		"DOS-EXT"	},	{ 0x06,		"DOS-BIG"	},	{ 0x07,		"HPFS/NTFS"	},	{ 0x08,		"AIX"		},	{ 0x09,		"COHERENT"	},	{ 0x0A,		"OS/2"		},	{ 0x10,		"OPUS"		},	{ 0x40,		"VENIX286"	},	{ 0x52,		"MICROPORT"	},	{ 0x63,		"386/IX"	},	{ 0x64,		"NOVELL286"	},	{ 0x65,		"NOVELL386"	},	{ 0x75,		"PC/IX"		},	{ 0x80,		"MINIX-OLD"	},	{ 0x81,		"MINIX"		},	{ 0x82,		"LINUXswap"	},	{ 0x83,		"LINUX"		},	{ 0x93,		"AMOEBA"	},	{ 0x94,		"AMOEBAbad"	},	{ 0xA5,		"386BSD"	},	{ 0xB7,		"BSDI"		},	{ 0xB8,		"BSDI swap"	},	{ 0xC7,		"SYRINX"	},	{ 0xDB,		"CPM"		},	{ 0xFF,		"BADBLOCKS"	},};char *typ2txt(int ind)/* Translate a numeric partition indicator for human eyes. */{	indicators_t *pind;	for (pind= ind_table; pind < arraylimit(ind_table); pind++) {		if (pind->ind == ind) return pind->name;	}	return "";}int round_sysind(int ind, int delta)/* Find the next known partition type starting with ind in direction delta. */{	indicators_t *pind;	ind= (ind + delta) & 0xFF;	if (delta < 0) {		for (pind= arraylimit(ind_table)-1; pind->ind > ind; pind--) {}	} else {		for (pind= ind_table; pind->ind < ind; pind++) {}	}	return pind->ind;}/* Objects on the screen, either simple pieces of the text or the cylinder * number of the start of partition three. */typedef enum objtype {	O_INFO, O_TEXT, O_DEV, O_SUB,	O_TYPTXT, O_SORT, O_NUM, O_TYPHEX,	O_CYL, O_HEAD, O_SEC,	O_SCYL, O_SHEAD, O_SSEC, O_LCYL, O_LHEAD, O_LSEC, O_BASE, O_SIZE, O_KB} objtype_t;#define ljust(type)	((type) <= O_TYPTXT)#define center(type)	((type) == O_SORT)#define rjust(type)	((type) >= O_NUM)#define computed(type)	((type) >= O_TYPTXT)typedef struct object {	struct object	*next;	objtype_t	type;		/* Text field, cylinder number, etc. */	char		flags;		/* Modifiable? */	char		row;	char		col;	char		len;	struct part_entry *entry;	/* What does the object refer to? */	char		  *text;	char		value[20];	/* Value when printed. */} object_t;#define OF_MOD		0x01	/* Object value is modifiable. */#define OF_ODD		0x02	/* It has a somewhat odd value. */#define OF_BAD		0x04	/* Its value is no good at all. *//* Events: (Keypress events are the value of the key pressed.) */#define E_ENTER		(-1)	/* Cursor moves onto object. */#define E_LEAVE		(-2)	/* Cursor leaves object. */#define E_WRITE		(-3)	/* Write, but not by typing 'w'. *//* The O_SIZE objects have a dual identity. */enum howend { SIZE, LAST } howend= SIZE;object_t *world= nil;object_t *curobj= nil;object_t *newobject(objtype_t type, int flags, int row, int col, int len)/* Make a new object given a type, flags, position and length on the screen. */{	object_t *new;	object_t **aop= &world;	new= alloc(sizeof(*new));	new->type= type;	new->flags= flags;	new->row= row;	new->col= col;	new->len= len;	new->entry= nil;	new->text= "";	new->value[0]= 0;	new->next= *aop;	*aop= new;	return new;}unsigned long entry2base(struct part_entry *pe)/* Return the base sector of the partition if defined. */{	return pe->sysind == NO_PART ? 0 : pe->lowsec;}unsigned long entry2last(struct part_entry *pe){	return pe->sysind == NO_PART ? -1 : pe->lowsec + pe->size - 1;}unsigned long entry2size(struct part_entry *pe){	return pe->sysind == NO_PART ? 0 : pe->size;}int overlap(unsigned long sec)/* See if sec is part of another partition. */{	struct part_entry *pe;	for (pe= table + 1; pe <= table + NR_PARTITIONS; pe++) {		if (pe->sysind == NO_PART) continue;		if (pe->lowsec < sec && sec < pe->lowsec + pe->size)			return 1;	}	return 0;}int aligned(unsigned long sec, unsigned unit)/* True if sec is aligned to unit or if it is no problem if it is unaligned. */{	return (offset != 0 && extbase == 0) || (sec % unit == 0);}void print(object_t *op)/* Print an object's value if it changed. */{	struct part_entry *pe= op->entry;	int n;	unsigned long t;	char *name;	int oldflags;	char oldvalue[20];	/* Remember the old flags and value. */	oldflags= op->flags;	strcpy(oldvalue, op->value);	op->flags&= ~(OF_ODD | OF_BAD);	switch (op->type) {	case O_INFO:		{				/* Current field. */		static struct field { int type; char *name; } fields[]= {			{ O_DEV,	"Select device"		},			{ O_NUM,	"Active flag"		},			{ O_TYPHEX,	"Hex partition type"	},			{ O_TYPTXT,	"Partition type"	},			{ O_SCYL,	"Start cylinder"	},			{ O_SHEAD,	"Start head"		},			{ O_SSEC,	"Start sector"		},			{ O_CYL,	"Number of cylinders"	},			{ O_HEAD,	"Number of heads"	},			{ O_SEC,	"Sectors per track"	},			{ O_LCYL,	"Last cylinder"		},			{ O_LHEAD,	"Last head"		},			{ O_LSEC,	"Last sector"		},			{ O_BASE,	"Base sector"		},			{ O_SIZE,	"Size in sectors"	},			{ O_KB,		"Size in kilobytes"	},			{ -1,		"?"			},		};		struct field *fp= fields;		while (fp->type >= 0 && fp->type != curobj->type) fp++;		strcpy(op->value, fp->name);		op->flags|= OF_ODD;		break;		}	case O_TEXT:				/* Simple text field. */		strcpy(op->value, op->text);		break;	case O_DEV:	case O_SUB:				/* Name of currently edited device. */		name= op->type == O_DEV ? curdev->name :					offset == 0 ? "" : curdev->subname;		if ((n= strlen(name)) < op->len) n= op->len;		strcpy(op->value, name + (n - op->len));		if (device < 0 && op->type == O_DEV) op->flags|= OF_BAD;		break;	case O_NUM:				/* Position and active flag. */		sprintf(op->value, "%d%c", (int) (pe - table),					pe->bootind & ACTIVE_FLAG ? '*' : ' ');		break;	case O_SORT:				/* Position if the driver sorts the table. */		name= curdev->part;		n= strlen(name);		switch (device < 0 ? DUNNO : curdev->parttype) {		case DUNNO:			sprintf(op->value, "%d", sort_index[pe - table]);			n= 1;			break;		case PRIMARY:			if (n > op->len) {				name+= (n - op->len); n= op->len;			}			strcpy(op->value, name);			op->value[n-1] += sort_index[pe - table];			break;		case SUBPART:			if (n > op->len-1) {				name+= (n - (op->len-1)); n= op->len-1;			}			strcpy(op->value, name);			op->value[n++] = 'a' + pe - table - 1;			break;		}		if (n < op->len) {			memmove(op->value+1, op->value, n);			op->value[0]= ' ';			n++;		}		op->value[n]= 0;		break;	case O_TYPHEX:				/* Hex partition type indicator. */		sprintf(op->value, "%02X", pe->sysind);		break;	case O_TYPTXT:				/* Ascii partition type indicator. */		strcpy(op->value, typ2txt(pe->sysind));		if (pe->sysind == OLD_MINIX_PART && pe->lowsec & 1)			op->flags|= OF_BAD;		break;	case O_SCYL:				/* Partition's start cylinder. */		sprintf(op->value, "%lu", entry2base(pe) / secpcyl);		break;	case O_SHEAD:				/* Start head. */		t= entry2base(pe);		sprintf(op->value, "%lu", t % secpcyl / sectors);		if (!aligned(t, secpcyl) && t != table[0].lowsec + sectors)			op->flags|= OF_ODD;		break;	case O_SSEC:				/* Start sector. */		t= entry2base(pe);		sprintf(op->value, "%lu", t % sectors);		if (!aligned(t, sectors)) op->flags|= OF_ODD;		break;	case O_CYL:				/* Number of cylinders. */		sprintf(op->value, "%u", cylinders);		break;	case O_HEAD:				/* Number of heads. */		sprintf(op->value, "%u", heads);		break;	case O_SEC:				/* Number of sectors per track. */		sprintf(op->value, "%u", sectors);		break;	case O_LCYL:				/* Partition's last cylinder. */		t= entry2last(pe);		sprintf(op->value, "%lu", t == -1 ? 0 : t / secpcyl);		break;	case O_LHEAD:				/* Partition's last head. */		t= entry2last(pe);		sprintf(op->value, "%lu", t == -1 ? 0 : t % secpcyl / sectors);		if (!aligned(t + 1, secpcyl)) op->flags|= OF_ODD;		break;	case O_LSEC:				/* Partition's last sector. */		t= entry2last(pe);		sprintf(op->value, t == -1 ? "-1" : "%lu", t % sectors);		if (!aligned(t + 1, sectors)) op->flags|= OF_ODD;		break;	case O_BASE:				/* Partition's base sector. */		sprintf(op->value, "%lu", entry2base(pe));		if (pe->sysind != NO_PART && pe != &table[0]		   && (pe->lowsec <= table[0].lowsec || overlap(pe->lowsec)))			op->flags|= OF_BAD;		break;	case O_SIZE:				/* Size of partitition in sectors. */		t= howend == SIZE ? entry2size(pe) : entry2last(pe);		sprintf(op->value, "%lu", pe->sysind == NO_PART ? 0 : t);		if (pe->sysind != NO_PART && (pe->size == 0		    || pe->lowsec + pe->size > table[0].lowsec + table[0].size		    || overlap(pe->lowsec + pe->size)))			op->flags|= OF_BAD;		break;	case O_KB:				/* Size of partitition in kilobytes. */		sprintf(op->value, "%lu", entry2size(pe) / 2);		break;	default:		sprintf(op->value, "?? %d ??", op->type);	}	if (device < 0 && computed(op->type)) strcpy(op->value, "?");	/* If a value overflows the print field then show a blank	 * reverse video field.	 */	if ((n= strlen(op->value)) > op->len) {		n= 0;		op->flags|= OF_BAD;	}	/* Left, center or right justified? */	if (ljust(op->type)) {		memset(op->value + n, ' ', op->len - n);	} else	if (center(op->type)) {		memset(op->value + n, ' ', op->len - n);		memmove(op->value + (op->len - n) / 2, op->value, n);		memset(op->value, ' ', (op->len - n) / 2);	} else {		memmove(op->value + (op->len - n), op->value, n);		memset(op->value, ' ', op->len - n);	}	op->value[op->len]= 0;	if ((op->flags & (OF_ODD | OF_BAD)) == (oldflags & (OF_ODD | OF_BAD))				&& strcmp(op->value, oldvalue) == 0) {		/* The value did not change. */		return;	}	set_cursor(op->row, rjust(op->type) ? op->col - (op->len-1) : op->col);	if (op->flags & OF_BAD) tputs(t_so, 1, putchr);	else	if (op->flags & OF_ODD) tputs(t_md, 1, putchr);	putstr(op->value);	if (op->flags & OF_BAD) tputs(t_se, 1, putchr);	else	if (op->flags & OF_ODD) tputs(t_me, 1, putchr);}void display(void)/* Repaint all objects that changed. */{	object_t *op;	for (op= world; op != nil; op= op->next) print(op);}int typing;	/* Set if a digit has been typed to set a value. */int magic;	/* Changes when using the magic key. */void event(int ev, object_t *op);void m_redraw(int ev, object_t *op)/* Redraw the screen. */{	object_t *op2;	if (ev != ctrl('L')) return;	clear_screen();	for (op2= world; op2 != nil; op2= op2->next) op2->value[0]= 0;}void m_toggle(int ev, object_t *op)/* Toggle between the driver and alternate geometry. */{	unsigned t;	if (ev != 'X') return;	if (alt_cyls == cylinders && alt_heads == heads && alt_secs == sectors)		return;	t= cylinders; cylinders= alt_cyls; alt_cyls= t;	t= heads; heads= alt_heads; alt_heads= t;	t= sectors; sectors= alt_secs; alt_secs= t;	dirty= 1;	recompute0();}char size_last[]= "Size";void m_orientation(int ev, object_t *op){	if (ev != ' ') return;	switch (howend) {	case SIZE:		howend= LAST;		strcpy(size_last, "Last");		break;	case LAST:		howend= SIZE;		strcpy(size_last, "Size");	}}void m_move(int ev, object_t *op)/* Move to the nearest modifiably object in the intended direction.  Objects * on the same row or column are really near. */{	object_t *near, *op2;	unsigned dist, d2, dr, dc;	if (ev != 'h' && ev != 'j' && ev != 'k' && ev != 'l' && ev != 'H')		return;

⌨️ 快捷键说明

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