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

📄 part.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	part 1.47 - Partition table editor		Author: Kees J. Bot *								13 Mar 1992 * Needs about 22k heap+stack. */#define nil 0#include <sys/types.h>#include <stdio.h>#include <termcap.h>#include <errno.h>#include <unistd.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <fcntl.h>#include <time.h>#include <dirent.h>#include <limits.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/ioctl.h>#include <minix/config.h>#include <minix/const.h>#include <minix/partition.h>#include <ibm/partition.h>#include <termios.h>#if !__minix_vmd#define div64u(i, j)	((i) / (j))#endif/* Template:                      ----first----  --geom/last--  ------sectors-----    Device             Cyl Head Sec   Cyl Head Sec      Base      Size       Kb    /dev/hd0                          977    5  17    /dev/hd0:2           0    0   2   976    4  16         2     83043    41521Num Sort   Type 1* hd1  81 MINIX        0    0   3    33    4   9         3      2880     1440 2  hd2  81 MINIX       33    4  10   178    2   2      2883     12284     6142 3  hd3  81 MINIX      178    2   3   976    4  16     15167     67878    33939 4  hd4  00 None         0    0   0     0    0  -1         0         0        0 */#define MAXSIZE		99999999L	/* Will 100 G be enough this year? */#define SECTOR_SIZE	512#define DEV_FD0		0x200		/* Device number of /dev/fd0 */#define DEV_HD0		0x300		/* Device number of /dev/hd0 */#define arraysize(a)	(sizeof(a) / sizeof((a)[0]))#define arraylimit(a)	((a) + arraysize(a))void report(const char *label){	fprintf(stderr, "part: %s: %s\n", label, strerror(errno));}void fatal(const char *label){	report(label);	exit(1);}struct termios termios;void save_ttyflags(void)/* Save tty attributes for later restoration. */{	if (tcgetattr(0, &termios) < 0) fatal("");}void restore_ttyflags(void)/* Reset the tty flags to how we got 'em. */{	if (tcsetattr(0, TCSANOW, &termios) < 0) fatal("");}void tty_raw(void)/* Set the terminal to raw mode, no signals, no echoing. */{	struct termios rawterm;	rawterm= termios;	rawterm.c_lflag &= ~(ICANON|ISIG|ECHO);	rawterm.c_iflag &= ~(ICRNL);	if (tcsetattr(0, TCSANOW, &rawterm) < 0) fatal("");}#define ctrl(c)		((c) == '?' ? '\177' : ((c) & '\37'))char t_cd[16], t_cm[32], t_so[16], t_se[16], t_md[16], t_me[16];int t_li, t_co;#define STATUSROW	10void init_tty(void)/* Get terminal capabilities and set the tty to "editor" mode. */{	char *term;	static char termbuf[1024];	char *tp;	if ((term= getenv("TERM")) == nil || tgetent(termbuf, term) != 1) {		fprintf(stderr, "part: Can't get terminal capabilities\n");		exit(1);	}	if (tgetstr("cd", (tp= t_cd, &tp)) == nil				|| tgetstr("cm", (tp= t_cm, &tp)) == nil) {		fprintf(stderr, "part: This terminal is too dumb\n");		exit(1);	}	t_li= tgetnum("li");	t_co= tgetnum("co");	(void) tgetstr("so", (tp= t_so, &tp));	(void) tgetstr("se", (tp= t_se, &tp));	(void) tgetstr("md", (tp= t_md, &tp));	(void) tgetstr("me", (tp= t_me, &tp));	save_ttyflags();	tty_raw();}void putchr(int c){	putchar(c);}void putstr(char *s){	int c;	while ((c= *s++) != 0) putchr(c);}void set_cursor(int row, int col){	tputs(tgoto(t_cm, col, row), 1, putchr);}int statusrow= STATUSROW;int stat_ktl= 1;int need_help= 1;void stat_start(int serious)/* Prepare for printing on a fresh status line, possibly highlighted. */{	set_cursor(statusrow++, 0);	tputs(t_cd, 1, putchr);	if (serious) tputs(t_so, 1, putchr);}void stat_end(int ktl)/* Closing bracket for stat_start.  Sets "keystrokes to live" of message. */{	tputs(t_se, 1, putchr);	stat_ktl= ktl;	need_help= 1;}void stat_reset(void)/* Reset the statusline pointer and clear old messages if expired. */{	if (stat_ktl > 0 && --stat_ktl == 0) {		statusrow= STATUSROW;		need_help= 1;	}	if (need_help && statusrow < (24-2)) {		if (statusrow > STATUSROW) stat_start(0);		stat_start(0);		putstr("Type '+' or '-' to change, 'r' to read, '?' for more help, '!' for advice");	}	statusrow= STATUSROW;	need_help= 0;}void clear_screen(void){	set_cursor(0, 0);	tputs(t_cd, 1, putchr);	stat_ktl= 1;	stat_reset();}void reset_tty(void)/* Reset the tty to cooked mode. */{	restore_ttyflags();	set_cursor(statusrow, 0);	tputs(t_cd, 1, putchr);}void *alloc(size_t n){	void *m;	if ((m= malloc(n)) == nil) { reset_tty(); fatal(""); }	return m;}#ifndef makedev		/* Missing in sys/types.h */#define minor(dev)	(((dev) >> MINOR) & BYTE)#define major(dev)	(((dev) >> MAJOR) & BYTE)#define makedev(major, minor)	\			((dev_t) (((major) << MAJOR) | ((minor) << MINOR)))#endiftypedef enum parttype { DUNNO, SUBPART, PRIMARY } parttype_t;typedef struct device {	struct device *next, *prev;	/* Circular dequeue. */	dev_t	rdev;			/* Device number (sorting only). */	char	*name;			/* E.g. /dev/hd0 */	char	*subname;		/* E.g. /dev/hd0:2 */	char	part[6];		/* E.g. hd2a */	parttype_t parttype;} device_t;device_t *firstdev= nil, *curdev;void newdevice(char *name, int scanning)/* Add a device to the device list.  If scanning is set then we are reading * /dev, so insert the device in device number order and make /dev/hd0 current. */{	device_t *new, *nextdev, *prevdev;	char *base;	int max, len;	struct stat st;	st.st_rdev= 0;	if (scanning) {		if (stat(name, &st) < 0 || !S_ISBLK(st.st_mode)) return;		switch (major(st.st_rdev)) {		case 0:		case 1:		case 15:			return;		case 2:			if (minor(st.st_rdev) >= 4) return;			break;		default:			if (minor(st.st_rdev) >= 0x80					|| minor(st.st_rdev) % 5 != 0) return;		}		/* Interesting device found. */	} else {		(void) stat(name, &st);	}	new= alloc(sizeof(*new));	new->rdev= st.st_rdev;	new->name= alloc((strlen(name) + 1) * sizeof(new->name[0]));	strcpy(new->name, name);	new->subname= new->name;	new->parttype= DUNNO;	if (major(st.st_rdev) == major(DEV_FD0)) {		new->parttype= SUBPART;	} else	if (st.st_rdev >= DEV_HD0 && minor(st.st_rdev) < 128			&& minor(st.st_rdev) % 5 == 0) {		new->parttype= PRIMARY;	}	if ((base= strrchr(name, '/')) == nil) base= name; else base++;	max= new->parttype == SUBPART ? 4 : 5;	len= strlen(base);	strcpy(new->part, len < max ? base : base + len - max);	if (firstdev == nil) {		firstdev= new;		new->next= new->prev= new;		curdev= firstdev;		return;	}	nextdev= firstdev;	while (new->rdev >= nextdev->rdev				&& (nextdev= nextdev->next) != firstdev) {}	prevdev= nextdev->prev;	new->next= nextdev;	nextdev->prev= new;	new->prev= prevdev;	prevdev->next= new;	if (new->rdev < firstdev->rdev) firstdev= new;	if (new->rdev == DEV_HD0) curdev= new;	if (curdev->rdev != DEV_HD0) curdev= firstdev;}void getdevices(void)/* Get all block devices from /dev that look interesting. */{	DIR *d;	struct dirent *e;	char name[5 + NAME_MAX + 1];	if ((d= opendir("/dev")) == nil) fatal("/dev");	while ((e= readdir(d)) != nil) {		strcpy(name, "/dev/");		strcpy(name + 5, e->d_name);		newdevice(name, 1);	}	(void) closedir(d);}/* One featureful master bootstrap. */unsigned char bootstrap[] = {0353,0001,0000,0061,0300,0216,0330,0216,0300,0372,0216,0320,0274,0000,0174,0373,0275,0276,0007,0211,0346,0126,0277,0000,0006,0271,0000,0001,0374,0363,0245,0352,0044,0006,0000,0000,0264,0002,0315,0026,0250,0010,0164,0033,0350,0071,0001,0174,0007,0060,0344,0315,0026,0242,0205,0007,0054,0060,0074,0012,0163,0363,0120,0350,0046,0001,0205,0007,0130,0353,0012,0240,0002,0006,0204,0300,0165,0003,0351,0147,0000,0230,0262,0005,0366,0362,0262,0200,0000,0302,0210,0340,0120,0350,0234,0000,0163,0003,0351,0147,0000,0130,0054,0001,0175,0003,0351,0141,0000,0276,0276,0175,0211,0357,0271,0040,0000,0363,0245,0200,0301,0004,0211,0356,0215,0174,0020,0070,0154,0004,0164,0016,0213,0135,0010,0053,0134,0010,0213,0135,0012,0033,0134,0012,0163,0014,0212,0044,0206,0144,0020,0210,0044,0106,0071,0376,0162,0364,0211,0376,0201,0376,0356,0007,0162,0326,0342,0322,0211,0356,0264,0020,0366,0344,0001,0306,0200,0174,0004,0001,0162,0026,0353,0021,0204,0322,0175,0041,0211,0356,0200,0174,0004,0000,0164,0013,0366,0004,0200,0164,0006,0350,0070,0000,0162,0053,0303,0203,0306,0020,0201,0376,0376,0007,0162,0346,0350,0215,0000,0211,0007,0376,0302,0204,0322,0174,0023,0315,0021,0321,0340,0321,0340,0200,0344,0003,0070,0342,0167,0355,0350,0011,0000,0162,0350,0303,0350,0003,0000,0162,0146,0303,0211,0356,0214,0134,0010,0214,0134,0012,0277,0003,0000,0122,0006,0127,0264,0010,0315,0023,0137,0007,0200,0341,0077,0376,0306,0210,0310,0366,0346,0211,0303,0213,0104,0010,0213,0124,0012,0367,0363,0222,0210,0325,0366,0361,0060,0322,0321,0352,0321,0352,0010,0342,0210,0321,0376,0301,0132,0210,0306,0273,0000,0174,0270,0001,0002,0315,0023,0163,0020,0200,0374,0200,0164,0011,0117,0174,0006,0060,0344,0315,0023,0163,0270,0371,0303,0201,0076,0376,0175,0125,0252,0165,0001,0303,0350,0013,0000,0243,0007,0353,0005,0350,0004,0000,0227,0007,0353,0376,0136,0255,0126,0211,0306,0254,0204,0300,0164,0011,0264,0016,0273,0001,0000,0315,0020,0353,0362,0303,0057,0144,0145,0166,0057,0150,0144,0077,0010,0000,0015,0012,0000,0116,0157,0156,0145,0040,0141,0143,0164,0151,0166,0145,0015,0012,0000,0122,0145,0141,0144,0040,0145,0162,0162,0157,0162,0040,0000,0116,0157,0164,0040,0142,0157,0157,0164,0141,0142,0154,0145,0040,0000,0000,};int dirty= 0;unsigned char bootblock[SECTOR_SIZE];struct part_entry table[1 + NR_PARTITIONS];int existing[1 + NR_PARTITIONS];unsigned long offset= 0, extbase= 0, extsize;int submerged= 0;char sort_index[1 + NR_PARTITIONS];unsigned cylinders= 1, heads= 1, sectors= 1, secpcyl= 1;unsigned alt_cyls= 1, alt_heads= 1, alt_secs= 1;int precise= 0;int device= -1;unsigned long sortbase(struct part_entry *pe){	return pe->sysind == NO_PART ? -1 : pe->lowsec;}void sort(void)/* Let the sort_index array show the order partitions are sorted in. */{	int i, j;	int idx[1 + NR_PARTITIONS];	for (i= 1; i <= NR_PARTITIONS; i++) idx[i]= i;	for (i= 1; i <= NR_PARTITIONS; i++) {		for (j= 1; j <= NR_PARTITIONS-1; j++) {			int sj= idx[j], sj1= idx[j+1];			if (sortbase(&table[sj]) > sortbase(&table[sj1])) {				idx[j]= sj1;				idx[j+1]= sj;			}		}	}	for (i= 1; i <= NR_PARTITIONS; i++) sort_index[idx[i]]= i;}void dos2chs(unsigned char *dos, unsigned *chs)/* Extract cylinder, head and sector from the three bytes DOS uses to address * a sector.  Note that bits 8 & 9 of the cylinder number come from bit 6 & 7 * of the sector byte.  The sector number is rebased to count from 0. */{	chs[0]= ((dos[1] & 0xC0) << 2) | dos[2];	chs[1]= dos[0];	chs[2]= (dos[1] & 0x3F) - 1;}void abs2dos(unsigned char *dos, unsigned long pos)/* Translate a sector offset to three DOS bytes. */{	unsigned h, c, s;	c= pos / secpcyl;	h= (pos % secpcyl) / sectors;	s= pos % sectors + 1;	dos[0]= h;	dos[1]= s | ((c >> 2) & 0xC0);	dos[2]= c & 0xFF;}void recompute0(void)/* Recompute the partition size for the device after a geometry change. */{	if (device < 0) {		cylinders= heads= sectors= 1;		memset(table, 0, sizeof(table));	} else	if (!precise && offset == 0) {		table[0].lowsec= 0;		table[0].size= (unsigned long) cylinders * heads * sectors;	}	table[0].sysind= device < 0 ? NO_PART : MINIX_PART;	secpcyl= heads * sectors;}void guess_geometry(void)/* With a bit of work one can deduce the disk geometry from the partition * table.  This may be necessary if the driver gets it wrong.  (If partition * tables didn't have C/H/S numbers we would not care at all...) */{	int i, n;	struct part_entry *pe;	unsigned chs[3];	unsigned long sec;	unsigned h, s;	unsigned char HS[256][8];	/* Bit map off all possible H/S */	alt_cyls= alt_heads= alt_secs= 0;	/* Initially all possible H/S combinations are possible.  HS[h][0]	 * bit 0 is used to rule out a head value.	 */	for (h= 1; h <= 255; h++) {		for (s= 0; s < 8; s++) HS[h][s]= 0xFF;	}	for (i= 0; i < 2*NR_PARTITIONS; i++) {		pe= &(table+1)[i >> 1];		if (pe->sysind == NO_PART) continue;		/* Get the end or start sector numbers (in that order). */		if ((i & 1) == 0) {			dos2chs(&pe->last_head, chs);			sec= pe->lowsec + pe->size - 1;		} else {			dos2chs(&pe->start_head, chs);			sec= pe->lowsec;		}		if (chs[0] >= alt_cyls) alt_cyls= chs[0]+1;		/* Which H/S combinations can be ruled out? */		for (h= 1; h <= 255; h++) {			if (HS[h][0] == 0) continue;			n = 0;			for (s= 1; s <= 63; s++) {				if ((chs[0] * h + chs[1]) * s + chs[2] != sec) {					HS[h][s/8] &= ~(1 << (s%8));				}				if (HS[h][s/8] & (1 << (s%8))) n++;			}			if (n == 0) HS[h][0]= 0;		}	}	/* See if only one remains. */	i= 0;	for (h= 1; h <= 255; h++) {		if (HS[h][0] == 0) continue;		for (s= 1; s <= 63; s++) {			if (HS[h][s/8] & (1 << (s%8))) {				i++;				alt_heads= h;				alt_secs= s;			}		}	}	/* Forget it if more than one choice... */	if (i > 1) alt_cyls= alt_heads= alt_secs= 0;}void geometry(void)/* Find out the geometry of the device by querying the driver, or by looking * at the partition table.  These numbers are crosschecked to make sure that * the geometry is correct.  Master bootstraps other than the Minix one use * the CHS numbers in the partition table to load the bootstrap of the active * partition. */{	struct stat dst;	int err= 0;	struct partition geometry;	if (submerged) {		/* Geometry already known. */		sort();		return;	}	precise= 0;	cylinders= 0;	recompute0();	if (device < 0) return;	/* Try to guess the geometry from the partition table. */	guess_geometry();	/* Try to get the geometry from the driver. */	(void) fstat(device, &dst);	if (S_ISBLK(dst.st_mode) || S_ISCHR(dst.st_mode)) {		/* Try to get the drive's geometry from the driver. */		if (ioctl(device, DIOCGETP, &geometry) < 0)			err= errno;		else {			table[0].lowsec= div64u(geometry.base, SECTOR_SIZE);			table[0].size= div64u(geometry.size, SECTOR_SIZE);			cylinders= geometry.cylinders;			heads= geometry.heads;

⌨️ 快捷键说明

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