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

📄 part.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (ev != '<' || diving == nil) return;	if (dirty) event(E_WRITE, op);	if (dirty) return;	if (device >= 0) { close(device); device= -1; }	olddiv= diving;	diving= olddiv->up;	table[0]= olddiv->old0;	free(curdev->subname);	curdev->subname= olddiv->oldsubname;	strcpy(curdev->part, olddiv->oldpart);	curdev->parttype= olddiv->oldparttype;	offset= olddiv->oldoffset;	extbase= olddiv->oldextbase;	free(olddiv);	event('r', op);	if (diving == nil) submerged= 0;	/* We surfaced. */}int seek_sector(int device, unsigned long sector)/* Seek to the given sector. */{#if __minix_vmd	if (fcntl(device, F_SEEK, mul64u(offset, SECTOR_SIZE)) == 0)		return 0;#endif	if ((off_t)(offset * SECTOR_SIZE) / SECTOR_SIZE != sector) {		errno= EINVAL;		return -1;	}	if (lseek(device, (off_t) offset * SECTOR_SIZE, SEEK_SET) == -1)		return -1;	return 0;}void m_read(int ev, object_t *op)/* Read the partition table from the current device. */{	int i, mode, n;	struct part_entry *pe;	if (ev != 'r' || device >= 0) return;	/* Open() may cause kernel messages: */	stat_start(0);	fflush(stdout);	if (((device= open(curdev->name, mode= O_RDWR|O_CREAT, 0666)) < 0		    && (errno != EACCES			|| (device= open(curdev->name, mode= O_RDONLY)) < 0))		|| seek_sector(device, offset) < 0	) {		stat_start(1);		printf("%s: %s", curdev->name, strerror(errno));		stat_end(5);		if (device >= 0) { close(device); device= -1; }		return;	}	/* Assume up to five lines of kernel messages. */	statusrow+= 5-1;	stat_end(5);	if (mode == O_RDONLY) {		stat_start(1);		printf("%s: Readonly", curdev->name);		stat_end(5);	}	memset(bootblock, 0, sizeof(bootblock));	n= read(device, bootblock, SECTOR_SIZE);	if (n <= 0) stat_start(1);	if (n < 0) {		printf("%s: %s", curdev->name, strerror(errno));		close(device);		device= -1;	} else	if (n < SECTOR_SIZE) printf("%s: Unexpected EOF", curdev->subname);	if (n <= 0) stat_end(5);	if (n < SECTOR_SIZE) n= SECTOR_SIZE;	memcpy(table+1, bootblock+PART_TABLE_OFF,					NR_PARTITIONS * sizeof(table[1]));	for (i= 1; i <= NR_PARTITIONS; i++) {		if ((table[i].bootind & ~ACTIVE_FLAG) != 0) break;	}	if (i <= NR_PARTITIONS || bootblock[510] != 0x55				|| bootblock[511] != 0xAA) {		/* Invalid boot block, install bootstrap, wipe partition table.		 */		memset(bootblock, 0, sizeof(bootblock));		memcpy(bootblock, (void *) bootstrap, sizeof(bootstrap));		memset(table+1, 0, NR_PARTITIONS * sizeof(table[1]));		stat_start(1);		printf("%s: Invalid partition table (reset)", curdev->subname);		stat_end(5);	}	/* Fix an extended partition table up to something mere mortals can	 * understand.  Record already defined partitions.	 */	for (i= 1; i <= NR_PARTITIONS; i++) {		pe= &table[i];		if (extbase != 0 && pe->sysind != NO_PART)			pe->lowsec+= pe->sysind == EXT_PART						? extbase : offset;		existing[i]= pe->sysind != NO_PART;	}	geometry();	dirty= 0;	/* Warn about grave dangers ahead. */	if (extbase != 0) {		stat_start(1);		printf("Warning: You are in a DOS extended partition.");		stat_end(5);	}}void m_write(int ev, object_t *op)/* Write the partition table back if modified. */{	int c;	struct part_entry new_table[NR_PARTITIONS], *pe;	if (ev != 'w' && ev != E_WRITE) return;	if (device < 0) { dirty= 0; return; }	if (!dirty) {		if (ev == 'w') {			stat_start(1);			printf("%s is not changed, or has already been written",							curdev->subname);			stat_end(2);		}		return;	}	if (bootblock[510] != 0x55 || bootblock[511] != 0xAA) {		/* Invalid boot block, warn user. */		stat_start(1);		printf("Warning: About to write a new table on %s",							curdev->subname);		stat_end(5);	}	if (extbase != 0) {		/* Will this stop the luser?  Probably not... */		stat_start(1);		printf("You have changed a DOS extended partition.  Bad Idea.");		stat_end(5);	}	stat_start(1);	putstr("Save partition table? (y/n) ");	fflush(stdout);	while ((c= getchar()) != 'y' && c != 'n' && c != ctrl('?')) {}	if (c == ctrl('?')) putstr("DEL"); else putchr(c);	stat_end(5);	if (c == 'n' && ev == E_WRITE) dirty= 0;	if (c != 'y') return;	memcpy(new_table, table+1, NR_PARTITIONS * sizeof(table[1]));	for (pe= new_table; pe < new_table + NR_PARTITIONS; pe++) {		if (pe->sysind == NO_PART) {			memset(pe, 0, sizeof(*pe));		} else {			abs2dos(&pe->start_head, pe->lowsec);			abs2dos(&pe->last_head, pe->lowsec + pe->size - 1);			/* Fear and loathing time: */			if (extbase != 0)				pe->lowsec-= pe->sysind == EXT_PART						? extbase : offset;		}	}	memcpy(bootblock+PART_TABLE_OFF, new_table, sizeof(new_table));	bootblock[510]= 0x55;	bootblock[511]= 0xAA;	if (seek_sector(device, offset) < 0		|| write(device, bootblock, SECTOR_SIZE) < 0	) {		stat_start(1);		printf("%s: %s", curdev->name, strerror(errno));		stat_end(5);		return;	}	dirty= 0;}void m_shell(int ev, object_t *op)/* Shell escape, to do calculations for instance. */{	int r, pid, status;	void (*sigint)(int), (*sigquit)(int), (*sigterm)(int);	if (ev != 's') return;	reset_tty();	fflush(stdout);	switch (pid= fork()) {	case -1:		stat_start(1);		printf("can't fork: %s\n", strerror(errno));		stat_end(3);		break;	case 0:		if (device >= 0) (void) close(device);		execl("/bin/sh", "sh", (char *) nil);		r= errno;		stat_start(1);		printf("/bin/sh: %s\n", strerror(errno));		stat_end(3);		exit(127);	}	sigint= signal(SIGINT, SIG_IGN);	sigquit= signal(SIGQUIT, SIG_IGN);	sigterm= signal(SIGTERM, SIG_IGN);	while (pid >= 0 && (r= wait(&status)) >= 0 && r != pid) {}	(void) signal(SIGINT, sigint);	(void) signal(SIGQUIT, sigquit);	(void) signal(SIGTERM, sigterm);	tty_raw();	if (pid < 0)		;	else	if (WIFEXITED(status) && WEXITSTATUS(status) == 127)		stat_start(0);	/* Match the stat_start in the child. */	else		event(ctrl('L'), op);}void m_dump(int ev, object_t *op)/* Raw dump of the partition table. */{	struct part_entry table[NR_PARTITIONS], *pe;	int i;	unsigned chs[3];	if (ev != 'p' || device < 0) return;	memcpy(table, bootblock+PART_TABLE_OFF,					NR_PARTITIONS * sizeof(table[0]));	for (i= 0; i < NR_PARTITIONS; i++) {		pe= &table[i];		stat_start(0);		dos2chs(&pe->start_head, chs);		printf("%2d%c      %02X%15d%5d%4d",			i+1,			pe->bootind & ACTIVE_FLAG ? '*' : ' ',			pe->sysind,			chs[0], chs[1], chs[2]);		dos2chs(&pe->last_head, chs);		printf("%6d%5d%4d%10lu%10ld%9lu",			chs[0], chs[1], chs[2],			pe->lowsec,			howend == SIZE ? pe->size : pe->size + pe->lowsec - 1,			pe->size / 2);		stat_end(10);	}	stat_start(0);	printf("(Raw dump of the original %.40s table)",		curdev->subname);	stat_end(10);}int quitting= 0;void m_quit(int ev, object_t *op)/* Write the partition table if modified and exit. */{	if (ev != 'q' && ev != 'x') return;	quitting= 1;	if (dirty) event(E_WRITE, op);	if (dirty) quitting= 0;}void m_help(int ev, object_t *op)/* For people without a clue; let's hope they can find the '?' key. */{	static struct help {		char	*keys;		char	*what;	} help[]= {	 { "? !",		 "This help / more advice!" },	 { "+ - (= _ PgUp PgDn)","Select/increment/decrement/make active" },	 { "0-9 (a-f)",		 "Enter value" },	 { "hjkl (arrow keys)",	 "Move around" },	 { "CTRL-K CTRL-J",	 "Move entry up/down" },	 { "CTRL-L",		 "Redraw screen" },	 { ">",			 "Start a subpartition table" },	 { "<",			 "Back to the primary partition table" },	 { "m",			 "Cycle through magic values" },	 { "spacebar",		 "Show \"Size\" or \"Last\"" },	 { "r w",		 "Read/write partition table" },	 { "p s q x",		 "Raw dump / Shell escape / Quit / Exit" },	 { "y n DEL",		 "Answer \"yes\", \"no\", \"cancel\"" },	};	static char *advice[] = {"* Choose a disk with '+' and '-', then hit 'r'.","* To change any value: Move to it and use '+', '-' or type the desired value.","* To make a new partition:  Move over to the Size or Kb field of an unused","  partition and type the size.  Hit the 'm' key to pad the partition out to","  a cylinder boundary.  Hit 'm' again to pad it out to the end of the disk.","  You can hit 'm' more than once on a base or size field to see several","  interesting values go by.  Note: Other Operating Systems can be picky about","  partitions that are not padded to cylinder boundaries.  Look for highlighted","  head or sector numbers.","* To reuse a partition:  Change the type to MINIX.","* To delete a partition:  Type a zero in the hex Type field.","* To make a partition active:  Type '+' in the Num field.","* To study the list of keys:  Type '?'.",	};	if (ev == '?') {		struct help *hp;		for (hp= help; hp < arraylimit(help); hp++) {			stat_start(0);			printf("%-25s - %s", hp->keys, hp->what);			stat_end(0);		}		stat_start(0);		putstr("Things like ");		putstr(t_so); putstr("this"); putstr(t_se);		putstr(" must be checked, but ");		putstr(t_md); putstr("this"); putstr(t_me);		putstr(" is not really a problem");		stat_end(0);	} else	if (ev == '!') {		char **ap;		for (ap= advice; ap < arraylimit(advice); ap++) {			stat_start(0);			putstr(*ap);			stat_end(0);		}	}}void event(int ev, object_t *op)/* Simply call all modifiers for an event, each one knows when to act. */{	m_help(ev, op);	m_redraw(ev, op);	m_toggle(ev, op);	m_orientation(ev, op);	m_move(ev, op);	m_updown(ev, op);	m_enter(ev, op);	m_leave(ev, op);	m_modify(ev, op);	m_magic(ev, op);	m_in(ev, op);	m_out(ev, op);	m_read(ev, op);	m_write(ev, op);	m_shell(ev, op);	m_dump(ev, op);	m_quit(ev, op);}int keypress(void)/* Get a single keypress.  Translate compound keypresses (arrow keys) to * their simpler equivalents. */{	char ch;	int c;	int esc= 0;	set_cursor(curobj->row, curobj->col);	fflush(stdout);	do {		if (read(0, &ch, sizeof(ch)) < 0) fatal("stdin");		c= (unsigned char) ch;		switch (esc) {		case 0:			switch (c) {			case ctrl('['):	esc= 1; break;			case '_':	c= '-'; break;			case '=':	c= '+'; break;			}			break;		case 1:			esc= c == '[' ? 2 : 0;			break;		case 2:			switch (c) {			case 'D':	c= 'h';	break;			case 'B':	c= 'j';	break;			case 'A':	c= 'k';	break;			case 'C':	c= 'l';	break;			case 'H':	c= 'H';	break;			case 'U':			case 'S':	c= '-';	break;			case 'V':			case 'T':	c= '+';	break;			}			/*FALL THROUGH*/		default:			esc= 0;		}	} while (esc > 0);	switch (c) {	case ctrl('B'):	c= 'h';	break;	case ctrl('N'):	c= 'j';	break;	case ctrl('P'):	c= 'k';	break;	case ctrl('F'):	c= 'l';	break;	}	return c;}void mainloop(void)/* Get keypress, handle event, display results, reset screen, ad infinitum. */{	int key;	while (!quitting) {		stat_reset();		key= keypress();		event(key, curobj);		display();	}}int main(int argc, char **argv){	object_t *op;	int i, r, key;	struct part_entry *pe;	/* Define a few objects to show on the screen.  First text: */	op= newobject(O_INFO, 0, 0,  2, 19);	op= newobject(O_TEXT, 0, 0, 22, 13); op->text= "----first----";	op= newobject(O_TEXT, 0, 0, 37, 13); op->text= "--geom/last--";	op= newobject(O_TEXT, 0, 0, 52, 18); op->text= "------sectors-----";	op= newobject(O_TEXT, 0, 1,  4,  6); op->text= "Device";	op= newobject(O_TEXT, 0, 1, 23, 12); op->text= "Cyl Head Sec";	op= newobject(O_TEXT, 0, 1, 38, 12); op->text= "Cyl Head Sec";	op= newobject(O_TEXT, 0, 1, 56,  4); op->text= "Base";	op= newobject(O_TEXT, 0, 1, 66,  4); op->text= size_last;	op= newobject(O_TEXT, 0, 1, 77,  2); op->text= "Kb";	op= newobject(O_TEXT, 0, 4,  0, 15); op->text= "Num Sort   Type";	/* The device is the current object: */    curobj= newobject(O_DEV,  OF_MOD, 2,  4, 15);	op= newobject(O_SUB,       0, 3,  4, 15);	/* Geometry: */	op= newobject(O_CYL,  OF_MOD, 2, 40,  4); op->entry= &table[0];	op= newobject(O_HEAD, OF_MOD, 2, 45,  3); op->entry= &table[0];	op= newobject(O_SEC,  OF_MOD, 2, 49,  2); op->entry= &table[0];	/* Objects for the device: */	op= newobject(O_SCYL,  0, 3, 25,  4); op->entry= &table[0];	op= newobject(O_SHEAD, 0, 3, 30,  3); op->entry= &table[0];	op= newobject(O_SSEC,  0, 3, 34,  2); op->entry= &table[0];	op= newobject(O_LCYL,  0, 3, 40,  4); op->entry= &table[0];	op= newobject(O_LHEAD, 0, 3, 45,  3); op->entry= &table[0];	op= newobject(O_LSEC,  0, 3, 49,  2); op->entry= &table[0];	op= newobject(O_BASE,  0, 3, 59,  8); op->entry= &table[0];	op= newobject(O_SIZE,  0, 3, 69,  8); op->entry= &table[0];	op= newobject(O_KB,    0, 3, 78,  8); op->entry= &table[0];	/* Objects for each partition: */	for (r= 5, pe= table+1; pe <= table+NR_PARTITIONS; r++, pe++) {		op= newobject(O_NUM,    OF_MOD, r,  2,  2); op->entry= pe;		op= newobject(O_SORT,        0, r,  3,  5); op->entry= pe;		op= newobject(O_TYPHEX, OF_MOD, r, 10,  2); op->entry= pe;		op= newobject(O_TYPTXT, OF_MOD, r, 12,  9); op->entry= pe;		op= newobject(O_SCYL,   OF_MOD, r, 25,  4); op->entry= pe;		op= newobject(O_SHEAD,  OF_MOD, r, 30,  3); op->entry= pe;		op= newobject(O_SSEC,   OF_MOD, r, 34,  2); op->entry= pe;		op= newobject(O_LCYL,   OF_MOD, r, 40,  4); op->entry= pe;		op= newobject(O_LHEAD,  OF_MOD, r, 45,  3); op->entry= pe;		op= newobject(O_LSEC,   OF_MOD, r, 49,  2); op->entry= pe;		op= newobject(O_BASE,   OF_MOD, r, 59,  8); op->entry= pe;		op= newobject(O_SIZE,   OF_MOD, r, 69,  8); op->entry= pe;		op= newobject(O_KB,     OF_MOD, r, 78,  8); op->entry= pe;	}	for (i= 1; i < argc; i++) newdevice(argv[i], 0);	if (firstdev == nil) {		getdevices();		key= ctrl('L');	} else {		key= 'r';	}	if (firstdev != nil) {		init_tty();		clear_screen();		event(key, curobj);		display();		mainloop();		reset_tty();	}	exit(0);}

⌨️ 快捷键说明

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