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