📄 cfdisk.c
字号:
current ++ ; if( !menuItems[current].key ) current = 0; } /* Repeat until allowable choice has been made */ while( !key ) { /* Display the menu */ ylast = menuUpdate( y, x, menuItems, itemLength, available, menuType, current ); refresh(); key = getch(); /* Clear out all prompts and such */ clear_warning(); for( i = y; i < ylast; i ++ ) { move( i, x ); clrtoeol(); } move( WARNING_START + 1, 0 ); clrtoeol(); /* Cursor keys */ if( key == ESC ) { /* Check whether this is a real ESC or one of extended keys */ /*nodelay(stdscr, TRUE);*/ key = getch(); /*nodelay(stdscr, FALSE);*/ if( key == /*ERR*/ ESC ) { /* This is a real ESC */ key = ESC; } if( key == '[' ) { /* This is one extended keys */ switch( getch() ) { case 'A': /* Up arrow */ if( menuType & MENU_VERT ) { do { current -- ; if( current < 0 ) while( menuItems[current+1].key ) current ++ ; } while( !strchr( available, menuItems[current].key ) ); key = 0; } else key = MENU_UP; break; case 'B': /* Down arrow */ if( menuType & MENU_VERT ) { do { current ++ ; if( !menuItems[current].key ) current = 0 ; } while( !strchr( available, menuItems[current].key ) ); key = 0; } else key = MENU_DOWN; break; case 'C': /* Right arrow */ if( menuType & MENU_HORIZ ) { do { current ++ ; if( !menuItems[current].key ) { current = 0 ; } } while( !strchr( available, menuItems[current].key ) ); key = 0; } else key = MENU_RIGHT; break; case 'D': /* Left arrow */ if( menuType & MENU_HORIZ ) { do { current -- ; if( current < 0 ) { while( menuItems[current + 1].key ) current ++ ; } } while( !strchr( available, menuItems[current].key ) ); key = 0; } else key = MENU_LEFT; break; } } } /* Enter equals to the keyboard shortcut of current menu item */ if( key == 13 ) { key = menuItems[current].key; } /* Should all keys to be accepted? */ if( key && (menuType & MENU_ACCEPT_OTHERS) ) break; /* Is pressed key among acceptable ones */ if( key && (strchr(available, tolower(key)) || strchr(available, key)) ) break; /* The key has not been accepted so far -> let's reject it */ if( key ) { key = 0; putchar( BELL ); print_warning("Illegal key"); } } /* Clear out prompts and such */ clear_warning(); for( i = y; i <= ylast; i ++ ) { move( i, x ); clrtoeol(); } move( WARNING_START + 1, 0 ); clrtoeol(); return key;}/* A function which displays "Press a key to continue" and waits for a keypress * * Perhaps calling function menuSelect is a bit overkill but who cares? */void menuContinue(void){ static struct MenuItem menuContinueBtn[]= { { 'c', "", "Press a key to continue" }, { 0, NULL, NULL } }; menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuContinueBtn, 0, "c", MENU_HORIZ | MENU_ACCEPT_OTHERS, 0 );}/* Function menuSelect takes way too many parameters * * Luckily, most of time we can do with this function */int menuSimple(struct MenuItem *menuItems, int menuDefault){ int i, j, itemLength = 0; char available[MENU_MAX_ITEMS]; for(i = 0; menuItems[i].key; i++) { j = strlen( menuItems[i].name ); if( j > itemLength ) itemLength = j; available[i] = menuItems[i].key; } available[i] = 0; return menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);}/* End of command menu support code */void new_part(int i){ char response[LINE_LENGTH], def[LINE_LENGTH]; char c; int first = p_info[i].first_sector; int last = p_info[i].last_sector; int offset = 0; int flags = 0; int id = LINUX; int num = -1; int num_sects = last - first + 1; int len, ext, j; if (p_info[i].num == PRI_OR_LOG) { static struct MenuItem menuPartType[]= { { 'p', "Primary", "Create a new primary partition" }, { 'l', "Logical", "Create a new logical partition" }, { ESC, "Cancel", "Don't create a partition" }, { 0, NULL, NULL } }; c = menuSimple( menuPartType, 0 ); if (toupper(c) == 'P') num = find_primary(); else if (toupper(c) == 'L') num = find_logical(i); else return; } else if (p_info[i].num == PRIMARY) num = find_primary(); else if (p_info[i].num == LOGICAL) num = find_logical(i); else print_warning("!!! Internal error !!!"); sprintf(def, "%.2f", ceiling(num_sects/20.48)/100); mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Size (in MB): "); if ((len = get_string(response, LINE_LENGTH, def)) <= 0 && len != GS_DEFAULT) return; else if (len > 0) {#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/(sectors*heads))) for (j = 0; j < len-1 && (isdigit(response[j]) || response[j] == '.'); j++); if (toupper(response[j]) == 'K') { num_sects = num_cyls(atof(response)*1024)*sectors*heads; } else if (toupper(response[j]) == 'M') { num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads; } else if (toupper(response[j]) == 'C') { num_sects = round_int(atof(response))*sectors*heads; } else if (toupper(response[j]) == 'S') { num_sects = round_int(atof(response)); } else { num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads; } } if (num_sects <= 0 || num_sects > p_info[i].last_sector - p_info[i].first_sector + 1) return; move( COMMAND_LINE_Y, COMMAND_LINE_X ); clrtoeol(); if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) { /* Determine where inside free space to put partition. */ static struct MenuItem menuPlace[]= { { 'b', "Beginning", "Add partition at beginning of free space" }, { 'e', "End", "Add partition at end of free space" }, { ESC, "Cancel", "Don't create a partition" }, { 0, NULL, NULL } }; c = menuSimple( menuPlace, 0 ); if (toupper(c) == 'B') last = first + num_sects - 1; else if (toupper(c) == 'E') first = last - num_sects + 1; else return; } if (IS_LOGICAL(num) && !is_extended(ext_info.id)) { /* We want to add a logical partition, but need to create an * extended partition first. */ if ((ext = find_primary()) < 0) { print_warning(NEED_EXT); return; } (void) add_part(ext, DOS_EXTENDED, 0, first, last, (first == 0 ? sectors : 0), 0); first = ext_info.first_sector + ext_info.offset; } if (IS_LOGICAL(num)) inc_logical(i); /* Now we have a complete partition to ourselves */ if (first == 0 || IS_LOGICAL(num)) offset = sectors; (void) add_part(num, id, flags, first, last, offset, 0);}void clear_p_info(void){ num_parts = 1; p_info[0].first_sector = 0; p_info[0].last_sector = sectors*heads*cylinders - 1; p_info[0].offset = 0; p_info[0].flags = 0; p_info[0].id = FREE_SPACE; p_info[0].num = PRI_OR_LOG; ext_info.first_sector = 0; ext_info.last_sector = 0; ext_info.offset = 0; ext_info.flags = 0; ext_info.id = FREE_SPACE; ext_info.num = PRIMARY;}void fill_p_info(void){ int p, i; struct hd_geometry geometry; partition_table buffer; partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY }; if ((fd = open(disk_device, O_RDWR)) < 0) { if ((fd = open(disk_device, O_RDONLY)) < 0) fatal(BAD_OPEN); opentype = O_RDONLY; print_warning(READONLY_WARN); if (curses_started) { refresh(); getch(); clear_warning(); } } else opentype = O_RDWR; opened = TRUE; /* Blocks are visible in more than one way: e.g. as block on /dev/hda and as block on /dev/hda3 By a bug in the Linux buffer cache, we will see the old contents of /dev/hda when the change was made to /dev/hda3. In order to avoid this, discard all blocks on /dev/hda. Note that partition table blocks do not live in /dev/hdaN, so this only plays a role if we want to show volume labels. */ ioctl(fd, BLKFLSBUF); /* ignore errors */ read_sector(buffer.c.b, 0); if (!ioctl(fd, HDIO_GETGEO, &geometry)) { if (!heads) heads = geometry.heads; if (!sectors) sectors = geometry.sectors; if (!cylinders) cylinders = geometry.cylinders; } if (!heads || !sectors || !cylinders) fatal(BAD_GEOMETRY); clear_p_info(); if (!zero_table) { for (i = 0; i < 4; i++) { int bs = buffer.p.part[i].start_sect; if (buffer.p.part[i].sys_ind > 0 && add_part(i, buffer.p.part[i].sys_ind, buffer.p.part[i].boot_ind, ((bs <= sectors) ? 0 : bs), buffer.p.part[i].start_sect + buffer.p.part[i].nr_sects - 1, ((bs <= sectors) ? bs : 0), 1)) { fatal(BAD_PRIMARY); } if (is_extended(buffer.p.part[i].sys_ind)) tmp_ext = ext_info; } if (is_extended(tmp_ext.id)) { ext_info = tmp_ext; logical_sectors[logical] = ext_info.first_sector + ext_info.offset; read_sector(buffer.c.b, logical_sectors[logical++]); i = 4; do { for (p = 0; p < 4 && (!buffer.p.part[p].sys_ind || is_extended(buffer.p.part[p].sys_ind)); p++); if (p < 4 && add_part(i++, buffer.p.part[p].sys_ind, buffer.p.part[p].boot_ind, logical_sectors[logical-1], logical_sectors[logical-1] + buffer.p.part[p].start_sect + buffer.p.part[p].nr_sects - 1, buffer.p.part[p].start_sect, 1)) { fatal(BAD_LOGICAL); } for (p = 0; p < 4 && !is_extended(buffer.p.part[p].sys_ind); p++); if (p < 4) { logical_sectors[logical] = ext_info.first_sector + ext_info.offset + buffer.p.part[p].start_sect; read_sector(buffer.c.b, logical_sectors[logical++]); } } while (p < 4 && logical < MAXIMUM_PARTS-4); } }}void fill_part_table(struct partition *p, partition_info *pi){ int sects; p->boot_ind = pi->flags; p->sys_ind = pi->id; if (IS_LOGICAL(pi->num)) p->start_sect = pi->offset; else p->start_sect = pi->first_sector + pi->offset; p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1; sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ? heads*sectors*1024 - 1 : pi->first_sector+pi->offset); set_hsc(p->head, p->sector, p->cyl, sects); sects = ((pi->last_sector/(sectors*heads) > 1023) ? heads*sectors*1024 - 1 : pi->last_sector); set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);}void fill_primary_table(partition_table *buffer){ int i; /* Zero out existing table */ for (i = 0x1BE; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; for (i = 0; i < num_parts; i++) if (IS_PRIMARY(p_info[i].num)) fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i])); if (is_extended(ext_info.id)) fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info); buffer->p.flag = PART_TABLE_FLAG;}void fill_logical_table(partition_table *buffer, partition_info *pi){ struct partition *p; int i, sects; for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++); if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG) for (i = 0; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; /* Zero out existing table */ for (i = 0x1BE; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; fill_part_table(&(buffer->p.part[0]), pi); for (i = 0; i < num_parts && pi->num != p_info[i].num - 1; i++); if (i < num_parts) { p = &(buffer->p.part[1]); pi = &(p_info[i]); p->boot_ind = 0; p->sys_ind = DOS_EXTENDED; p->start_sect = pi->first_sector - ext_info.first_sector - ext_info.offset; p->nr_sects = pi->last_sector - pi->first_sector + 1; sects = ((pi->first_sector/(sectors*heads) > 1023) ? heads*sectors*1024 - 1 : pi->first_sector); set_hsc(p->head, p->sector, p->cyl, sects); sects = ((pi->last_sector/(sectors*heads) > 1023) ? heads*sectors*1024 - 1 : pi->last_sector); set_hsc(p->end_head, p->end_sector, p->end_cyl, sects); } buffer->p.flag = PART_TABLE_FLAG;}void write_part_table(void){ int i, done = FALSE, len; partition_table buffer; struct stat s; int is_bdev; char response[LINE_LENGTH]; if (opentype == O_RDONLY) { print_warning(READONLY_WARN); refresh(); getch(); clear_warning(); return; } is_bdev = 0; if(fstat(fd, &s) == 0 && S_ISBLK(s.st_mode)) is_bdev = 1; if (is_bdev) { print_warning(WRITE_WARN); while (!done) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -