📄 part.c
字号:
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 + -