1142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* fdisk.c - fdisk program to modify partitions on disk. 2142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * 3142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com> 41c8b0090a6529ce35f877973778e7814387c1e3fRob Landley * Copyright 2013 Kyungwan Han <asura321@gmail.com> 5142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * 6142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * No Standard. 7142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 8142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini SharmaUSE_FDISK(NEWTOY(fdisk, "C#<0H#<0S#<0b#<512ul", TOYFLAG_SBIN)) 9142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 10142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmaconfig FDISK 11142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma bool "fdisk" 12142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma default n 13142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma help 14142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma usage: fdisk [-lu] [-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SECTSZ] DISK 15142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 16142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma Change partition table 17142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 18142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -u Start and End are in sectors (instead of cylinders) 19142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -l Show partition table for each DISK, then exit 20142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -b size sector size (512, 1024, 2048 or 4096) 21142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -C CYLINDERS Set number of cylinders/heads/sectors 22142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -H HEADS 23142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma -S SECTORS 24142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma*/ 25142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 26142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define FOR_fdisk 27142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#include "toys.h" 28142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#include <linux/hdreg.h> 29142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 30142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini SharmaGLOBALS( 31142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma long sect_sz; 32142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma long sectors; 33142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma long heads; 34142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma long cylinders; 35142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma) 36142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 37142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define EXTENDED 0x05 38142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define WIN98_EXTENDED 0x0f 39142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define LINUX_NATIVE 0x83 40142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define LINUX_EXTENDED 0x85 41142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 42142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define SECTOR_SIZE 512 43142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define ONE_K 1024 44142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define PARTITION_MAX 60 //partition max is modifiable 45142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define IS_EXTENDED(i) ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED) 46142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define sector(s) ((s) & 0x3f) 47142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) 48142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 49142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmatypedef off_t sector_t; 50142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 51142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastruct partition { 52142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned char boot_ind, head, sector, cyl, sys_ind, end_head, 53142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_sector, end_cyl, start4[4], size4[4]; 54142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma}; 55142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 56142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastruct part_entry { 57142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *part; 58142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *sec_buffer; 59142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t start_offset; 60142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int modified; 61142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma}; 62142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 63142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastruct part_types { 64142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int id; 659d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham char type[24]; 66142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} sys_types[] = { 67142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x00, "Empty"}, {0x01, "FAT12"}, {0x04, "FAT16 <32M"}, {0x05, "Extended"}, 68142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x06, "FAT16"}, {0x07, "HPFS/NTFS"}, {0x0a, "OS/2 Boot Manager"}, 69142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x0b, "Win95 FAT32"}, {0x0c, "Win95 FAT32 (LBA)"}, {0x0e, "Win95 FAT16 (LBA)"}, 70142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x0f, "Win95 Ext'd (LBA)"}, {0x11, "Hidden FAT12"}, {0x12, "Compaq diagnostics"}, 71142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x14, "Hidden FAT16 <32M"}, {0x16, "Hidden FAT16"}, {0x17, "Hidden HPFS/NTFS"}, 72142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x1b, "Hidden Win95 FAT32"}, {0x1c, "Hidden W95 FAT32 (LBA)"}, {0x1e, "Hidden W95 FAT16 (LBA)"}, 73142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x3c, "Part.Magic recovery"}, {0x41, "PPC PReP Boot"}, {0x42, "SFS"}, 74142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x63, "GNU HURD or SysV"}, {0x80, "Old Minix"}, {0x81, "Minix / old Linux"}, 75142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x82, "Linux swap"}, {0x83, "Linux"}, {0x84, "OS/2 hidden C: drive"}, 76142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x85, "Linux extended"}, {0x86, "NTFS volume set"}, {0x87, "NTFS volume set"}, 77142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0x8e, "Linux LVM"}, {0x9f, "BSD/OS"}, {0xa0, "Thinkpad hibernation"}, 78142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0xa5, "FreeBSD"}, {0xa6, "OpenBSD"}, {0xa8, "Darwin UFS"}, {0xa9, "NetBSD"}, 79142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0xab, "Darwin boot"}, {0xb7, "BSDI fs"}, {0xb8, "BSDI swap"}, 80142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0xbe, "Solaris boot"}, {0xeb, "BeOS fs"}, {0xee, "EFI GPT"}, 81142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0xef, "EFI (FAT-12/16/32)"}, {0xf0, "Linux/PA-RISC boot"}, 82142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma {0xf2, "DOS secondary"}, {0xfd, "Linux raid autodetect"}, 83142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma}; 84142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 85142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int num_parts, disp_unit_cyl, dos_flag, dev_fd = 3; 86142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic long g_cylinders, g_heads, g_sectors, g_sect_size; 87142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic sector_t total_number_sectors, extended_offset; 88142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic char MBRbuf[2048], *disk_device; 89142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastruct part_entry partitions[PARTITION_MAX]; 90142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 91142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic struct partition* part_offset(char *secbuf, int i) 92142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 93142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return (struct partition*)(secbuf + 0x1be + i*(sizeof(struct partition))); 94142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 95142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 96142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void set_levalue(unsigned char *cp, sector_t value ) 97142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 98142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma uint32_t val = SWAP_LE32(value); 99142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy(cp, (void*)&val, 4); 100142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 101142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 102142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void set_hsc(struct partition *p, sector_t start, sector_t end) 103142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 104142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (dos_flag && (start / (g_sectors * g_heads) > 1023)) 105142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = g_heads * g_sectors * ONE_K - 1; 106142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sector = (start % g_sectors) + 1; 107142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start /= g_sectors; 108142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->head = start % g_heads; 109142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start /= g_heads; 110142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->cyl = start & 0xFF; 111142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sector |= (start >> 2) & 0xc0; 112142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 113142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (dos_flag && (end / (g_sectors * g_heads) > 1023)) 114142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end = g_heads * g_sectors * ONE_K - 1; 115142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->end_sector = (end % g_sectors) + 1; 116142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end /= g_sectors; 117142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->end_head = end % g_heads; 118142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end /= g_heads; 119142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->end_cyl = end & 0xFF; 120142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->end_sector |= (end >> 2) & 0xc0; 121142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 122142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 123142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int chs_warn(void) 124142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 125142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_heads && g_sectors && g_cylinders) 126142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 127142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 128142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma printf("Unknown value(s) for:"); 129142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!g_heads) printf(" heads"); 130142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!g_sectors) printf(" sectors"); 131142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!g_cylinders) printf(" cylinders"); 132142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma printf(". can set in the expert menu.\n"); 133142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 1; 134142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 135142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 136142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void list_types(void) 137142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 138142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, adjust = 0, size = ARRAY_LEN(sys_types); 139142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 140142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(size % 2) adjust = 1; 141142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < (size - adjust); i+=2) 142142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%2x %-22s\t\t%2x %-22.22s\n", sys_types[i].id, sys_types[i].type, 143142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sys_types[i+1].id, sys_types[i+1].type); 144142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (adjust) xprintf("%2x %-22s\n",sys_types[size-1].id, sys_types[size-1].type); 145142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 146142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 147142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 148142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void read_sec_sz() 149142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 150142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int arg; 151142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ioctl(dev_fd, BLKSSZGET, &arg) == 0) g_sect_size = arg; 1529d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (toys.optflags & FLAG_b) { 1539d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (TT.sect_sz != 512 && TT.sect_sz != 1024 && TT.sect_sz != 2048 && 1549d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham TT.sect_sz != 4096) { 1559d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham toys.exithelp++; 1569d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham error_exit("bad sector size"); 1579d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham } 1589d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham g_sect_size = TT.sect_sz; 1599d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham } 160142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 161142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 162142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic sector_t read_size() 163142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 164142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma uint64_t sec64 = 0; 165142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned long sectors = 0; 166142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ioctl(dev_fd, BLKGETSIZE64, &sec64) == 0) { 167142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sec64 = sec64 >> 9; //convert to 512 block size. 168142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (sec64 != (uint32_t) sec64) { 169142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma perror_msg("device has more than 2^32 sectors, can't use all of them"); 170142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sec64 = (uint32_t) - 1L; 171142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 172142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return sec64; 173142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 174142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ioctl(dev_fd, BLKGETSIZE, §ors) == 0) 175142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (sizeof(long) > sizeof(sector_t) && sectors != (sector_t)sectors) 176142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sectors = (uint32_t) - 1L; 177142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return sectors; 178142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 179142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 180142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int validate_part_buff(char *buffer) 181142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 182142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((buffer[510] != 0x55) || (buffer[511] != 0xAA)) return 0; 183142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 1; 184142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 185142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 186142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int is_partition_clear(struct partition* p) 187142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 188142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i = 0; 189142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned char res = 0; 190142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma const char *ptr = (const char*)p; 191142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 192142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < sizeof(struct partition); i++) res |= (unsigned char)ptr[i]; 193142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return (res == 0x00); 194142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 195142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 196142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic uint32_t swap_le32toh(unsigned char *cp) 197142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 198142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma uint32_t val; 199142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy((void*)&val, cp, 4); 200142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return le32toh(val); 201142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 202142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 203142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int check_order(void) 204142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 205142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t first[num_parts], last_seen_val = 0; 206142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i; 207142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 208142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *px; 209142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 210142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 211142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (i == 4) last_seen_val = 0; 212142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 213142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma px = pe->part; 214142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (px->sys_ind) { 215142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma first[i] = swap_le32toh(px->start4) + pe->start_offset; 216142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (last_seen_val > first[i]) return 1; 217142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma last_seen_val = first[i]; 218142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 219142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 220142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 221142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 222142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 223142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void read_geometry(struct hd_geometry *disk) 224142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 225142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct hd_geometry geometry; 226142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 227142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ioctl(dev_fd, HDIO_GETGEO, &geometry)) return; 228142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disk->heads = geometry.heads; 229142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disk->sectors = geometry.sectors; 230142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 231142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 232142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* Read the extended boot record for the 233142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * logical partion details. 234142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 235142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void read_ebr(int idx) 236142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 237142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *sec_buf = NULL; 238142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t offset = 0, local_start_off = 0; 239142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p, *q; 240142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 241142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma q = p = partitions[idx].part; 242142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma local_start_off = swap_le32toh(p->start4); 243142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 244142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!extended_offset) extended_offset = local_start_off; 245142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma do { 24630f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma if (num_parts >= 60) { 24730f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma xprintf("Warning: deleting partitions after 60\n"); 24830f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma memset(q, 0, sizeof(struct partition)); //clear_partition 24930f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma partitions[num_parts-1].modified = 1; 25030f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma break; 25130f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma } 25230f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma 253142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sec_buf = xzalloc(g_sect_size); 254142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[num_parts].part = part_offset(sec_buf, 0); 255142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[num_parts].sec_buffer = sec_buf; 256142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma offset = swap_le32toh(q->start4); 257142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 258142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (num_parts > 4) offset += local_start_off; 259142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[num_parts].start_offset = offset; 260142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xlseek(dev_fd, (off_t)(offset * g_sect_size), SEEK_SET); 261142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 262142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_sect_size != readall(dev_fd, sec_buf, g_sect_size)) { 263142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(dev_fd); 264142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma error_exit("Couldn't read sector zero\n"); 265142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 266142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts++; //extended partions present. 267142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma q = part_offset(sec_buf, 1); 26830f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma } while (!is_partition_clear(q) && IS_EXTENDED(q->sys_ind)); 269142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 270142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 271142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void physical_HS(int* h, int *s) 272142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 273142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p; 274142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, end_h, end_s, e_hh = 0, e_ss = 0, ini = 1, dirty = 0; 275142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma const unsigned char *bufp = (const unsigned char *)MBRbuf; 276142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 277142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!(validate_part_buff((char*)bufp))) return; 278142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 279142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < 4; i++) { 280142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = part_offset((char*)bufp, i); 281142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (p->sys_ind) { 282142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_h = p->end_head + 1; 283142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_s = (p->end_sector & 077); 284142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ini) { 285142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma e_hh = end_h; 286142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma e_ss = end_s; 287142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ini = 0; 288142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else if (e_hh !=end_h || e_ss != end_s) 289142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma dirty = 1; 290142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 291142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 292142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!dirty && !ini) { 293142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *h = e_hh; 294142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *s = e_ss; 295142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 296142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 297142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 298142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//Reset the primary partition table 299142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void reset_boot(int change) 300142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 301142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i; 302142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for(i = 0; i < 4; i++) { 303142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe = &partitions[i]; 304142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->part = part_offset(MBRbuf, i); 305142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->start_offset = 0; 306142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->sec_buffer = MBRbuf; 307142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = change; 308142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 309142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 310142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 311142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic inline void write_table_flag(char *buf) 312142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 313142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma buf[510] = 0x55; 314142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma buf[511] = 0xaa; 315142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 316142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 317142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* free the buffers used for holding details of 318142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * extended logical partions 319142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma*/ 320142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void free_bufs(void) 321142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 322142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i = 4; 323142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (; i < num_parts; i++) free(partitions[i].sec_buffer); 324142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 325142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 326142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void create_empty_doslabel(void) 327142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 328142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Building a new DOS Disklabel. The changes will\n" 329142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "remain in memory only, until you write it.\n"); 330142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 331142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts = 4; 332142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma extended_offset = 0; 333142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(&MBRbuf[510 - 4*16], 0, 4*16); 334142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma write_table_flag(MBRbuf); 335142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[0].modified = 1; 336142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma reset_boot(1); 337142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 338142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 339142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* Read the Master Boot sector of the device for the 340142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * partition table entries/details. 341142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * If any extended partition is found then read the EBR 342142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * for logical partition details 343142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 344142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int read_mbr(char *device, int validate) 345142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 346142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int fd, sector_fac, i, h = 0, s = 0; 347142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct hd_geometry disk; 348142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma fd = open(device, O_RDWR); 349142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(fd < 0) { 350142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma perror_msg("can't open '%s'",device); 351142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 1; 352142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 353142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 354142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disk_device = strdup(device); 355142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(fd != dev_fd) { 356142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(dup2(fd, dev_fd) != dev_fd) perror_exit("Can't dup2"); 357142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(fd); 358142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 359142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 360142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma //read partition table - MBR 361142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (SECTOR_SIZE != readall(dev_fd, MBRbuf, SECTOR_SIZE)) { 362142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(dev_fd); 363142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma perror_exit("Couldn't read sector zero\n"); 364142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 365142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (validate && !validate_part_buff(MBRbuf)) { 366142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Device contains neither a valid DOS " 367142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "partition table, nor Sun, SGI, OSF or GPT " 368142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "disklabel\n"); 369142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma create_empty_doslabel(); 370142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 371142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 372142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disk.heads = disk.sectors = 0; 373142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma read_geometry(&disk); //CHS values 374142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total_number_sectors = read_size(); //Device size 375142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma read_sec_sz(); 376142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_fac = g_sect_size/SECTOR_SIZE; //512 is hardware sector size. 377142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physical_HS(&h, &s); //physical dimensions may be diferent from HDIO_GETGEO 378142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_sectors = (toys.optflags & FLAG_S && TT.sectors)? TT.sectors : s? s : disk.sectors?disk.sectors : 63; 379142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_heads = (toys.optflags & FLAG_H && TT.heads)? TT.heads : h? h : disk.heads? disk.heads : 255; 380142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_cylinders = total_number_sectors/(g_heads * g_sectors * sector_fac); 381142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 382142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!g_cylinders) g_cylinders = toys.optflags & FLAG_C? TT.cylinders : 0; 383142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((g_cylinders > ONE_K) && !(toys.optflags & (FLAG_l | FLAG_S))) 384142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("\nThe number of cylinders for this disk is set to %lu.\n" 385142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "There is nothing wrong with that, but this is larger than 1024,\n" 386142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "and could in certain setups cause problems.\n", g_cylinders); 387142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 388142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (IS_EXTENDED(partitions[i].part->sys_ind)) { 389142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma read_ebr(i); 390142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 391142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 392142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 393142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma chs_warn(); 394142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 395142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 396142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 397142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 398142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic char* get_type(int sys_ind) 399142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 400142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, size = ARRAY_LEN(sys_types); 401142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < size; i++) 402142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (sys_ind == sys_types[i].id) 403142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return sys_types[i].type; 404142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return "Unknown"; 405142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 406142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 407142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void consistency_check(const struct partition *p, int partition) 408142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 409142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned physbc, physbh, physbs, physec, physeh, physes; 410142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned lbc, lbh, lbs, lec, leh, les; 411142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t start, end; 412142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 413142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!g_heads || !g_sectors || (partition >= 4)) return; 414142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // physical beginning c, h, s 415142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physbc = cylinder(p->sector,p->cyl); 416142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physbh = p->head; 417142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physbs = sector(p->sector); 418142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // physical ending c, h, s 419142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physec = cylinder(p->end_sector, p->end_cyl); 420142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physeh = p->end_head; 421142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma physes = sector(p->end_sector); 422142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // logical begin and end CHS values 423142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = swap_le32toh((unsigned char*)(p->start4)); 424142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end = start + swap_le32toh((unsigned char*)(p->size4)) -1; 425142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 426142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma lbc = start/(g_sectors * g_heads); 427142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma lbh = (start/g_sectors) % g_heads; 428142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma lbs = (start % g_sectors) + 1; 429142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 430142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma lec = end/(g_sectors * g_heads); 431142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma leh = (end/g_sectors) % g_heads; 432142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma les = (end % g_sectors) + 1; 433142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 434142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma //Logical and Physical diff 435142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_cylinders <= ONE_K && (physbc != lbc || physbh != lbh || physbs != lbs)) { 436142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u has different physical/logical beginings (Non-Linux?): \n", partition+1); 437142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("phys = (%u %u %u) ",physbc, physbh, physbs); 438142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("logical = (%u %u %u)\n", lbc, lbh, lbs); 439142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 440142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_cylinders <= ONE_K && (physec != lec || physeh != leh || physes != les)) { 441142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u has different physical/logical endings: \n", partition+1); 442142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("phys = (%u %u %u) ",physec, physeh, physes); 443142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("logical = (%u %u %u)\n", lec, leh, les); 444142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 445142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // Ending on cylinder boundary? 446142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (physeh != (g_heads - 1) || physes != g_sectors) 447142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u does not end on cylinder boundary\n", partition + 1); 448142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 449142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 450142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma// List the partition details 451142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void list_partitions(int validate) 452142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 453142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p; 454142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma uint32_t start_cyl, end_cyl, start_sec, end_sec, blocks, secs; 455142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char boot, lastchar = '\0', *dev = disk_device; 456142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i = 0, len = strlen(disk_device), odds = 0; 457142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 458142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (validate && !validate_part_buff(MBRbuf)) { 459142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(dev_fd); 460142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.exitval = 1; 461142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Device %s: doesn't contain a valid partition table\n", disk_device); 462142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 463142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 464142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (isdigit(dev[len - 1])) lastchar = 'p'; 465142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 466142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%*s Boot Start End Blocks Id System\n", len+1, "Device"); 467142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 468142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = partitions[i].part; 469142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p)) continue; 470142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 47130f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma boot = ((p->boot_ind == 0x80)?'*':(!p->boot_ind)?' ':'?'); 472142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start_sec = swap_le32toh(p->start4) + partitions[i].start_offset; 473142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma secs = swap_le32toh(p->size4); 474142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 475142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((start_sec + secs) == 0) end_sec = 0; 476142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else end_sec = start_sec + secs -1; 477142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start_cyl = start_sec/(g_heads * g_sectors) + 1; 478142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_cyl = end_sec/(g_heads * g_sectors) + 1; 479142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma blocks = secs; 480142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_sect_size < ONE_K) { 481142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma blocks /= (ONE_K/g_sect_size); 482142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma odds = secs %(ONE_K/g_sect_size); 483142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else if (g_sect_size > ONE_K) blocks *= (g_sect_size/ONE_K); 484142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 485142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (lastchar) xprintf("%s%c%d",dev, lastchar, i+1); 486142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else xprintf("%s%d",dev, i+1); 487142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 488142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf(" %c %11u %11u %11u%c %2x %s\n", 489142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma boot, 490142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl == 0? start_sec: start_cyl, 491142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl == 0? end_sec: end_cyl, 492142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma blocks,odds?'+':' ', p->sys_ind, get_type(p->sys_ind)); 493142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 494142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma consistency_check(p, i); 495142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 496142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (check_order()) xprintf("\nPartition table entries are not in disk order"); 497142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 498142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 499142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//Print device details 500142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void print_mbr(int validate) 501142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 502142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned long long bytes = ((unsigned long long)total_number_sectors << 9); 503142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma long mbytes = bytes/1000000; 504142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 505142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (mbytes < 10000) xprintf("Disk %s: %lu MB, %llu bytes\n", disk_device, mbytes, bytes); 506142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else xprintf("Disk %s: %lu.%lu GB, %llu bytes\n", disk_device, mbytes/1000, (mbytes/100)%10, bytes); 507142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%ld heads, %ld sectors/track, %ld cylinders", g_heads, g_sectors, g_cylinders); 508142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!disp_unit_cyl) { 509142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf(", total %lld sectors\n", total_number_sectors/(g_sect_size/SECTOR_SIZE)); 510142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Units = sectors of 1 * %ld = %ld bytes\n",g_sect_size, g_sect_size); 511142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else xprintf("\nUnits = cylinders of %ld * %ld = %ld bytes\n\n", 512142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_heads * g_sectors, g_sect_size, g_heads * g_sectors * g_sect_size); 513142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma list_partitions(validate); 514142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 515142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 516142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 517142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void init_members(void) 518142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 519142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i = 0; 520142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts = 4; //max of primaries in a part table 521142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl = dos_flag = 1; 522142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma extended_offset = 0; 523142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_sect_size = SECTOR_SIZE; 524142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 525142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].part = part_offset(MBRbuf, i); 526142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].sec_buffer = MBRbuf; 527142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].modified = 0; 528142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].start_offset = 0; 529142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 530142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 531142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 532142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int read_input(char *mesg, char *outp) 533142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 534142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *p; 535142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int size = 0; 5369d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham do { 5379d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham xprintf("%s", mesg); 5389d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham p = fgets(toybuf, 80, stdin); 539142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 5409d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (!p || !(size = strlen(p))) exit(0); 5419d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (p[size-1] == '\n') p[--size] = '\0'; 5429d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham } while (!size); 543142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 544142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (*p != '\0' && *p <= ' ') p++; 545142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (outp) memcpy(outp, p, strlen(p) + 1); //1 for nul 546142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return *p; 547142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 548142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 549142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int read_hex(char *mesg) 550142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 551142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int val; 552142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char input[80], *endp; 553142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (1) { 554142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma read_input(mesg, input); 555142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((*input | 0x20) == 'l') { 556142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma list_types(); 557142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(input, 0, 80); 558142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma continue; 559142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 560142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = strtoul(input, &endp, 16); 561142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (endp && *endp) continue; 562142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (val <= 0xff) return val; 563142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 564142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 565142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 566142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* Delete an exiting partition, 567142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * if its primary, then just clear the partition details 568142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * if extended, then clear the partition details, also for logical 569142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * if only logical, then move the later partitions backwards 1 step 570142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 571142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmavoid delete_partition(int i) 572142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 573142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int sys_id, looper = 0; 574142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p, *q, *ext_p, *ext_q; 575142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t new_start; 576142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe = &partitions[i]; 577142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 578142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (chs_warn()) return; 579142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 580142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sys_id = p->sys_ind; 581142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!sys_id) xprintf("Partition %u is empty\n", i+1); 582142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 583142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (i < 4 && !IS_EXTENDED(sys_id)) { 584142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(p, 0, sizeof(struct partition)); //clear_partition 585142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 586142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else if (i < 4 && IS_EXTENDED(sys_id)) { 587142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(p, 0, sizeof(struct partition)); //clear_partition 588142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 589142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (looper = 4; looper < num_parts; looper++) { 590142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[looper]; 591142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 592142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p)) break; 593142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else { 594142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(p, 0, sizeof(struct partition)); //clear_partition 595142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 596142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma free(pe->sec_buffer); 597142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 598142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 599142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma extended_offset = 0; 600142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts = 4; 601142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 602142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma //only logical is delete, need to move the rest of them backwards 603142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (i == 4) { //move partiton# 6 to 5. 604142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].modified = 1; 605142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (num_parts > i+1) { 606142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma q = partitions[i + 1].part; 607142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *p = *q; //copy the part table 608142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ext_p = part_offset(partitions[i].sec_buffer, 1); 609142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ext_q = part_offset(partitions[i + 1].sec_buffer, 1); 610142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *ext_p = *ext_q; //copy the extended info pointer 611142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // change the start of the 4th partiton. 612142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma new_start = partitions[i + 1].start_offset + swap_le32toh(q->start4) - extended_offset; 613142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma new_start = SWAP_LE32(new_start); 614142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy(p->start4, (void *)&new_start, 4); 615142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 616142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(partitions[i].part, 0, sizeof(struct partition)); 617142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; //only logical 618142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 619142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else if (i > 4) { 620142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ext_p = part_offset(partitions[i-1].sec_buffer, 1); 621142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ext_q = part_offset(partitions[i].sec_buffer, 1); 622142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy((void*)ext_p, (void *)ext_q, sizeof(struct partition)); 623142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i-1].modified = 1; 624142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 625142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (i == 4) looper = i+2; 626142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else if (i > 4) looper = i+1; 627142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (; looper < num_parts; looper++) 628142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[looper-1] = partitions[looper]; 629142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts--; 630142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 631142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 632142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 633142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int ask_partition(int num_parts) 634142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 635142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int val; 636142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (1) { 637142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma do { 638142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition (%u - %u):", 1, num_parts); 639142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma fgets(toybuf, 80, stdin); 640142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } while (!isdigit(*toybuf)); 641142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = atoi(toybuf); 642142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (val > 0 && val <= num_parts) return val; 643142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else xprintf("Invalid number entered\n"); 644142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 645142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 646142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 647142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void toggle_active_flag(int i) 648142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 649142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p = partitions[i].part; 650142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p)) xprintf("Partition %u is empty\n", i+1); 651142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 652142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (IS_EXTENDED(p->sys_ind) && !p->boot_ind) 653142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("WARNING: Partition %u is an extended partition\n", i + 1); 654142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->boot_ind = p->boot_ind == 0x80?0 : 0x80; 655142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[i].modified = 1; 656142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 657142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 658142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//Write the partition details from Buffer to Disk. 659142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmavoid write_table(void) 660142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 661142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i =0; 662142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 663142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t offset; 664142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 665142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < 4; i++) 666142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (partitions[i].modified) partitions[3].modified = 1; 667142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 668142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 3; i < num_parts; i++) { 669142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 670142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma write_table_flag(pe->sec_buffer); 671142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma offset = pe->start_offset; 672142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (pe->modified == 1) { 673142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xlseek(dev_fd, offset * g_sect_size, SEEK_SET); 674142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xwrite(dev_fd, pe->sec_buffer, g_sect_size); 675142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 676142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 677142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("The partition table has been altered.\n"); 678142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Calling ioctl() to re-read partition table\n"); 679142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sync(); 680142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 4; i < num_parts; i++) free(partitions[i].sec_buffer); 681142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(ioctl(dev_fd, BLKRRPART, NULL) < 0) 682142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma perror_exit("WARNING: rereading partition table failed, kernel still uses old table"); 683142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 684142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 685142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 686142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* try to find a partition for deletion, if only 687142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * one, then select the same, else ask from USER 688142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 689142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int get_non_free_partition(int max) 690142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 691142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int num = -1, i = 0; 692142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 693142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < max; i++) { 694142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!is_partition_clear(partitions[i].part)) { 6959d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (num >= 0) 6969d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham return ask_partition(num_parts)-1; 697142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num = i; 698142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 699142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 700142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (num >= 0) ? xprintf("Selected partition %d\n",num+1): 701142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("No partition is defined yet!\n"); 702142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return num; 703142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 704142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 705142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* a try at autodetecting an empty partition table entry, 706142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * if multiple options then get USER's choce. 707142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 708142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int get_free_partition(int max) 709142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 710142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int num = -1, i = 0; 711142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 712142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < max; i++) { 713142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(partitions[i].part)) { 7149d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (num >= 0) 7159d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham return ask_partition(4)-1; 716142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num = i; 717142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 718142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 719142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (num >= 0) ? xprintf("Selected partition %d\n",num+1): 720142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("All primary partitions have been defined already!\n"); 721142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return num; 722142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 723142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 724142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//taking user input for partition start/end sectors/cyinders 725142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic uint32_t ask_value(char *mesg, sector_t left, sector_t right, sector_t defalt) 726142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 727142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *str = toybuf; 728142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma uint32_t val; 729142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int use_default = 1; 730142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 731142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (1) { 732142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma use_default = 1; 733142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma do { 734142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%s",mesg); 735142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma fgets(str, 80, stdin); 736142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } while (!isdigit(*str) && (*str != '\n') 737142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma && (*str != '-') && (*str != '+') && (!isblank(*str))); 738142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (isblank(*str)) str++; //remove leading white spaces 739142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (*str == '+' || *str == '-') { 740142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int minus = (*str == '-'); 741142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int absolute = 0; 742142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 743142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = atoi(str + 1); 744142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (isdigit(*++str)) use_default = 0; 745142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 746142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma switch (*str) { 747142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'c': 748142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'C': 749142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!disp_unit_cyl) val *= g_heads * g_sectors; 750142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 751142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'K': 752142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma absolute = ONE_K; 753142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 754142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'k': 755142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma absolute = 1000; 756142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 757142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'm': 758142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'M': 759142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma absolute = 1000000; 760142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 761142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'g': 762142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'G': 763142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma absolute = 1000000000; 764142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 765142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma default: 766142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 767142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 768142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (absolute) { 769142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned long long bytes = (unsigned long long) val * absolute; 770142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned long unit = (disp_unit_cyl && (g_heads * g_sectors))? g_heads * g_sectors : 1; 771142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 772142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unit = unit * g_sect_size; 773142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma bytes += unit/2; // rounding 774142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma bytes /= unit; 775142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = bytes; 776142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 777142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (minus) 778142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = -val; 779142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val += left; 780142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 781142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = atoi(str); 782142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (isdigit(*str)) { 783142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma str++; 784142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma use_default = 0; 785142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 786142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 787142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(use_default) { 788142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma val = defalt; 789142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Using default value %lld\n", defalt); 790142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 791142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (val >= left && val <= right) return val; 792142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else xprintf("Value out of range\n"); 793142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 794142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 795142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 796142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//validating if the start given falls in a limit or not 797142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int validate(int start_index, sector_t* begin,sector_t* end, sector_t start 798142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma , int asked) 799142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 800142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, valid = 0; 801142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = start_index; i < num_parts; i++) { 802142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (start >= begin[i] && start <= end[i]) { 803142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (asked) xprintf("Sector %lld is already allocated\n",start); 804142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma valid = 0; 805142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 806142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else valid = 1; 807142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 808142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return valid; 809142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 810142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 811142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//get the start sector/cylinder of a new partition 812142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic sector_t ask_start_sector(int idx, sector_t* begin, sector_t* end, int ext_idx) 813142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 814142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t start, limit, temp = 0, start_cyl, limit_cyl, offset = 1; 815142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char mesg[256]; 816142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, asked = 0, valid = 0, start_index = 0; 817142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 818142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (dos_flag) offset = g_sectors; 819142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = offset; 820142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) limit = (sector_t)g_sectors * g_heads * g_cylinders - 1; 821142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else limit = total_number_sectors - 1; 822142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 823142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) //make the begin of every partition to cylnder boundary 824142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) 825142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin[i] = (begin[i]/(g_heads* g_sectors)) * (g_heads* g_sectors); 826142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 827142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx >= 4) { 828142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!begin[ext_idx] && extended_offset) begin[ext_idx] = extended_offset; 829142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = begin[ext_idx] + offset; 830142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma limit = end[ext_idx]; 831142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start_index = 4; 832142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 833142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma do { 834142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (asked) valid = validate(start_index, begin, end, start, asked); 835142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (valid) break; 836142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 8379d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham do { 8389d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham for (i = start_index; i < num_parts; i++) 8399d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham if (start >= begin[i] && start <= end[i]) 8409d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham start = end[i] + 1 + ((idx >= 4)? offset : 0); 8419d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham } while (!validate(start_index, begin, end, start, 0)); 842142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 843142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start_cyl = start/(g_sectors * g_heads) + 1; 844142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma limit_cyl = limit/(g_sectors * g_heads) + 1; 845142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 846142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (start > limit) break; 847142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "First %s (%lld - %lld, default %lld): ", disp_unit_cyl? "cylinder" : "sector", 848142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? start_cyl : start), 849142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? limit_cyl : limit), 850142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? start_cyl : start)); 851142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma temp = ask_value(mesg, disp_unit_cyl? start_cyl : start, 852142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl? limit_cyl : limit, disp_unit_cyl? start_cyl : start); 853142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma asked = 1; 854142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 855142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) { 856142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // point to the cylinder start sector 857142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma temp = (temp-1) * g_heads * g_sectors; 858142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (temp < start) //the boundary is falling in the already used sectors. 859142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma temp = start; 860142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 861142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = temp; 862142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } while (asked && !valid); 863142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return start; 864142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 865142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 866142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//get the end sector/cylinder of a new partition 867142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic sector_t ask_end_sector(int idx, sector_t* begin, sector_t* end, int ext_idx, sector_t start_sec) 868142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 869142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t limit, temp = 0, start_cyl, limit_cyl, start = start_sec; 870142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char mesg[256]; 871142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i; 872142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 873142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) limit = (sector_t)g_sectors * g_heads * g_cylinders - 1; 874142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else limit = total_number_sectors - 1; 875142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 876142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) //make the begin of every partition to cylnder boundary 877142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) 878142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin[i] = (begin[i]/(g_heads* g_sectors)) * (g_heads* g_sectors); 879142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 880142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx >= 4) limit = end[ext_idx]; 881142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 88230f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma for (i = 0; i < num_parts; i++) { 88330f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma struct part_entry *pe = &partitions[i]; 88430f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma if (start < pe->start_offset && limit >= pe->start_offset) limit = pe->start_offset - 1; 885142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (start < begin[i] && limit >= begin[i]) limit = begin[i] - 1; 88630f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma } 887142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 888142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start_cyl = start/(g_sectors * g_heads) + 1; 889142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma limit_cyl = limit/(g_sectors * g_heads) + 1; 890142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (limit < start) { //the boundary is falling in the already used sectors. 891142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("No Free sectors available\n"); 892142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 893142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 894142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "Last %s or +size or +sizeM or +sizeK (%lld - %lld, default %lld): ", 895142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl? "cylinder" : "sector", 896142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? start_cyl : start), 897142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? limit_cyl : limit), 898142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(disp_unit_cyl? limit_cyl : limit)); 899142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma temp = ask_value(mesg, disp_unit_cyl? start_cyl : start, 900142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl? limit_cyl : limit, disp_unit_cyl? limit_cyl : limit); 901142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 902142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disp_unit_cyl) { // point to the cylinder start sector 903142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma temp = temp * g_heads * g_sectors - 1; 904142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (temp > limit) temp = limit; 905142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 906142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (temp < start) { //the boundary is falling in the already used sectors. 907142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("No Free sectors available\n"); 908142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 909142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 910142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return temp; 911142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 912142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 913142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma// add a new partition to the partition table 914142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int add_partition(int idx, int sys_id) 915142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 916142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, ext_idx = -1; 917142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t start, end, begin_sec[num_parts], end_sec[num_parts]; 918142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe = &partitions[idx]; 919142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p = pe->part; 920142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 921142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (p && !is_partition_clear(p)) { 922142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u is already defined, delete it to re-add\n", idx+1); 923142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 0; 924142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 925142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 926142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 927142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 928142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p)) { 929142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin_sec[i] = 0xffffffff; 930142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_sec[i] = 0; 931142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 932142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin_sec[i] = swap_le32toh(p->start4) + pe->start_offset; 933142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_sec[i] = begin_sec[i] + swap_le32toh(p->size4) - 1; 934142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 935142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (IS_EXTENDED(p->sys_ind)) ext_idx = i; 936142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 937142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = ask_start_sector(idx, begin_sec, end_sec, ext_idx); 938142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end = ask_end_sector(idx, begin_sec, end_sec, ext_idx, start); 939142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!end) return 0; 940142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma //Populate partition table entry - 16 bytes 941142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[idx]; 942142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 943142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 944142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx > 4) { 945142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (dos_flag) pe->start_offset = start - (sector_t)g_sectors; 946142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else pe->start_offset = start - 1; 947142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (pe->start_offset == extended_offset) pe->start_offset++; 948142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!dos_flag) start++; 949142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 950142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 951142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->start4, start - pe->start_offset); 952142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->size4, end - start + 1); 953142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_hsc(p, start, end); 954142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->boot_ind = 0; 955142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sys_ind = sys_id; 956142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 957142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 958142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx > 4) { 959142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = partitions[idx-1].part + 1; //extended pointer for logical partitions 960142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->start4, pe->start_offset - extended_offset); 961142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->size4, end - start + 1 + (dos_flag? g_sectors: 1)); 96230f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma set_hsc(p, pe->start_offset, end); 963142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->boot_ind = 0; 964142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sys_ind = EXTENDED; 965142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[idx-1].modified = 1; 966142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 967142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (IS_EXTENDED(sys_id)) { 968142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[4]; 969142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 970142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->sec_buffer = xzalloc(g_sect_size); 971142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->part = part_offset(pe->sec_buffer, 0); 972142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->start_offset = extended_offset = start; 973142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts = 5; 974142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 975142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 1; 976142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 977142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 978142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void add_logical_partition(void) 979142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 980142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 981142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (num_parts > 5 || !is_partition_clear(partitions[4].part)) { 982142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[num_parts]; 983142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 984142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->sec_buffer = xzalloc(g_sect_size); 985142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->part = part_offset(pe->sec_buffer, 0); 986142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->start_offset = 0; 987142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts++; 988142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!add_partition(num_parts - 1, LINUX_NATIVE)) { 989142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts--; 990142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma free(pe->sec_buffer); 991142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 992142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 993142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else add_partition(num_parts -1, LINUX_NATIVE); 994142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 995142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 996142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* Add a new partiton to the partition table. 997142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * MAX partitions limit is taken to be 60, can be changed 998142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 999142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void add_new_partition(void) 1000142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1001142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int choice, idx, i, free_part = 0; 1002142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *msg = NULL; 1003142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1004142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (chs_warn()) return; 1005142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < 4; i++) if(is_partition_clear(partitions[i].part)) free_part++; 1006142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1007142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!free_part && num_parts >= 60) { 1008142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("The maximum number of partitions has been created\n"); 1009142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1010142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1011142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!free_part) { 1012142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (extended_offset) add_logical_partition(); 1013142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else xprintf("You must delete some partition and add " 1014142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "an extended partition first\n"); 1015142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1016142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1017142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 101859d85e2bb065a3bdc27868acb7a65f89d872c7faRob Landley msg = xmprintf(" %s\n p primary partition(1-4)\n", 1019142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma extended_offset? "l logical (5 or over)" : "e extended"); 1020142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1021142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma choice = 0x20 | read_input(msg, NULL); 1022142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma free(msg); 1023142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (choice == 'p') { 1024142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma idx = get_free_partition(4); 1025142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx >= 0) add_partition(idx, LINUX_NATIVE); 1026142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1027142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1028142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (choice =='l' && extended_offset) { 1029142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma add_logical_partition(); 1030142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1031142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1032142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (choice == 'e' && !extended_offset) { 1033142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma idx = get_free_partition(4); 1034142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (idx >= 0) add_partition(idx, EXTENDED); 1035142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1036142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1037142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1038142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1039142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void change_systype(void ) 1040142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1041142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, sys_id; 1042142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p; 1043142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 1044142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1045142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma i = ask_partition(num_parts); 1046142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i-1]; 1047142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 1048142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p)) { 1049142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %d doesn't exist yet!\n", i); 1050142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1051142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1052142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sys_id = read_hex("Hex code (L to list codes): "); 1053142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((IS_EXTENDED(p->sys_ind) && !IS_EXTENDED(sys_id)) || 1054142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (!IS_EXTENDED(p->sys_ind) && IS_EXTENDED(sys_id))) { 1055142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("you can't change a partition to an extended or vice-versa\n"); 1056142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1057142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1058142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1059142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Changed system type of partition %u to %0x (%s)\n",i, sys_id, get_type(sys_id)); 1060142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sys_ind = sys_id; 1061142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 1062142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1063142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1064142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void check(int n, unsigned h, unsigned s, unsigned c, sector_t start) 1065142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1066142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t total, real_s, real_c; 1067142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1068142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma real_s = sector(s) - 1; 1069142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma real_c = cylinder(s, c); 1070142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total = (real_c * g_sectors + real_s) * g_heads + h; 1071142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!total) xprintf("Partition %u contains sector 0\n", n); 1072142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (h >= g_heads) 1073142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u: head %u greater than maximum %lu\n", n, h + 1, g_heads); 1074142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (real_s >= g_sectors) 1075142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u: sector %u greater than maximum %lu\n", n, s, g_sectors); 1076142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (real_c >= g_cylinders) 1077142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u: cylinder %lld greater than maximum %lu\n", n, real_c + 1, g_cylinders); 1078142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (g_cylinders <= ONE_K && start != total) 1079142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u: previous sectors %lld disagrees with total %lld\n", n, start, total); 1080142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1081142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1082142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void verify_table(void) 1083142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1084142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, j, ext_idx = -1; 1085142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t begin_sec[num_parts], end_sec[num_parts], total = 1; 1086142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 1087142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p; 1088142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1089142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 1090142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 1091142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 1092142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(p) || IS_EXTENDED(p->sys_ind)) { 1093142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin_sec[i] = 0xffffffff; 1094142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_sec[i] = 0; 1095142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 1096142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma begin_sec[i] = swap_le32toh(p->start4) + pe->start_offset; 1097142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end_sec[i] = begin_sec[i] + swap_le32toh(p->size4) - 1; 1098142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1099142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (IS_EXTENDED(p->sys_ind)) ext_idx = i; 1100142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1101142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 1102142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 1103142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 1104142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) { 1105142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma consistency_check(p, i); 1106142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((swap_le32toh(p->start4) + pe->start_offset) < begin_sec[i]) 1107142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Warning: bad start-of-data in partition %u\n", i + 1); 1108142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma check(i + 1, p->end_head, p->end_sector, p->end_cyl, end_sec[i]); 1109142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total += end_sec[i] + 1 - begin_sec[i]; 1110142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 0; j < i; j++) { 1111142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((begin_sec[i] >= begin_sec[j] && begin_sec[i] <= end_sec[j]) 1112142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma || ((end_sec[i] <= end_sec[j] && end_sec[i] >= begin_sec[j]))) { 1113142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Warning: partition %u overlaps partition %u\n", j + 1, i + 1); 1114142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total += begin_sec[i] >= begin_sec[j] ? begin_sec[i] : begin_sec[j]; 1115142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total -= end_sec[i] <= end_sec[j] ? end_sec[i] : end_sec[j]; 1116142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1117142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1118142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1119142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1120142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (extended_offset) { 1121142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pex = &partitions[ext_idx]; 1122142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t e_last = swap_le32toh(pex->part->start4) + 1123142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma swap_le32toh(pex->part->size4) - 1; 1124142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1125142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 4; i < num_parts; i++) { 1126142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total++; 1127142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = partitions[i].part; 1128142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!p->sys_ind) { 1129142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (i != 4 || i + 1 < num_parts) 1130142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Warning: partition %u is empty\n", i + 1); 1131142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else if (begin_sec[i] < extended_offset || end_sec[i] > e_last) 1132142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Logical partition %u not entirely in partition %u\n", i + 1, ext_idx + 1); 1133142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1134142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1135142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (total > g_heads * g_sectors * g_cylinders) 1136142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Total allocated sectors %lld greater than the maximum " 1137142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "%lu\n", total, g_heads * g_sectors * g_cylinders); 1138142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else { 1139142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma total = g_heads * g_sectors * g_cylinders - total; 1140142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (total) xprintf("%lld unallocated sectors\n", total); 1141142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1142142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1143142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1144142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void move_begning(int idx) 1145142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1146142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t start, num, new_start, end; 1147142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char mesg[256]; 1148142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe = &partitions[idx]; 1149142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p = pe->part; 1150142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1151142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (chs_warn()) return; 1152142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma start = swap_le32toh(p->start4) + pe->start_offset; 1153142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num = swap_le32toh(p->size4); 1154142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma end = start + num -1; 1155142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1156142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!num || IS_EXTENDED(p->sys_ind)) { 1157142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Partition %u doesn't have data area\n", idx+1); 1158142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1159142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1160142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "New begining of data (0 - %lld, default %lld): ", 1161142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma (long long int)(end), (long long int)(start)); 1162142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma new_start = ask_value(mesg, 0, end, start); 1163142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (new_start != start) { 1164142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->start4, new_start - pe->start_offset); 1165142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(p->size4, end - new_start +1); 1166142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if ((read_input("Recalculate C/H/S (Y/n): ", NULL) | 0x20) == 'y') 1167142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_hsc(p, new_start, end); 1168142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe->modified = 1; 1169142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1170142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1171142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1172142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void print_raw_sectors() 1173142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1174142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, j; 1175142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 1176142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1177142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Device: %s\n", disk_device); 1178142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 3; i < num_parts; i++) { 1179142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 1180142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 0; j < g_sect_size; j++) { 1181142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!(j % 16)) xprintf("\n0x%03X: ",j); 1182142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%02X ",pe->sec_buffer[j]); 1183142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1184142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 1185142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1186142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1187142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1188142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void print_partitions_list(int ext) 1189142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1190142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i; 1191142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 1192142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *p; 1193142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1194142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Disk %s: %lu heads, %lu sectors, %lu cylinders\n\n", disk_device, g_heads, g_sectors, g_cylinders); 1195142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); 1196142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1197142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 1198142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 1199142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = pe->part; 1200142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (p) { 1201142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (ext && (i >= 4)) p = pe->part + 1; 1202142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(ext && i < 4 && !IS_EXTENDED(p->sys_ind)) continue; 1203142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1204142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%2u %02x%4u%4u%5u%4u%4u%5u%11u%11u %02x\n", 1205142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma i+1, p->boot_ind, p->head, 1206142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector(p->sector), cylinder(p->sector, p->cyl), 1207142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->end_head, 1208142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector(p->end_sector), cylinder(p->end_sector, p->end_cyl), 1209142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma swap_le32toh(p->start4), 1210142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma swap_le32toh(p->size4), 1211142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p->sys_ind); 1212142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (p->sys_ind) consistency_check(p, i); 1213142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1214142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1215142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1216142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1217142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//fix the partition table order to ascending 1218142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void fix_order(void) 1219142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1220142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t first[num_parts], min; 1221142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i, j, oj, ojj, sj, sjj; 1222142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct part_entry *pe; 1223142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct partition *px, *py, temp, *pj, *pjj, tmp; 1224142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1225142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < num_parts; i++) { 1226142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pe = &partitions[i]; 1227142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma px = pe->part; 1228142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (is_partition_clear(px)) first[i] = 0xffffffff; 1229142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else first[i] = swap_le32toh(px->start4) + pe->start_offset; 1230142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1231142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1232142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!check_order()) { 1233142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Ordering is already correct\n\n"); 1234142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1235142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1236142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 0; i < 4; i++) { 1237142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 0; j < 3; j++) { 1238142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (first[j] > first[j+1]) { 1239142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma py = partitions[j+1].part; 1240142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma px = partitions[j].part; 1241142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy(&temp, py, sizeof(struct partition)); 1242142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy(py, px, sizeof(struct partition)); 1243142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memcpy(px, &temp, sizeof(struct partition)); 1244142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma min = first[j+1]; 1245142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma first[j+1] = first[j]; 1246142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma first[j] = min; 1247142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[j].modified = 1; 1248142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1249142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1250142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1251142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 5; i < num_parts; i++) { 1252142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 5; j < num_parts - 1; j++) { 1253142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma oj = partitions[j].start_offset; 1254142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ojj = partitions[j+1].start_offset; 1255142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (oj > ojj) { 1256142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[j].start_offset = ojj; 1257142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma partitions[j+1].start_offset = oj; 1258142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pj = partitions[j].part; 1259142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(pj->start4, swap_le32toh(pj->start4)+oj-ojj); 1260142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pjj = partitions[j+1].part; 1261142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(pjj->start4, swap_le32toh(pjj->start4)+ojj-oj); 1262142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue((partitions[j-1].part+1)->start4, ojj-extended_offset); 1263142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue((partitions[j].part+1)->start4, oj-extended_offset); 1264142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1265142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1266142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1267142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 4; i < num_parts; i++) { 1268142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 4; j < num_parts - 1; j++) { 1269142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pj = partitions[j].part; 1270142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma pjj = partitions[j+1].part; 1271142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sj = swap_le32toh(pj->start4); 1272142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sjj = swap_le32toh(pjj->start4); 1273142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma oj = partitions[j].start_offset; 1274142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma ojj = partitions[j+1].start_offset; 1275142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (oj+sj > ojj+sjj) { 1276142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma tmp = *pj; 1277142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *pj = *pjj; 1278142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma *pjj = tmp; 1279142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(pj->start4, ojj+sjj-oj); 1280142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma set_levalue(pjj->start4, oj+sj-ojj); 1281142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1282142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1283142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1284142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma // If anything changed 1285142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (j = 4; j < num_parts; j++) partitions[j].modified = 1; 1286142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Done!\n"); 1287142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1288142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1289142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void print_menu(void) 1290142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 12919d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham xprintf("a\ttoggle a bootable flag\n" 12929d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "b\tedit bsd disklabel\n" 12939d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "c\ttoggle the dos compatibility flag\n" 12949d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "d\tdelete a partition\n" 12959d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "l\tlist known partition types\n" 12969d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "n\tadd a new partition\n" 12979d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "o\tcreate a new empty DOS partition table\n" 12989d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "p\tprint the partition table\n" 12999d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "q\tquit without saving changes\n" 13009d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "s\tcreate a new empty Sun disklabel\n" 13019d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "t\tchange a partition's system id\n" 13029d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "u\tchange display/entry units\n" 13039d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "v\tverify the partition table\n" 13049d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "w\twrite table to disk and exit\n" 13059d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "x\textra functionality (experts only)\n"); 1306142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1307142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1308142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void print_xmenu(void) 1309142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 13109d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham xprintf("b\tmove beginning of data in a partition\n" 13119d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "c\tchange number of cylinders\n" 13129d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "d\tprint the raw data in the partition table\n" 13139d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "e\tlist extended partitions\n" 13149d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "f\tfix partition order\n" 13159d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "h\tchange number of heads\n" 13169d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "p\tprint the partition table\n" 13179d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "q\tquit without saving changes\n" 13189d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "r\treturn to main menu\n" 13199d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "s\tchange number of sectors/track\n" 13209d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "v\tverify the partition table\n" 13219d44ab3f179e0e914abc1d6edc79a22c265baaa9Isaac Dunham "w\twrite table to disk and exit\n"); 1322142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1323142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1324142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void expert_menu(void) 1325142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1326142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int choice, idx; 1327142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sector_t value; 1328142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char mesg[256]; 1329142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1330142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (1) { 1331142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 1332142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *msg = "Expert Command ('m' for help): "; 1333142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma choice = 0x20 | read_input(msg, NULL); 1334142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma switch (choice) { 1335142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'b': //move data begining in partition 1336142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma idx = ask_partition(num_parts); 1337142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma move_begning(idx - 1); 1338142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1339142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'c': //change cylinders 1340142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "Number of cylinders (1 - 1048576, default %lu): ", g_cylinders); 1341142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma value = ask_value(mesg, 1, 1048576, g_cylinders); 1342142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_cylinders = TT.cylinders = value; 1343142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.optflags |= FLAG_C; 1344142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(g_cylinders > ONE_K) 1345142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("\nThe number of cylinders for this disk is set to %lu.\n" 1346142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "There is nothing wrong with that, but this is larger than 1024,\n" 1347142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma "and could in certain setups cause problems.\n", g_cylinders); 1348142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1349142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'd': //print raw data in part tables 1350142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_raw_sectors(); 1351142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1352142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'e': //list extended partitions 1353142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_partitions_list(1); 1354142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1355142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'f': //fix part order 1356142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma fix_order(); 1357142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1358142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'h': //change number of heads 1359142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "Number of heads (1 - 256, default %lu): ", g_heads); 1360142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma value = ask_value(mesg, 1, 256, g_heads); 1361142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_heads = TT.heads = value; 1362142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.optflags |= FLAG_H; 1363142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1364142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'p': //print partition table 1365142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_partitions_list(0); 1366142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1367142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'q': 1368142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma free_bufs(); 1369142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(dev_fd); 1370142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 1371142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma exit(0); 1372142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1373142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'r': 1374142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1375142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1376142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 's': //change sector/track 1377142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(mesg, "Number of sectors (1 - 63, default %lu): ", g_sectors); 1378142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma value = ask_value(mesg, 1, 63, g_sectors); 1379142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma g_sectors = TT.sectors = value; 1380142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.optflags |= FLAG_H; 1381142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1382142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'v': 1383142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma verify_table(); 1384142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1385142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'w': 1386142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma write_table(); 1387142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.exitval = 0; 1388142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma exit(0); 1389142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1390142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'm': 1391142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_xmenu(); 1392142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1393142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma default: 1394142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Unknown command '%c'\n",choice); 1395142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_xmenu(); 1396142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1397142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1398142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } //while(1) 1399142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1400142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1401142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic int disk_proper(const char *device) 1402142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1403142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned length; 1404142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int fd = open(device, O_RDONLY); 1405142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1406142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (fd != -1) { 1407142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma struct hd_geometry dev_geo; 1408142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma dev_geo.heads = 0; 1409142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma dev_geo.sectors = 0; 1410142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int err = ioctl(fd, HDIO_GETGEO, &dev_geo); 1411142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(fd); 1412142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!err) return (dev_geo.start == 0); 1413142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1414142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma length = strlen(device); 1415142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (length != 0 && isdigit(device[length - 1])) return 0; 1416142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return 1; 1417142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1418142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1419142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void reset_entries() 1420142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1421142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int i; 1422142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1423142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(MBRbuf, 0, sizeof(MBRbuf)); 1424142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma for (i = 4; i < num_parts; i++) 1425142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(&partitions[i], 0, sizeof(struct part_entry)); 1426142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1427142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1428142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma//this will keep dev_fd = 3 always alive 1429142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void move_fd() 1430142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1431142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int fd = xopen("/dev/null", O_RDONLY); 1432142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(fd != dev_fd) { 1433142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(dup2(fd, dev_fd) != dev_fd) perror_exit("Can't dup2"); 1434142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(fd); 1435142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1436142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1437142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1438142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma/* Read proc/partitions and then print the details 1439142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma * for partitions on each device 1440142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma */ 1441142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmastatic void read_and_print_parts() 1442142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1443142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma unsigned int ma, mi, sz; 1444142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *name = toybuf, *buffer = toybuf + ONE_K, *device = toybuf + 2048; 1445142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma FILE* fp = xfopen("/proc/partitions", "r"); 1446142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1447142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (fgets(buffer, ONE_K, fp)) { 1448142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma reset_entries(); 1449142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma num_parts = 4; 1450142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma memset(name, 0, sizeof(name)); 1451142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (sscanf(buffer, " %u %u %u %[^\n ]", &ma, &mi, &sz, name) != 4) 1452142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma continue; 1453142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1454142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma sprintf(device,"/dev/%s",name); 1455142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (disk_proper(device)) { 1456142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (read_mbr(device, 0)) continue; 1457142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_mbr(1); 1458142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma move_fd(); 1459142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1460142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1461142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma fclose(fp); 1462142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1463142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1464142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharmavoid fdisk_main(void) 1465142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma{ 1466142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma int choice, p; 1467142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma 1468142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma init_members(); 1469142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma move_fd(); 1470142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (TT.heads >= 256) TT.heads = 0; 1471142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (TT.sectors >= 64) TT.sectors = 0; 1472142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (toys.optflags & FLAG_u) disp_unit_cyl = 0; 1473142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (toys.optflags & FLAG_l) { 1474142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!toys.optc) read_and_print_parts(); 1475142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma else { 1476142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while(*toys.optargs){ 1477142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (read_mbr(*toys.optargs, 0)) { 1478142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.optargs++; 1479142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma continue; 1480142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1481142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_mbr(1); 1482142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma move_fd(); 1483142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.optargs++; 1484142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1485142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1486142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.exitval = 0; 1487142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1488142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } else { 1489142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (!toys.optc || toys.optc > 1 ) { 1490142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.exitval = toys.exithelp = 1; 1491142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma show_help(); 1492142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1493142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1494142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if (read_mbr(toys.optargs[0], 1)) return; 1495142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma while (1) { 1496142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 1497142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma char *msg = "Command ('m' for help): "; 1498142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma choice = 0x20 | read_input(msg, NULL); 1499142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma switch (choice) { 1500142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'a': 1501142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = ask_partition(num_parts); 1502142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toggle_active_flag(p - 1); //partition table index start from 0. 1503142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1504142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'b': 1505142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1506142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'c': 1507142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma dos_flag = !dos_flag; 1508142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Dos compatible flag is %s\n", dos_flag?"Set" : "Not set"); 1509142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1510142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'd': 1511142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma p = get_non_free_partition(num_parts); //4 was here 1512142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma if(p >= 0) delete_partition(p); 1513142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1514142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'l': 1515142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma list_types(); 1516142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1517142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'n': //add new partition 1518142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma add_new_partition(); 1519142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1520142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'o': 1521142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma create_empty_doslabel(); 1522142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1523142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'p': 1524142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_mbr(0); 1525142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1526142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'q': 1527142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma free_bufs(); 1528142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma close(dev_fd); 1529142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xputc('\n'); 1530142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma exit(0); 1531142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1532142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 's': 1533142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1534142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 't': 1535142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma change_systype(); 1536142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1537142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'u': 1538142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma disp_unit_cyl = !disp_unit_cyl; 1539142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("Changing Display/Entry units to %s\n",disp_unit_cyl?"cylinders" : "sectors"); 1540142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1541142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'v': 1542142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma verify_table(); 1543142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1544142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'w': 1545142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma write_table(); 1546142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma toys.exitval = 0; 1547142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma return; 1548142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1549142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'x': 1550142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma expert_menu(); 1551142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1552142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma case 'm': 1553142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma print_menu(); 1554142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1555142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma default: 1556142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma xprintf("%c: Unknown command\n",choice); 1557142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma break; 1558142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1559142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } //while(1) 1560142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma } 1561142ebdcfbe01007cd86d699d85dc608bbcaacf82Ashwini Sharma} 1562