Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/util-linux/fdisk.c
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/util-linux/fdisk.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* fdisk.c -- Partition table manipulator for Linux. 2 3 * … … 7 8 */ 8 9 9 /* Current changes have not compatibility with this version */ 10 #define UTIL_LINUX_VERSION "2.12" 11 12 13 #define _(x) x 14 15 #define PROC_PARTITIONS "/proc/partitions" 16 17 #include <features.h> 18 #include <sys/types.h> 19 #include <sys/stat.h> /* stat */ 20 #include <ctype.h> 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <string.h> 24 #include <errno.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <setjmp.h> 10 #ifndef _LARGEFILE64_SOURCE 11 /* For lseek64 */ 12 #define _LARGEFILE64_SOURCE 13 #endif 28 14 #include <assert.h> /* assert */ 29 #include <getopt.h> 30 #include <endian.h> 31 #include <sys/ioctl.h> 32 #include <sys/param.h> 33 #include <sys/sysmacros.h> /* major */ 34 35 #include <stdint.h> /* for uint32_t, uint16_t, uint8_t, int16_t, etc */ 36 37 /* Copied from linux/major.h */ 38 #define FLOPPY_MAJOR 2 39 40 #include <sys/utsname.h> 41 42 #include "busybox.h" 43 44 #define DKTYPENAMES 45 46 /* 47 fdisk.h 48 */ 15 #include "libbb.h" 16 17 /* Looks like someone forgot to add this to config system */ 18 #ifndef ENABLE_FEATURE_FDISK_BLKSIZE 19 # define ENABLE_FEATURE_FDISK_BLKSIZE 0 20 # define USE_FEATURE_FDISK_BLKSIZE(a) 21 #endif 49 22 50 23 #define DEFAULT_SECTOR_SIZE 512 51 24 #define MAX_SECTOR_SIZE 2048 52 #define SECTOR_SIZE 512 /* still used in BSDcode */25 #define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 53 26 #define MAXIMUM_PARTS 60 54 27 … … 64 37 #define LINUX_RAID 0xfd 65 38 66 #define SUNOS_SWAP 3 67 #define WHOLE_DISK 5 68 69 #define IS_EXTENDED(i) \ 70 ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED) 71 72 #define SIZE(a) (sizeof(a)/sizeof((a)[0])) 73 74 #define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n)) 75 #define scround(x) (((x)+units_per_sector-1)/units_per_sector) 76 77 #ifdef CONFIG_FEATURE_SUN_LABEL 78 #define SCSI_IOCTL_GET_IDLUN 0x5382 79 #endif 80 81 82 /* including <linux/hdreg.h> also fails */ 39 /* Used for sector numbers. Today's disk sizes make it necessary */ 40 typedef unsigned long long ullong; 41 83 42 struct hd_geometry { 84 43 unsigned char heads; … … 88 47 }; 89 48 90 #define HDIO_GETGEO 0x0301 /* get device geometry */ 91 92 93 struct systypes { 94 const char *name; 95 }; 96 97 static uint sector_size = DEFAULT_SECTOR_SIZE; 98 static uint user_set_sector_size; 99 static uint sector_offset = 1; 100 101 /* 102 * Raw disk label. For DOS-type partition tables the MBR, 103 * with descriptions of the primary partitions. 104 */ 105 #if (MAX_SECTOR_SIZE) > (BUFSIZ+1) 106 static char MBRbuffer[MAX_SECTOR_SIZE]; 107 #else 108 # define MBRbuffer bb_common_bufsiz1 109 #endif 110 111 #ifdef CONFIG_FEATURE_OSF_LABEL 49 #define HDIO_GETGEO 0x0301 /* get device geometry */ 50 51 static const char msg_building_new_label[] ALIGN1 = 52 "Building a new %s. Changes will remain in memory only,\n" 53 "until you decide to write them. After that the previous content\n" 54 "won't be recoverable.\n\n"; 55 56 static const char msg_part_already_defined[] ALIGN1 = 57 "Partition %d is already defined, delete it before re-adding\n"; 58 59 60 static unsigned sector_size = DEFAULT_SECTOR_SIZE; 61 static unsigned user_set_sector_size; 62 static unsigned sector_offset = 1; 63 64 #if ENABLE_FEATURE_OSF_LABEL 112 65 static int possibly_osf_label; 113 66 #endif 114 67 115 static u intheads, sectors, cylinders;68 static unsigned heads, sectors, cylinders; 116 69 static void update_units(void); 117 70 118 119 /*120 * return partition name - uses static storage unless buf is supplied121 */122 static const char *123 partname(const char *dev, int pno, int lth)124 {125 static char buffer[80];126 const char *p;127 int w, wp;128 int bufsiz;129 char *bufp;130 131 bufp = buffer;132 bufsiz = sizeof(buffer);133 134 w = strlen(dev);135 p = "";136 137 if (isdigit(dev[w-1]))138 p = "p";139 140 /* devfs kludge - note: fdisk partition names are not supposed141 to equal kernel names, so there is no reason to do this */142 if (strcmp(dev + w - 4, "disc") == 0) {143 w -= 4;144 p = "part";145 }146 147 wp = strlen(p);148 149 if (lth) {150 snprintf(bufp, bufsiz, "%*.*s%s%-2u",151 lth-wp-2, w, dev, p, pno);152 } else {153 snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno);154 }155 return bufp;156 }157 71 158 72 struct partition { … … 169 83 } ATTRIBUTE_PACKED; 170 84 171 enum failure { 172 ioctl_error, unable_to_open, unable_to_read, unable_to_seek, 173 unable_to_write 174 }; 175 176 enum label_type{ 85 static const char unable_to_open[] ALIGN1 = "cannot open %s"; 86 static const char unable_to_read[] ALIGN1 = "cannot read from %s"; 87 static const char unable_to_seek[] ALIGN1 = "cannot seek on %s"; 88 static const char unable_to_write[] ALIGN1 = "cannot write to %s"; 89 static const char ioctl_error[] ALIGN1 = "BLKGETSIZE ioctl failed on %s"; 90 static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN; 91 92 enum label_type { 177 93 label_dos, label_sun, label_sgi, label_aix, label_osf 178 94 }; 95 96 #define LABEL_IS_DOS (label_dos == current_label_type) 97 98 #if ENABLE_FEATURE_SUN_LABEL 99 #define LABEL_IS_SUN (label_sun == current_label_type) 100 #define STATIC_SUN static 101 #else 102 #define LABEL_IS_SUN 0 103 #define STATIC_SUN extern 104 #endif 105 106 #if ENABLE_FEATURE_SGI_LABEL 107 #define LABEL_IS_SGI (label_sgi == current_label_type) 108 #define STATIC_SGI static 109 #else 110 #define LABEL_IS_SGI 0 111 #define STATIC_SGI extern 112 #endif 113 114 #if ENABLE_FEATURE_AIX_LABEL 115 #define LABEL_IS_AIX (label_aix == current_label_type) 116 #define STATIC_AIX static 117 #else 118 #define LABEL_IS_AIX 0 119 #define STATIC_AIX extern 120 #endif 121 122 #if ENABLE_FEATURE_OSF_LABEL 123 #define LABEL_IS_OSF (label_osf == current_label_type) 124 #define STATIC_OSF static 125 #else 126 #define LABEL_IS_OSF 0 127 #define STATIC_OSF extern 128 #endif 179 129 180 130 enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun }; … … 185 135 static int fd; /* the disk */ 186 136 static int partitions = 4; /* maximum partition + 1 */ 187 static uint display_in_cyl_units = 1; 188 static uint units_per_sector = 1; 189 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 190 static char *line_ptr; 137 static int display_in_cyl_units = 1; 138 static unsigned units_per_sector = 1; 139 #if ENABLE_FEATURE_FDISK_WRITABLE 191 140 static void change_units(void); 192 141 static void reread_partition_table(int leave); 193 142 static void delete_partition(int i); 194 143 static int get_partition(int warn, int max); 195 static void list_types(const struct systypes*sys);196 static u int read_int(uint low, uint dflt, uint high, uint base,char *mesg);144 static void list_types(const char *const *sys); 145 static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg); 197 146 #endif 198 147 static const char *partition_type(unsigned char type); 199 static void fdisk_fatal(enum failure why) ATTRIBUTE_NORETURN;200 148 static void get_geometry(void); 201 149 static int get_boot(enum action what); … … 204 152 #define SINGULAR 1 205 153 206 #define hex_val(c) ({ \ 207 char _c = (c); \ 208 isdigit(_c) ? _c - '0' : \ 209 tolower(_c) + 10 - 'a'; \ 210 }) 211 212 213 #define LINE_LENGTH 800 214 #define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \ 215 (n) * sizeof(struct partition))) 216 #define sector(s) ((s) & 0x3f) 217 #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) 218 219 #define hsc2sector(h,s,c) (sector(s) - 1 + sectors * \ 220 ((h) + heads * cylinder(s,c))) 221 #define set_hsc(h,s,c,sector) { \ 222 s = sector % sectors + 1; \ 223 sector /= sectors; \ 224 h = sector % heads; \ 225 sector /= heads; \ 226 c = sector & 0xff; \ 227 s |= (sector >> 2) & 0xc0; \ 228 } 229 230 231 static int32_t get_start_sect(const struct partition *p); 232 static int32_t get_nr_sects(const struct partition *p); 154 static unsigned get_start_sect(const struct partition *p); 155 static unsigned get_nr_sects(const struct partition *p); 233 156 234 157 /* … … 240 163 * partition and one link to the next one. 241 164 */ 242 st atic struct pte {165 struct pte { 243 166 struct partition *part_table; /* points into sectorbuffer */ 244 167 struct partition *ext_pointer; /* points into sectorbuffer */ 245 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 168 ullong offset; /* disk sector number */ 169 char *sectorbuffer; /* disk sector contents */ 170 #if ENABLE_FEATURE_FDISK_WRITABLE 246 171 char changed; /* boolean */ 247 172 #endif 248 off_t offset; /* disk sector number */ 249 char *sectorbuffer; /* disk sector contents */ 250 } ptes[MAXIMUM_PARTS]; 251 252 253 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 173 }; 174 175 /* DOS partition types */ 176 177 static const char *const i386_sys_types[] = { 178 "\x00" "Empty", 179 "\x01" "FAT12", 180 "\x04" "FAT16 <32M", 181 "\x05" "Extended", /* DOS 3.3+ extended partition */ 182 "\x06" "FAT16", /* DOS 16-bit >=32M */ 183 "\x07" "HPFS/NTFS", /* OS/2 IFS, eg, HPFS or NTFS or QNX */ 184 "\x0a" "OS/2 Boot Manager",/* OS/2 Boot Manager */ 185 "\x0b" "Win95 FAT32", 186 "\x0c" "Win95 FAT32 (LBA)",/* LBA really is 'Extended Int 13h' */ 187 "\x0e" "Win95 FAT16 (LBA)", 188 "\x0f" "Win95 Ext'd (LBA)", 189 "\x11" "Hidden FAT12", 190 "\x12" "Compaq diagnostics", 191 "\x14" "Hidden FAT16 <32M", 192 "\x16" "Hidden FAT16", 193 "\x17" "Hidden HPFS/NTFS", 194 "\x1b" "Hidden Win95 FAT32", 195 "\x1c" "Hidden W95 FAT32 (LBA)", 196 "\x1e" "Hidden W95 FAT16 (LBA)", 197 "\x3c" "Part.Magic recovery", 198 "\x41" "PPC PReP Boot", 199 "\x42" "SFS", 200 "\x63" "GNU HURD or SysV", /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ 201 "\x80" "Old Minix", /* Minix 1.4a and earlier */ 202 "\x81" "Minix / old Linux",/* Minix 1.4b and later */ 203 "\x82" "Linux swap", /* also Solaris */ 204 "\x83" "Linux", 205 "\x84" "OS/2 hidden C: drive", 206 "\x85" "Linux extended", 207 "\x86" "NTFS volume set", 208 "\x87" "NTFS volume set", 209 "\x8e" "Linux LVM", 210 "\x9f" "BSD/OS", /* BSDI */ 211 "\xa0" "Thinkpad hibernation", 212 "\xa5" "FreeBSD", /* various BSD flavours */ 213 "\xa6" "OpenBSD", 214 "\xa8" "Darwin UFS", 215 "\xa9" "NetBSD", 216 "\xab" "Darwin boot", 217 "\xb7" "BSDI fs", 218 "\xb8" "BSDI swap", 219 "\xbe" "Solaris boot", 220 "\xeb" "BeOS fs", 221 "\xee" "EFI GPT", /* Intel EFI GUID Partition Table */ 222 "\xef" "EFI (FAT-12/16/32)", /* Intel EFI System Partition */ 223 "\xf0" "Linux/PA-RISC boot", /* Linux/PA-RISC boot loader */ 224 "\xf2" "DOS secondary", /* DOS 3.3+ secondary */ 225 "\xfd" "Linux raid autodetect", /* New (2.2.x) raid partition with 226 autodetect using persistent 227 superblock */ 228 #if 0 /* ENABLE_WEIRD_PARTITION_TYPES */ 229 "\x02" "XENIX root", 230 "\x03" "XENIX usr", 231 "\x08" "AIX", /* AIX boot (AIX -- PS/2 port) or SplitDrive */ 232 "\x09" "AIX bootable", /* AIX data or Coherent */ 233 "\x10" "OPUS", 234 "\x18" "AST SmartSleep", 235 "\x24" "NEC DOS", 236 "\x39" "Plan 9", 237 "\x40" "Venix 80286", 238 "\x4d" "QNX4.x", 239 "\x4e" "QNX4.x 2nd part", 240 "\x4f" "QNX4.x 3rd part", 241 "\x50" "OnTrack DM", 242 "\x51" "OnTrack DM6 Aux1", /* (or Novell) */ 243 "\x52" "CP/M", /* CP/M or Microport SysV/AT */ 244 "\x53" "OnTrack DM6 Aux3", 245 "\x54" "OnTrackDM6", 246 "\x55" "EZ-Drive", 247 "\x56" "Golden Bow", 248 "\x5c" "Priam Edisk", 249 "\x61" "SpeedStor", 250 "\x64" "Novell Netware 286", 251 "\x65" "Novell Netware 386", 252 "\x70" "DiskSecure Multi-Boot", 253 "\x75" "PC/IX", 254 "\x93" "Amoeba", 255 "\x94" "Amoeba BBT", /* (bad block table) */ 256 "\xa7" "NeXTSTEP", 257 "\xbb" "Boot Wizard hidden", 258 "\xc1" "DRDOS/sec (FAT-12)", 259 "\xc4" "DRDOS/sec (FAT-16 < 32M)", 260 "\xc6" "DRDOS/sec (FAT-16)", 261 "\xc7" "Syrinx", 262 "\xda" "Non-FS data", 263 "\xdb" "CP/M / CTOS / ...",/* CP/M or Concurrent CP/M or 264 Concurrent DOS or CTOS */ 265 "\xde" "Dell Utility", /* Dell PowerEdge Server utilities */ 266 "\xdf" "BootIt", /* BootIt EMBRM */ 267 "\xe1" "DOS access", /* DOS access or SpeedStor 12-bit FAT 268 extended partition */ 269 "\xe3" "DOS R/O", /* DOS R/O or SpeedStor */ 270 "\xe4" "SpeedStor", /* SpeedStor 16-bit FAT extended 271 partition < 1024 cyl. */ 272 "\xf1" "SpeedStor", 273 "\xf4" "SpeedStor", /* SpeedStor large partition */ 274 "\xfe" "LANstep", /* SpeedStor >1024 cyl. or LANstep */ 275 "\xff" "BBT", /* Xenix Bad Block Table */ 276 #endif 277 NULL 278 }; 279 280 281 /* Globals */ 282 283 struct globals { 284 char *line_ptr; 285 char line_buffer[80]; 286 char partname_buffer[80]; 287 jmp_buf listingbuf; 288 /* Raw disk label. For DOS-type partition tables the MBR, 289 * with descriptions of the primary partitions. */ 290 char MBRbuffer[MAX_SECTOR_SIZE]; 291 /* Partition tables */ 292 struct pte ptes[MAXIMUM_PARTS]; 293 }; 294 /* bb_common_bufsiz1 is too small for this on 64 bit CPUs */ 295 #define G (*ptr_to_globals) 296 297 #define line_ptr (G.line_ptr) 298 #define listingbuf (G.listingbuf) 299 #define line_buffer (G.line_buffer) 300 #define partname_buffer (G.partname_buffer) 301 #define MBRbuffer (G.MBRbuffer) 302 #define ptes (G.ptes) 303 304 305 /* Code */ 306 307 #define IS_EXTENDED(i) \ 308 ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED) 309 310 #define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n)) 311 312 #define scround(x) (((x)+units_per_sector-1)/units_per_sector) 313 314 #define pt_offset(b, n) \ 315 ((struct partition *)((b) + 0x1be + (n) * sizeof(struct partition))) 316 317 #define sector(s) ((s) & 0x3f) 318 319 #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) 320 321 #define hsc2sector(h,s,c) \ 322 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c))) 323 324 #define set_hsc(h,s,c,sector) \ 325 do { \ 326 s = sector % sectors + 1; \ 327 sector /= sectors; \ 328 h = sector % heads; \ 329 sector /= heads; \ 330 c = sector & 0xff; \ 331 s |= (sector >> 2) & 0xc0; \ 332 } while (0) 333 334 #if ENABLE_FEATURE_FDISK_WRITABLE 335 /* read line; return 0 or first printable char */ 336 static int 337 read_line(const char *prompt) 338 { 339 int sz; 340 341 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); 342 if (sz <= 0) 343 exit(0); /* Ctrl-D or Ctrl-C */ 344 345 if (line_buffer[sz-1] == '\n') 346 line_buffer[--sz] = '\0'; 347 348 line_ptr = line_buffer; 349 while (*line_ptr && !isgraph(*line_ptr)) 350 line_ptr++; 351 return *line_ptr; 352 } 353 #endif 354 355 /* 356 * return partition name - uses static storage 357 */ 358 static const char * 359 partname(const char *dev, int pno, int lth) 360 { 361 const char *p; 362 int w, wp; 363 int bufsiz; 364 char *bufp; 365 366 bufp = partname_buffer; 367 bufsiz = sizeof(partname_buffer); 368 369 w = strlen(dev); 370 p = ""; 371 372 if (isdigit(dev[w-1])) 373 p = "p"; 374 375 /* devfs kludge - note: fdisk partition names are not supposed 376 to equal kernel names, so there is no reason to do this */ 377 if (strcmp(dev + w - 4, "disc") == 0) { 378 w -= 4; 379 p = "part"; 380 } 381 382 wp = strlen(p); 383 384 if (lth) { 385 snprintf(bufp, bufsiz, "%*.*s%s%-2u", 386 lth-wp-2, w, dev, p, pno); 387 } else { 388 snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno); 389 } 390 return bufp; 391 } 392 393 #if ENABLE_FEATURE_FDISK_WRITABLE 254 394 static void 255 395 set_all_unchanged(void) … … 261 401 } 262 402 263 static void403 static ALWAYS_INLINE void 264 404 set_changed(int i) 265 405 { 266 406 ptes[i].changed = 1; 267 407 } 268 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 269 270 #if defined(CONFIG_FEATURE_SGI_LABEL) || defined(CONFIG_FEATURE_OSF_LABEL) 271 static struct partition * 408 #endif /* FEATURE_FDISK_WRITABLE */ 409 410 static ALWAYS_INLINE struct partition * 272 411 get_part_table(int i) 273 412 { 274 413 return ptes[i].part_table; 275 414 } 276 #endif277 415 278 416 static const char * … … 280 418 { /* n==1: use singular */ 281 419 if (n == 1) 282 return display_in_cyl_units ? _("cylinder") : _("sector"); 283 else 284 return display_in_cyl_units ? _("cylinders") : _("sectors"); 420 return display_in_cyl_units ? "cylinder" : "sector"; 421 return display_in_cyl_units ? "cylinders" : "sectors"; 285 422 } 286 423 287 424 static int 288 valid_part_table_flag(const char *mbuffer) { 289 const unsigned char *b = (const unsigned char *)mbuffer; 290 return (b[510] == 0x55 && b[511] == 0xaa); 291 } 292 293 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 294 static char line_buffer[LINE_LENGTH]; 295 296 /* read line; return 0 or first char */ 425 valid_part_table_flag(const char *mbuffer) 426 { 427 return (mbuffer[510] == 0x55 && (uint8_t)mbuffer[511] == 0xaa); 428 } 429 430 #if ENABLE_FEATURE_FDISK_WRITABLE 431 static ALWAYS_INLINE void 432 write_part_table_flag(char *b) 433 { 434 b[510] = 0x55; 435 b[511] = 0xaa; 436 } 437 438 static char 439 read_nonempty(const char *mesg) 440 { 441 while (!read_line(mesg)) /* repeat */; 442 return *line_ptr; 443 } 444 445 static char 446 read_maybe_empty(const char *mesg) 447 { 448 if (!read_line(mesg)) { 449 line_ptr = line_buffer; 450 line_ptr[0] = '\n'; 451 line_ptr[1] = '\0'; 452 } 453 return line_ptr[0]; 454 } 455 297 456 static int 298 read_line(void) 299 { 300 static int got_eof = 0; 301 302 fflush (stdout); /* requested by niles@scyld.com */ 303 line_ptr = line_buffer; 304 if (!fgets(line_buffer, LINE_LENGTH, stdin)) { 305 if (feof(stdin)) 306 got_eof++; /* user typed ^D ? */ 307 if (got_eof >= 3) { 308 fprintf(stderr, _("\ngot EOF thrice - exiting..\n")); 309 exit(1); 310 } 311 return 0; 312 } 313 while (*line_ptr && !isgraph(*line_ptr)) 314 line_ptr++; 315 return *line_ptr; 316 } 317 318 static char 319 read_char(const char *mesg) 320 { 321 do { 322 fputs(mesg, stdout); 323 } while (!read_line()); 324 return *line_ptr; 325 } 326 327 static char 328 read_chars(const char *mesg) 329 { 330 fputs(mesg, stdout); 331 if (!read_line()) { 332 *line_ptr = '\n'; 333 line_ptr[1] = 0; 334 } 335 return *line_ptr; 336 } 337 338 static int 339 read_hex(const struct systypes *sys) 340 { 341 int hex; 342 457 read_hex(const char *const *sys) 458 { 459 unsigned long v; 343 460 while (1) { 344 read_ char(_("Hex code (type L to list codes): "));345 if (*line_ptr == 'l' || *line_ptr == 'L') 461 read_nonempty("Hex code (type L to list codes): "); 462 if (*line_ptr == 'l' || *line_ptr == 'L') { 346 463 list_types(sys); 347 else if (isxdigit (*line_ptr)) { 348 hex = 0; 349 do 350 hex = hex << 4 | hex_val(*line_ptr++); 351 while (isxdigit(*line_ptr)); 352 return hex; 353 } 354 } 355 } 356 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 357 358 #ifdef CONFIG_FEATURE_AIX_LABEL 359 /* 360 * Copyright (C) Andreas Neuper, Sep 1998. 361 * This file may be redistributed under 362 * the terms of the GNU Public License. 363 */ 364 365 typedef struct { 366 unsigned int magic; /* expect AIX_LABEL_MAGIC */ 367 unsigned int fillbytes1[124]; 368 unsigned int physical_volume_id; 369 unsigned int fillbytes2[124]; 370 } aix_partition; 371 372 #define AIX_LABEL_MAGIC 0xc9c2d4c1 373 #define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9 374 #define AIX_INFO_MAGIC 0x00072959 375 #define AIX_INFO_MAGIC_SWAPPED 0x59290700 376 377 #define aixlabel ((aix_partition *)MBRbuffer) 378 379 380 /* 381 Changes: 382 * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 383 * Internationalization 384 * 385 * 2003-03-20 Phillip Kesling <pkesling@sgi.com> 386 * Some fixes 387 */ 388 389 static int aix_other_endian; 390 static short aix_volumes = 1; 391 392 /* 393 * only dealing with free blocks here 394 */ 395 396 static void 397 aix_info(void) 398 { 399 puts( 400 _("\n\tThere is a valid AIX label on this disk.\n" 401 "\tUnfortunately Linux cannot handle these\n" 402 "\tdisks at the moment. Nevertheless some\n" 403 "\tadvice:\n" 404 "\t1. fdisk will destroy its contents on write.\n" 405 "\t2. Be sure that this disk is NOT a still vital\n" 406 "\t part of a volume group. (Otherwise you may\n" 407 "\t erase the other disks as well, if unmirrored.)\n" 408 "\t3. Before deleting this physical volume be sure\n" 409 "\t to remove the disk logically from your AIX\n" 410 "\t machine. (Otherwise you become an AIXpert).") 411 ); 412 } 413 414 static int 415 check_aix_label(void) 416 { 417 if (aixlabel->magic != AIX_LABEL_MAGIC && 418 aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) { 419 current_label_type = 0; 420 aix_other_endian = 0; 421 return 0; 422 } 423 aix_other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED); 424 update_units(); 425 current_label_type = label_aix; 426 partitions = 1016; 427 aix_volumes = 15; 428 aix_info(); 429 /*aix_nolabel();*/ /* %% */ 430 /*aix_label = 1;*/ /* %% */ 431 return 1; 432 } 433 #endif /* AIX_LABEL */ 434 435 #ifdef CONFIG_FEATURE_OSF_LABEL 436 /* 437 * Copyright (c) 1987, 1988 Regents of the University of California. 438 * All rights reserved. 439 * 440 * Redistribution and use in source and binary forms, with or without 441 * modification, are permitted provided that the following conditions 442 * are met: 443 * 1. Redistributions of source code must retain the above copyright 444 * notice, this list of conditions and the following disclaimer. 445 * 2. Redistributions in binary form must reproduce the above copyright 446 * notice, this list of conditions and the following disclaimer in the 447 * documentation and/or other materials provided with the distribution. 448 * 3. All advertising materials mentioning features or use of this software 449 * must display the following acknowledgment: 450 * This product includes software developed by the University of 451 * California, Berkeley and its contributors. 452 * 4. Neither the name of the University nor the names of its contributors 453 * may be used to endorse or promote products derived from this software 454 * without specific prior written permission. 455 * 456 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 457 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 458 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 459 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 460 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 461 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 462 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 463 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 464 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 465 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 466 * SUCH DAMAGE. 467 */ 468 469 470 #ifndef BSD_DISKMAGIC 471 #define BSD_DISKMAGIC ((uint32_t) 0x82564557) 472 #endif 473 474 #ifndef BSD_MAXPARTITIONS 475 #define BSD_MAXPARTITIONS 16 476 #endif 477 478 #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" 479 480 #if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__m68k__) || defined (__mips__) || defined (__s390__) || defined (__sh__) || defined(__x86_64__) 481 #define BSD_LABELSECTOR 1 482 #define BSD_LABELOFFSET 0 483 #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__) 484 #define BSD_LABELSECTOR 0 485 #define BSD_LABELOFFSET 64 486 #elif defined (__s390__) || defined (__s390x__) 487 #define BSD_LABELSECTOR 1 488 #define BSD_LABELOFFSET 0 489 #else 490 #error unknown architecture 491 #endif 492 493 #define BSD_BBSIZE 8192 /* size of boot area, with label */ 494 #define BSD_SBSIZE 8192 /* max size of fs superblock */ 495 496 struct xbsd_disklabel { 497 uint32_t d_magic; /* the magic number */ 498 int16_t d_type; /* drive type */ 499 int16_t d_subtype; /* controller/d_type specific */ 500 char d_typename[16]; /* type name, e.g. "eagle" */ 501 char d_packname[16]; /* pack identifier */ 502 /* disk geometry: */ 503 uint32_t d_secsize; /* # of bytes per sector */ 504 uint32_t d_nsectors; /* # of data sectors per track */ 505 uint32_t d_ntracks; /* # of tracks per cylinder */ 506 uint32_t d_ncylinders; /* # of data cylinders per unit */ 507 uint32_t d_secpercyl; /* # of data sectors per cylinder */ 508 uint32_t d_secperunit; /* # of data sectors per unit */ 509 /* 510 * Spares (bad sector replacements) below 511 * are not counted in d_nsectors or d_secpercyl. 512 * Spare sectors are assumed to be physical sectors 513 * which occupy space at the end of each track and/or cylinder. 514 */ 515 uint16_t d_sparespertrack; /* # of spare sectors per track */ 516 uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ 517 /* 518 * Alternate cylinders include maintenance, replacement, 519 * configuration description areas, etc. 520 */ 521 uint32_t d_acylinders; /* # of alt. cylinders per unit */ 522 523 /* hardware characteristics: */ 524 /* 525 * d_interleave, d_trackskew and d_cylskew describe perturbations 526 * in the media format used to compensate for a slow controller. 527 * Interleave is physical sector interleave, set up by the formatter 528 * or controller when formatting. When interleaving is in use, 529 * logically adjacent sectors are not physically contiguous, 530 * but instead are separated by some number of sectors. 531 * It is specified as the ratio of physical sectors traversed 532 * per logical sector. Thus an interleave of 1:1 implies contiguous 533 * layout, while 2:1 implies that logical sector 0 is separated 534 * by one sector from logical sector 1. 535 * d_trackskew is the offset of sector 0 on track N 536 * relative to sector 0 on track N-1 on the same cylinder. 537 * Finally, d_cylskew is the offset of sector 0 on cylinder N 538 * relative to sector 0 on cylinder N-1. 539 */ 540 uint16_t d_rpm; /* rotational speed */ 541 uint16_t d_interleave; /* hardware sector interleave */ 542 uint16_t d_trackskew; /* sector 0 skew, per track */ 543 uint16_t d_cylskew; /* sector 0 skew, per cylinder */ 544 uint32_t d_headswitch; /* head switch time, usec */ 545 uint32_t d_trkseek; /* track-to-track seek, usec */ 546 uint32_t d_flags; /* generic flags */ 547 #define NDDATA 5 548 uint32_t d_drivedata[NDDATA]; /* drive-type specific information */ 549 #define NSPARE 5 550 uint32_t d_spare[NSPARE]; /* reserved for future use */ 551 uint32_t d_magic2; /* the magic number (again) */ 552 uint16_t d_checksum; /* xor of data incl. partitions */ 553 /* filesystem and partition information: */ 554 uint16_t d_npartitions; /* number of partitions in following */ 555 uint32_t d_bbsize; /* size of boot area at sn0, bytes */ 556 uint32_t d_sbsize; /* max size of fs superblock, bytes */ 557 struct xbsd_partition { /* the partition table */ 558 uint32_t p_size; /* number of sectors in partition */ 559 uint32_t p_offset; /* starting sector */ 560 uint32_t p_fsize; /* filesystem basic fragment size */ 561 uint8_t p_fstype; /* filesystem type, see below */ 562 uint8_t p_frag; /* filesystem fragments per block */ 563 uint16_t p_cpg; /* filesystem cylinders per group */ 564 } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ 565 }; 566 567 /* d_type values: */ 568 #define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ 569 #define BSD_DTYPE_MSCP 2 /* MSCP */ 570 #define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */ 571 #define BSD_DTYPE_SCSI 4 /* SCSI */ 572 #define BSD_DTYPE_ESDI 5 /* ESDI interface */ 573 #define BSD_DTYPE_ST506 6 /* ST506 etc. */ 574 #define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */ 575 #define BSD_DTYPE_HPFL 8 /* HP Fiber-link */ 576 #define BSD_DTYPE_FLOPPY 10 /* floppy */ 577 578 /* d_subtype values: */ 579 #define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */ 580 #define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ 581 #define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ 582 583 #ifdef DKTYPENAMES 584 static const char * const xbsd_dktypenames[] = { 585 "unknown", 586 "SMD", 587 "MSCP", 588 "old DEC", 589 "SCSI", 590 "ESDI", 591 "ST506", 592 "HP-IB", 593 "HP-FL", 594 "type 9", 595 "floppy", 596 0 597 }; 598 #define BSD_DKMAXTYPES (sizeof(xbsd_dktypenames) / sizeof(xbsd_dktypenames[0]) - 1) 599 #endif 600 601 /* 602 * Filesystem type and version. 603 * Used to interpret other filesystem-specific 604 * per-partition information. 605 */ 606 #define BSD_FS_UNUSED 0 /* unused */ 607 #define BSD_FS_SWAP 1 /* swap */ 608 #define BSD_FS_V6 2 /* Sixth Edition */ 609 #define BSD_FS_V7 3 /* Seventh Edition */ 610 #define BSD_FS_SYSV 4 /* System V */ 611 #define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ 612 #define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */ 613 #define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */ 614 #define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */ 615 #define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */ 616 #define BSD_FS_HPFS 11 /* OS/2 high-performance file system */ 617 #define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */ 618 #define BSD_FS_ISOFS BSD_FS_ISO9660 619 #define BSD_FS_BOOT 13 /* partition contains bootstrap */ 620 #define BSD_FS_ADOS 14 /* AmigaDOS fast file system */ 621 #define BSD_FS_HFS 15 /* Macintosh HFS */ 622 #define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */ 623 624 /* this is annoying, but it's also the way it is :-( */ 625 #ifdef __alpha__ 626 #define BSD_FS_EXT2 8 /* ext2 file system */ 627 #else 628 #define BSD_FS_MSDOS 8 /* MS-DOS file system */ 629 #endif 630 631 #ifdef DKTYPENAMES 632 static const struct systypes xbsd_fstypes[] = { 633 { "\x00" "unused" }, /* BSD_FS_UNUSED */ 634 { "\x01" "swap" }, /* BSD_FS_SWAP */ 635 { "\x02" "Version 6" }, /* BSD_FS_V6 */ 636 { "\x03" "Version 7" }, /* BSD_FS_V7 */ 637 { "\x04" "System V" }, /* BSD_FS_SYSV */ 638 { "\x05" "4.1BSD" }, /* BSD_FS_V71K */ 639 { "\x06" "Eighth Edition" }, /* BSD_FS_V8 */ 640 { "\x07" "4.2BSD" }, /* BSD_FS_BSDFFS */ 641 #ifdef __alpha__ 642 { "\x08" "ext2" }, /* BSD_FS_EXT2 */ 643 #else 644 { "\x08" "MS-DOS" }, /* BSD_FS_MSDOS */ 645 #endif 646 { "\x09" "4.4LFS" }, /* BSD_FS_BSDLFS */ 647 { "\x0a" "unknown" }, /* BSD_FS_OTHER */ 648 { "\x0b" "HPFS" }, /* BSD_FS_HPFS */ 649 { "\x0c" "ISO-9660" }, /* BSD_FS_ISO9660 */ 650 { "\x0d" "boot" }, /* BSD_FS_BOOT */ 651 { "\x0e" "ADOS" }, /* BSD_FS_ADOS */ 652 { "\x0f" "HFS" }, /* BSD_FS_HFS */ 653 { "\x10" "AdvFS" }, /* BSD_FS_ADVFS */ 654 { NULL } 655 }; 656 #define BSD_FSMAXTYPES (SIZE(xbsd_fstypes)-1) 657 658 #endif 659 660 /* 661 * flags shared by various drives: 662 */ 663 #define BSD_D_REMOVABLE 0x01 /* removable media */ 664 #define BSD_D_ECC 0x02 /* supports ECC */ 665 #define BSD_D_BADSECT 0x04 /* supports bad sector forw. */ 666 #define BSD_D_RAMDISK 0x08 /* disk emulator */ 667 #define BSD_D_CHAIN 0x10 /* can do back-back transfers */ 668 #define BSD_D_DOSPART 0x20 /* within MSDOS partition */ 669 670 #endif /* OSF_LABEL */ 671 672 /* 673 * Copyright (C) Andreas Neuper, Sep 1998. 674 * This file may be modified and redistributed under 675 * the terms of the GNU Public License. 676 */ 677 678 struct device_parameter { /* 48 bytes */ 679 unsigned char skew; 680 unsigned char gap1; 681 unsigned char gap2; 682 unsigned char sparecyl; 683 unsigned short pcylcount; 684 unsigned short head_vol0; 685 unsigned short ntrks; /* tracks in cyl 0 or vol 0 */ 686 unsigned char cmd_tag_queue_depth; 687 unsigned char unused0; 688 unsigned short unused1; 689 unsigned short nsect; /* sectors/tracks in cyl 0 or vol 0 */ 690 unsigned short bytes; 691 unsigned short ilfact; 692 unsigned int flags; /* controller flags */ 693 unsigned int datarate; 694 unsigned int retries_on_error; 695 unsigned int ms_per_word; 696 unsigned short xylogics_gap1; 697 unsigned short xylogics_syncdelay; 698 unsigned short xylogics_readdelay; 699 unsigned short xylogics_gap2; 700 unsigned short xylogics_readgate; 701 unsigned short xylogics_writecont; 702 }; 703 704 #define SGI_VOLHDR 0x00 705 /* 1 and 2 were used for drive types no longer supported by SGI */ 706 #define SGI_SWAP 0x03 707 /* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */ 708 #define SGI_VOLUME 0x06 709 #define SGI_EFS 0x07 710 #define SGI_LVOL 0x08 711 #define SGI_RLVOL 0x09 712 #define SGI_XFS 0x0a 713 #define SGI_XFSLOG 0x0b 714 #define SGI_XLV 0x0c 715 #define SGI_XVM 0x0d 716 #define ENTIRE_DISK SGI_VOLUME 717 /* 718 * controller flags 719 */ 720 #define SECTOR_SLIP 0x01 721 #define SECTOR_FWD 0x02 722 #define TRACK_FWD 0x04 723 #define TRACK_MULTIVOL 0x08 724 #define IGNORE_ERRORS 0x10 725 #define RESEEK 0x20 726 #define ENABLE_CMDTAGQ 0x40 727 728 typedef struct { 729 unsigned int magic; /* expect SGI_LABEL_MAGIC */ 730 unsigned short boot_part; /* active boot partition */ 731 unsigned short swap_part; /* active swap partition */ 732 unsigned char boot_file[16]; /* name of the bootfile */ 733 struct device_parameter devparam; /* 1 * 48 bytes */ 734 struct volume_directory { /* 15 * 16 bytes */ 735 unsigned char vol_file_name[8]; /* a character array */ 736 unsigned int vol_file_start; /* number of logical block */ 737 unsigned int vol_file_size; /* number of bytes */ 738 } directory[15]; 739 struct sgi_partition { /* 16 * 12 bytes */ 740 unsigned int num_sectors; /* number of blocks */ 741 unsigned int start_sector; /* must be cylinder aligned */ 742 unsigned int id; 743 } partitions[16]; 744 unsigned int csum; 745 unsigned int fillbytes; 746 } sgi_partition; 747 748 typedef struct { 749 unsigned int magic; /* looks like a magic number */ 750 unsigned int a2; 751 unsigned int a3; 752 unsigned int a4; 753 unsigned int b1; 754 unsigned short b2; 755 unsigned short b3; 756 unsigned int c[16]; 757 unsigned short d[3]; 758 unsigned char scsi_string[50]; 759 unsigned char serial[137]; 760 unsigned short check1816; 761 unsigned char installer[225]; 762 } sgiinfo; 763 764 #define SGI_LABEL_MAGIC 0x0be5a941 765 #define SGI_LABEL_MAGIC_SWAPPED 0x41a9e50b 766 #define SGI_INFO_MAGIC 0x00072959 767 #define SGI_INFO_MAGIC_SWAPPED 0x59290700 768 #define SGI_SSWAP16(x) (sgi_other_endian ? __swap16(x) \ 769 : (uint16_t)(x)) 770 #define SGI_SSWAP32(x) (sgi_other_endian ? __swap32(x) \ 771 : (uint32_t)(x)) 772 773 #define sgilabel ((sgi_partition *)MBRbuffer) 774 #define sgiparam (sgilabel->devparam) 464 continue; 465 } 466 v = bb_strtoul(line_ptr, NULL, 16); 467 if (v > 0xff) 468 /* Bad input also triggers this */ 469 continue; 470 return v; 471 } 472 } 473 #endif /* FEATURE_FDISK_WRITABLE */ 474 475 #include "fdisk_aix.c" 775 476 776 477 typedef struct { … … 794 495 unsigned short nsect; /* Sectors per track */ 795 496 unsigned char spare3[4]; /* Even more magic... */ 796 struct sun_parti tion{497 struct sun_partinfo { 797 498 uint32_t start_cylinder; 798 499 uint32_t num_sectors; … … 801 502 unsigned short csum; /* Label xor'd checksum */ 802 503 } sun_partition; 803 804 805 #define SUN_LABEL_MAGIC 0xDABE806 #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA807 504 #define sunlabel ((sun_partition *)MBRbuffer) 808 #define SUN_SSWAP16(x) (sun_other_endian ? __swap16(x) \ 809 : (uint16_t)(x)) 810 #define SUN_SSWAP32(x) (sun_other_endian ? __swap32(x) \ 811 : (uint32_t)(x)) 812 813 814 #ifdef CONFIG_FEATURE_OSF_LABEL 815 /* 816 Changes: 817 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls 818 819 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better 820 support for OSF/1 disklabels on Alpha. 821 Also fixed unaligned accesses in alpha_bootblock_checksum() 822 */ 823 824 #define FREEBSD_PARTITION 0xa5 825 #define NETBSD_PARTITION 0xa9 826 827 static void xbsd_delete_part(void); 828 static void xbsd_new_part(void); 829 static void xbsd_write_disklabel(void); 830 static int xbsd_create_disklabel(void); 831 static void xbsd_edit_disklabel(void); 832 static void xbsd_write_bootstrap(void); 833 static void xbsd_change_fstype(void); 834 static int xbsd_get_part_index(int max); 835 static int xbsd_check_new_partition(int *i); 836 static void xbsd_list_types(void); 837 static u_short xbsd_dkcksum(struct xbsd_disklabel *lp); 838 static int xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d); 839 static int xbsd_readlabel(struct partition *p, struct xbsd_disklabel *d); 840 static int xbsd_writelabel(struct partition *p, struct xbsd_disklabel *d); 841 842 #if defined (__alpha__) 843 static void alpha_bootblock_checksum(char *boot); 844 #endif 845 846 #if !defined (__alpha__) 847 static int xbsd_translate_fstype(int linux_type); 848 static void xbsd_link_part(void); 849 static struct partition *xbsd_part; 850 static int xbsd_part_index; 851 #endif 852 853 #if defined (__alpha__) 854 /* We access this through a uint64_t * when checksumming */ 855 static char disklabelbuffer[BSD_BBSIZE] ATTRIBUTE_ALIGNED(8); 856 #else 857 static char disklabelbuffer[BSD_BBSIZE]; 858 #endif 859 860 static struct xbsd_disklabel xbsd_dlabel; 861 862 #define bsd_cround(n) \ 863 (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) 864 865 /* 866 * Test whether the whole disk has BSD disk label magic. 867 * 868 * Note: often reformatting with DOS-type label leaves the BSD magic, 869 * so this does not mean that there is a BSD disk label. 870 */ 871 static int 872 check_osf_label(void) 873 { 874 if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0) 875 return 0; 876 return 1; 877 } 878 879 static void xbsd_print_disklabel(int); 880 881 static int 882 btrydev(const char * dev) 883 { 884 if (xbsd_readlabel (NULL, &xbsd_dlabel) == 0) 885 return -1; 886 printf(_("\nBSD label for device: %s\n"), dev); 887 xbsd_print_disklabel (0); 888 return 0; 889 } 890 891 static void 892 bmenu(void) 893 { 894 puts (_("Command action")); 895 puts (_("\td\tdelete a BSD partition")); 896 puts (_("\te\tedit drive data")); 897 puts (_("\ti\tinstall bootstrap")); 898 puts (_("\tl\tlist known filesystem types")); 899 puts (_("\tm\tprint this menu")); 900 puts (_("\tn\tadd a new BSD partition")); 901 puts (_("\tp\tprint BSD partition table")); 902 puts (_("\tq\tquit without saving changes")); 903 puts (_("\tr\treturn to main menu")); 904 puts (_("\ts\tshow complete disklabel")); 905 puts (_("\tt\tchange a partition's filesystem id")); 906 puts (_("\tu\tchange units (cylinders/sectors)")); 907 puts (_("\tw\twrite disklabel to disk")); 908 #if !defined (__alpha__) 909 puts (_("\tx\tlink BSD partition to non-BSD partition")); 910 #endif 911 } 912 913 #if !defined (__alpha__) 914 static int 915 hidden(int type) 916 { 917 return type ^ 0x10; 918 } 919 920 static int 921 is_bsd_partition_type(int type) 922 { 923 return (type == FREEBSD_PARTITION || 924 type == hidden(FREEBSD_PARTITION) || 925 type == NETBSD_PARTITION || 926 type == hidden(NETBSD_PARTITION)); 927 } 928 #endif 929 930 static void 931 bselect(void) 932 { 933 #if !defined (__alpha__) 934 int t, ss; 935 struct partition *p; 936 937 for (t = 0; t < 4; t++) { 938 p = get_part_table(t); 939 if (p && is_bsd_partition_type(p->sys_ind)) { 940 xbsd_part = p; 941 xbsd_part_index = t; 942 ss = get_start_sect(xbsd_part); 943 if (ss == 0) { 944 fprintf(stderr, _("Partition %s has invalid starting sector 0.\n"), 945 partname(disk_device, t+1, 0)); 946 return; 947 } 948 printf(_("Reading disklabel of %s at sector %d.\n"), 949 partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); 950 if (xbsd_readlabel(xbsd_part, &xbsd_dlabel) == 0) 951 if (xbsd_create_disklabel() == 0) 952 return; 953 break; 954 } 955 } 956 957 if (t == 4) { 958 printf(_("There is no *BSD partition on %s.\n"), disk_device); 959 return; 960 } 961 962 #elif defined (__alpha__) 963 964 if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0) 965 if (xbsd_create_disklabel() == 0) 966 exit (EXIT_SUCCESS); 967 968 #endif 969 970 while (1) { 971 putchar('\n'); 972 switch (tolower(read_char(_("BSD disklabel command (m for help): ")))) { 973 case 'd': 974 xbsd_delete_part(); 975 break; 976 case 'e': 977 xbsd_edit_disklabel(); 978 break; 979 case 'i': 980 xbsd_write_bootstrap(); 981 break; 982 case 'l': 983 xbsd_list_types(); 984 break; 985 case 'n': 986 xbsd_new_part(); 987 break; 988 case 'p': 989 xbsd_print_disklabel(0); 990 break; 991 case 'q': 992 close(fd); 993 exit(EXIT_SUCCESS); 994 case 'r': 995 return; 996 case 's': 997 xbsd_print_disklabel(1); 998 break; 999 case 't': 1000 xbsd_change_fstype(); 1001 break; 1002 case 'u': 1003 change_units(); 1004 break; 1005 case 'w': 1006 xbsd_write_disklabel(); 1007 break; 1008 #if !defined (__alpha__) 1009 case 'x': 1010 xbsd_link_part(); 1011 break; 1012 #endif 1013 default: 1014 bmenu(); 1015 break; 1016 } 1017 } 1018 } 1019 1020 static void 1021 xbsd_delete_part(void) 1022 { 1023 int i; 1024 1025 i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); 1026 xbsd_dlabel.d_partitions[i].p_size = 0; 1027 xbsd_dlabel.d_partitions[i].p_offset = 0; 1028 xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; 1029 if (xbsd_dlabel.d_npartitions == i + 1) 1030 while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0) 1031 xbsd_dlabel.d_npartitions--; 1032 } 1033 1034 static void 1035 xbsd_new_part(void) 1036 { 1037 off_t begin, end; 1038 char mesg[256]; 1039 int i; 1040 1041 if (!xbsd_check_new_partition(&i)) 1042 return; 1043 1044 #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__) 1045 begin = get_start_sect(xbsd_part); 1046 end = begin + get_nr_sects(xbsd_part) - 1; 1047 #else 1048 begin = 0; 1049 end = xbsd_dlabel.d_secperunit - 1; 1050 #endif 1051 1052 snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); 1053 begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), 1054 0, mesg); 1055 1056 if (display_in_cyl_units) 1057 begin = (begin - 1) * xbsd_dlabel.d_secpercyl; 1058 1059 snprintf(mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"), 1060 str_units(SINGULAR)); 1061 end = read_int(bsd_cround (begin), bsd_cround (end), bsd_cround (end), 1062 bsd_cround (begin), mesg); 1063 1064 if (display_in_cyl_units) 1065 end = end * xbsd_dlabel.d_secpercyl - 1; 1066 1067 xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; 1068 xbsd_dlabel.d_partitions[i].p_offset = begin; 1069 xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; 1070 } 1071 1072 static void 1073 xbsd_print_disklabel(int show_all) 1074 { 1075 struct xbsd_disklabel *lp = &xbsd_dlabel; 1076 struct xbsd_partition *pp; 1077 int i, j; 1078 1079 if (show_all) { 1080 #if defined (__alpha__) 1081 printf("# %s:\n", disk_device); 1082 #else 1083 printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0)); 1084 #endif 1085 if ((unsigned) lp->d_type < BSD_DKMAXTYPES) 1086 printf(_("type: %s\n"), xbsd_dktypenames[lp->d_type]); 1087 else 1088 printf(_("type: %d\n"), lp->d_type); 1089 printf(_("disk: %.*s\n"), (int) sizeof(lp->d_typename), lp->d_typename); 1090 printf(_("label: %.*s\n"), (int) sizeof(lp->d_packname), lp->d_packname); 1091 printf(_("flags:")); 1092 if (lp->d_flags & BSD_D_REMOVABLE) 1093 printf(_(" removable")); 1094 if (lp->d_flags & BSD_D_ECC) 1095 printf(_(" ecc")); 1096 if (lp->d_flags & BSD_D_BADSECT) 1097 printf(_(" badsect")); 1098 printf("\n"); 1099 /* On various machines the fields of *lp are short/int/long */ 1100 /* In order to avoid problems, we cast them all to long. */ 1101 printf(_("bytes/sector: %ld\n"), (long) lp->d_secsize); 1102 printf(_("sectors/track: %ld\n"), (long) lp->d_nsectors); 1103 printf(_("tracks/cylinder: %ld\n"), (long) lp->d_ntracks); 1104 printf(_("sectors/cylinder: %ld\n"), (long) lp->d_secpercyl); 1105 printf(_("cylinders: %ld\n"), (long) lp->d_ncylinders); 1106 printf(_("rpm: %d\n"), lp->d_rpm); 1107 printf(_("interleave: %d\n"), lp->d_interleave); 1108 printf(_("trackskew: %d\n"), lp->d_trackskew); 1109 printf(_("cylinderskew: %d\n"), lp->d_cylskew); 1110 printf(_("headswitch: %ld\t\t# milliseconds\n"), 1111 (long) lp->d_headswitch); 1112 printf(_("track-to-track seek: %ld\t# milliseconds\n"), 1113 (long) lp->d_trkseek); 1114 printf(_("drivedata: ")); 1115 for (i = NDDATA - 1; i >= 0; i--) 1116 if (lp->d_drivedata[i]) 1117 break; 1118 if (i < 0) 1119 i = 0; 1120 for (j = 0; j <= i; j++) 1121 printf("%ld ", (long) lp->d_drivedata[j]); 1122 } 1123 printf(_("\n%d partitions:\n"), lp->d_npartitions); 1124 printf(_("# start end size fstype [fsize bsize cpg]\n")); 1125 pp = lp->d_partitions; 1126 for (i = 0; i < lp->d_npartitions; i++, pp++) { 1127 if (pp->p_size) { 1128 if (display_in_cyl_units && lp->d_secpercyl) { 1129 printf(" %c: %8ld%c %8ld%c %8ld%c ", 1130 'a' + i, 1131 (long) pp->p_offset / lp->d_secpercyl + 1, 1132 (pp->p_offset % lp->d_secpercyl) ? '*' : ' ', 1133 (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl, 1134 ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ', 1135 (long) pp->p_size / lp->d_secpercyl, 1136 (pp->p_size % lp->d_secpercyl) ? '*' : ' ' 1137 ); 1138 } else { 1139 printf(" %c: %8ld %8ld %8ld ", 1140 'a' + i, 1141 (long) pp->p_offset, 1142 (long) pp->p_offset + pp->p_size - 1, 1143 (long) pp->p_size 1144 ); 1145 } 1146 1147 if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES) 1148 printf("%8.8s", xbsd_fstypes[pp->p_fstype].name); 1149 else 1150 printf("%8x", pp->p_fstype); 1151 1152 switch (pp->p_fstype) { 1153 case BSD_FS_UNUSED: 1154 printf(" %5ld %5ld %5.5s ", 1155 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, ""); 1156 break; 1157 case BSD_FS_BSDFFS: 1158 printf(" %5ld %5ld %5d ", 1159 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg); 1160 break; 1161 default: 1162 printf("%22.22s", ""); 1163 break; 1164 } 1165 printf("\n"); 1166 } 1167 } 1168 } 1169 1170 static void 1171 xbsd_write_disklabel(void) 1172 { 1173 #if defined (__alpha__) 1174 printf(_("Writing disklabel to %s.\n"), disk_device); 1175 xbsd_writelabel(NULL, &xbsd_dlabel); 1176 #else 1177 printf(_("Writing disklabel to %s.\n"), 1178 partname(disk_device, xbsd_part_index + 1, 0)); 1179 xbsd_writelabel(xbsd_part, &xbsd_dlabel); 1180 #endif 1181 reread_partition_table(0); /* no exit yet */ 1182 } 1183 1184 static int 1185 xbsd_create_disklabel(void) 1186 { 1187 char c; 1188 1189 #if defined (__alpha__) 1190 fprintf(stderr, _("%s contains no disklabel.\n"), disk_device); 1191 #else 1192 fprintf(stderr, _("%s contains no disklabel.\n"), 1193 partname(disk_device, xbsd_part_index + 1, 0)); 1194 #endif 1195 1196 while (1) { 1197 c = read_char(_("Do you want to create a disklabel? (y/n) ")); 1198 if (c == 'y' || c == 'Y') { 1199 if (xbsd_initlabel( 1200 #if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \ 1201 defined (__s390__) || defined (__s390x__) 1202 NULL, &xbsd_dlabel 1203 #else 1204 xbsd_part, &xbsd_dlabel/* not used, xbsd_part_index*/ 1205 #endif 1206 ) == 1) { 1207 xbsd_print_disklabel (1); 1208 return 1; 1209 } else 1210 return 0; 1211 } else if (c == 'n') 1212 return 0; 1213 } 1214 } 1215 1216 static int 1217 edit_int(int def, char *mesg) 1218 { 1219 do { 1220 fputs(mesg, stdout); 1221 printf(" (%d): ", def); 1222 if (!read_line()) 1223 return def; 1224 } 1225 while (!isdigit(*line_ptr)); /* FIXME: ?!! */ 1226 return atoi(line_ptr); 1227 } 1228 1229 static void 1230 xbsd_edit_disklabel(void) 1231 { 1232 struct xbsd_disklabel *d; 1233 1234 d = &xbsd_dlabel; 1235 1236 #if defined (__alpha__) || defined (__ia64__) 1237 d->d_secsize = (u_long) edit_int((u_long) d->d_secsize ,_("bytes/sector")); 1238 d->d_nsectors = (u_long) edit_int((u_long) d->d_nsectors ,_("sectors/track")); 1239 d->d_ntracks = (u_long) edit_int((u_long) d->d_ntracks ,_("tracks/cylinder")); 1240 d->d_ncylinders = (u_long) edit_int((u_long) d->d_ncylinders ,_("cylinders")); 1241 #endif 1242 1243 /* d->d_secpercyl can be != d->d_nsectors * d->d_ntracks */ 1244 while (1) { 1245 d->d_secpercyl = (u_long) edit_int((u_long) d->d_nsectors * d->d_ntracks, 1246 _("sectors/cylinder")); 1247 if (d->d_secpercyl <= d->d_nsectors * d->d_ntracks) 1248 break; 1249 1250 printf(_("Must be <= sectors/track * tracks/cylinder (default).\n")); 1251 } 1252 d->d_rpm = (u_short) edit_int((u_short) d->d_rpm ,_("rpm")); 1253 d->d_interleave = (u_short) edit_int((u_short) d->d_interleave,_("interleave")); 1254 d->d_trackskew = (u_short) edit_int((u_short) d->d_trackskew ,_("trackskew")); 1255 d->d_cylskew = (u_short) edit_int((u_short) d->d_cylskew ,_("cylinderskew")); 1256 d->d_headswitch = (u_long) edit_int((u_long) d->d_headswitch ,_("headswitch")); 1257 d->d_trkseek = (u_long) edit_int((u_long) d->d_trkseek ,_("track-to-track seek")); 1258 1259 d->d_secperunit = d->d_secpercyl * d->d_ncylinders; 1260 } 1261 1262 static int 1263 xbsd_get_bootstrap (char *path, void *ptr, int size) 1264 { 1265 int fdb; 1266 1267 if ((fdb = open (path, O_RDONLY)) < 0) { 1268 perror(path); 1269 return 0; 1270 } 1271 if (read(fdb, ptr, size) < 0) { 1272 perror(path); 1273 close(fdb); 1274 return 0; 1275 } 1276 printf(" ... %s\n", path); 1277 close(fdb); 1278 return 1; 1279 } 1280 1281 static void 1282 sync_disks(void) 1283 { 1284 printf(_("\nSyncing disks.\n")); 1285 sync(); 1286 sleep(4); /* What? */ 1287 } 1288 1289 static void 1290 xbsd_write_bootstrap(void) 1291 { 1292 char *bootdir = BSD_LINUX_BOOTDIR; 1293 char path[MAXPATHLEN]; 1294 char *dkbasename; 1295 struct xbsd_disklabel dl; 1296 char *d, *p, *e; 1297 int sector; 1298 1299 if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI) 1300 dkbasename = "sd"; 1301 else 1302 dkbasename = "wd"; 1303 1304 printf(_("Bootstrap: %sboot -> boot%s (%s): "), 1305 dkbasename, dkbasename, dkbasename); 1306 if (read_line()) { 1307 line_ptr[strlen(line_ptr)-1] = '\0'; 1308 dkbasename = line_ptr; 1309 } 1310 snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); 1311 if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) 1312 return; 1313 1314 /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ 1315 d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; 1316 memmove(&dl, d, sizeof(struct xbsd_disklabel)); 1317 1318 /* The disklabel will be overwritten by 0's from bootxx anyway */ 1319 memset(d, 0, sizeof(struct xbsd_disklabel)); 1320 1321 snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename); 1322 if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize], 1323 (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) 1324 return; 1325 1326 e = d + sizeof(struct xbsd_disklabel); 1327 for (p = d; p < e; p++) 1328 if (*p) { 1329 fprintf(stderr, _("Bootstrap overlaps with disk label!\n")); 1330 exit(EXIT_FAILURE); 1331 } 1332 1333 memmove(d, &dl, sizeof(struct xbsd_disklabel)); 1334 1335 #if defined (__powerpc__) || defined (__hppa__) 1336 sector = 0; 1337 #elif defined (__alpha__) 1338 sector = 0; 1339 alpha_bootblock_checksum(disklabelbuffer); 1340 #else 1341 sector = get_start_sect(xbsd_part); 1342 #endif 1343 1344 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) 1345 fdisk_fatal(unable_to_seek); 1346 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) 1347 fdisk_fatal(unable_to_write); 1348 1349 #if defined (__alpha__) 1350 printf(_("Bootstrap installed on %s.\n"), disk_device); 1351 #else 1352 printf(_("Bootstrap installed on %s.\n"), 1353 partname (disk_device, xbsd_part_index+1, 0)); 1354 #endif 1355 1356 sync_disks(); 1357 } 1358 1359 static void 1360 xbsd_change_fstype(void) 1361 { 1362 int i; 1363 1364 i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); 1365 xbsd_dlabel.d_partitions[i].p_fstype = read_hex(xbsd_fstypes); 1366 } 1367 1368 static int 1369 xbsd_get_part_index(int max) 1370 { 1371 char prompt[256]; 1372 char l; 1373 1374 snprintf(prompt, sizeof(prompt), _("Partition (a-%c): "), 'a' + max - 1); 1375 do 1376 l = tolower(read_char(prompt)); 1377 while (l < 'a' || l > 'a' + max - 1); 1378 return l - 'a'; 1379 } 1380 1381 static int 1382 xbsd_check_new_partition(int *i) 1383 { 1384 /* room for more? various BSD flavours have different maxima */ 1385 if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) { 1386 int t; 1387 1388 for (t = 0; t < BSD_MAXPARTITIONS; t++) 1389 if (xbsd_dlabel.d_partitions[t].p_size == 0) 1390 break; 1391 1392 if (t == BSD_MAXPARTITIONS) { 1393 fprintf(stderr, _("The maximum number of partitions " 1394 "has been created\n")); 1395 return 0; 1396 } 1397 } 1398 1399 *i = xbsd_get_part_index (BSD_MAXPARTITIONS); 1400 1401 if (*i >= xbsd_dlabel.d_npartitions) 1402 xbsd_dlabel.d_npartitions = (*i) + 1; 1403 1404 if (xbsd_dlabel.d_partitions[*i].p_size != 0) { 1405 fprintf(stderr, _("This partition already exists.\n")); 1406 return 0; 1407 } 1408 1409 return 1; 1410 } 1411 1412 static void 1413 xbsd_list_types(void) 1414 { 1415 list_types(xbsd_fstypes); 1416 } 1417 1418 static u_short 1419 xbsd_dkcksum(struct xbsd_disklabel *lp) 1420 { 1421 u_short *start, *end; 1422 u_short sum = 0; 1423 1424 start = (u_short *) lp; 1425 end = (u_short *) &lp->d_partitions[lp->d_npartitions]; 1426 while (start < end) 1427 sum ^= *start++; 1428 return sum; 1429 } 1430 1431 static int 1432 xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d) 1433 { 1434 struct xbsd_partition *pp; 1435 1436 get_geometry(); 1437 memset(d, 0, sizeof(struct xbsd_disklabel)); 1438 1439 d->d_magic = BSD_DISKMAGIC; 1440 1441 if (strncmp(disk_device, "/dev/sd", 7) == 0) 1442 d->d_type = BSD_DTYPE_SCSI; 1443 else 1444 d->d_type = BSD_DTYPE_ST506; 1445 1446 #if 0 /* not used (at least not written to disk) by NetBSD/i386 1.0 */ 1447 d->d_subtype = BSD_DSTYPE_INDOSPART & pindex; 1448 #endif 1449 1450 #if !defined (__alpha__) 1451 d->d_flags = BSD_D_DOSPART; 1452 #else 1453 d->d_flags = 0; 1454 #endif 1455 d->d_secsize = SECTOR_SIZE; /* bytes/sector */ 1456 d->d_nsectors = sectors; /* sectors/track */ 1457 d->d_ntracks = heads; /* tracks/cylinder (heads) */ 1458 d->d_ncylinders = cylinders; 1459 d->d_secpercyl = sectors * heads;/* sectors/cylinder */ 1460 if (d->d_secpercyl == 0) 1461 d->d_secpercyl = 1; /* avoid segfaults */ 1462 d->d_secperunit = d->d_secpercyl * d->d_ncylinders; 1463 1464 d->d_rpm = 3600; 1465 d->d_interleave = 1; 1466 d->d_trackskew = 0; 1467 d->d_cylskew = 0; 1468 d->d_headswitch = 0; 1469 d->d_trkseek = 0; 1470 1471 d->d_magic2 = BSD_DISKMAGIC; 1472 d->d_bbsize = BSD_BBSIZE; 1473 d->d_sbsize = BSD_SBSIZE; 1474 1475 #if !defined (__alpha__) 1476 d->d_npartitions = 4; 1477 pp = &d->d_partitions[2]; /* Partition C should be 1478 the NetBSD partition */ 1479 pp->p_offset = get_start_sect(p); 1480 pp->p_size = get_nr_sects(p); 1481 pp->p_fstype = BSD_FS_UNUSED; 1482 pp = &d->d_partitions[3]; /* Partition D should be 1483 the whole disk */ 1484 pp->p_offset = 0; 1485 pp->p_size = d->d_secperunit; 1486 pp->p_fstype = BSD_FS_UNUSED; 1487 #elif defined (__alpha__) 1488 d->d_npartitions = 3; 1489 pp = &d->d_partitions[2]; /* Partition C should be 1490 the whole disk */ 1491 pp->p_offset = 0; 1492 pp->p_size = d->d_secperunit; 1493 pp->p_fstype = BSD_FS_UNUSED; 1494 #endif 1495 1496 return 1; 1497 } 1498 1499 /* 1500 * Read a xbsd_disklabel from sector 0 or from the starting sector of p. 1501 * If it has the right magic, return 1. 1502 */ 1503 static int 1504 xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d) 1505 { 1506 int t, sector; 1507 1508 /* p is used only to get the starting sector */ 1509 #if !defined (__alpha__) 1510 sector = (p ? get_start_sect(p) : 0); 1511 #elif defined (__alpha__) 1512 sector = 0; 1513 #endif 1514 1515 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) 1516 fdisk_fatal(unable_to_seek); 1517 if (BSD_BBSIZE != read(fd, disklabelbuffer, BSD_BBSIZE)) 1518 fdisk_fatal(unable_to_read); 1519 1520 memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], 1521 sizeof(struct xbsd_disklabel)); 1522 1523 if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) 1524 return 0; 1525 1526 for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) { 1527 d->d_partitions[t].p_size = 0; 1528 d->d_partitions[t].p_offset = 0; 1529 d->d_partitions[t].p_fstype = BSD_FS_UNUSED; 1530 } 1531 1532 if (d->d_npartitions > BSD_MAXPARTITIONS) 1533 fprintf(stderr, _("Warning: too many partitions " 1534 "(%d, maximum is %d).\n"), 1535 d->d_npartitions, BSD_MAXPARTITIONS); 1536 return 1; 1537 } 1538 1539 static int 1540 xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) 1541 { 1542 unsigned int sector; 1543 1544 #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__) 1545 sector = get_start_sect(p) + BSD_LABELSECTOR; 1546 #else 1547 sector = BSD_LABELSECTOR; 1548 #endif 1549 1550 d->d_checksum = 0; 1551 d->d_checksum = xbsd_dkcksum (d); 1552 1553 /* This is necessary if we want to write the bootstrap later, 1554 otherwise we'd write the old disklabel with the bootstrap. 1555 */ 1556 memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], 1557 d, sizeof(struct xbsd_disklabel)); 1558 1559 #if defined (__alpha__) && BSD_LABELSECTOR == 0 1560 alpha_bootblock_checksum (disklabelbuffer); 1561 if (lseek(fd, 0, SEEK_SET) == -1) 1562 fdisk_fatal(unable_to_seek); 1563 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) 1564 fdisk_fatal(unable_to_write); 1565 #else 1566 if (lseek(fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1) 1567 fdisk_fatal(unable_to_seek); 1568 if (sizeof(struct xbsd_disklabel) != write(fd, d, sizeof(struct xbsd_disklabel))) 1569 fdisk_fatal(unable_to_write); 1570 #endif 1571 sync_disks(); 1572 return 1; 1573 } 1574 1575 1576 #if !defined (__alpha__) 1577 static int 1578 xbsd_translate_fstype(int linux_type) 1579 { 1580 switch (linux_type) { 1581 case 0x01: /* DOS 12-bit FAT */ 1582 case 0x04: /* DOS 16-bit <32M */ 1583 case 0x06: /* DOS 16-bit >=32M */ 1584 case 0xe1: /* DOS access */ 1585 case 0xe3: /* DOS R/O */ 1586 case 0xf2: /* DOS secondary */ 1587 return BSD_FS_MSDOS; 1588 case 0x07: /* OS/2 HPFS */ 1589 return BSD_FS_HPFS; 1590 default: 1591 return BSD_FS_OTHER; 1592 } 1593 } 1594 1595 static void 1596 xbsd_link_part(void) 1597 { 1598 int k, i; 1599 struct partition *p; 1600 1601 k = get_partition(1, partitions); 1602 1603 if (!xbsd_check_new_partition(&i)) 1604 return; 1605 1606 p = get_part_table(k); 1607 1608 xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p); 1609 xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p); 1610 xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind); 1611 } 1612 #endif 1613 1614 #if defined (__alpha__) 1615 1616 #if !defined(__GLIBC__) 1617 typedef unsigned long long uint64_t; 1618 #endif 1619 1620 static void 1621 alpha_bootblock_checksum(char *boot) 1622 { 1623 uint64_t *dp, sum; 1624 int i; 1625 1626 dp = (uint64_t *)boot; 1627 sum = 0; 1628 for (i = 0; i < 63; i++) 1629 sum += dp[i]; 1630 dp[63] = sum; 1631 } 1632 #endif /* __alpha__ */ 1633 1634 #endif /* OSF_LABEL */ 1635 1636 #if defined(CONFIG_FEATURE_SGI_LABEL) || defined(CONFIG_FEATURE_SUN_LABEL) 1637 static inline unsigned short 1638 __swap16(unsigned short x) 1639 { 1640 return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8); 1641 } 1642 1643 static inline uint32_t 1644 __swap32(uint32_t x) 1645 { 1646 return (((x & 0xFF) << 24) | 1647 ((x & 0xFF00) << 8) | 1648 ((x & 0xFF0000) >> 8) | 1649 ((x & 0xFF000000) >> 24)); 1650 } 1651 #endif 1652 1653 #ifdef CONFIG_FEATURE_SGI_LABEL 1654 /* 1655 * 1656 * fdisksgilabel.c 1657 * 1658 * Copyright (C) Andreas Neuper, Sep 1998. 1659 * This file may be modified and redistributed under 1660 * the terms of the GNU Public License. 1661 * 1662 * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 1663 * Internationalization 1664 */ 1665 1666 1667 static int sgi_other_endian; 1668 static int debug; 1669 static short sgi_volumes = 1; 1670 1671 /* 1672 * only dealing with free blocks here 1673 */ 1674 1675 typedef struct { 1676 unsigned int first; 1677 unsigned int last; 1678 } freeblocks; 1679 static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */ 1680 1681 static void 1682 setfreelist(int i, unsigned int f, unsigned int l) 1683 { 1684 freelist[i].first = f; 1685 freelist[i].last = l; 1686 } 1687 1688 static void 1689 add2freelist(unsigned int f, unsigned int l) 1690 { 1691 int i; 1692 for (i = 0; i < 17 ; i++) 1693 if (freelist[i].last == 0) 1694 break; 1695 setfreelist(i, f, l); 1696 } 1697 1698 static void 1699 clearfreelist(void) 1700 { 1701 int i; 1702 1703 for (i = 0; i < 17 ; i++) 1704 setfreelist(i, 0, 0); 1705 } 1706 1707 static unsigned int 1708 isinfreelist(unsigned int b) 1709 { 1710 int i; 1711 1712 for (i = 0; i < 17 ; i++) 1713 if (freelist[i].first <= b && freelist[i].last >= b) 1714 return freelist[i].last; 1715 return 0; 1716 } 1717 /* return last vacant block of this stride (never 0). */ 1718 /* the '>=' is not quite correct, but simplifies the code */ 1719 /* 1720 * end of free blocks section 1721 */ 1722 1723 static const struct systypes sgi_sys_types[] = { 1724 /* SGI_VOLHDR */ { "\x00" "SGI volhdr" }, 1725 /* 0x01 */ { "\x01" "SGI trkrepl" }, 1726 /* 0x02 */ { "\x02" "SGI secrepl" }, 1727 /* SGI_SWAP */ { "\x03" "SGI raw" }, 1728 /* 0x04 */ { "\x04" "SGI bsd" }, 1729 /* 0x05 */ { "\x05" "SGI sysv" }, 1730 /* ENTIRE_DISK */ { "\x06" "SGI volume" }, 1731 /* SGI_EFS */ { "\x07" "SGI efs" }, 1732 /* 0x08 */ { "\x08" "SGI lvol" }, 1733 /* 0x09 */ { "\x09" "SGI rlvol" }, 1734 /* SGI_XFS */ { "\x0a" "SGI xfs" }, 1735 /* SGI_XFSLOG */ { "\x0b" "SGI xfslog" }, 1736 /* SGI_XLV */ { "\x0c" "SGI xlv" }, 1737 /* SGI_XVM */ { "\x0d" "SGI xvm" }, 1738 /* LINUX_SWAP */ { "\x82" "Linux swap" }, 1739 /* LINUX_NATIVE */ { "\x83" "Linux native" }, 1740 /* LINUX_LVM */ { "\x8d" "Linux LVM" }, 1741 /* LINUX_RAID */ { "\xfd" "Linux RAID" }, 1742 { NULL } 1743 }; 1744 1745 1746 static int 1747 sgi_get_nsect(void) 1748 { 1749 return SGI_SSWAP16(sgilabel->devparam.nsect); 1750 } 1751 1752 static int 1753 sgi_get_ntrks(void) 1754 { 1755 return SGI_SSWAP16(sgilabel->devparam.ntrks); 1756 } 1757 1758 static unsigned int 1759 two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */) 1760 { 1761 int i = 0; 1762 unsigned int sum = 0; 1763 1764 size /= sizeof(unsigned int); 1765 for (i = 0; i < size; i++) 1766 sum -= SGI_SSWAP32(base[i]); 1767 return sum; 1768 } 1769 1770 static int 1771 check_sgi_label(void) 1772 { 1773 if (sizeof(sgilabel) > 512) { 1774 fprintf(stderr, 1775 _("According to MIPS Computer Systems, Inc the " 1776 "Label must not contain more than 512 bytes\n")); 1777 exit(1); 1778 } 1779 1780 if (sgilabel->magic != SGI_LABEL_MAGIC 1781 && sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED) { 1782 current_label_type = label_dos; 1783 return 0; 1784 } 1785 1786 sgi_other_endian = (sgilabel->magic == SGI_LABEL_MAGIC_SWAPPED); 1787 /* 1788 * test for correct checksum 1789 */ 1790 if (two_s_complement_32bit_sum((unsigned int*)sgilabel, 1791 sizeof(*sgilabel))) { 1792 fprintf(stderr, 1793 _("Detected sgi disklabel with wrong checksum.\n")); 1794 } 1795 update_units(); 1796 current_label_type = label_sgi; 1797 partitions = 16; 1798 sgi_volumes = 15; 1799 return 1; 1800 } 1801 1802 static unsigned int 1803 sgi_get_start_sector(int i) 1804 { 1805 return SGI_SSWAP32(sgilabel->partitions[i].start_sector); 1806 } 1807 1808 static unsigned int 1809 sgi_get_num_sectors(int i) 1810 { 1811 return SGI_SSWAP32(sgilabel->partitions[i].num_sectors); 1812 } 1813 1814 static int 1815 sgi_get_sysid(int i) 1816 { 1817 return SGI_SSWAP32(sgilabel->partitions[i].id); 1818 } 1819 1820 static int 1821 sgi_get_bootpartition(void) 1822 { 1823 return SGI_SSWAP16(sgilabel->boot_part); 1824 } 1825 1826 static int 1827 sgi_get_swappartition(void) 1828 { 1829 return SGI_SSWAP16(sgilabel->swap_part); 1830 } 1831 1832 static void 1833 sgi_list_table(int xtra) 1834 { 1835 int i, w, wd; 1836 int kpi = 0; /* kernel partition ID */ 1837 1838 if(xtra) { 1839 printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n" 1840 "%d cylinders, %d physical cylinders\n" 1841 "%d extra sects/cyl, interleave %d:1\n" 1842 "%s\n" 1843 "Units = %s of %d * 512 bytes\n\n"), 1844 disk_device, heads, sectors, cylinders, 1845 SGI_SSWAP16(sgiparam.pcylcount), 1846 SGI_SSWAP16(sgiparam.sparecyl), 1847 SGI_SSWAP16(sgiparam.ilfact), 1848 (char *)sgilabel, 1849 str_units(PLURAL), units_per_sector); 1850 } else { 1851 printf( _("\nDisk %s (SGI disk label): " 1852 "%d heads, %d sectors, %d cylinders\n" 1853 "Units = %s of %d * 512 bytes\n\n"), 1854 disk_device, heads, sectors, cylinders, 1855 str_units(PLURAL), units_per_sector ); 1856 } 1857 1858 w = strlen(disk_device); 1859 wd = strlen(_("Device")); 1860 if (w < wd) 1861 w = wd; 1862 1863 printf(_("----- partitions -----\n" 1864 "Pt# %*s Info Start End Sectors Id System\n"), 1865 w + 2, _("Device")); 1866 for (i = 0 ; i < partitions; i++) { 1867 if( sgi_get_num_sectors(i) || debug ) { 1868 uint32_t start = sgi_get_start_sector(i); 1869 uint32_t len = sgi_get_num_sectors(i); 1870 kpi++; /* only count nonempty partitions */ 1871 printf( 1872 "%2d: %s %4s %9ld %9ld %9ld %2x %s\n", 1873 /* fdisk part number */ i+1, 1874 /* device */ partname(disk_device, kpi, w+3), 1875 /* flags */ (sgi_get_swappartition() == i) ? "swap" : 1876 /* flags */ (sgi_get_bootpartition() == i) ? "boot" : " ", 1877 /* start */ (long) scround(start), 1878 /* end */ (long) scround(start+len)-1, 1879 /* no odd flag on end */(long) len, 1880 /* type id */ sgi_get_sysid(i), 1881 /* type name */ partition_type(sgi_get_sysid(i))); 1882 } 1883 } 1884 printf(_("----- Bootinfo -----\nBootfile: %s\n" 1885 "----- Directory Entries -----\n"), 1886 sgilabel->boot_file); 1887 for (i = 0 ; i < sgi_volumes; i++) { 1888 if (sgilabel->directory[i].vol_file_size) { 1889 uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start); 1890 uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size); 1891 unsigned char *name = sgilabel->directory[i].vol_file_name; 1892 1893 printf(_("%2d: %-10s sector%5u size%8u\n"), 1894 i, (char*)name, (unsigned int) start, (unsigned int) len); 1895 } 1896 } 1897 } 1898 1899 static void 1900 sgi_set_bootpartition(int i) 1901 { 1902 sgilabel->boot_part = SGI_SSWAP16(((short)i)); 1903 } 1904 1905 static unsigned int 1906 sgi_get_lastblock(void) 1907 { 1908 return heads * sectors * cylinders; 1909 } 1910 1911 static void 1912 sgi_set_swappartition(int i) 1913 { 1914 sgilabel->swap_part = SGI_SSWAP16(((short)i)); 1915 } 1916 1917 static int 1918 sgi_check_bootfile(const char* aFile) 1919 { 1920 if (strlen(aFile) < 3) /* "/a\n" is minimum */ { 1921 printf(_("\nInvalid Bootfile!\n" 1922 "\tThe bootfile must be an absolute non-zero pathname,\n" 1923 "\te.g. \"/unix\" or \"/unix.save\".\n")); 1924 return 0; 1925 } else { 1926 if (strlen(aFile) > 16) { 1927 printf(_("\n\tName of Bootfile too long: " 1928 "16 bytes maximum.\n")); 1929 return 0; 1930 } else { 1931 if (aFile[0] != '/') { 1932 printf(_("\n\tBootfile must have a " 1933 "fully qualified pathname.\n")); 1934 return 0; 1935 } 1936 } 1937 } 1938 if (strncmp(aFile, (char*)sgilabel->boot_file, 16)) { 1939 printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t" 1940 "SGI's default is \"/unix\" and for backup \"/unix.save\".\n")); 1941 /* filename is correct and did change */ 1942 return 1; 1943 } 1944 return 0; /* filename did not change */ 1945 } 1946 1947 static const char * 1948 sgi_get_bootfile(void) 1949 { 1950 return (char*)sgilabel->boot_file; 1951 } 1952 1953 static void 1954 sgi_set_bootfile(const char* aFile) 1955 { 1956 int i = 0; 1957 1958 if (sgi_check_bootfile(aFile)) { 1959 while (i < 16) { 1960 if ((aFile[i] != '\n') /* in principle caught again by next line */ 1961 && (strlen(aFile) > i)) 1962 sgilabel->boot_file[i] = aFile[i]; 1963 else 1964 sgilabel->boot_file[i] = 0; 1965 i++; 1966 } 1967 printf(_("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file); 1968 } 1969 } 1970 1971 static void 1972 create_sgiinfo(void) 1973 { 1974 /* I keep SGI's habit to write the sgilabel to the second block */ 1975 sgilabel->directory[0].vol_file_start = SGI_SSWAP32(2); 1976 sgilabel->directory[0].vol_file_size = SGI_SSWAP32(sizeof(sgiinfo)); 1977 strcpy((char*)sgilabel->directory[0].vol_file_name, "sgilabel"); 1978 } 1979 1980 static sgiinfo *fill_sgiinfo(void); 1981 1982 static void 1983 sgi_write_table(void) 1984 { 1985 sgilabel->csum = 0; 1986 sgilabel->csum = SGI_SSWAP32(two_s_complement_32bit_sum( 1987 (unsigned int*)sgilabel, sizeof(*sgilabel))); 1988 assert(two_s_complement_32bit_sum( 1989 (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); 1990 1991 if (lseek(fd, 0, SEEK_SET) < 0) 1992 fdisk_fatal(unable_to_seek); 1993 if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE) 1994 fdisk_fatal(unable_to_write); 1995 if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { 1996 /* 1997 * keep this habit of first writing the "sgilabel". 1998 * I never tested whether it works without (AN 981002). 1999 */ 2000 sgiinfo *info = fill_sgiinfo(); 2001 int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); 2002 if (lseek(fd, infostartblock*SECTOR_SIZE, SEEK_SET) < 0) 2003 fdisk_fatal(unable_to_seek); 2004 if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE) 2005 fdisk_fatal(unable_to_write); 2006 free(info); 2007 } 2008 } 2009 2010 static int 2011 compare_start(int *x, int *y) 2012 { 2013 /* 2014 * sort according to start sectors 2015 * and prefers largest partition: 2016 * entry zero is entire disk entry 2017 */ 2018 unsigned int i = *x; 2019 unsigned int j = *y; 2020 unsigned int a = sgi_get_start_sector(i); 2021 unsigned int b = sgi_get_start_sector(j); 2022 unsigned int c = sgi_get_num_sectors(i); 2023 unsigned int d = sgi_get_num_sectors(j); 2024 2025 if (a == b) 2026 return (d > c) ? 1 : (d == c) ? 0 : -1; 2027 return (a > b) ? 1 : -1; 2028 } 2029 2030 2031 static int 2032 verify_sgi(int verbose) 2033 { 2034 int Index[16]; /* list of valid partitions */ 2035 int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ 2036 int entire = 0, i = 0; 2037 unsigned int start = 0; 2038 long long gap = 0; /* count unused blocks */ 2039 unsigned int lastblock = sgi_get_lastblock(); 2040 2041 clearfreelist(); 2042 for (i = 0; i < 16; i++) { 2043 if (sgi_get_num_sectors(i) != 0) { 2044 Index[sortcount++] = i; 2045 if (sgi_get_sysid(i) == ENTIRE_DISK) { 2046 if (entire++ == 1) { 2047 if (verbose) 2048 printf(_("More than one entire disk entry present.\n")); 2049 } 2050 } 2051 } 2052 } 2053 if (sortcount == 0) { 2054 if (verbose) 2055 printf(_("No partitions defined\n")); 2056 return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; 2057 } 2058 qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start); 2059 if (sgi_get_sysid(Index[0]) == ENTIRE_DISK) { 2060 if ((Index[0] != 10) && verbose) 2061 printf(_("IRIX likes when Partition 11 covers the entire disk.\n")); 2062 if ((sgi_get_start_sector(Index[0]) != 0) && verbose) 2063 printf(_("The entire disk partition should start " 2064 "at block 0,\n" 2065 "not at diskblock %d.\n"), 2066 sgi_get_start_sector(Index[0])); 2067 if (debug) /* I do not understand how some disks fulfil it */ 2068 if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) 2069 printf(_("The entire disk partition is only %d diskblock large,\n" 2070 "but the disk is %d diskblocks long.\n"), 2071 sgi_get_num_sectors(Index[0]), lastblock); 2072 lastblock = sgi_get_num_sectors(Index[0]); 2073 } else { 2074 if (verbose) 2075 printf(_("One Partition (#11) should cover the entire disk.\n")); 2076 if (debug > 2) 2077 printf("sysid=%d\tpartition=%d\n", 2078 sgi_get_sysid(Index[0]), Index[0]+1); 2079 } 2080 for (i = 1, start = 0; i < sortcount; i++) { 2081 int cylsize = sgi_get_nsect() * sgi_get_ntrks(); 2082 2083 if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { 2084 if (debug) /* I do not understand how some disks fulfil it */ 2085 if (verbose) 2086 printf(_("Partition %d does not start on cylinder boundary.\n"), 2087 Index[i]+1); 2088 } 2089 if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { 2090 if (debug) /* I do not understand how some disks fulfil it */ 2091 if (verbose) 2092 printf(_("Partition %d does not end on cylinder boundary.\n"), 2093 Index[i]+1); 2094 } 2095 /* We cannot handle several "entire disk" entries. */ 2096 if (sgi_get_sysid(Index[i]) == ENTIRE_DISK) continue; 2097 if (start > sgi_get_start_sector(Index[i])) { 2098 if (verbose) 2099 printf(_("The Partition %d and %d overlap by %d sectors.\n"), 2100 Index[i-1]+1, Index[i]+1, 2101 start - sgi_get_start_sector(Index[i])); 2102 if (gap > 0) gap = -gap; 2103 if (gap == 0) gap = -1; 2104 } 2105 if (start < sgi_get_start_sector(Index[i])) { 2106 if (verbose) 2107 printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), 2108 sgi_get_start_sector(Index[i]) - start, 2109 start, sgi_get_start_sector(Index[i])-1); 2110 gap += sgi_get_start_sector(Index[i]) - start; 2111 add2freelist(start, sgi_get_start_sector(Index[i])); 2112 } 2113 start = sgi_get_start_sector(Index[i]) 2114 + sgi_get_num_sectors(Index[i]); 2115 if (debug > 1) { 2116 if (verbose) 2117 printf("%2d:%12d\t%12d\t%12d\n", Index[i], 2118 sgi_get_start_sector(Index[i]), 2119 sgi_get_num_sectors(Index[i]), 2120 sgi_get_sysid(Index[i])); 2121 } 2122 } 2123 if (start < lastblock) { 2124 if (verbose) 2125 printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"), 2126 lastblock - start, start, lastblock-1); 2127 gap += lastblock - start; 2128 add2freelist(start, lastblock); 2129 } 2130 /* 2131 * Done with arithmetics 2132 * Go for details now 2133 */ 2134 if (verbose) { 2135 if (!sgi_get_num_sectors(sgi_get_bootpartition())) { 2136 printf(_("\nThe boot partition does not exist.\n")); 2137 } 2138 if (!sgi_get_num_sectors(sgi_get_swappartition())) { 2139 printf(_("\nThe swap partition does not exist.\n")); 2140 } else { 2141 if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP) 2142 && (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP)) 2143 printf(_("\nThe swap partition has no swap type.\n")); 2144 } 2145 if (sgi_check_bootfile("/unix")) 2146 printf(_("\tYou have chosen an unusual boot file name.\n")); 2147 } 2148 return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; 2149 } 2150 2151 static int 2152 sgi_gaps(void) 2153 { 2154 /* 2155 * returned value is: 2156 * = 0 : disk is properly filled to the rim 2157 * < 0 : there is an overlap 2158 * > 0 : there is still some vacant space 2159 */ 2160 return verify_sgi(0); 2161 } 2162 2163 static void 2164 sgi_change_sysid(int i, int sys) 2165 { 2166 if( sgi_get_num_sectors(i) == 0 ) { /* caught already before, ... */ 2167 printf(_("Sorry You may change the Tag of non-empty partitions.\n")); 2168 return; 2169 } 2170 if (((sys != ENTIRE_DISK ) && (sys != SGI_VOLHDR)) 2171 && (sgi_get_start_sector(i) < 1) ) { 2172 read_chars( 2173 _("It is highly recommended that the partition at offset 0\n" 2174 "is of type \"SGI volhdr\", the IRIX system will rely on it to\n" 2175 "retrieve from its directory standalone tools like sash and fx.\n" 2176 "Only the \"SGI volume\" entire disk section may violate this.\n" 2177 "Type YES if you are sure about tagging this partition differently.\n")); 2178 if (strcmp(line_ptr, _("YES\n"))) 2179 return; 2180 } 2181 sgilabel->partitions[i].id = SGI_SSWAP32(sys); 2182 } 2183 2184 /* returns partition index of first entry marked as entire disk */ 2185 static int 2186 sgi_entire(void) 2187 { 2188 int i; 2189 2190 for (i = 0; i < 16; i++) 2191 if (sgi_get_sysid(i) == SGI_VOLUME) 2192 return i; 2193 return -1; 2194 } 2195 2196 static void 2197 sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) 2198 { 2199 sgilabel->partitions[i].id = SGI_SSWAP32(sys); 2200 sgilabel->partitions[i].num_sectors = SGI_SSWAP32(length); 2201 sgilabel->partitions[i].start_sector = SGI_SSWAP32(start); 2202 set_changed(i); 2203 if (sgi_gaps() < 0) /* rebuild freelist */ 2204 printf(_("Do You know, You got a partition overlap on the disk?\n")); 2205 } 2206 2207 static void 2208 sgi_set_entire(void) 2209 { 2210 int n; 2211 2212 for (n = 10; n < partitions; n++) { 2213 if(!sgi_get_num_sectors(n) ) { 2214 sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME); 2215 break; 2216 } 2217 } 2218 } 2219 2220 static void 2221 sgi_set_volhdr(void) 2222 { 2223 int n; 2224 2225 for (n = 8; n < partitions; n++) { 2226 if (!sgi_get_num_sectors(n)) { 2227 /* 2228 * 5 cylinders is an arbitrary value I like 2229 * IRIX 5.3 stored files in the volume header 2230 * (like sash, symmon, fx, ide) with ca. 3200 2231 * sectors. 2232 */ 2233 if (heads * sectors * 5 < sgi_get_lastblock()) 2234 sgi_set_partition(n, 0, heads * sectors * 5, SGI_VOLHDR); 2235 break; 2236 } 2237 } 2238 } 2239 2240 static void 2241 sgi_delete_partition(int i) 2242 { 2243 sgi_set_partition(i, 0, 0, 0); 2244 } 2245 2246 static void 2247 sgi_add_partition(int n, int sys) 2248 { 2249 char mesg[256]; 2250 unsigned int first = 0, last = 0; 2251 2252 if (n == 10) { 2253 sys = SGI_VOLUME; 2254 } else if (n == 8) { 2255 sys = 0; 2256 } 2257 if(sgi_get_num_sectors(n)) { 2258 printf(_("Partition %d is already defined. Delete " 2259 "it before re-adding it.\n"), n + 1); 2260 return; 2261 } 2262 if ((sgi_entire() == -1) && (sys != SGI_VOLUME)) { 2263 printf(_("Attempting to generate entire disk entry automatically.\n")); 2264 sgi_set_entire(); 2265 sgi_set_volhdr(); 2266 } 2267 if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) { 2268 printf(_("The entire disk is already covered with partitions.\n")); 2269 return; 2270 } 2271 if (sgi_gaps() < 0) { 2272 printf(_("You got a partition overlap on the disk. Fix it first!\n")); 2273 return; 2274 } 2275 snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); 2276 while (1) { 2277 if(sys == SGI_VOLUME) { 2278 last = sgi_get_lastblock(); 2279 first = read_int(0, 0, last-1, 0, mesg); 2280 if (first != 0) { 2281 printf(_("It is highly recommended that eleventh partition\n" 2282 "covers the entire disk and is of type `SGI volume'\n")); 2283 } 2284 } else { 2285 first = freelist[0].first; 2286 last = freelist[0].last; 2287 first = read_int(scround(first), scround(first), scround(last)-1, 2288 0, mesg); 2289 } 2290 if (display_in_cyl_units) 2291 first *= units_per_sector; 2292 else 2293 first = first; /* align to cylinder if you know how ... */ 2294 if(!last ) 2295 last = isinfreelist(first); 2296 if(last == 0) { 2297 printf(_("You will get a partition overlap on the disk. " 2298 "Fix it first!\n")); 2299 } else 2300 break; 2301 } 2302 snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR)); 2303 last = read_int(scround(first), scround(last)-1, scround(last)-1, 2304 scround(first), mesg)+1; 2305 if (display_in_cyl_units) 2306 last *= units_per_sector; 2307 else 2308 last = last; /* align to cylinder if You know how ... */ 2309 if ( (sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock() ) ) 2310 printf(_("It is highly recommended that eleventh partition\n" 2311 "covers the entire disk and is of type `SGI volume'\n")); 2312 sgi_set_partition(n, first, last-first, sys); 2313 } 2314 2315 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 2316 static void 2317 create_sgilabel(void) 2318 { 2319 struct hd_geometry geometry; 2320 struct { 2321 unsigned int start; 2322 unsigned int nsect; 2323 int sysid; 2324 } old[4]; 2325 int i = 0; 2326 long longsectors; /* the number of sectors on the device */ 2327 int res; /* the result from the ioctl */ 2328 int sec_fac; /* the sector factor */ 2329 2330 sec_fac = sector_size / 512; /* determine the sector factor */ 2331 2332 fprintf( stderr, 2333 _("Building a new SGI disklabel. Changes will remain in memory only,\n" 2334 "until you decide to write them. After that, of course, the previous\n" 2335 "content will be unrecoverably lost.\n\n")); 2336 2337 sgi_other_endian = (BB_LITTLE_ENDIAN); 2338 res = ioctl(fd, BLKGETSIZE, &longsectors); 2339 if (!ioctl(fd, HDIO_GETGEO, &geometry)) { 2340 heads = geometry.heads; 2341 sectors = geometry.sectors; 2342 if (res == 0) { 2343 /* the get device size ioctl was successful */ 2344 cylinders = longsectors / (heads * sectors); 2345 cylinders /= sec_fac; 2346 } else { 2347 /* otherwise print error and use truncated version */ 2348 cylinders = geometry.cylinders; 2349 fprintf(stderr, 2350 _("Warning: BLKGETSIZE ioctl failed on %s. " 2351 "Using geometry cylinder value of %d.\n" 2352 "This value may be truncated for devices" 2353 " > 33.8 GB.\n"), disk_device, cylinders); 2354 } 2355 } 2356 for (i = 0; i < 4; i++) { 2357 old[i].sysid = 0; 2358 if (valid_part_table_flag(MBRbuffer)) { 2359 if(get_part_table(i)->sys_ind) { 2360 old[i].sysid = get_part_table(i)->sys_ind; 2361 old[i].start = get_start_sect(get_part_table(i)); 2362 old[i].nsect = get_nr_sects(get_part_table(i)); 2363 printf(_("Trying to keep parameters of partition %d.\n"), i); 2364 if (debug) 2365 printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"), 2366 old[i].sysid, old[i].start, old[i].nsect); 2367 } 2368 } 2369 } 2370 2371 memset(MBRbuffer, 0, sizeof(MBRbuffer)); 2372 sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC); 2373 sgilabel->boot_part = SGI_SSWAP16(0); 2374 sgilabel->swap_part = SGI_SSWAP16(1); 2375 2376 /* sizeof(sgilabel->boot_file) = 16 > 6 */ 2377 memset(sgilabel->boot_file, 0, 16); 2378 strcpy((char*)sgilabel->boot_file, "/unix"); 2379 2380 sgilabel->devparam.skew = (0); 2381 sgilabel->devparam.gap1 = (0); 2382 sgilabel->devparam.gap2 = (0); 2383 sgilabel->devparam.sparecyl = (0); 2384 sgilabel->devparam.pcylcount = SGI_SSWAP16(geometry.cylinders); 2385 sgilabel->devparam.head_vol0 = SGI_SSWAP16(0); 2386 sgilabel->devparam.ntrks = SGI_SSWAP16(geometry.heads); 2387 /* tracks/cylinder (heads) */ 2388 sgilabel->devparam.cmd_tag_queue_depth = (0); 2389 sgilabel->devparam.unused0 = (0); 2390 sgilabel->devparam.unused1 = SGI_SSWAP16(0); 2391 sgilabel->devparam.nsect = SGI_SSWAP16(geometry.sectors); 2392 /* sectors/track */ 2393 sgilabel->devparam.bytes = SGI_SSWAP16(512); 2394 sgilabel->devparam.ilfact = SGI_SSWAP16(1); 2395 sgilabel->devparam.flags = SGI_SSWAP32(TRACK_FWD| 2396 IGNORE_ERRORS|RESEEK); 2397 sgilabel->devparam.datarate = SGI_SSWAP32(0); 2398 sgilabel->devparam.retries_on_error = SGI_SSWAP32(1); 2399 sgilabel->devparam.ms_per_word = SGI_SSWAP32(0); 2400 sgilabel->devparam.xylogics_gap1 = SGI_SSWAP16(0); 2401 sgilabel->devparam.xylogics_syncdelay = SGI_SSWAP16(0); 2402 sgilabel->devparam.xylogics_readdelay = SGI_SSWAP16(0); 2403 sgilabel->devparam.xylogics_gap2 = SGI_SSWAP16(0); 2404 sgilabel->devparam.xylogics_readgate = SGI_SSWAP16(0); 2405 sgilabel->devparam.xylogics_writecont = SGI_SSWAP16(0); 2406 memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 ); 2407 memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16 ); 2408 current_label_type = label_sgi; 2409 partitions = 16; 2410 sgi_volumes = 15; 2411 sgi_set_entire(); 2412 sgi_set_volhdr(); 2413 for (i = 0; i < 4; i++) { 2414 if(old[i].sysid) { 2415 sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid); 2416 } 2417 } 2418 } 2419 2420 static void 2421 sgi_set_xcyl(void) 2422 { 2423 /* do nothing in the beginning */ 2424 } 2425 #endif /* CONFIG_FEATURE_FDISK_ADVANCED */ 2426 2427 /* _____________________________________________________________ 2428 */ 2429 2430 static sgiinfo * 2431 fill_sgiinfo(void) 2432 { 2433 sgiinfo *info = calloc(1, sizeof(sgiinfo)); 2434 2435 info->magic = SGI_SSWAP32(SGI_INFO_MAGIC); 2436 info->b1 = SGI_SSWAP32(-1); 2437 info->b2 = SGI_SSWAP16(-1); 2438 info->b3 = SGI_SSWAP16(1); 2439 /* You may want to replace this string !!!!!!! */ 2440 strcpy( (char*)info->scsi_string, "IBM OEM 0662S12 3 30" ); 2441 strcpy( (char*)info->serial, "0000" ); 2442 info->check1816 = SGI_SSWAP16(18*256 +16 ); 2443 strcpy( (char*)info->installer, "Sfx version 5.3, Oct 18, 1994" ); 2444 return info; 2445 } 2446 #endif /* SGI_LABEL */ 2447 2448 2449 #ifdef CONFIG_FEATURE_SUN_LABEL 2450 /* 2451 * fdisksunlabel.c 2452 * 2453 * I think this is mostly, or entirely, due to 2454 * Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996 2455 * 2456 * Merged with fdisk for other architectures, aeb, June 1998. 2457 * 2458 * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 2459 * Internationalization 2460 */ 2461 2462 2463 static int sun_other_endian; 2464 static int scsi_disk; 2465 static int floppy; 2466 2467 #ifndef IDE0_MAJOR 2468 #define IDE0_MAJOR 3 2469 #endif 2470 #ifndef IDE1_MAJOR 2471 #define IDE1_MAJOR 22 2472 #endif 2473 2474 static void 2475 guess_device_type(void) 2476 { 2477 struct stat bootstat; 2478 2479 if (fstat(fd, &bootstat) < 0) { 2480 scsi_disk = 0; 2481 floppy = 0; 2482 } else if (S_ISBLK(bootstat.st_mode) 2483 && (major(bootstat.st_rdev) == IDE0_MAJOR || 2484 major(bootstat.st_rdev) == IDE1_MAJOR)) { 2485 scsi_disk = 0; 2486 floppy = 0; 2487 } else if (S_ISBLK(bootstat.st_mode) 2488 && major(bootstat.st_rdev) == FLOPPY_MAJOR) { 2489 scsi_disk = 0; 2490 floppy = 1; 2491 } else { 2492 scsi_disk = 1; 2493 floppy = 0; 2494 } 2495 } 2496 2497 static const struct systypes sun_sys_types[] = { 2498 { "\x00" "Empty" }, /* 0 */ 2499 { "\x01" "Boot" }, /* 1 */ 2500 { "\x02" "SunOS root" }, /* 2 */ 2501 { "\x03" "SunOS swap" }, /* SUNOS_SWAP */ 2502 { "\x04" "SunOS usr" }, /* 4 */ 2503 { "\x05" "Whole disk" }, /* WHOLE_DISK */ 2504 { "\x06" "SunOS stand" }, /* 6 */ 2505 { "\x07" "SunOS var" }, /* 7 */ 2506 { "\x08" "SunOS home" }, /* 8 */ 2507 { "\x82" "Linux swap" }, /* LINUX_SWAP */ 2508 { "\x83" "Linux native" }, /* LINUX_NATIVE */ 2509 { "\x8e" "Linux LVM" }, /* 0x8e */ 2510 /* New (2.2.x) raid partition with autodetect using persistent superblock */ 2511 { "\xfd" "Linux raid autodetect" }, /* 0xfd */ 2512 { NULL } 2513 }; 2514 2515 2516 static void 2517 set_sun_partition(int i, uint start, uint stop, int sysid) 2518 { 2519 sunlabel->infos[i].id = sysid; 2520 sunlabel->partitions[i].start_cylinder = 2521 SUN_SSWAP32(start / (heads * sectors)); 2522 sunlabel->partitions[i].num_sectors = 2523 SUN_SSWAP32(stop - start); 2524 set_changed(i); 2525 } 2526 2527 static int 2528 check_sun_label(void) 2529 { 2530 unsigned short *ush; 2531 int csum; 2532 2533 if (sunlabel->magic != SUN_LABEL_MAGIC 2534 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { 2535 current_label_type = label_dos; 2536 sun_other_endian = 0; 2537 return 0; 2538 } 2539 sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED); 2540 ush = ((unsigned short *) (sunlabel + 1)) - 1; 2541 for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; 2542 if (csum) { 2543 fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n" 2544 "Probably you'll have to set all the values,\n" 2545 "e.g. heads, sectors, cylinders and partitions\n" 2546 "or force a fresh label (s command in main menu)\n")); 2547 } else { 2548 heads = SUN_SSWAP16(sunlabel->ntrks); 2549 cylinders = SUN_SSWAP16(sunlabel->ncyl); 2550 sectors = SUN_SSWAP16(sunlabel->nsect); 2551 } 2552 update_units(); 2553 current_label_type = label_sun; 2554 partitions = 8; 2555 return 1; 2556 } 2557 2558 static const struct sun_predefined_drives { 2559 const char *vendor; 2560 const char *model; 2561 unsigned short sparecyl; 2562 unsigned short ncyl; 2563 unsigned short nacyl; 2564 unsigned short pcylcount; 2565 unsigned short ntrks; 2566 unsigned short nsect; 2567 unsigned short rspeed; 2568 } sun_drives[] = { 2569 { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662}, 2570 { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662}, 2571 { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600}, 2572 { "IBM","DPES-31080",0,4901,2,4903,4,108,5400}, 2573 { "IBM","DORS-32160",0,1015,2,1017,67,62,5400}, 2574 { "IBM","DNES-318350",0,11199,2,11474,10,320,7200}, 2575 { "SEAGATE","ST34371",0,3880,2,3882,16,135,7228}, 2576 { "","SUN0104",1,974,2,1019,6,35,3662}, 2577 { "","SUN0207",4,1254,2,1272,9,36,3600}, 2578 { "","SUN0327",3,1545,2,1549,9,46,3600}, 2579 { "","SUN0340",0,1538,2,1544,6,72,4200}, 2580 { "","SUN0424",2,1151,2,2500,9,80,4400}, 2581 { "","SUN0535",0,1866,2,2500,7,80,5400}, 2582 { "","SUN0669",5,1614,2,1632,15,54,3600}, 2583 { "","SUN1.0G",5,1703,2,1931,15,80,3597}, 2584 { "","SUN1.05",0,2036,2,2038,14,72,5400}, 2585 { "","SUN1.3G",6,1965,2,3500,17,80,5400}, 2586 { "","SUN2.1G",0,2733,2,3500,19,80,5400}, 2587 { "IOMEGA","Jaz",0,1019,2,1021,64,32,5394}, 2588 }; 2589 2590 static const struct sun_predefined_drives * 2591 sun_autoconfigure_scsi(void) 2592 { 2593 const struct sun_predefined_drives *p = NULL; 2594 2595 #ifdef SCSI_IOCTL_GET_IDLUN 2596 unsigned int id[2]; 2597 char buffer[2048]; 2598 char buffer2[2048]; 2599 FILE *pfd; 2600 char *vendor; 2601 char *model; 2602 char *q; 2603 int i; 2604 2605 if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) { 2606 sprintf(buffer, 2607 "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n", 2608 #if 0 2609 ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33, 2610 #else 2611 /* This is very wrong (works only if you have one HBA), 2612 but I haven't found a way how to get hostno 2613 from the current kernel */ 2614 0, 2615 #endif 2616 (id[0]>>16) & 0xff, 2617 id[0] & 0xff, 2618 (id[0]>>8) & 0xff 2619 ); 2620 pfd = fopen("/proc/scsi/scsi","r"); 2621 if (pfd) { 2622 while (fgets(buffer2, 2048, pfd)) { 2623 if (!strcmp(buffer, buffer2)) { 2624 if (fgets(buffer2,2048,pfd)) { 2625 q = strstr(buffer2,"Vendor: "); 2626 if (q) { 2627 q += 8; 2628 vendor = q; 2629 q = strstr(q," "); 2630 *q++ = 0; /* truncate vendor name */ 2631 q = strstr(q,"Model: "); 2632 if (q) { 2633 *q = 0; 2634 q += 7; 2635 model = q; 2636 q = strstr(q," Rev: "); 2637 if (q) { 2638 *q = 0; 2639 for (i = 0; i < SIZE(sun_drives); i++) { 2640 if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor)) 2641 continue; 2642 if (!strstr(model, sun_drives[i].model)) 2643 continue; 2644 printf(_("Autoconfigure found a %s%s%s\n"),sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model); 2645 p = sun_drives + i; 2646 break; 2647 } 2648 } 2649 } 2650 } 2651 } 2652 break; 2653 } 2654 } 2655 fclose(pfd); 2656 } 2657 } 2658 #endif 2659 return p; 2660 } 2661 2662 static void 2663 create_sunlabel(void) 2664 { 2665 struct hd_geometry geometry; 2666 unsigned int ndiv; 2667 int i; 2668 unsigned char c; 2669 const struct sun_predefined_drives *p = NULL; 2670 2671 fprintf(stderr, 2672 _("Building a new sun disklabel. Changes will remain in memory only,\n" 2673 "until you decide to write them. After that, of course, the previous\n" 2674 "content won't be recoverable.\n\n")); 2675 sun_other_endian = BB_LITTLE_ENDIAN; 2676 memset(MBRbuffer, 0, sizeof(MBRbuffer)); 2677 sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC); 2678 if (!floppy) { 2679 puts(_("Drive type\n" 2680 " ? auto configure\n" 2681 " 0 custom (with hardware detected defaults)")); 2682 for (i = 0; i < SIZE(sun_drives); i++) { 2683 printf(" %c %s%s%s\n", 2684 i + 'a', sun_drives[i].vendor, 2685 (*sun_drives[i].vendor) ? " " : "", 2686 sun_drives[i].model); 2687 } 2688 while (1) { 2689 c = read_char(_("Select type (? for auto, 0 for custom): ")); 2690 if (c >= 'a' && c < 'a' + SIZE(sun_drives)) { 2691 p = sun_drives + c - 'a'; 2692 break; 2693 } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) { 2694 p = sun_drives + c - 'A'; 2695 break; 2696 } else if (c == '0') { 2697 break; 2698 } else if (c == '?' && scsi_disk) { 2699 p = sun_autoconfigure_scsi(); 2700 if (!p) 2701 printf(_("Autoconfigure failed.\n")); 2702 else 2703 break; 2704 } 2705 } 2706 } 2707 if (!p || floppy) { 2708 if (!ioctl(fd, HDIO_GETGEO, &geometry)) { 2709 heads = geometry.heads; 2710 sectors = geometry.sectors; 2711 cylinders = geometry.cylinders; 2712 } else { 2713 heads = 0; 2714 sectors = 0; 2715 cylinders = 0; 2716 } 2717 if (floppy) { 2718 sunlabel->nacyl = 0; 2719 sunlabel->pcylcount = SUN_SSWAP16(cylinders); 2720 sunlabel->rspeed = SUN_SSWAP16(300); 2721 sunlabel->ilfact = SUN_SSWAP16(1); 2722 sunlabel->sparecyl = 0; 2723 } else { 2724 heads = read_int(1,heads,1024,0,_("Heads")); 2725 sectors = read_int(1,sectors,1024,0,_("Sectors/track")); 2726 if (cylinders) 2727 cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders")); 2728 else 2729 cylinders = read_int(1,0,65535,0,_("Cylinders")); 2730 sunlabel->nacyl = SUN_SSWAP16(read_int(0,2,65535,0, _("Alternate cylinders"))); 2731 sunlabel->pcylcount = SUN_SSWAP16(read_int(0,cylinders+SUN_SSWAP16(sunlabel->nacyl), 65535,0, _("Physical cylinders"))); 2732 sunlabel->rspeed = SUN_SSWAP16(read_int(1,5400,100000,0, _("Rotation speed (rpm)"))); 2733 sunlabel->ilfact = SUN_SSWAP16(read_int(1,1,32,0, _("Interleave factor"))); 2734 sunlabel->sparecyl = SUN_SSWAP16(read_int(0,0,sectors,0, _("Extra sectors per cylinder"))); 2735 } 2736 } else { 2737 sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl); 2738 sunlabel->ncyl = SUN_SSWAP16(p->ncyl); 2739 sunlabel->nacyl = SUN_SSWAP16(p->nacyl); 2740 sunlabel->pcylcount = SUN_SSWAP16(p->pcylcount); 2741 sunlabel->ntrks = SUN_SSWAP16(p->ntrks); 2742 sunlabel->nsect = SUN_SSWAP16(p->nsect); 2743 sunlabel->rspeed = SUN_SSWAP16(p->rspeed); 2744 sunlabel->ilfact = SUN_SSWAP16(1); 2745 cylinders = p->ncyl; 2746 heads = p->ntrks; 2747 sectors = p->nsect; 2748 puts(_("You may change all the disk params from the x menu")); 2749 } 2750 2751 snprintf((char *)(sunlabel->info), sizeof(sunlabel->info), 2752 "%s%s%s cyl %d alt %d hd %d sec %d", 2753 p ? p->vendor : "", (p && *p->vendor) ? " " : "", 2754 p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")), 2755 cylinders, SUN_SSWAP16(sunlabel->nacyl), heads, sectors); 2756 2757 sunlabel->ntrks = SUN_SSWAP16(heads); 2758 sunlabel->nsect = SUN_SSWAP16(sectors); 2759 sunlabel->ncyl = SUN_SSWAP16(cylinders); 2760 if (floppy) 2761 set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE); 2762 else { 2763 if (cylinders * heads * sectors >= 150 * 2048) { 2764 ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */ 2765 } else 2766 ndiv = cylinders * 2 / 3; 2767 set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE); 2768 set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP); 2769 sunlabel->infos[1].flags |= 0x01; /* Not mountable */ 2770 } 2771 set_sun_partition(2, 0, cylinders * heads * sectors, WHOLE_DISK); 2772 { 2773 unsigned short *ush = (unsigned short *)sunlabel; 2774 unsigned short csum = 0; 2775 while (ush < (unsigned short *)(&sunlabel->csum)) 2776 csum ^= *ush++; 2777 sunlabel->csum = csum; 2778 } 2779 2780 set_all_unchanged(); 2781 set_changed(0); 2782 get_boot(create_empty_sun); 2783 } 2784 2785 static void 2786 toggle_sunflags(int i, unsigned char mask) 2787 { 2788 if (sunlabel->infos[i].flags & mask) 2789 sunlabel->infos[i].flags &= ~mask; 2790 else 2791 sunlabel->infos[i].flags |= mask; 2792 set_changed(i); 2793 } 2794 2795 static void 2796 fetch_sun(uint *starts, uint *lens, uint *start, uint *stop) 2797 { 2798 int i, continuous = 1; 2799 2800 *start = 0; 2801 *stop = cylinders * heads * sectors; 2802 for (i = 0; i < partitions; i++) { 2803 if (sunlabel->partitions[i].num_sectors 2804 && sunlabel->infos[i].id 2805 && sunlabel->infos[i].id != WHOLE_DISK) { 2806 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; 2807 lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); 2808 if (continuous) { 2809 if (starts[i] == *start) 2810 *start += lens[i]; 2811 else if (starts[i] + lens[i] >= *stop) 2812 *stop = starts[i]; 2813 else 2814 continuous = 0; 2815 /* There will be probably more gaps 2816 than one, so lets check afterwards */ 2817 } 2818 } else { 2819 starts[i] = 0; 2820 lens[i] = 0; 2821 } 2822 } 2823 } 2824 2825 static uint *verify_sun_starts; 2826 2827 static int 2828 verify_sun_cmp(int *a, int *b) 2829 { 2830 if (*a == -1) return 1; 2831 if (*b == -1) return -1; 2832 if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1; 2833 return -1; 2834 } 2835 2836 static void 2837 verify_sun(void) 2838 { 2839 uint starts[8], lens[8], start, stop; 2840 int i,j,k,starto,endo; 2841 int array[8]; 2842 2843 verify_sun_starts = starts; 2844 fetch_sun(starts,lens,&start,&stop); 2845 for (k = 0; k < 7; k++) { 2846 for (i = 0; i < 8; i++) { 2847 if (k && (lens[i] % (heads * sectors))) { 2848 printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1); 2849 } 2850 if (lens[i]) { 2851 for (j = 0; j < i; j++) 2852 if (lens[j]) { 2853 if (starts[j] == starts[i]+lens[i]) { 2854 starts[j] = starts[i]; lens[j] += lens[i]; 2855 lens[i] = 0; 2856 } else if (starts[i] == starts[j]+lens[j]){ 2857 lens[j] += lens[i]; 2858 lens[i] = 0; 2859 } else if (!k) { 2860 if (starts[i] < starts[j]+lens[j] 2861 && starts[j] < starts[i]+lens[i]) { 2862 starto = starts[i]; 2863 if (starts[j] > starto) 2864 starto = starts[j]; 2865 endo = starts[i]+lens[i]; 2866 if (starts[j]+lens[j] < endo) 2867 endo = starts[j]+lens[j]; 2868 printf(_("Partition %d overlaps with others in " 2869 "sectors %d-%d\n"), i+1, starto, endo); 2870 } 2871 } 2872 } 2873 } 2874 } 2875 } 2876 for (i = 0; i < 8; i++) { 2877 if (lens[i]) 2878 array[i] = i; 2879 else 2880 array[i] = -1; 2881 } 2882 qsort(array,SIZE(array),sizeof(array[0]), 2883 (int (*)(const void *,const void *)) verify_sun_cmp); 2884 if (array[0] == -1) { 2885 printf(_("No partitions defined\n")); 2886 return; 2887 } 2888 stop = cylinders * heads * sectors; 2889 if (starts[array[0]]) 2890 printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]); 2891 for (i = 0; i < 7 && array[i+1] != -1; i++) { 2892 printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]); 2893 } 2894 start = starts[array[i]] + lens[array[i]]; 2895 if (start < stop) 2896 printf(_("Unused gap - sectors %d-%d\n"),start,stop); 2897 } 2898 2899 static void 2900 add_sun_partition(int n, int sys) 2901 { 2902 uint start, stop, stop2; 2903 uint starts[8], lens[8]; 2904 int whole_disk = 0; 2905 2906 char mesg[256]; 2907 int i, first, last; 2908 2909 if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) { 2910 printf(_("Partition %d is already defined. Delete " 2911 "it before re-adding it.\n"), n + 1); 2912 return; 2913 } 2914 2915 fetch_sun(starts,lens,&start,&stop); 2916 if (stop <= start) { 2917 if (n == 2) 2918 whole_disk = 1; 2919 else { 2920 printf(_("Other partitions already cover the whole disk.\nDelete " 2921 "some/shrink them before retry.\n")); 2922 return; 2923 } 2924 } 2925 snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); 2926 while (1) { 2927 if (whole_disk) 2928 first = read_int(0, 0, 0, 0, mesg); 2929 else 2930 first = read_int(scround(start), scround(stop)+1, 2931 scround(stop), 0, mesg); 2932 if (display_in_cyl_units) 2933 first *= units_per_sector; 2934 else 2935 /* Starting sector has to be properly aligned */ 2936 first = (first + heads * sectors - 1) / (heads * sectors); 2937 if (n == 2 && first != 0) 2938 printf("\ 2939 It is highly recommended that the third partition covers the whole disk\n\ 2940 and is of type `Whole disk'\n"); 2941 /* ewt asks to add: "don't start a partition at cyl 0" 2942 However, edmundo@rano.demon.co.uk writes: 2943 "In addition to having a Sun partition table, to be able to 2944 boot from the disc, the first partition, /dev/sdX1, must 2945 start at cylinder 0. This means that /dev/sdX1 contains 2946 the partition table and the boot block, as these are the 2947 first two sectors of the disc. Therefore you must be 2948 careful what you use /dev/sdX1 for. In particular, you must 2949 not use a partition starting at cylinder 0 for Linux swap, 2950 as that would overwrite the partition table and the boot 2951 block. You may, however, use such a partition for a UFS 2952 or EXT2 file system, as these file systems leave the first 2953 1024 bytes undisturbed. */ 2954 /* On the other hand, one should not use partitions 2955 starting at block 0 in an md, or the label will 2956 be trashed. */ 2957 for (i = 0; i < partitions; i++) 2958 if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) 2959 break; 2960 if (i < partitions && !whole_disk) { 2961 if (n == 2 && !first) { 2962 whole_disk = 1; 2963 break; 2964 } 2965 printf(_("Sector %d is already allocated\n"), first); 2966 } else 2967 break; 2968 } 2969 stop = cylinders * heads * sectors; 2970 stop2 = stop; 2971 for (i = 0; i < partitions; i++) { 2972 if (starts[i] > first && starts[i] < stop) 2973 stop = starts[i]; 2974 } 2975 snprintf(mesg, sizeof(mesg), 2976 _("Last %s or +size or +sizeM or +sizeK"), 2977 str_units(SINGULAR)); 2978 if (whole_disk) 2979 last = read_int(scround(stop2), scround(stop2), scround(stop2), 2980 0, mesg); 2981 else if (n == 2 && !first) 2982 last = read_int(scround(first), scround(stop2), scround(stop2), 2983 scround(first), mesg); 2984 else 2985 last = read_int(scround(first), scround(stop), scround(stop), 2986 scround(first), mesg); 2987 if (display_in_cyl_units) 2988 last *= units_per_sector; 2989 if (n == 2 && !first) { 2990 if (last >= stop2) { 2991 whole_disk = 1; 2992 last = stop2; 2993 } else if (last > stop) { 2994 printf(_("You haven't covered the whole disk with " 2995 "the 3rd partition, but your value\n" 2996 "%d %s covers some other partition. " 2997 "Your entry has been changed\n" 2998 "to %d %s\n"), 2999 scround(last), str_units(SINGULAR), 3000 scround(stop), str_units(SINGULAR)); 3001 last = stop; 3002 } 3003 } else if (!whole_disk && last > stop) 3004 last = stop; 3005 3006 if (whole_disk) 3007 sys = WHOLE_DISK; 3008 set_sun_partition(n, first, last, sys); 3009 } 3010 3011 static void 3012 sun_delete_partition(int i) 3013 { 3014 unsigned int nsec; 3015 3016 if (i == 2 3017 && sunlabel->infos[i].id == WHOLE_DISK 3018 && !sunlabel->partitions[i].start_cylinder 3019 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders) 3020 printf(_("If you want to maintain SunOS/Solaris compatibility, " 3021 "consider leaving this\n" 3022 "partition as Whole disk (5), starting at 0, with %u " 3023 "sectors\n"), nsec); 3024 sunlabel->infos[i].id = 0; 3025 sunlabel->partitions[i].num_sectors = 0; 3026 } 3027 3028 static void 3029 sun_change_sysid(int i, int sys) 3030 { 3031 if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) { 3032 read_chars( 3033 _("It is highly recommended that the partition at offset 0\n" 3034 "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" 3035 "there may destroy your partition table and bootblock.\n" 3036 "Type YES if you're very sure you would like that partition\n" 3037 "tagged with 82 (Linux swap): ")); 3038 if (strcmp (line_ptr, _("YES\n"))) 3039 return; 3040 } 3041 switch (sys) { 3042 case SUNOS_SWAP: 3043 case LINUX_SWAP: 3044 /* swaps are not mountable by default */ 3045 sunlabel->infos[i].flags |= 0x01; 3046 break; 3047 default: 3048 /* assume other types are mountable; 3049 user can change it anyway */ 3050 sunlabel->infos[i].flags &= ~0x01; 3051 break; 3052 } 3053 sunlabel->infos[i].id = sys; 3054 } 3055 3056 static void 3057 sun_list_table(int xtra) 3058 { 3059 int i, w; 3060 3061 w = strlen(disk_device); 3062 if (xtra) 3063 printf( 3064 _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n" 3065 "%d cylinders, %d alternate cylinders, %d physical cylinders\n" 3066 "%d extra sects/cyl, interleave %d:1\n" 3067 "%s\n" 3068 "Units = %s of %d * 512 bytes\n\n"), 3069 disk_device, heads, sectors, SUN_SSWAP16(sunlabel->rspeed), 3070 cylinders, SUN_SSWAP16(sunlabel->nacyl), 3071 SUN_SSWAP16(sunlabel->pcylcount), 3072 SUN_SSWAP16(sunlabel->sparecyl), 3073 SUN_SSWAP16(sunlabel->ilfact), 3074 (char *)sunlabel, 3075 str_units(PLURAL), units_per_sector); 3076 else 3077 printf( 3078 _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n" 3079 "Units = %s of %d * 512 bytes\n\n"), 3080 disk_device, heads, sectors, cylinders, 3081 str_units(PLURAL), units_per_sector); 3082 3083 printf(_("%*s Flag Start End Blocks Id System\n"), 3084 w + 1, _("Device")); 3085 for (i = 0 ; i < partitions; i++) { 3086 if (sunlabel->partitions[i].num_sectors) { 3087 uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; 3088 uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); 3089 printf("%s %c%c %9ld %9ld %9ld%c %2x %s\n", 3090 partname(disk_device, i+1, w), /* device */ 3091 (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ', /* flags */ 3092 (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ', 3093 (long) scround(start), /* start */ 3094 (long) scround(start+len), /* end */ 3095 (long) len / 2, len & 1 ? '+' : ' ', /* odd flag on end */ 3096 sunlabel->infos[i].id, /* type id */ 3097 partition_type(sunlabel->infos[i].id)); /* type name */ 3098 } 3099 } 3100 } 3101 3102 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 3103 3104 static void 3105 sun_set_alt_cyl(void) 3106 { 3107 sunlabel->nacyl = 3108 SUN_SSWAP16(read_int(0,SUN_SSWAP16(sunlabel->nacyl), 65535, 0, 3109 _("Number of alternate cylinders"))); 3110 } 3111 3112 static void 3113 sun_set_ncyl(int cyl) 3114 { 3115 sunlabel->ncyl = SUN_SSWAP16(cyl); 3116 } 3117 3118 static void 3119 sun_set_xcyl(void) 3120 { 3121 sunlabel->sparecyl = 3122 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), sectors, 0, 3123 _("Extra sectors per cylinder"))); 3124 } 3125 3126 static void 3127 sun_set_ilfact(void) 3128 { 3129 sunlabel->ilfact = 3130 SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0, 3131 _("Interleave factor"))); 3132 } 3133 3134 static void 3135 sun_set_rspeed(void) 3136 { 3137 sunlabel->rspeed = 3138 SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0, 3139 _("Rotation speed (rpm)"))); 3140 } 3141 3142 static void 3143 sun_set_pcylcount(void) 3144 { 3145 sunlabel->pcylcount = 3146 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0, 3147 _("Number of physical cylinders"))); 3148 } 3149 #endif /* CONFIG_FEATURE_FDISK_ADVANCED */ 3150 3151 static void 3152 sun_write_table(void) 3153 { 3154 unsigned short *ush = (unsigned short *)sunlabel; 3155 unsigned short csum = 0; 3156 3157 while (ush < (unsigned short *)(&sunlabel->csum)) 3158 csum ^= *ush++; 3159 sunlabel->csum = csum; 3160 if (lseek(fd, 0, SEEK_SET) < 0) 3161 fdisk_fatal(unable_to_seek); 3162 if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE) 3163 fdisk_fatal(unable_to_write); 3164 } 3165 #endif /* SUN_LABEL */ 3166 3167 /* DOS partition types */ 3168 3169 static const struct systypes i386_sys_types[] = { 3170 { "\x00" "Empty" }, 3171 { "\x01" "FAT12" }, 3172 { "\x04" "FAT16 <32M" }, 3173 { "\x05" "Extended" }, /* DOS 3.3+ extended partition */ 3174 { "\x06" "FAT16" }, /* DOS 16-bit >=32M */ 3175 { "\x07" "HPFS/NTFS" }, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ 3176 { "\x0a" "OS/2 Boot Manager" },/* OS/2 Boot Manager */ 3177 { "\x0b" "Win95 FAT32" }, 3178 { "\x0c" "Win95 FAT32 (LBA)" },/* LBA really is `Extended Int 13h' */ 3179 { "\x0e" "Win95 FAT16 (LBA)" }, 3180 { "\x0f" "Win95 Ext'd (LBA)" }, 3181 { "\x11" "Hidden FAT12" }, 3182 { "\x12" "Compaq diagnostics" }, 3183 { "\x14" "Hidden FAT16 <32M" }, 3184 { "\x16" "Hidden FAT16" }, 3185 { "\x17" "Hidden HPFS/NTFS" }, 3186 { "\x1b" "Hidden Win95 FAT32" }, 3187 { "\x1c" "Hidden Win95 FAT32 (LBA)" }, 3188 { "\x1e" "Hidden Win95 FAT16 (LBA)" }, 3189 { "\x3c" "PartitionMagic recovery" }, 3190 { "\x41" "PPC PReP Boot" }, 3191 { "\x42" "SFS" }, 3192 { "\x63" "GNU HURD or SysV" }, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ 3193 { "\x80" "Old Minix" }, /* Minix 1.4a and earlier */ 3194 { "\x81" "Minix / old Linux" },/* Minix 1.4b and later */ 3195 { "\x82" "Linux swap" }, /* also Solaris */ 3196 { "\x83" "Linux" }, 3197 { "\x84" "OS/2 hidden C: drive" }, 3198 { "\x85" "Linux extended" }, 3199 { "\x86" "NTFS volume set" }, 3200 { "\x87" "NTFS volume set" }, 3201 { "\x8e" "Linux LVM" }, 3202 { "\x9f" "BSD/OS" }, /* BSDI */ 3203 { "\xa0" "IBM Thinkpad hibernation" }, 3204 { "\xa5" "FreeBSD" }, /* various BSD flavours */ 3205 { "\xa6" "OpenBSD" }, 3206 { "\xa8" "Darwin UFS" }, 3207 { "\xa9" "NetBSD" }, 3208 { "\xab" "Darwin boot" }, 3209 { "\xb7" "BSDI fs" }, 3210 { "\xb8" "BSDI swap" }, 3211 { "\xbe" "Solaris boot" }, 3212 { "\xeb" "BeOS fs" }, 3213 { "\xee" "EFI GPT" }, /* Intel EFI GUID Partition Table */ 3214 { "\xef" "EFI (FAT-12/16/32)" },/* Intel EFI System Partition */ 3215 { "\xf0" "Linux/PA-RISC boot" },/* Linux/PA-RISC boot loader */ 3216 { "\xf2" "DOS secondary" }, /* DOS 3.3+ secondary */ 3217 { "\xfd" "Linux raid autodetect" },/* New (2.2.x) raid partition with 3218 autodetect using persistent 3219 superblock */ 3220 #ifdef CONFIG_WEIRD_PARTITION_TYPES 3221 { "\x02" "XENIX root" }, 3222 { "\x03" "XENIX usr" }, 3223 { "\x08" "AIX" }, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ 3224 { "\x09" "AIX bootable" }, /* AIX data or Coherent */ 3225 { "\x10" "OPUS" }, 3226 { "\x18" "AST SmartSleep" }, 3227 { "\x24" "NEC DOS" }, 3228 { "\x39" "Plan 9" }, 3229 { "\x40" "Venix 80286" }, 3230 { "\x4d" "QNX4.x" }, 3231 { "\x4e" "QNX4.x 2nd part" }, 3232 { "\x4f" "QNX4.x 3rd part" }, 3233 { "\x50" "OnTrack DM" }, 3234 { "\x51" "OnTrack DM6 Aux1" }, /* (or Novell) */ 3235 { "\x52" "CP/M" }, /* CP/M or Microport SysV/AT */ 3236 { "\x53" "OnTrack DM6 Aux3" }, 3237 { "\x54" "OnTrackDM6" }, 3238 { "\x55" "EZ-Drive" }, 3239 { "\x56" "Golden Bow" }, 3240 { "\x5c" "Priam Edisk" }, 3241 { "\x61" "SpeedStor" }, 3242 { "\x64" "Novell Netware 286" }, 3243 { "\x65" "Novell Netware 386" }, 3244 { "\x70" "DiskSecure Multi-Boot" }, 3245 { "\x75" "PC/IX" }, 3246 { "\x93" "Amoeba" }, 3247 { "\x94" "Amoeba BBT" }, /* (bad block table) */ 3248 { "\xa7" "NeXTSTEP" }, 3249 { "\xbb" "Boot Wizard hidden" }, 3250 { "\xc1" "DRDOS/sec (FAT-12)" }, 3251 { "\xc4" "DRDOS/sec (FAT-16 < 32M)" }, 3252 { "\xc6" "DRDOS/sec (FAT-16)" }, 3253 { "\xc7" "Syrinx" }, 3254 { "\xda" "Non-FS data" }, 3255 { "\xdb" "CP/M / CTOS / ..." },/* CP/M or Concurrent CP/M or 3256 Concurrent DOS or CTOS */ 3257 { "\xde" "Dell Utility" }, /* Dell PowerEdge Server utilities */ 3258 { "\xdf" "BootIt" }, /* BootIt EMBRM */ 3259 { "\xe1" "DOS access" }, /* DOS access or SpeedStor 12-bit FAT 3260 extended partition */ 3261 { "\xe3" "DOS R/O" }, /* DOS R/O or SpeedStor */ 3262 { "\xe4" "SpeedStor" }, /* SpeedStor 16-bit FAT extended 3263 partition < 1024 cyl. */ 3264 { "\xf1" "SpeedStor" }, 3265 { "\xf4" "SpeedStor" }, /* SpeedStor large partition */ 3266 { "\xfe" "LANstep" }, /* SpeedStor >1024 cyl. or LANstep */ 3267 { "\xff" "BBT" }, /* Xenix Bad Block Table */ 3268 #endif 3269 { 0 } 3270 }; 3271 3272 3273 3274 /* A valid partition table sector ends in 0x55 0xaa */ 3275 static unsigned int 3276 part_table_flag(const char *b) 3277 { 3278 return ((uint) b[510]) + (((uint) b[511]) << 8); 3279 } 3280 3281 3282 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 3283 static void 3284 write_part_table_flag(char *b) 3285 { 3286 b[510] = 0x55; 3287 b[511] = 0xaa; 3288 } 3289 505 STATIC_OSF void bsd_select(void); 506 STATIC_OSF void xbsd_print_disklabel(int); 507 #include "fdisk_osf.c" 508 509 #if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL 510 static uint16_t 511 fdisk_swap16(uint16_t x) 512 { 513 return (x << 8) | (x >> 8); 514 } 515 516 static uint32_t 517 fdisk_swap32(uint32_t x) 518 { 519 return (x << 24) | 520 ((x & 0xFF00) << 8) | 521 ((x & 0xFF0000) >> 8) | 522 (x >> 24); 523 } 524 #endif 525 526 STATIC_SGI const char *const sgi_sys_types[]; 527 STATIC_SGI unsigned sgi_get_num_sectors(int i); 528 STATIC_SGI int sgi_get_sysid(int i); 529 STATIC_SGI void sgi_delete_partition(int i); 530 STATIC_SGI void sgi_change_sysid(int i, int sys); 531 STATIC_SGI void sgi_list_table(int xtra); 532 #if ENABLE_FEATURE_FDISK_ADVANCED 533 STATIC_SGI void sgi_set_xcyl(void); 534 #endif 535 STATIC_SGI int verify_sgi(int verbose); 536 STATIC_SGI void sgi_add_partition(int n, int sys); 537 STATIC_SGI void sgi_set_swappartition(int i); 538 STATIC_SGI const char *sgi_get_bootfile(void); 539 STATIC_SGI void sgi_set_bootfile(const char* aFile); 540 STATIC_SGI void create_sgiinfo(void); 541 STATIC_SGI void sgi_write_table(void); 542 STATIC_SGI void sgi_set_bootpartition(int i); 543 #include "fdisk_sgi.c" 544 545 STATIC_SUN const char *const sun_sys_types[]; 546 STATIC_SUN void sun_delete_partition(int i); 547 STATIC_SUN void sun_change_sysid(int i, int sys); 548 STATIC_SUN void sun_list_table(int xtra); 549 STATIC_SUN void add_sun_partition(int n, int sys); 550 #if ENABLE_FEATURE_FDISK_ADVANCED 551 STATIC_SUN void sun_set_alt_cyl(void); 552 STATIC_SUN void sun_set_ncyl(int cyl); 553 STATIC_SUN void sun_set_xcyl(void); 554 STATIC_SUN void sun_set_ilfact(void); 555 STATIC_SUN void sun_set_rspeed(void); 556 STATIC_SUN void sun_set_pcylcount(void); 557 #endif 558 STATIC_SUN void toggle_sunflags(int i, unsigned char mask); 559 STATIC_SUN void verify_sun(void); 560 STATIC_SUN void sun_write_table(void); 561 #include "fdisk_sun.c" 562 563 #if ENABLE_FEATURE_FDISK_WRITABLE 3290 564 /* start_sect and nr_sects are stored little endian on all machines */ 3291 565 /* moreover, they are not aligned correctly */ 3292 566 static void 3293 store4_little_endian(unsigned char *cp, unsigned intval)3294 { 3295 cp[0] = (val & 0xff);3296 cp[1] = ((val >> 8) & 0xff);3297 cp[2] = ((val >> 16) & 0xff);3298 cp[3] = ((val >> 24) & 0xff);3299 } 3300 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */3301 3302 static unsigned int567 store4_little_endian(unsigned char *cp, unsigned val) 568 { 569 cp[0] = val; 570 cp[1] = val >> 8; 571 cp[2] = val >> 16; 572 cp[3] = val >> 24; 573 } 574 #endif /* FEATURE_FDISK_WRITABLE */ 575 576 static unsigned 3303 577 read4_little_endian(const unsigned char *cp) 3304 578 { 3305 return (uint)(cp[0]) + ((uint)(cp[1]) << 8) 3306 + ((uint)(cp[2]) << 16) + ((uint)(cp[3]) << 24); 3307 } 3308 3309 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 3310 static void 3311 set_start_sect(struct partition *p, unsigned int start_sect) 579 return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24); 580 } 581 582 #if ENABLE_FEATURE_FDISK_WRITABLE 583 static void 584 set_start_sect(struct partition *p, unsigned start_sect) 3312 585 { 3313 586 store4_little_endian(p->start4, start_sect); … … 3315 588 #endif 3316 589 3317 static int32_t590 static unsigned 3318 591 get_start_sect(const struct partition *p) 3319 592 { … … 3321 594 } 3322 595 3323 #if def CONFIG_FEATURE_FDISK_WRITABLE3324 static void 3325 set_nr_sects(struct partition *p, int32_tnr_sects)596 #if ENABLE_FEATURE_FDISK_WRITABLE 597 static void 598 set_nr_sects(struct partition *p, unsigned nr_sects) 3326 599 { 3327 600 store4_little_endian(p->size4, nr_sects); … … 3329 602 #endif 3330 603 3331 static int32_t604 static unsigned 3332 605 get_nr_sects(const struct partition *p) 3333 606 { … … 3338 611 static int type_open = O_RDWR; 3339 612 3340 3341 613 static int ext_index; /* the prime extended partition */ 3342 static int listing; 614 static int listing; /* no aborts for fdisk -l */ 3343 615 static int dos_compatible_flag = ~0; 3344 #if def CONFIG_FEATURE_FDISK_WRITABLE616 #if ENABLE_FEATURE_FDISK_WRITABLE 3345 617 static int dos_changed; 3346 618 static int nowarn; /* no warnings for fdisk -l/-s */ 3347 619 #endif 3348 620 3349 3350 3351 static uint user_cylinders, user_heads, user_sectors; 3352 static uint pt_heads, pt_sectors; 3353 static uint kern_heads, kern_sectors; 3354 3355 static off_t extended_offset; /* offset of link pointers */ 3356 3357 static unsigned long long total_number_of_sectors; 3358 3359 3360 static jmp_buf listingbuf; 3361 3362 static void fdisk_fatal(enum failure why) 3363 { 3364 const char *message; 3365 621 static unsigned user_cylinders, user_heads, user_sectors; 622 static unsigned pt_heads, pt_sectors; 623 static unsigned kern_heads, kern_sectors; 624 625 static ullong extended_offset; /* offset of link pointers */ 626 static ullong total_number_of_sectors; 627 628 static void fdisk_fatal(const char *why) 629 { 3366 630 if (listing) { 3367 631 close(fd); 3368 632 longjmp(listingbuf, 1); 3369 633 } 3370 3371 switch (why) { 3372 case unable_to_open: 3373 message = "Unable to open %s\n"; 3374 break; 3375 case unable_to_read: 3376 message = "Unable to read %s\n"; 3377 break; 3378 case unable_to_seek: 3379 message = "Unable to seek on %s\n"; 3380 break; 3381 case unable_to_write: 3382 message = "Unable to write %s\n"; 3383 break; 3384 case ioctl_error: 3385 message = "BLKGETSIZE ioctl failed on %s\n"; 3386 break; 3387 default: 3388 message = "Fatal error\n"; 3389 } 3390 3391 fputc('\n', stderr); 3392 fprintf(stderr, message, disk_device); 3393 exit(1); 3394 } 3395 3396 static void 3397 seek_sector(off_t secno) 3398 { 3399 off_t offset = secno * sector_size; 3400 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) 634 bb_error_msg_and_die(why, disk_device); 635 } 636 637 static void 638 seek_sector(ullong secno) 639 { 640 secno *= sector_size; 641 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS 642 if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1) 3401 643 fdisk_fatal(unable_to_seek); 3402 } 3403 3404 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 3405 static void 3406 write_sector(off_t secno, char *buf) 644 #else 645 if (secno > MAXINT(off_t) 646 || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1 647 ) { 648 fdisk_fatal(unable_to_seek); 649 } 650 #endif 651 } 652 653 #if ENABLE_FEATURE_FDISK_WRITABLE 654 static void 655 write_sector(ullong secno, char *buf) 3407 656 { 3408 657 seek_sector(secno); … … 3414 663 /* Allocate a buffer and read a partition table sector */ 3415 664 static void 3416 read_pte(struct pte *pe, off_toffset)665 read_pte(struct pte *pe, ullong offset) 3417 666 { 3418 667 pe->offset = offset; 3419 pe->sectorbuffer = (char *)xmalloc(sector_size);668 pe->sectorbuffer = xmalloc(sector_size); 3420 669 seek_sector(offset); 3421 670 if (read(fd, pe->sectorbuffer, sector_size) != sector_size) 3422 671 fdisk_fatal(unable_to_read); 3423 #if def CONFIG_FEATURE_FDISK_WRITABLE672 #if ENABLE_FEATURE_FDISK_WRITABLE 3424 673 pe->changed = 0; 3425 674 #endif … … 3427 676 } 3428 677 3429 static unsigned int678 static unsigned 3430 679 get_partition_start(const struct pte *pe) 3431 680 { … … 3433 682 } 3434 683 3435 #if def CONFIG_FEATURE_FDISK_WRITABLE684 #if ENABLE_FEATURE_FDISK_WRITABLE 3436 685 /* 3437 686 * Avoid warning about DOS partitions when no DOS partition was changed. … … 3453 702 menu(void) 3454 703 { 3455 #ifdef CONFIG_FEATURE_SUN_LABEL 3456 if (label_sun == current_label_type) { 3457 puts(_("Command action")); 3458 puts(_("\ta\ttoggle a read only flag")); /* sun */ 3459 puts(_("\tb\tedit bsd disklabel")); 3460 puts(_("\tc\ttoggle the mountable flag")); /* sun */ 3461 puts(_("\td\tdelete a partition")); 3462 puts(_("\tl\tlist known partition types")); 3463 puts(_("\tm\tprint this menu")); 3464 puts(_("\tn\tadd a new partition")); 3465 puts(_("\to\tcreate a new empty DOS partition table")); 3466 puts(_("\tp\tprint the partition table")); 3467 puts(_("\tq\tquit without saving changes")); 3468 puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ 3469 puts(_("\tt\tchange a partition's system id")); 3470 puts(_("\tu\tchange display/entry units")); 3471 puts(_("\tv\tverify the partition table")); 3472 puts(_("\tw\twrite table to disk and exit")); 3473 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 3474 puts(_("\tx\textra functionality (experts only)")); 3475 #endif 3476 } else 3477 #endif 3478 #ifdef CONFIG_FEATURE_SGI_LABEL 3479 if (label_sgi == current_label_type) { 3480 puts(_("Command action")); 3481 puts(_("\ta\tselect bootable partition")); /* sgi flavour */ 3482 puts(_("\tb\tedit bootfile entry")); /* sgi */ 3483 puts(_("\tc\tselect sgi swap partition")); /* sgi flavour */ 3484 puts(_("\td\tdelete a partition")); 3485 puts(_("\tl\tlist known partition types")); 3486 puts(_("\tm\tprint this menu")); 3487 puts(_("\tn\tadd a new partition")); 3488 puts(_("\to\tcreate a new empty DOS partition table")); 3489 puts(_("\tp\tprint the partition table")); 3490 puts(_("\tq\tquit without saving changes")); 3491 puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ 3492 puts(_("\tt\tchange a partition's system id")); 3493 puts(_("\tu\tchange display/entry units")); 3494 puts(_("\tv\tverify the partition table")); 3495 puts(_("\tw\twrite table to disk and exit")); 3496 } else 3497 #endif 3498 #ifdef CONFIG_FEATURE_AIX_LABEL 3499 if (label_aix == current_label_type) { 3500 puts(_("Command action")); 3501 puts(_("\tm\tprint this menu")); 3502 puts(_("\to\tcreate a new empty DOS partition table")); 3503 puts(_("\tq\tquit without saving changes")); 3504 puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ 3505 } else 3506 #endif 3507 { 3508 puts(_("Command action")); 3509 puts(_("\ta\ttoggle a bootable flag")); 3510 puts(_("\tb\tedit bsd disklabel")); 3511 puts(_("\tc\ttoggle the dos compatibility flag")); 3512 puts(_("\td\tdelete a partition")); 3513 puts(_("\tl\tlist known partition types")); 3514 puts(_("\tm\tprint this menu")); 3515 puts(_("\tn\tadd a new partition")); 3516 puts(_("\to\tcreate a new empty DOS partition table")); 3517 puts(_("\tp\tprint the partition table")); 3518 puts(_("\tq\tquit without saving changes")); 3519 puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ 3520 puts(_("\tt\tchange a partition's system id")); 3521 puts(_("\tu\tchange display/entry units")); 3522 puts(_("\tv\tverify the partition table")); 3523 puts(_("\tw\twrite table to disk and exit")); 3524 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 3525 puts(_("\tx\textra functionality (experts only)")); 3526 #endif 3527 } 3528 } 3529 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 3530 3531 3532 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 704 puts("Command Action"); 705 if (LABEL_IS_SUN) { 706 puts("a\ttoggle a read only flag"); /* sun */ 707 puts("b\tedit bsd disklabel"); 708 puts("c\ttoggle the mountable flag"); /* sun */ 709 puts("d\tdelete a partition"); 710 puts("l\tlist known partition types"); 711 puts("n\tadd a new partition"); 712 puts("o\tcreate a new empty DOS partition table"); 713 puts("p\tprint the partition table"); 714 puts("q\tquit without saving changes"); 715 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 716 puts("t\tchange a partition's system id"); 717 puts("u\tchange display/entry units"); 718 puts("v\tverify the partition table"); 719 puts("w\twrite table to disk and exit"); 720 #if ENABLE_FEATURE_FDISK_ADVANCED 721 puts("x\textra functionality (experts only)"); 722 #endif 723 } else if (LABEL_IS_SGI) { 724 puts("a\tselect bootable partition"); /* sgi flavour */ 725 puts("b\tedit bootfile entry"); /* sgi */ 726 puts("c\tselect sgi swap partition"); /* sgi flavour */ 727 puts("d\tdelete a partition"); 728 puts("l\tlist known partition types"); 729 puts("n\tadd a new partition"); 730 puts("o\tcreate a new empty DOS partition table"); 731 puts("p\tprint the partition table"); 732 puts("q\tquit without saving changes"); 733 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 734 puts("t\tchange a partition's system id"); 735 puts("u\tchange display/entry units"); 736 puts("v\tverify the partition table"); 737 puts("w\twrite table to disk and exit"); 738 } else if (LABEL_IS_AIX) { 739 puts("o\tcreate a new empty DOS partition table"); 740 puts("q\tquit without saving changes"); 741 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 742 } else { 743 puts("a\ttoggle a bootable flag"); 744 puts("b\tedit bsd disklabel"); 745 puts("c\ttoggle the dos compatibility flag"); 746 puts("d\tdelete a partition"); 747 puts("l\tlist known partition types"); 748 puts("n\tadd a new partition"); 749 puts("o\tcreate a new empty DOS partition table"); 750 puts("p\tprint the partition table"); 751 puts("q\tquit without saving changes"); 752 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 753 puts("t\tchange a partition's system id"); 754 puts("u\tchange display/entry units"); 755 puts("v\tverify the partition table"); 756 puts("w\twrite table to disk and exit"); 757 #if ENABLE_FEATURE_FDISK_ADVANCED 758 puts("x\textra functionality (experts only)"); 759 #endif 760 } 761 } 762 #endif /* FEATURE_FDISK_WRITABLE */ 763 764 765 #if ENABLE_FEATURE_FDISK_ADVANCED 3533 766 static void 3534 767 xmenu(void) 3535 768 { 3536 #ifdef CONFIG_FEATURE_SUN_LABEL 3537 if (label_sun == current_label_type) { 3538 puts(_("Command action")); 3539 puts(_("\ta\tchange number of alternate cylinders")); /*sun*/ 3540 puts(_("\tc\tchange number of cylinders")); 3541 puts(_("\td\tprint the raw data in the partition table")); 3542 puts(_("\te\tchange number of extra sectors per cylinder"));/*sun*/ 3543 puts(_("\th\tchange number of heads")); 3544 puts(_("\ti\tchange interleave factor")); /*sun*/ 3545 puts(_("\to\tchange rotation speed (rpm)")); /*sun*/ 3546 puts(_("\tm\tprint this menu")); 3547 puts(_("\tp\tprint the partition table")); 3548 puts(_("\tq\tquit without saving changes")); 3549 puts(_("\tr\treturn to main menu")); 3550 puts(_("\ts\tchange number of sectors/track")); 3551 puts(_("\tv\tverify the partition table")); 3552 puts(_("\tw\twrite table to disk and exit")); 3553 puts(_("\ty\tchange number of physical cylinders")); /*sun*/ 3554 } else 3555 #endif 3556 #ifdef CONFIG_FEATURE_SGI_LABEL 3557 if (label_sgi == current_label_type) { 3558 puts(_("Command action")); 3559 puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ 3560 puts(_("\tc\tchange number of cylinders")); 3561 puts(_("\td\tprint the raw data in the partition table")); 3562 puts(_("\te\tlist extended partitions")); /* !sun */ 3563 puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ 3564 puts(_("\th\tchange number of heads")); 3565 puts(_("\tm\tprint this menu")); 3566 puts(_("\tp\tprint the partition table")); 3567 puts(_("\tq\tquit without saving changes")); 3568 puts(_("\tr\treturn to main menu")); 3569 puts(_("\ts\tchange number of sectors/track")); 3570 puts(_("\tv\tverify the partition table")); 3571 puts(_("\tw\twrite table to disk and exit")); 3572 } else 3573 #endif 3574 #ifdef CONFIG_FEATURE_AIX_LABEL 3575 if (label_aix == current_label_type) { 3576 puts(_("Command action")); 3577 puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ 3578 puts(_("\tc\tchange number of cylinders")); 3579 puts(_("\td\tprint the raw data in the partition table")); 3580 puts(_("\te\tlist extended partitions")); /* !sun */ 3581 puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ 3582 puts(_("\th\tchange number of heads")); 3583 puts(_("\tm\tprint this menu")); 3584 puts(_("\tp\tprint the partition table")); 3585 puts(_("\tq\tquit without saving changes")); 3586 puts(_("\tr\treturn to main menu")); 3587 puts(_("\ts\tchange number of sectors/track")); 3588 puts(_("\tv\tverify the partition table")); 3589 puts(_("\tw\twrite table to disk and exit")); 3590 } else 3591 #endif 3592 { 3593 puts(_("Command action")); 3594 puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ 3595 puts(_("\tc\tchange number of cylinders")); 3596 puts(_("\td\tprint the raw data in the partition table")); 3597 puts(_("\te\tlist extended partitions")); /* !sun */ 3598 puts(_("\tf\tfix partition order")); /* !sun, !aix, !sgi */ 3599 #ifdef CONFIG_FEATURE_SGI_LABEL 3600 puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ 3601 #endif 3602 puts(_("\th\tchange number of heads")); 3603 puts(_("\tm\tprint this menu")); 3604 puts(_("\tp\tprint the partition table")); 3605 puts(_("\tq\tquit without saving changes")); 3606 puts(_("\tr\treturn to main menu")); 3607 puts(_("\ts\tchange number of sectors/track")); 3608 puts(_("\tv\tverify the partition table")); 3609 puts(_("\tw\twrite table to disk and exit")); 769 puts("Command Action"); 770 if (LABEL_IS_SUN) { 771 puts("a\tchange number of alternate cylinders"); /*sun*/ 772 puts("c\tchange number of cylinders"); 773 puts("d\tprint the raw data in the partition table"); 774 puts("e\tchange number of extra sectors per cylinder");/*sun*/ 775 puts("h\tchange number of heads"); 776 puts("i\tchange interleave factor"); /*sun*/ 777 puts("o\tchange rotation speed (rpm)"); /*sun*/ 778 puts("p\tprint the partition table"); 779 puts("q\tquit without saving changes"); 780 puts("r\treturn to main menu"); 781 puts("s\tchange number of sectors/track"); 782 puts("v\tverify the partition table"); 783 puts("w\twrite table to disk and exit"); 784 puts("y\tchange number of physical cylinders"); /*sun*/ 785 } else if (LABEL_IS_SGI) { 786 puts("b\tmove beginning of data in a partition"); /* !sun */ 787 puts("c\tchange number of cylinders"); 788 puts("d\tprint the raw data in the partition table"); 789 puts("e\tlist extended partitions"); /* !sun */ 790 puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ 791 puts("h\tchange number of heads"); 792 puts("p\tprint the partition table"); 793 puts("q\tquit without saving changes"); 794 puts("r\treturn to main menu"); 795 puts("s\tchange number of sectors/track"); 796 puts("v\tverify the partition table"); 797 puts("w\twrite table to disk and exit"); 798 } else if (LABEL_IS_AIX) { 799 puts("b\tmove beginning of data in a partition"); /* !sun */ 800 puts("c\tchange number of cylinders"); 801 puts("d\tprint the raw data in the partition table"); 802 puts("e\tlist extended partitions"); /* !sun */ 803 puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ 804 puts("h\tchange number of heads"); 805 puts("p\tprint the partition table"); 806 puts("q\tquit without saving changes"); 807 puts("r\treturn to main menu"); 808 puts("s\tchange number of sectors/track"); 809 puts("v\tverify the partition table"); 810 puts("w\twrite table to disk and exit"); 811 } else { 812 puts("b\tmove beginning of data in a partition"); /* !sun */ 813 puts("c\tchange number of cylinders"); 814 puts("d\tprint the raw data in the partition table"); 815 puts("e\tlist extended partitions"); /* !sun */ 816 puts("f\tfix partition order"); /* !sun, !aix, !sgi */ 817 #if ENABLE_FEATURE_SGI_LABEL 818 puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ 819 #endif 820 puts("h\tchange number of heads"); 821 puts("p\tprint the partition table"); 822 puts("q\tquit without saving changes"); 823 puts("r\treturn to main menu"); 824 puts("s\tchange number of sectors/track"); 825 puts("v\tverify the partition table"); 826 puts("w\twrite table to disk and exit"); 3610 827 } 3611 828 } 3612 829 #endif /* ADVANCED mode */ 3613 830 3614 #if def CONFIG_FEATURE_FDISK_WRITABLE3615 static const struct systypes*831 #if ENABLE_FEATURE_FDISK_WRITABLE 832 static const char *const * 3616 833 get_sys_types(void) 3617 834 { 3618 835 return ( 3619 #ifdef CONFIG_FEATURE_SUN_LABEL 3620 label_sun == current_label_type ? sun_sys_types : 3621 #endif 3622 #ifdef CONFIG_FEATURE_SGI_LABEL 3623 label_sgi == current_label_type ? sgi_sys_types : 3624 #endif 836 LABEL_IS_SUN ? sun_sys_types : 837 LABEL_IS_SGI ? sgi_sys_types : 3625 838 i386_sys_types); 3626 839 } 3627 840 #else 3628 841 #define get_sys_types() i386_sys_types 3629 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 3630 3631 static const char *partition_type(unsigned char type) 842 #endif /* FEATURE_FDISK_WRITABLE */ 843 844 static const char * 845 partition_type(unsigned char type) 3632 846 { 3633 847 int i; 3634 const struct systypes*types = get_sys_types();3635 3636 for (i = 0; types[i] .name; i++)3637 if ((unsigned char )types[i].name[0] == type)3638 return types[i] .name+ 1;3639 3640 return _("Unknown");3641 } 3642 3643 3644 #if def CONFIG_FEATURE_FDISK_WRITABLE848 const char *const *types = get_sys_types(); 849 850 for (i = 0; types[i]; i++) 851 if ((unsigned char)types[i][0] == type) 852 return types[i] + 1; 853 854 return "Unknown"; 855 } 856 857 858 #if ENABLE_FEATURE_FDISK_WRITABLE 3645 859 static int 3646 860 get_sysid(int i) 3647 861 { 3648 return ( 3649 #ifdef CONFIG_FEATURE_SUN_LABEL 3650 label_sun == current_label_type ? sunlabel->infos[i].id : 3651 #endif 3652 #ifdef CONFIG_FEATURE_SGI_LABEL 3653 label_sgi == current_label_type ? sgi_get_sysid(i) : 3654 #endif 3655 ptes[i].part_table->sys_ind); 3656 } 3657 3658 void list_types(const struct systypes *sys) 3659 { 3660 uint last[4], done = 0, next = 0, size; 862 return LABEL_IS_SUN ? sunlabel->infos[i].id : 863 (LABEL_IS_SGI ? sgi_get_sysid(i) : 864 ptes[i].part_table->sys_ind); 865 } 866 867 static void 868 list_types(const char *const *sys) 869 { 870 enum { COLS = 3 }; 871 872 unsigned last[COLS]; 873 unsigned done, next, size; 3661 874 int i; 3662 875 3663 for (i = 0; sys[i].name; i++); 3664 size = i; 3665 3666 for (i = 3; i >= 0; i--) 3667 last[3 - i] = done += (size + i - done) / (i + 1); 3668 i = done = 0; 3669 876 for (size = 0; sys[size]; size++) /* */; 877 878 done = 0; 879 for (i = COLS-1; i >= 0; i--) { 880 done += (size + i - done) / (i + 1); 881 last[COLS-1 - i] = done; 882 } 883 884 i = done = next = 0; 3670 885 do { 3671 printf("%c%2x %-15.15s", i ? ' ' : '\n',3672 (unsigned char)sys[next] .name[0],3673 partition_type((unsigned char)sys[next].name[0]));886 printf("%c%2x %-22.22s", i ? ' ' : '\n', 887 (unsigned char)sys[next][0], 888 sys[next] + 1); 3674 889 next = last[i++] + done; 3675 if (i > 3|| next >= last[i]) {890 if (i >= COLS || next >= last[i]) { 3676 891 i = 0; 3677 892 next = ++done; … … 3680 895 putchar('\n'); 3681 896 } 3682 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */897 #endif /* FEATURE_FDISK_WRITABLE */ 3683 898 3684 899 static int … … 3698 913 } 3699 914 3700 #if def CONFIG_FEATURE_FDISK_WRITABLE3701 static void 3702 set_partition(int i, int doext, off_t start, off_tstop, int sysid)915 #if ENABLE_FEATURE_FDISK_WRITABLE 916 static void 917 set_partition(int i, int doext, ullong start, ullong stop, int sysid) 3703 918 { 3704 919 struct partition *p; 3705 off_toffset;920 ullong offset; 3706 921 3707 922 if (doext) { … … 3727 942 3728 943 static int 3729 test_c(const char **m, const char *mesg)3730 {3731 int val = 0;3732 if (!*m)3733 fprintf(stderr, _("You must set"));3734 else {3735 fprintf(stderr, " %s", *m);3736 val = 1;3737 }3738 *m = mesg;3739 return val;3740 }3741 3742 static int3743 944 warn_geometry(void) 3744 945 { 3745 const char *m = NULL; 3746 int prev = 0; 3747 946 if (heads && sectors && cylinders) 947 return 0; 948 949 printf("Unknown value(s) for:"); 3748 950 if (!heads) 3749 pr ev = test_c(&m, _("heads"));951 printf(" heads"); 3750 952 if (!sectors) 3751 pr ev = test_c(&m, _("sectors"));953 printf(" sectors"); 3752 954 if (!cylinders) 3753 prev = test_c(&m, _("cylinders")); 3754 if (!m) 3755 return 0; 3756 3757 fprintf(stderr, "%s%s.\n" 3758 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 3759 "You can do this from the extra functions menu.\n" 3760 #endif 3761 , prev ? _(" and ") : " ", m); 3762 955 printf(" cylinders"); 956 printf( 957 #if ENABLE_FEATURE_FDISK_WRITABLE 958 " (settable in the extra functions menu)" 959 #endif 960 "\n"); 3763 961 return 1; 3764 962 } 3765 963 3766 static void update_units(void) 964 static void 965 update_units(void) 3767 966 { 3768 967 int cyl_units = heads * sectors; … … 3774 973 } 3775 974 3776 #if def CONFIG_FEATURE_FDISK_WRITABLE975 #if ENABLE_FEATURE_FDISK_WRITABLE 3777 976 static void 3778 977 warn_cylinders(void) 3779 978 { 3780 if ( label_dos == current_label_type&& cylinders > 1024 && !nowarn)3781 fprintf(stderr, _("\n"979 if (LABEL_IS_DOS && cylinders > 1024 && !nowarn) 980 printf("\n" 3782 981 "The number of cylinders for this disk is set to %d.\n" 3783 982 "There is nothing wrong with that, but this is larger than 1024,\n" … … 3785 984 "1) software that runs at boot time (e.g., old versions of LILO)\n" 3786 985 "2) booting and partitioning software from other OSs\n" 3787 " (e.g., DOS FDISK, OS/2 FDISK)\n" ),986 " (e.g., DOS FDISK, OS/2 FDISK)\n", 3788 987 cylinders); 3789 988 } … … 3803 1002 p = pex->part_table; 3804 1003 if (!get_start_sect(p)) { 3805 fprintf(stderr, 3806 _("Bad offset in primary extended partition\n")); 1004 printf("Bad offset in primary extended partition\n"); 3807 1005 return; 3808 1006 } … … 3814 1012 /* This is not a Linux restriction, but 3815 1013 this program uses arrays of size MAXIMUM_PARTS. 3816 Do not try to `improve' this test. */1014 Do not try to 'improve' this test. */ 3817 1015 struct pte *pre = &ptes[partitions-1]; 3818 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 3819 fprintf(stderr, 3820 _("Warning: deleting partitions after %d\n"), 1016 #if ENABLE_FEATURE_FDISK_WRITABLE 1017 printf("Warning: deleting partitions after %d\n", 3821 1018 partitions); 3822 1019 pre->changed = 1; … … 3835 1032 if (IS_EXTENDED(p->sys_ind)) { 3836 1033 if (pe->ext_pointer) 3837 fprintf(stderr, 3838 _("Warning: extra link " 3839 "pointer in partition table" 3840 " %d\n"), partitions + 1); 1034 printf("Warning: extra link " 1035 "pointer in partition table" 1036 " %d\n", partitions + 1); 3841 1037 else 3842 1038 pe->ext_pointer = p; 3843 1039 } else if (p->sys_ind) { 3844 1040 if (pe->part_table) 3845 fprintf(stderr, 3846 _("Warning: ignoring extra " 1041 printf("Warning: ignoring extra " 3847 1042 "data in partition table" 3848 " %d\n" ), partitions + 1);1043 " %d\n", partitions + 1); 3849 1044 else 3850 1045 pe->part_table = p; … … 3870 1065 } 3871 1066 3872 #if def CONFIG_FEATURE_FDISK_WRITABLE1067 #if ENABLE_FEATURE_FDISK_WRITABLE 3873 1068 /* remove empty links */ 3874 1069 remove: … … 3876 1071 struct pte *pe = &ptes[i]; 3877 1072 3878 if (!get_nr_sects(pe->part_table) && 3879 (partitions > 5 || ptes[4].part_table->sys_ind)) { 3880 printf("omitting empty partition (%d)\n", i+1); 1073 if (!get_nr_sects(pe->part_table) 1074 && (partitions > 5 || ptes[4].part_table->sys_ind) 1075 ) { 1076 printf("Omitting empty partition (%d)\n", i+1); 3881 1077 delete_partition(i); 3882 1078 goto remove; /* numbering changed */ … … 3886 1082 } 3887 1083 3888 #if def CONFIG_FEATURE_FDISK_WRITABLE1084 #if ENABLE_FEATURE_FDISK_WRITABLE 3889 1085 static void 3890 1086 create_doslabel(void) … … 3892 1088 int i; 3893 1089 3894 fprintf(stderr, 3895 _("Building a new DOS disklabel. Changes will remain in memory only,\n" 3896 "until you decide to write them. After that, of course, the previous\n" 3897 "content won't be recoverable.\n\n")); 1090 printf(msg_building_new_label, "DOS disklabel"); 3898 1091 3899 1092 current_label_type = label_dos; 3900 1093 3901 #if def CONFIG_FEATURE_OSF_LABEL1094 #if ENABLE_FEATURE_OSF_LABEL 3902 1095 possibly_osf_label = 0; 3903 1096 #endif … … 3912 1105 get_boot(create_empty_dos); 3913 1106 } 3914 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */1107 #endif /* FEATURE_FDISK_WRITABLE */ 3915 1108 3916 1109 static void … … 3922 1115 sector_size = arg; 3923 1116 if (sector_size != DEFAULT_SECTOR_SIZE) 3924 printf( _("Note: sector size is %d (not %d)\n"),1117 printf("Note: sector size is %d (not %d)\n", 3925 1118 sector_size, DEFAULT_SECTOR_SIZE); 3926 1119 } 3927 1120 } 3928 1121 3929 static inlinevoid1122 static void 3930 1123 get_kernel_geometry(void) 3931 1124 { … … 3976 1169 { 3977 1170 int sec_fac; 3978 u nsigned long long bytes; /* really u64 */1171 uint64_t v64; 3979 1172 3980 1173 get_sectorsize(); 3981 1174 sec_fac = sector_size / 512; 3982 #if def CONFIG_FEATURE_SUN_LABEL1175 #if ENABLE_FEATURE_SUN_LABEL 3983 1176 guess_device_type(); 3984 1177 #endif … … 3996 1189 pt_sectors ? pt_sectors : 3997 1190 kern_sectors ? kern_sectors : 63; 3998 if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) { 3999 /* got bytes */ 1191 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) { 1192 /* got bytes, convert to 512 byte sectors */ 1193 total_number_of_sectors = (v64 >> 9); 4000 1194 } else { 4001 unsigned long longsectors; 4002 4003 if (ioctl(fd, BLKGETSIZE, &longsectors)) 4004 longsectors = 0; 4005 bytes = ((unsigned long long) longsectors) << 9; 4006 } 4007 4008 total_number_of_sectors = (bytes >> 9); 1195 unsigned long longsectors; /* need temp of type long */ 1196 if (ioctl(fd, BLKGETSIZE, &longsectors)) 1197 longsectors = 0; 1198 total_number_of_sectors = longsectors; 1199 } 4009 1200 4010 1201 sector_offset = 1; … … 4037 1228 pe->offset = 0; 4038 1229 pe->sectorbuffer = MBRbuffer; 4039 #if def CONFIG_FEATURE_FDISK_WRITABLE1230 #if ENABLE_FEATURE_FDISK_WRITABLE 4040 1231 pe->changed = (what == create_empty_dos); 4041 1232 #endif 4042 1233 } 4043 1234 4044 #if def CONFIG_FEATURE_SUN_LABEL1235 #if ENABLE_FEATURE_SUN_LABEL 4045 1236 if (what == create_empty_sun && check_sun_label()) 4046 1237 return 0; … … 4049 1240 memset(MBRbuffer, 0, 512); 4050 1241 4051 #if def CONFIG_FEATURE_FDISK_WRITABLE1242 #if ENABLE_FEATURE_FDISK_WRITABLE 4052 1243 if (what == create_empty_dos) 4053 1244 goto got_dos_table; /* skip reading disk */ 4054 1245 4055 if ((fd = open(disk_device, type_open)) < 0) { 4056 if ((fd = open(disk_device, O_RDONLY)) < 0) { 1246 fd = open(disk_device, type_open); 1247 if (fd < 0) { 1248 fd = open(disk_device, O_RDONLY); 1249 if (fd < 0) { 4057 1250 if (what == try_only) 4058 1251 return 1; 4059 1252 fdisk_fatal(unable_to_open); 4060 1253 } else 4061 printf( _("You will not be able to write "4062 "the partition table .\n"));1254 printf("You will not be able to write " 1255 "the partition table\n"); 4063 1256 } 4064 1257 … … 4069 1262 } 4070 1263 #else 4071 if ((fd = open(disk_device, O_RDONLY)) < 0) 1264 fd = open(disk_device, O_RDONLY); 1265 if (fd < 0) 4072 1266 return 1; 4073 1267 if (512 != read(fd, MBRbuffer, 512)) … … 4079 1273 update_units(); 4080 1274 4081 #if def CONFIG_FEATURE_SUN_LABEL1275 #if ENABLE_FEATURE_SUN_LABEL 4082 1276 if (check_sun_label()) 4083 1277 return 0; 4084 1278 #endif 4085 1279 4086 #if def CONFIG_FEATURE_SGI_LABEL1280 #if ENABLE_FEATURE_SGI_LABEL 4087 1281 if (check_sgi_label()) 4088 1282 return 0; 4089 1283 #endif 4090 1284 4091 #if def CONFIG_FEATURE_AIX_LABEL1285 #if ENABLE_FEATURE_AIX_LABEL 4092 1286 if (check_aix_label()) 4093 1287 return 0; 4094 1288 #endif 4095 1289 4096 #if def CONFIG_FEATURE_OSF_LABEL1290 #if ENABLE_FEATURE_OSF_LABEL 4097 1291 if (check_osf_label()) { 4098 1292 possibly_osf_label = 1; … … 4101 1295 return 0; 4102 1296 } 4103 printf( _("This disk has both DOS and BSD magic.\n"4104 "Give the 'b' command to go to BSD mode.\n") );4105 } 4106 #endif 4107 4108 #if def CONFIG_FEATURE_FDISK_WRITABLE1297 printf("This disk has both DOS and BSD magic.\n" 1298 "Give the 'b' command to go to BSD mode.\n"); 1299 } 1300 #endif 1301 1302 #if ENABLE_FEATURE_FDISK_WRITABLE 4109 1303 got_dos_table: 4110 1304 #endif 4111 1305 4112 1306 if (!valid_part_table_flag(MBRbuffer)) { 4113 #if ndef CONFIG_FEATURE_FDISK_WRITABLE1307 #if !ENABLE_FEATURE_FDISK_WRITABLE 4114 1308 return -1; 4115 1309 #else 4116 1310 switch (what) { 4117 1311 case fdisk: 4118 fprintf(stderr, 4119 _("Device contains neither a valid DOS " 1312 printf("Device contains neither a valid DOS " 4120 1313 "partition table, nor Sun, SGI or OSF " 4121 "disklabel\n") );1314 "disklabel\n"); 4122 1315 #ifdef __sparc__ 4123 #if def CONFIG_FEATURE_SUN_LABEL1316 #if ENABLE_FEATURE_SUN_LABEL 4124 1317 create_sunlabel(); 4125 1318 #endif … … 4131 1324 return -1; 4132 1325 case create_empty_dos: 4133 #if def CONFIG_FEATURE_SUN_LABEL1326 #if ENABLE_FEATURE_SUN_LABEL 4134 1327 case create_empty_sun: 4135 1328 #endif 4136 1329 break; 4137 1330 default: 4138 fprintf(stderr, _("Internal error\n")); 4139 exit(1); 4140 } 4141 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 4142 } 4143 4144 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 1331 bb_error_msg_and_die("internal error"); 1332 } 1333 #endif /* FEATURE_FDISK_WRITABLE */ 1334 } 1335 1336 #if ENABLE_FEATURE_FDISK_WRITABLE 4145 1337 warn_cylinders(); 4146 1338 #endif … … 4152 1344 if (IS_EXTENDED(pe->part_table->sys_ind)) { 4153 1345 if (partitions != 4) 4154 fprintf(stderr, _("Ignoring extra extended "4155 "partition %d\n" ), i + 1);1346 printf("Ignoring extra extended " 1347 "partition %d\n", i + 1); 4156 1348 else 4157 1349 read_extended(i); … … 4163 1355 4164 1356 if (!valid_part_table_flag(pe->sectorbuffer)) { 4165 fprintf(stderr, 4166 _("Warning: invalid flag 0x%04x of partition " 4167 "table %d will be corrected by w(rite)\n"), 4168 part_table_flag(pe->sectorbuffer), i + 1); 4169 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 1357 printf("Warning: invalid flag 0x%02x,0x%02x of partition " 1358 "table %d will be corrected by w(rite)\n", 1359 pe->sectorbuffer[510], 1360 pe->sectorbuffer[511], 1361 i + 1); 1362 #if ENABLE_FEATURE_FDISK_WRITABLE 4170 1363 pe->changed = 1; 4171 1364 #endif … … 4176 1369 } 4177 1370 4178 #if def CONFIG_FEATURE_FDISK_WRITABLE1371 #if ENABLE_FEATURE_FDISK_WRITABLE 4179 1372 /* 4180 1373 * Print the message MESG, then read an integer between LOW and HIGH (inclusive). … … 4184 1377 * There is no default if DFLT is not between LOW and HIGH. 4185 1378 */ 4186 static u int4187 read_int(u int low, uint dflt, uint high, uint base,char *mesg)4188 { 4189 u inti;1379 static unsigned 1380 read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg) 1381 { 1382 unsigned i; 4190 1383 int default_ok = 1; 4191 static char *ms = NULL; 4192 static int mslen = 0; 4193 4194 if (!ms || strlen(mesg)+100 > mslen) { 4195 mslen = strlen(mesg)+200; 4196 ms = xrealloc(ms,mslen); 4197 } 4198 4199 if (dflt < low || dflt > high) 1384 const char *fmt = "%s (%u-%u, default %u): "; 1385 1386 if (dflt < low || dflt > high) { 1387 fmt = "%s (%u-%u): "; 4200 1388 default_ok = 0; 4201 4202 if (default_ok) 4203 snprintf(ms, mslen, _("%s (%u-%u, default %u): "), 4204 mesg, low, high, dflt); 4205 else 4206 snprintf(ms, mslen, "%s (%u-%u): ", mesg, low, high); 1389 } 4207 1390 4208 1391 while (1) { … … 4210 1393 4211 1394 /* ask question and read answer */ 4212 while (read_chars(ms) != '\n' && !isdigit(*line_ptr) 4213 && *line_ptr != '-' && *line_ptr != '+') 4214 continue; 1395 do { 1396 printf(fmt, mesg, low, high, dflt); 1397 read_maybe_empty(""); 1398 } while (*line_ptr != '\n' && !isdigit(*line_ptr) 1399 && *line_ptr != '-' && *line_ptr != '+'); 4215 1400 4216 1401 if (*line_ptr == '+' || *line_ptr == '-') { … … 4218 1403 int absolute = 0; 4219 1404 4220 i = atoi(line_ptr +1);1405 i = atoi(line_ptr + 1); 4221 1406 4222 1407 while (isdigit(*++line_ptr)) … … 4247 1432 } 4248 1433 if (absolute) { 4249 u nsigned longlong bytes;1434 ullong bytes; 4250 1435 unsigned long unit; 4251 1436 4252 bytes = (u nsigned longlong) i * absolute;1437 bytes = (ullong) i * absolute; 4253 1438 unit = sector_size * units_per_sector; 4254 1439 bytes += unit/2; /* round */ … … 4266 1451 } 4267 1452 } 4268 if (use_default) 4269 printf(_("Using default value %u\n"), i = dflt); 1453 if (use_default) { 1454 i = dflt; 1455 printf("Using default value %u\n", i); 1456 } 4270 1457 if (i >= low && i <= high) 4271 1458 break; 4272 else 4273 printf(_("Value out of range.\n")); 1459 printf("Value is out of range\n"); 4274 1460 } 4275 1461 return i; … … 4282 1468 int i; 4283 1469 4284 i = read_int(1, 0, max, 0, _("Partition number")) - 1;1470 i = read_int(1, 0, max, 0, "Partition number") - 1; 4285 1471 pe = &ptes[i]; 4286 1472 4287 1473 if (warn) { 4288 if ( 4289 ( 4290 label_sun != current_label_type && 4291 label_sgi != current_label_type && 4292 !pe->part_table->sys_ind 4293 ) 4294 #ifdef CONFIG_FEATURE_SUN_LABEL 4295 || ( 4296 label_sun == current_label_type && 4297 ( 4298 !sunlabel->partitions[i].num_sectors 4299 || !sunlabel->infos[i].id 4300 ) 4301 ) 4302 #endif 4303 #ifdef CONFIG_FEATURE_SGI_LABEL 4304 || ( 4305 label_sgi == current_label_type && 4306 !sgi_get_num_sectors(i) 4307 ) 4308 #endif 4309 ){ 4310 fprintf(stderr, 4311 _("Warning: partition %d has empty type\n"), 4312 i+1 4313 ); 1474 if ((!LABEL_IS_SUN && !LABEL_IS_SGI && !pe->part_table->sys_ind) 1475 || (LABEL_IS_SUN && (!sunlabel->partitions[i].num_sectors || !sunlabel->infos[i].id)) 1476 || (LABEL_IS_SGI && !sgi_get_num_sectors(i)) 1477 ) { 1478 printf("Warning: partition %d has empty type\n", i+1); 4314 1479 } 4315 1480 } … … 4334 1499 } 4335 1500 if (pno >= 0) { 4336 printf( _("Selected partition %d\n"), pno+1);1501 printf("Selected partition %d\n", pno+1); 4337 1502 return pno; 4338 1503 } 4339 printf( _("No partition is defined yet!\n"));1504 printf("No partition is defined yet!\n"); 4340 1505 return -1; 4341 1506 … … 4361 1526 } 4362 1527 if (pno >= 0) { 4363 printf( _("Selected partition %d\n"), pno+1);1528 printf("Selected partition %d\n", pno+1); 4364 1529 return pno; 4365 1530 } 4366 printf( _("All primary partitions have been defined already!\n"));1531 printf("All primary partitions have been defined already!\n"); 4367 1532 return -1; 4368 1533 … … 4372 1537 4373 1538 4374 void change_units(void) 1539 static void 1540 change_units(void) 4375 1541 { 4376 1542 display_in_cyl_units = !display_in_cyl_units; 4377 1543 update_units(); 4378 printf( _("Changing display/entry units to %s\n"),1544 printf("Changing display/entry units to %s\n", 4379 1545 str_units(PLURAL)); 4380 1546 } … … 4387 1553 4388 1554 if (IS_EXTENDED(p->sys_ind) && !p->boot_ind) 4389 fprintf(stderr, 4390 _("WARNING: Partition %d is an extended partition\n"), 4391 i + 1); 1555 printf("WARNING: Partition %d is an extended partition\n", i + 1); 4392 1556 p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); 4393 1557 pe->changed = 1; … … 4400 1564 if (dos_compatible_flag) { 4401 1565 sector_offset = sectors; 4402 printf(_("DOS Compatibility flag is set\n")); 4403 } 4404 else { 1566 printf("DOS Compatibility flag is set\n"); 1567 } else { 4405 1568 sector_offset = 1; 4406 printf( _("DOS Compatibility flag is not set\n"));1569 printf("DOS Compatibility flag is not set\n"); 4407 1570 } 4408 1571 } … … 4423 1586 pe->changed = 1; 4424 1587 4425 #ifdef CONFIG_FEATURE_SUN_LABEL 4426 if (label_sun == current_label_type) { 1588 if (LABEL_IS_SUN) { 4427 1589 sun_delete_partition(i); 4428 1590 return; 4429 1591 } 4430 #endif 4431 #ifdef CONFIG_FEATURE_SGI_LABEL 4432 if (label_sgi == current_label_type) { 1592 if (LABEL_IS_SGI) { 4433 1593 sgi_delete_partition(i); 4434 1594 return; 4435 1595 } 4436 #endif4437 1596 4438 1597 if (i < 4) { … … 4491 1650 struct partition *p; 4492 1651 4493 #ifdef CONFIG_FEATURE_SGI_LABEL4494 1652 /* If sgi_label then don't use get_existing_partition, 4495 1653 let the user select a partition, since get_existing_partition() 4496 1654 only works for Linux like partition tables. */ 4497 if ( label_sgi != current_label_type) {1655 if (!LABEL_IS_SGI) { 4498 1656 i = get_existing_partition(0, partitions); 4499 1657 } else { 4500 1658 i = get_partition(0, partitions); 4501 1659 } 4502 #else4503 i = get_existing_partition(0, partitions);4504 #endif4505 1660 if (i == -1) 4506 1661 return; … … 4510 1665 /* if changing types T to 0 is allowed, then 4511 1666 the reverse change must be allowed, too */ 4512 if (!sys && label_sgi != current_label_type && 4513 label_sun != current_label_type && !get_nr_sects(p)) 4514 { 4515 printf(_("Partition %d does not exist yet!\n"), i + 1); 4516 }else{ 4517 while (1) { 4518 sys = read_hex (get_sys_types()); 4519 4520 if (!sys && label_sgi != current_label_type && 4521 label_sun != current_label_type) 4522 { 4523 printf(_("Type 0 means free space to many systems\n" 1667 if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN && !get_nr_sects(p)) { 1668 printf("Partition %d does not exist yet!\n", i + 1); 1669 return; 1670 } 1671 while (1) { 1672 sys = read_hex(get_sys_types()); 1673 1674 if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { 1675 printf("Type 0 means free space to many systems\n" 4524 1676 "(but not to Linux). Having partitions of\n" 4525 "type 0 is probably unwise. You can delete\n" 4526 "a partition using the `d' command.\n")); 1677 "type 0 is probably unwise.\n"); 4527 1678 /* break; */ 4528 1679 } 4529 1680 4530 if ( label_sun != current_label_type && label_sgi != current_label_type) {1681 if (!LABEL_IS_SUN && !LABEL_IS_SGI) { 4531 1682 if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { 4532 printf(_("You cannot change a partition into" 4533 " an extended one or vice versa\n" 4534 "Delete it first.\n")); 1683 printf("You cannot change a partition into" 1684 " an extended one or vice versa\n"); 4535 1685 break; 4536 1686 } … … 4538 1688 4539 1689 if (sys < 256) { 4540 #if def CONFIG_FEATURE_SUN_LABEL4541 if ( label_sun == current_label_type && i == 2 && sys !=WHOLE_DISK)4542 printf( _("Consider leaving partition 3 "1690 #if ENABLE_FEATURE_SUN_LABEL 1691 if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) 1692 printf("Consider leaving partition 3 " 4543 1693 "as Whole disk (5),\n" 4544 1694 "as SunOS/Solaris expects it and " 4545 "even Linux likes it .\n\n"));4546 #endif 4547 #if def CONFIG_FEATURE_SGI_LABEL4548 if ( label_sgi == current_label_type&&1695 "even Linux likes it\n\n"); 1696 #endif 1697 #if ENABLE_FEATURE_SGI_LABEL 1698 if (LABEL_IS_SGI && 4549 1699 ( 4550 (i == 10 && sys != ENTIRE_DISK) ||1700 (i == 10 && sys != SGI_ENTIRE_DISK) || 4551 1701 (i == 8 && sys != 0) 4552 1702 ) 4553 ) {4554 printf( _("Consider leaving partition 9 "1703 ) { 1704 printf("Consider leaving partition 9 " 4555 1705 "as volume header (0),\nand " 4556 1706 "partition 11 as entire volume (6)" 4557 "as IRIX expects it .\n\n"));1707 "as IRIX expects it\n\n"); 4558 1708 } 4559 1709 #endif 4560 1710 if (sys == origsys) 4561 1711 break; 4562 #ifdef CONFIG_FEATURE_SUN_LABEL 4563 if (label_sun == current_label_type) { 1712 if (LABEL_IS_SUN) { 4564 1713 sun_change_sysid(i, sys); 4565 } else 4566 #endif 4567 #ifdef CONFIG_FEATURE_SGI_LABEL 4568 if (label_sgi == current_label_type) { 1714 } else if (LABEL_IS_SGI) { 4569 1715 sgi_change_sysid(i, sys); 4570 1716 } else 4571 #endif4572 1717 p->sys_ind = sys; 4573 1718 4574 printf( _("Changed system type of partition %d "4575 "to %x (%s)\n" ), i + 1, sys,1719 printf("Changed system type of partition %d " 1720 "to %x (%s)\n", i + 1, sys, 4576 1721 partition_type(sys)); 4577 1722 ptes[i].changed = 1; … … 4581 1726 break; 4582 1727 } 4583 } 4584 } 4585 } 4586 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 4587 4588 4589 /* check_consistency() and long2chs() added Sat Mar 6 12:28:16 1993, 1728 } 1729 } 1730 #endif /* FEATURE_FDISK_WRITABLE */ 1731 1732 1733 /* check_consistency() and linear2chs() added Sat Mar 6 12:28:16 1993, 4590 1734 * faith@cs.unc.edu, based on code fragments from pfdisk by Gordon W. Ross, 4591 1735 * Jan. 1990 (version 1.2.1 by Gordon W. Ross Aug. 1990; Modified by S. … … 4593 1737 4594 1738 static void 4595 l ong2chs(ulong ls, uint *c, uint *h, uint*s)1739 linear2chs(unsigned ls, unsigned *c, unsigned *h, unsigned *s) 4596 1740 { 4597 1741 int spc = heads * sectors; … … 4606 1750 check_consistency(const struct partition *p, int partition) 4607 1751 { 4608 u intpbc, pbh, pbs; /* physical beginning c, h, s */4609 u intpec, peh, pes; /* physical ending c, h, s */4610 u intlbc, lbh, lbs; /* logical beginning c, h, s */4611 u intlec, leh, les; /* logical ending c, h, s */1752 unsigned pbc, pbh, pbs; /* physical beginning c, h, s */ 1753 unsigned pec, peh, pes; /* physical ending c, h, s */ 1754 unsigned lbc, lbh, lbs; /* logical beginning c, h, s */ 1755 unsigned lec, leh, les; /* logical ending c, h, s */ 4612 1756 4613 1757 if (!heads || !sectors || (partition >= 4)) … … 4625 1769 4626 1770 /* compute logical beginning (c, h, s) */ 4627 l ong2chs(get_start_sect(p), &lbc, &lbh, &lbs);1771 linear2chs(get_start_sect(p), &lbc, &lbh, &lbs); 4628 1772 4629 1773 /* compute logical ending (c, h, s) */ 4630 l ong2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);1774 linear2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les); 4631 1775 4632 1776 /* Same physical / logical beginning? */ 4633 1777 if (cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { 4634 printf( _("Partition %d has different physical/logical "4635 "beginnings (non-Linux?):\n" ), partition + 1);4636 printf( _(" phys=(%d, %d, %d) "), pbc, pbh, pbs);4637 printf( _("logical=(%d, %d, %d)\n"),lbc, lbh, lbs);1778 printf("Partition %d has different physical/logical " 1779 "beginnings (non-Linux?):\n", partition + 1); 1780 printf(" phys=(%d, %d, %d) ", pbc, pbh, pbs); 1781 printf("logical=(%d, %d, %d)\n",lbc, lbh, lbs); 4638 1782 } 4639 1783 4640 1784 /* Same physical / logical ending? */ 4641 1785 if (cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { 4642 printf(_("Partition %d has different physical/logical " 4643 "endings:\n"), partition + 1); 4644 printf(_(" phys=(%d, %d, %d) "), pec, peh, pes); 4645 printf(_("logical=(%d, %d, %d)\n"),lec, leh, les); 4646 } 4647 4648 #if 0 4649 /* Beginning on cylinder boundary? */ 4650 if (pbh != !pbc || pbs != 1) { 4651 printf(_("Partition %i does not start on cylinder " 4652 "boundary:\n"), partition + 1); 4653 printf(_(" phys=(%d, %d, %d) "), pbc, pbh, pbs); 4654 printf(_("should be (%d, %d, 1)\n"), pbc, !pbc); 4655 } 4656 #endif 1786 printf("Partition %d has different physical/logical " 1787 "endings:\n", partition + 1); 1788 printf(" phys=(%d, %d, %d) ", pec, peh, pes); 1789 printf("logical=(%d, %d, %d)\n", lec, leh, les); 1790 } 4657 1791 4658 1792 /* Ending on cylinder boundary? */ 4659 1793 if (peh != (heads - 1) || pes != sectors) { 4660 printf( _("Partition %i does not end on cylinder boundary.\n"),1794 printf("Partition %i does not end on cylinder boundary\n", 4661 1795 partition + 1); 4662 #if 04663 printf(_(" phys=(%d, %d, %d) "), pec, peh, pes);4664 printf(_("should be (%d, %d, %d)\n"),4665 pec, heads - 1, sectors);4666 #endif4667 1796 } 4668 1797 } … … 4675 1804 4676 1805 if (megabytes < 10000) 4677 printf( _("\nDisk %s: %ld MB, %lld bytes\n"),1806 printf("\nDisk %s: %ld MB, %lld bytes\n", 4678 1807 disk_device, megabytes, bytes); 4679 1808 else 4680 printf( _("\nDisk %s: %ld.%ld GB, %lld bytes\n"),1809 printf("\nDisk %s: %ld.%ld GB, %lld bytes\n", 4681 1810 disk_device, megabytes/1000, (megabytes/100)%10, bytes); 4682 printf( _("%d heads, %d sectors/track, %d cylinders"),1811 printf("%d heads, %d sectors/track, %d cylinders", 4683 1812 heads, sectors, cylinders); 4684 1813 if (units_per_sector == 1) 4685 printf( _(", total %llu sectors"),1814 printf(", total %llu sectors", 4686 1815 total_number_of_sectors / (sector_size/512)); 4687 printf( _("\nUnits = %s of %d * %d = %d bytes\n\n"),1816 printf("\nUnits = %s of %d * %d = %d bytes\n\n", 4688 1817 str_units(PLURAL), 4689 1818 units_per_sector, sector_size, units_per_sector * sector_size); … … 4700 1829 const struct pte *pe; 4701 1830 const struct partition *p; 4702 off_tlast_p_start_pos = 0, p_start_pos;1831 ullong last_p_start_pos = 0, p_start_pos; 4703 1832 int i, last_i = 0; 4704 1833 4705 for (i = 0 1834 for (i = 0; i < partitions; i++) { 4706 1835 if (i == 4) { 4707 1836 last_i = 4; … … 4725 1854 } 4726 1855 4727 #if def CONFIG_FEATURE_FDISK_ADVANCED1856 #if ENABLE_FEATURE_FDISK_ADVANCED 4728 1857 /* 4729 1858 * Fix the chain of logicals. … … 4798 1927 4799 1928 if (!wrong_p_order(NULL)) { 4800 printf( _("Nothing to do. Ordering is correct already.\n\n"));1929 printf("Ordering is already correct\n\n"); 4801 1930 return; 4802 1931 } … … 4837 1966 int i, w; 4838 1967 4839 #ifdef CONFIG_FEATURE_SUN_LABEL 4840 if (label_sun == current_label_type) { 1968 if (LABEL_IS_SUN) { 4841 1969 sun_list_table(xtra); 4842 1970 return; 4843 1971 } 4844 #endif 4845 4846 #ifdef CONFIG_FEATURE_SGI_LABEL 4847 if (label_sgi == current_label_type) { 1972 if (LABEL_IS_SUN) { 4848 1973 sgi_list_table(xtra); 4849 1974 return; 4850 1975 } 4851 #endif4852 1976 4853 1977 list_disk_geometry(); 4854 1978 4855 #ifdef CONFIG_FEATURE_OSF_LABEL 4856 if (label_osf == current_label_type) { 1979 if (LABEL_IS_OSF) { 4857 1980 xbsd_print_disklabel(xtra); 4858 1981 return; 4859 1982 } 4860 #endif4861 1983 4862 1984 /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3, … … 4869 1991 w = 5; 4870 1992 4871 printf(_("%*s Boot Start End Blocks Id System\n"), 4872 w+1, _("Device")); 1993 // 1 12345678901 12345678901 12345678901 12 1994 printf("%*s Boot Start End Blocks Id System\n", 1995 w+1, "Device"); 4873 1996 4874 1997 for (i = 0; i < partitions; i++) { 4875 1998 const struct pte *pe = &ptes[i]; 1999 ullong psects; 2000 ullong pblocks; 2001 unsigned podd; 4876 2002 4877 2003 p = pe->part_table; 4878 if (p && !is_cleared_partition(p)) { 4879 off_t psects = get_nr_sects(p); 4880 off_t pblocks = psects; 4881 unsigned int podd = 0; 4882 4883 if (sector_size < 1024) { 4884 pblocks /= (1024 / sector_size); 4885 podd = psects % (1024 / sector_size); 4886 } 4887 if (sector_size > 1024) 4888 pblocks *= (sector_size / 1024); 4889 printf( 4890 "%s %c %11llu %11llu %11llu%c %2x %s\n", 2004 if (!p || is_cleared_partition(p)) 2005 continue; 2006 2007 psects = get_nr_sects(p); 2008 pblocks = psects; 2009 podd = 0; 2010 2011 if (sector_size < 1024) { 2012 pblocks /= (1024 / sector_size); 2013 podd = psects % (1024 / sector_size); 2014 } 2015 if (sector_size > 1024) 2016 pblocks *= (sector_size / 1024); 2017 2018 printf("%s %c %11llu %11llu %11llu%c %2x %s\n", 4891 2019 partname(disk_device, i+1, w+2), 4892 /* boot flag */ !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG 4893 ? '*' : '?',4894 /* start */ (unsigned long long) cround(get_partition_start(pe)), 4895 /* end */ (unsigned long long) cround(get_partition_start(pe) + psects 2020 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ 2021 ? '*' : '?', 2022 (ullong) cround(get_partition_start(pe)), /* start */ 2023 (ullong) cround(get_partition_start(pe) + psects /* end */ 4896 2024 - (psects ? 1 : 0)), 4897 /* odd flag on end */ (unsigned long long) pblocks, podd ? '+' : ' ', 4898 /* type id */ p->sys_ind, 4899 /* type name */ partition_type(p->sys_ind)); 4900 check_consistency(p, i); 4901 }2025 (ullong) pblocks, podd ? '+' : ' ', /* odd flag on end */ 2026 p->sys_ind, /* type id */ 2027 partition_type(p->sys_ind)); /* type name */ 2028 2029 check_consistency(p, i); 4902 2030 } 4903 2031 … … 4905 2033 /* partition table entries are not checked for correct order if this 4906 2034 is a sgi, sun or aix labeled disk... */ 4907 if ( label_dos == current_label_type&& wrong_p_order(NULL)) {2035 if (LABEL_IS_DOS && wrong_p_order(NULL)) { 4908 2036 /* FIXME */ 4909 printf( _("\nPartition table entries are not in disk order\n"));4910 } 4911 } 4912 4913 #if def CONFIG_FEATURE_FDISK_ADVANCED2037 printf("\nPartition table entries are not in disk order\n"); 2038 } 2039 } 2040 2041 #if ENABLE_FEATURE_FDISK_ADVANCED 4914 2042 static void 4915 2043 x_list_table(int extend) … … 4919 2047 int i; 4920 2048 4921 printf( _("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"),2049 printf("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n", 4922 2050 disk_device, heads, sectors, cylinders); 4923 printf( _("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"));4924 for (i = 0 2051 printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); 2052 for (i = 0; i < partitions; i++) { 4925 2053 pe = &ptes[i]; 4926 2054 p = (extend ? pe->ext_pointer : pe->part_table); … … 4940 2068 #endif 4941 2069 4942 #if def CONFIG_FEATURE_FDISK_WRITABLE4943 static void 4944 fill_bounds( off_t *first, off_t*last)2070 #if ENABLE_FEATURE_FDISK_WRITABLE 2071 static void 2072 fill_bounds(ullong *first, ullong *last) 4945 2073 { 4946 2074 int i; … … 4961 2089 4962 2090 static void 4963 check(int n, u int h, uint s, uint c, off_tstart)4964 { 4965 off_ttotal, real_s, real_c;2091 check(int n, unsigned h, unsigned s, unsigned c, ullong start) 2092 { 2093 ullong total, real_s, real_c; 4966 2094 4967 2095 real_s = sector(s) - 1; … … 4969 2097 total = (real_c * sectors + real_s) * heads + h; 4970 2098 if (!total) 4971 fprintf(stderr, _("Warning: partition %d contains sector 0\n"), n);2099 printf("Partition %d contains sector 0\n", n); 4972 2100 if (h >= heads) 4973 fprintf(stderr, 4974 _("Partition %d: head %d greater than maximum %d\n"), 2101 printf("Partition %d: head %d greater than maximum %d\n", 4975 2102 n, h + 1, heads); 4976 2103 if (real_s >= sectors) 4977 fprintf(stderr, _("Partition %d: sector %d greater than "4978 "maximum %d\n" ), n, s, sectors);2104 printf("Partition %d: sector %d greater than " 2105 "maximum %d\n", n, s, sectors); 4979 2106 if (real_c >= cylinders) 4980 fprintf(stderr, _("Partitions%d: cylinder %llu greater than "4981 "maximum %d\n" ), n, (unsigned long long)real_c + 1, cylinders);2107 printf("Partition %d: cylinder %llu greater than " 2108 "maximum %d\n", n, real_c + 1, cylinders); 4982 2109 if (cylinders <= 1024 && start != total) 4983 fprintf(stderr, 4984 _("Partition %d: previous sectors %llu disagrees with " 4985 "total %llu\n"), n, (unsigned long long)start, (unsigned long long)total); 2110 printf("Partition %d: previous sectors %llu disagrees with " 2111 "total %llu\n", n, start, total); 4986 2112 } 4987 2113 … … 4990 2116 { 4991 2117 int i, j; 4992 u inttotal = 1;4993 off_tfirst[partitions], last[partitions];2118 unsigned total = 1; 2119 ullong first[partitions], last[partitions]; 4994 2120 struct partition *p; 4995 2121 … … 4997 2123 return; 4998 2124 4999 #ifdef CONFIG_FEATURE_SUN_LABEL 5000 if (label_sun == current_label_type) { 2125 if (LABEL_IS_SUN) { 5001 2126 verify_sun(); 5002 2127 return; 5003 2128 } 5004 #endif 5005 #ifdef CONFIG_FEATURE_SGI_LABEL 5006 if (label_sgi == current_label_type) { 2129 if (LABEL_IS_SGI) { 5007 2130 verify_sgi(1); 5008 2131 return; 5009 2132 } 5010 #endif5011 2133 5012 2134 fill_bounds(first, last); … … 5018 2140 check_consistency(p, i); 5019 2141 if (get_partition_start(pe) < first[i]) 5020 printf( _("Warning: bad start-of-data in "5021 "partition %d\n" ), i + 1);2142 printf("Warning: bad start-of-data in " 2143 "partition %d\n", i + 1); 5022 2144 check(i + 1, p->end_head, p->end_sector, p->end_cyl, 5023 2145 last[i]); 5024 2146 total += last[i] + 1 - first[i]; 5025 for (j = 0; j < i; j++) 5026 if ((first[i] >= first[j] && first[i] <= last[j]) 5027 || ((last[i] <= last[j] && last[i] >= first[j]))) { 5028 printf(_("Warning: partition %d overlaps " 5029 "partition %d.\n"), j + 1, i + 1); 5030 total += first[i] >= first[j] ? 5031 first[i] : first[j]; 5032 total -= last[i] <= last[j] ? 5033 last[i] : last[j]; 2147 for (j = 0; j < i; j++) { 2148 if ((first[i] >= first[j] && first[i] <= last[j]) 2149 || ((last[i] <= last[j] && last[i] >= first[j]))) { 2150 printf("Warning: partition %d overlaps " 2151 "partition %d\n", j + 1, i + 1); 2152 total += first[i] >= first[j] ? 2153 first[i] : first[j]; 2154 total -= last[i] <= last[j] ? 2155 last[i] : last[j]; 2156 } 5034 2157 } 5035 2158 } … … 5038 2161 if (extended_offset) { 5039 2162 struct pte *pex = &ptes[ext_index]; 5040 off_te_last = get_start_sect(pex->part_table) +2163 ullong e_last = get_start_sect(pex->part_table) + 5041 2164 get_nr_sects(pex->part_table) - 1; 5042 2165 … … 5046 2169 if (!p->sys_ind) { 5047 2170 if (i != 4 || i + 1 < partitions) 5048 printf(_("Warning: partition %d " 5049 "is empty\n"), i + 1); 2171 printf("Warning: partition %d " 2172 "is empty\n", i + 1); 2173 } else if (first[i] < extended_offset || last[i] > e_last) { 2174 printf("Logical partition %d not entirely in " 2175 "partition %d\n", i + 1, ext_index + 1); 5050 2176 } 5051 else if (first[i] < extended_offset ||5052 last[i] > e_last)5053 printf(_("Logical partition %d not entirely in "5054 "partition %d\n"), i + 1, ext_index + 1);5055 2177 } 5056 2178 } 5057 2179 5058 2180 if (total > heads * sectors * cylinders) 5059 printf(_("Total allocated sectors %d greater than the maximum " 5060 "%d\n"), total, heads * sectors * cylinders); 5061 else if ((total = heads * sectors * cylinders - total) != 0) 5062 printf(_("%d unallocated sectors\n"), total); 2181 printf("Total allocated sectors %d greater than the maximum " 2182 "%d\n", total, heads * sectors * cylinders); 2183 else { 2184 total = heads * sectors * cylinders - total; 2185 if (total != 0) 2186 printf("%d unallocated sectors\n", total); 2187 } 5063 2188 } 5064 2189 … … 5070 2195 struct partition *p = ptes[n].part_table; 5071 2196 struct partition *q = ptes[ext_index].part_table; 5072 long long llimit;5073 off_t start, stop = 0, limit, temp,5074 2197 ullong limit, temp; 2198 ullong start, stop = 0; 2199 ullong first[partitions], last[partitions]; 5075 2200 5076 2201 if (p && p->sys_ind) { 5077 printf(_("Partition %d is already defined. Delete " 5078 "it before re-adding it.\n"), n + 1); 2202 printf(msg_part_already_defined, n + 1); 5079 2203 return; 5080 2204 } … … 5083 2207 start = sector_offset; 5084 2208 if (display_in_cyl_units || !total_number_of_sectors) 5085 l limit =heads * sectors * cylinders - 1;2209 limit = (ullong) heads * sectors * cylinders - 1; 5086 2210 else 5087 llimit = total_number_of_sectors - 1; 5088 limit = llimit; 5089 if (limit != llimit) 5090 limit = 0x7fffffff; 2211 limit = total_number_of_sectors - 1; 5091 2212 if (extended_offset) { 5092 2213 first[ext_index] = extended_offset; … … 5102 2223 first[i] = (cround(first[i]) - 1) * units_per_sector; 5103 2224 5104 snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));2225 snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR)); 5105 2226 do { 5106 2227 temp = start; … … 5117 2238 break; 5118 2239 if (start >= temp+units_per_sector && num_read) { 5119 printf( _("Sector %llu is already allocated\n"), (unsigned long long)temp);2240 printf("Sector %lld is already allocated\n", temp); 5120 2241 temp = start; 5121 2242 num_read = 0; 5122 2243 } 5123 2244 if (!num_read && start == temp) { 5124 off_tsaved_start;2245 ullong saved_start; 5125 2246 5126 2247 saved_start = start; … … 5154 2275 } 5155 2276 if (start > limit) { 5156 printf( _("No free sectors available\n"));2277 printf("No free sectors available\n"); 5157 2278 if (n > 4) 5158 2279 partitions--; … … 5163 2284 } else { 5164 2285 snprintf(mesg, sizeof(mesg), 5165 _("Last %s or +size or +sizeM or +sizeK"),2286 "Last %s or +size or +sizeM or +sizeK", 5166 2287 str_units(SINGULAR)); 5167 2288 stop = read_int(cround(start), cround(limit), cround(limit), … … 5185 2306 pen->ext_pointer = p; 5186 2307 pe4->offset = extended_offset = start; 5187 pe4->sectorbuffer = x calloc(1,sector_size);2308 pe4->sectorbuffer = xzalloc(sector_size); 5188 2309 pe4->part_table = pt_offset(pe4->sectorbuffer, 0); 5189 2310 pe4->ext_pointer = pe4->part_table + 1; … … 5199 2320 struct pte *pe = &ptes[partitions]; 5200 2321 5201 pe->sectorbuffer = x calloc(1,sector_size);2322 pe->sectorbuffer = xzalloc(sector_size); 5202 2323 pe->part_table = pt_offset(pe->sectorbuffer, 0); 5203 2324 pe->ext_pointer = pe->part_table + 1; … … 5217 2338 return; 5218 2339 5219 #ifdef CONFIG_FEATURE_SUN_LABEL 5220 if (label_sun == current_label_type) { 2340 if (LABEL_IS_SUN) { 5221 2341 add_sun_partition(get_partition(0, partitions), LINUX_NATIVE); 5222 2342 return; 5223 2343 } 5224 #endif 5225 #ifdef CONFIG_FEATURE_SGI_LABEL 5226 if (label_sgi == current_label_type) { 2344 if (LABEL_IS_SGI) { 5227 2345 sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE); 5228 2346 return; 5229 2347 } 5230 #endif 5231 #ifdef CONFIG_FEATURE_AIX_LABEL 5232 if (label_aix == current_label_type) { 5233 printf(_("\tSorry - this fdisk cannot handle AIX disk labels." 5234 "\n\tIf you want to add DOS-type partitions, create" 5235 "\n\ta new empty DOS partition table first. (Use o.)" 5236 "\n\tWARNING: " 5237 "This will destroy the present disk contents.\n")); 2348 if (LABEL_IS_AIX) { 2349 printf("Sorry - this fdisk cannot handle AIX disk labels.\n" 2350 "If you want to add DOS-type partitions, create a new empty DOS partition\n" 2351 "table first (use 'o'). This will destroy the present disk contents.\n"); 5238 2352 return; 5239 2353 } 5240 #endif5241 2354 5242 2355 for (i = 0; i < 4; i++) … … 5244 2357 5245 2358 if (!free_primary && partitions >= MAXIMUM_PARTS) { 5246 printf( _("The maximum number of partitions has been created\n"));2359 printf("The maximum number of partitions has been created\n"); 5247 2360 return; 5248 2361 } … … 5252 2365 add_logical(); 5253 2366 else 5254 printf( _("You must delete some partition and add "5255 "an extended partition first\n") );2367 printf("You must delete some partition and add " 2368 "an extended partition first\n"); 5256 2369 } else { 5257 char c, line[LINE_LENGTH]; 5258 snprintf(line, sizeof(line), "%s\n %s\n p primary " 5259 "partition (1-4)\n", 5260 "Command action", (extended_offset ? 5261 "l logical (5 or over)" : "e extended")); 2370 char c, line[80]; 2371 snprintf(line, sizeof(line), 2372 "Command action\n" 2373 " %s\n" 2374 " p primary partition (1-4)\n", 2375 (extended_offset ? 2376 "l logical (5 or over)" : "e extended")); 5262 2377 while (1) { 5263 if ((c = read_char(line)) == 'p' || c == 'P') { 2378 c = read_nonempty(line); 2379 if (c == 'p' || c == 'P') { 5264 2380 i = get_nonexisting_partition(0, 4); 5265 2381 if (i >= 0) … … 5267 2383 return; 5268 2384 } 5269 elseif (c == 'l' && extended_offset) {2385 if (c == 'l' && extended_offset) { 5270 2386 add_logical(); 5271 2387 return; 5272 2388 } 5273 elseif (c == 'e' && !extended_offset) {2389 if (c == 'e' && !extended_offset) { 5274 2390 i = get_nonexisting_partition(0, 4); 5275 2391 if (i >= 0) … … 5277 2393 return; 5278 2394 } 5279 else 5280 printf(_("Invalid partition number " 5281 "for type `%c'\n"), c); 2395 printf("Invalid partition number " 2396 "for type '%c'\n", c); 5282 2397 } 5283 2398 } … … 5289 2404 int i; 5290 2405 5291 if ( label_dos == current_label_type) {2406 if (LABEL_IS_DOS) { 5292 2407 for (i = 0; i < 3; i++) 5293 2408 if (ptes[i].changed) … … 5302 2417 } 5303 2418 } 5304 #ifdef CONFIG_FEATURE_SGI_LABEL 5305 else if (label_sgi == current_label_type) { 2419 else if (LABEL_IS_SGI) { 5306 2420 /* no test on change? the printf below might be mistaken */ 5307 2421 sgi_write_table(); 5308 2422 } 5309 #endif 5310 #ifdef CONFIG_FEATURE_SUN_LABEL 5311 else if (label_sun == current_label_type) { 2423 else if (LABEL_IS_SUN) { 5312 2424 int needw = 0; 5313 2425 … … 5318 2430 sun_write_table(); 5319 2431 } 5320 #endif 5321 5322 printf(_("The partition table has been altered!\n\n")); 2432 2433 printf("The partition table has been altered!\n\n"); 5323 2434 reread_partition_table(1); 5324 2435 } … … 5327 2438 reread_partition_table(int leave) 5328 2439 { 5329 int error = 0;5330 2440 int i; 5331 2441 5332 printf( _("Calling ioctl() to re-read partition table.\n"));2442 printf("Calling ioctl() to re-read partition table\n"); 5333 2443 sync(); 5334 sleep(2); 5335 if ((i = ioctl(fd, BLKRRPART)) != 0) { 5336 error = errno; 5337 } else { 5338 /* some kernel versions (1.2.x) seem to have trouble 5339 rereading the partition table, but if asked to do it 5340 twice, the second time works. - biro@yggdrasil.com */ 5341 sync(); 5342 sleep(2); 5343 if ((i = ioctl(fd, BLKRRPART)) != 0) 5344 error = errno; 5345 } 5346 5347 if (i) { 5348 printf(_("\nWARNING: Re-reading the partition table " 5349 "failed with error %d: %s.\n" 5350 "The kernel still uses the old table.\n" 5351 "The new table will be used " 5352 "at the next reboot.\n"), 5353 error, strerror(error)); 5354 } 5355 2444 /* sleep(2); Huh? */ 2445 i = ioctl_or_perror(fd, BLKRRPART, NULL, 2446 "WARNING: rereading partition table " 2447 "failed, kernel still uses old table"); 2448 #if 0 5356 2449 if (dos_changed) 5357 2450 printf( 5358 _("\nWARNING: If you have created or modified any DOS 6.x\n"2451 "\nWARNING: If you have created or modified any DOS 6.x\n" 5359 2452 "partitions, please see the fdisk manual page for additional\n" 5360 "information.\n")); 2453 "information\n"); 2454 #endif 5361 2455 5362 2456 if (leave) { 5363 close(fd); 5364 5365 printf(_("Syncing disks.\n")); 5366 sync(); 5367 sleep(4); /* for sync() */ 5368 exit(!!i); 5369 } 5370 } 5371 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */ 5372 5373 #ifdef CONFIG_FEATURE_FDISK_ADVANCED 2457 if (ENABLE_FEATURE_CLEAN_UP) 2458 close(fd); 2459 exit(i != 0); 2460 } 2461 } 2462 #endif /* FEATURE_FDISK_WRITABLE */ 2463 2464 #if ENABLE_FEATURE_FDISK_ADVANCED 5374 2465 #define MAX_PER_LINE 16 5375 2466 static void … … 5383 2474 printf(" %02X", (unsigned char) pbuffer[i]); 5384 2475 if (l == MAX_PER_LINE - 1) { 5385 p rintf("\n");2476 puts(""); 5386 2477 l = -1; 5387 2478 } 5388 2479 } 5389 2480 if (l > 0) 5390 printf("\n"); 5391 printf("\n"); 5392 } 5393 2481 puts(""); 2482 puts(""); 2483 } 5394 2484 5395 2485 static void … … 5398 2488 int i; 5399 2489 5400 printf(_("Device: %s\n"), disk_device); 5401 #if defined(CONFIG_FEATURE_SGI_LABEL) || defined(CONFIG_FEATURE_SUN_LABEL) 5402 if (label_sun == current_label_type || label_sgi == current_label_type) 2490 printf("Device: %s\n", disk_device); 2491 if (LABEL_IS_SGI || LABEL_IS_SUN) 5403 2492 print_buffer(MBRbuffer); 5404 else 5405 #endif 2493 else { 5406 2494 for (i = 3; i < partitions; i++) 5407 2495 print_buffer(ptes[i].sectorbuffer); 2496 } 5408 2497 } 5409 2498 … … 5413 2502 struct pte *pe = &ptes[i]; 5414 2503 struct partition *p = pe->part_table; 5415 off_tnew, first;2504 ullong new, first; 5416 2505 5417 2506 if (warn_geometry()) 5418 2507 return; 5419 2508 if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED(p->sys_ind)) { 5420 printf( _("Partition %d has no data area\n"), i + 1);2509 printf("Partition %d has no data area\n", i + 1); 5421 2510 return; 5422 2511 } 5423 2512 first = get_partition_start(pe); 5424 2513 new = read_int(first, first, first + get_nr_sects(p) - 1, first, 5425 _("New beginning of data")) - pe->offset;2514 "New beginning of data") - pe->offset; 5426 2515 5427 2516 if (new != get_nr_sects(p)) { … … 5440 2529 while (1) { 5441 2530 putchar('\n'); 5442 c = tolower(read_ char(_("Expert command (m for help): ")));2531 c = tolower(read_nonempty("Expert command (m for help): ")); 5443 2532 switch (c) { 5444 2533 case 'a': 5445 #ifdef CONFIG_FEATURE_SUN_LABEL 5446 if (label_sun == current_label_type) 2534 if (LABEL_IS_SUN) 5447 2535 sun_set_alt_cyl(); 5448 #endif5449 2536 break; 5450 2537 case 'b': 5451 if ( label_dos == current_label_type)2538 if (LABEL_IS_DOS) 5452 2539 move_begin(get_partition(0, partitions)); 5453 2540 break; … … 5455 2542 user_cylinders = cylinders = 5456 2543 read_int(1, cylinders, 1048576, 0, 5457 _("Number of cylinders")); 5458 #ifdef CONFIG_FEATURE_SUN_LABEL 5459 if (label_sun == current_label_type) 2544 "Number of cylinders"); 2545 if (LABEL_IS_SUN) 5460 2546 sun_set_ncyl(cylinders); 5461 #endif 5462 if (label_dos == current_label_type) 2547 if (LABEL_IS_DOS) 5463 2548 warn_cylinders(); 5464 2549 break; … … 5467 2552 break; 5468 2553 case 'e': 5469 #ifdef CONFIG_FEATURE_SGI_LABEL 5470 if (label_sgi == current_label_type) 2554 if (LABEL_IS_SGI) 5471 2555 sgi_set_xcyl(); 5472 else 5473 #endif 5474 #ifdef CONFIG_FEATURE_SUN_LABEL 5475 if (label_sun == current_label_type) 2556 else if (LABEL_IS_SUN) 5476 2557 sun_set_xcyl(); 5477 else 5478 #endif 5479 if (label_dos == current_label_type) 2558 else if (LABEL_IS_DOS) 5480 2559 x_list_table(1); 5481 2560 break; 5482 2561 case 'f': 5483 if ( label_dos == current_label_type)2562 if (LABEL_IS_DOS) 5484 2563 fix_partition_table_order(); 5485 2564 break; 5486 2565 case 'g': 5487 #if def CONFIG_FEATURE_SGI_LABEL2566 #if ENABLE_FEATURE_SGI_LABEL 5488 2567 create_sgilabel(); 5489 2568 #endif … … 5491 2570 case 'h': 5492 2571 user_heads = heads = read_int(1, heads, 256, 0, 5493 _("Number of heads"));2572 "Number of heads"); 5494 2573 update_units(); 5495 2574 break; 5496 2575 case 'i': 5497 #ifdef CONFIG_FEATURE_SUN_LABEL 5498 if (label_sun == current_label_type) 2576 if (LABEL_IS_SUN) 5499 2577 sun_set_ilfact(); 5500 #endif5501 2578 break; 5502 2579 case 'o': 5503 #ifdef CONFIG_FEATURE_SUN_LABEL 5504 if (label_sun == current_label_type) 2580 if (LABEL_IS_SUN) 5505 2581 sun_set_rspeed(); 5506 #endif5507 2582 break; 5508 2583 case 'p': 5509 #ifdef CONFIG_FEATURE_SUN_LABEL 5510 if (label_sun == current_label_type) 2584 if (LABEL_IS_SUN) 5511 2585 list_table(1); 5512 2586 else 5513 #endif5514 2587 x_list_table(0); 5515 2588 break; 5516 2589 case 'q': 5517 2590 close(fd); 5518 p rintf("\n");2591 puts(""); 5519 2592 exit(0); 5520 2593 case 'r': … … 5522 2595 case 's': 5523 2596 user_sectors = sectors = read_int(1, sectors, 63, 0, 5524 _("Number of sectors"));2597 "Number of sectors"); 5525 2598 if (dos_compatible_flag) { 5526 2599 sector_offset = sectors; 5527 fprintf(stderr, _("Warning: setting " 5528 "sector offset for DOS " 5529 "compatiblity\n")); 2600 printf("Warning: setting sector offset for DOS " 2601 "compatiblity\n"); 5530 2602 } 5531 2603 update_units(); … … 5538 2610 break; 5539 2611 case 'y': 5540 #ifdef CONFIG_FEATURE_SUN_LABEL 5541 if (label_sun == current_label_type) 2612 if (LABEL_IS_SUN) 5542 2613 sun_set_pcylcount(); 5543 #endif5544 2614 break; 5545 2615 default: … … 5586 2656 5587 2657 static void 5588 try (const char *device, int user_specified)2658 trydev(const char *device, int user_specified) 5589 2659 { 5590 2660 int gb; … … 5596 2666 if (is_ide_cdrom_or_tape(device)) 5597 2667 return; 5598 if ((fd = open(disk_device, type_open)) >= 0) { 2668 fd = open(disk_device, type_open); 2669 if (fd >= 0) { 5599 2670 gb = get_boot(try_only); 5600 2671 if (gb > 0) { /* I/O error */ … … 5602 2673 } else if (gb < 0) { /* no DOS signature */ 5603 2674 list_disk_geometry(); 5604 if ( label_aix == current_label_type){2675 if (LABEL_IS_AIX) { 5605 2676 return; 5606 2677 } 5607 #ifdef CONFIG_FEATURE_OSF_LABEL 5608 if (btrydev(device) < 0) 5609 #endif 5610 fprintf(stderr, 5611 _("Disk %s doesn't contain a valid " 5612 "partition table\n"), device); 2678 #if ENABLE_FEATURE_OSF_LABEL 2679 if (bsd_trydev(device) < 0) 2680 #endif 2681 printf("Disk %s doesn't contain a valid " 2682 "partition table\n", device); 5613 2683 close(fd); 5614 2684 } else { 5615 2685 close(fd); 5616 2686 list_table(0); 5617 #if def CONFIG_FEATURE_FDISK_WRITABLE5618 if ( label_sun != current_label_type&& partitions > 4){2687 #if ENABLE_FEATURE_FDISK_WRITABLE 2688 if (!LABEL_IS_SUN && partitions > 4){ 5619 2689 delete_partition(ext_index); 5620 2690 } … … 5626 2696 installed on the system. */ 5627 2697 if (errno == EACCES) { 5628 fprintf(stderr, _("Cannot open %s\n"), device);2698 printf("Cannot open %s\n", device); 5629 2699 return; 5630 2700 } … … 5641 2711 int ma, mi, sz; 5642 2712 5643 procpt = bb_wfopen(PROC_PARTITIONS, "r");2713 procpt = fopen_or_warn("/proc/partitions", "r"); 5644 2714 5645 2715 while (fgets(line, sizeof(line), procpt)) { … … 5651 2721 continue; 5652 2722 sprintf(devname, "/dev/%s", ptname); 5653 try (devname, 0);5654 } 5655 #if def CONFIG_FEATURE_CLEAN_UP2723 trydev(devname, 0); 2724 } 2725 #if ENABLE_FEATURE_CLEAN_UP 5656 2726 fclose(procpt); 5657 2727 #endif 5658 2728 } 5659 2729 5660 #if def CONFIG_FEATURE_FDISK_WRITABLE2730 #if ENABLE_FEATURE_FDISK_WRITABLE 5661 2731 static void 5662 2732 unknown_command(int c) 5663 2733 { 5664 printf(_("%c: unknown command\n"), c); 5665 } 5666 #endif 5667 2734 printf("%c: unknown command\n", c); 2735 } 2736 #endif 2737 2738 int fdisk_main(int argc, char **argv); 5668 2739 int fdisk_main(int argc, char **argv) 5669 2740 { 5670 int c; 5671 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 5672 int optl = 0; 5673 #endif 5674 #ifdef CONFIG_FEATURE_FDISK_BLKSIZE 5675 int opts = 0; 5676 #endif 2741 char *str_b, *str_C, *str_H, *str_S; 2742 unsigned opt; 5677 2743 /* 5678 * Calls:5679 2744 * fdisk -v 5680 2745 * fdisk -l [-b sectorsize] [-u] device ... … … 5683 2748 * 5684 2749 * Options -C, -H, -S set the geometry. 5685 *5686 2750 */ 5687 while ((c = getopt(argc, argv, "b:C:H:lS:uvV" 5688 #ifdef CONFIG_FEATURE_FDISK_BLKSIZE 5689 "s" 5690 #endif 5691 )) != -1) { 5692 switch (c) { 5693 case 'b': 5694 /* Ugly: this sector size is really per device, 5695 so cannot be combined with multiple disks, 5696 and te same goes for the C/H/S options. 5697 */ 5698 sector_size = atoi(optarg); 5699 if (sector_size != 512 && sector_size != 1024 && 5700 sector_size != 2048) 5701 bb_show_usage(); 5702 sector_offset = 2; 5703 user_set_sector_size = 1; 5704 break; 5705 case 'C': 5706 user_cylinders = atoi(optarg); 5707 break; 5708 case 'H': 5709 user_heads = atoi(optarg); 5710 if (user_heads <= 0 || user_heads >= 256) 5711 user_heads = 0; 5712 break; 5713 case 'S': 5714 user_sectors = atoi(optarg); 5715 if (user_sectors <= 0 || user_sectors >= 64) 5716 user_sectors = 0; 5717 break; 5718 case 'l': 5719 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 5720 optl = 1; 5721 #endif 5722 break; 5723 #ifdef CONFIG_FEATURE_FDISK_BLKSIZE 5724 case 's': 5725 opts = 1; 5726 break; 5727 #endif 5728 case 'u': 5729 display_in_cyl_units = 0; 5730 break; 5731 case 'V': 5732 case 'v': 5733 printf("fdisk v" UTIL_LINUX_VERSION "\n"); 5734 return 0; 5735 default: 2751 enum { 2752 OPT_b = 1 << 0, 2753 OPT_C = 1 << 1, 2754 OPT_H = 1 << 2, 2755 OPT_l = 1 << 3, 2756 OPT_S = 1 << 4, 2757 OPT_u = 1 << 5, 2758 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 2759 }; 2760 2761 PTR_TO_GLOBALS = xzalloc(sizeof(G)); 2762 2763 opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), 2764 &str_b, &str_C, &str_H, &str_S); 2765 argc -= optind; 2766 argv += optind; 2767 if (opt & OPT_b) { // -b 2768 /* Ugly: this sector size is really per device, 2769 so cannot be combined with multiple disks, 2770 and the same goes for the C/H/S options. 2771 */ 2772 sector_size = xatoi_u(str_b); 2773 if (sector_size != 512 && sector_size != 1024 && 2774 sector_size != 2048) 5736 2775 bb_show_usage(); 5737 } 5738 } 5739 5740 #if 0 5741 printf(_("This kernel finds the sector size itself - " 5742 "-b option ignored\n")); 5743 #else 5744 if (user_set_sector_size && argc-optind != 1) 5745 printf(_("Warning: the -b (set sector size) option should" 5746 " be used with one specified device\n")); 5747 #endif 5748 5749 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 5750 if (optl) { 2776 sector_offset = 2; 2777 user_set_sector_size = 1; 2778 } 2779 if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C 2780 if (opt & OPT_H) { // -H 2781 user_heads = xatoi_u(str_H); 2782 if (user_heads <= 0 || user_heads >= 256) 2783 user_heads = 0; 2784 } 2785 //if (opt & OPT_l) // -l 2786 if (opt & OPT_S) { // -S 2787 user_sectors = xatoi_u(str_S); 2788 if (user_sectors <= 0 || user_sectors >= 64) 2789 user_sectors = 0; 2790 } 2791 if (opt & OPT_u) display_in_cyl_units = 0; // -u 2792 //if (opt & OPT_s) // -s 2793 2794 if (user_set_sector_size && argc != 1) 2795 printf("Warning: the -b (set sector size) option should" 2796 " be used with one specified device\n"); 2797 2798 #if ENABLE_FEATURE_FDISK_WRITABLE 2799 if (opt & OPT_l) { 5751 2800 nowarn = 1; 5752 2801 #endif 5753 2802 type_open = O_RDONLY; 5754 if (argc > optind) {2803 if (argc > 0) { 5755 2804 int k; 5756 #if __GNUC__2805 #if defined(__GNUC__) 5757 2806 /* avoid gcc warning: 5758 2807 variable `k' might be clobbered by `longjmp' */ … … 5760 2809 #endif 5761 2810 listing = 1; 5762 for (k = optind; k < argc; k++)5763 try (argv[k], 1);2811 for (k = 0; k < argc; k++) 2812 trydev(argv[k], 1); 5764 2813 } else { 5765 2814 /* we no longer have default device names */ … … 5768 2817 } 5769 2818 return 0; 5770 #if def CONFIG_FEATURE_FDISK_WRITABLE5771 } 5772 #endif 5773 5774 #if def CONFIG_FEATURE_FDISK_BLKSIZE5775 if (opt s) {2819 #if ENABLE_FEATURE_FDISK_WRITABLE 2820 } 2821 #endif 2822 2823 #if ENABLE_FEATURE_FDISK_BLKSIZE 2824 if (opt & OPT_s) { 5776 2825 long size; 5777 2826 int j; … … 5780 2829 type_open = O_RDONLY; 5781 2830 5782 opts = argc - optind; 5783 if (opts <= 0) 2831 if (argc <= 0) 5784 2832 bb_show_usage(); 5785 2833 5786 for (j = optind; j < argc; j++) {2834 for (j = 0; j < argc; j++) { 5787 2835 disk_device = argv[j]; 5788 if ((fd = open(disk_device, type_open)) < 0) 2836 fd = open(disk_device, type_open); 2837 if (fd < 0) 5789 2838 fdisk_fatal(unable_to_open); 5790 2839 if (ioctl(fd, BLKGETSIZE, &size)) 5791 2840 fdisk_fatal(ioctl_error); 5792 2841 close(fd); 5793 if ( opts== 1)2842 if (argc == 1) 5794 2843 printf("%ld\n", size/2); 5795 2844 else … … 5800 2849 #endif 5801 2850 5802 #ifdef CONFIG_FEATURE_FDISK_WRITABLE 5803 if (argc-optind == 1) 5804 disk_device = argv[optind]; 5805 else 2851 #if ENABLE_FEATURE_FDISK_WRITABLE 2852 if (argc != 1) 5806 2853 bb_show_usage(); 5807 2854 2855 disk_device = argv[0]; 5808 2856 get_boot(fdisk); 5809 2857 5810 #ifdef CONFIG_FEATURE_OSF_LABEL 5811 if (label_osf == current_label_type) { 2858 if (LABEL_IS_OSF) { 5812 2859 /* OSF label, and no DOS label */ 5813 printf(_("Detected an OSF/1 disklabel on %s, entering " 5814 "disklabel mode.\n"), 5815 disk_device); 5816 bselect(); 2860 printf("Detected an OSF/1 disklabel on %s, entering " 2861 "disklabel mode\n", disk_device); 2862 bsd_select(); 5817 2863 /*Why do we do this? It seems to be counter-intuitive*/ 5818 2864 current_label_type = label_dos; 5819 2865 /* If we return we may want to make an empty DOS label? */ 5820 2866 } 5821 #endif5822 2867 5823 2868 while (1) { 2869 int c; 5824 2870 putchar('\n'); 5825 c = tolower(read_ char(_("Command (m for help): ")));2871 c = tolower(read_nonempty("Command (m for help): ")); 5826 2872 switch (c) { 5827 2873 case 'a': 5828 if ( label_dos == current_label_type)2874 if (LABEL_IS_DOS) 5829 2875 toggle_active(get_partition(1, partitions)); 5830 #ifdef CONFIG_FEATURE_SUN_LABEL 5831 else if (label_sun == current_label_type) 2876 else if (LABEL_IS_SUN) 5832 2877 toggle_sunflags(get_partition(1, partitions), 5833 2878 0x01); 5834 #endif 5835 #ifdef CONFIG_FEATURE_SGI_LABEL 5836 else if (label_sgi == current_label_type) 2879 else if (LABEL_IS_SGI) 5837 2880 sgi_set_bootpartition( 5838 2881 get_partition(1, partitions)); 5839 #endif5840 2882 else 5841 2883 unknown_command(c); 5842 2884 break; 5843 2885 case 'b': 5844 #ifdef CONFIG_FEATURE_SGI_LABEL 5845 if (label_sgi == current_label_type) { 5846 printf(_("\nThe current boot file is: %s\n"), 2886 if (LABEL_IS_SGI) { 2887 printf("\nThe current boot file is: %s\n", 5847 2888 sgi_get_bootfile()); 5848 if (read_ chars(_("Please enter the name of the "5849 "new boot file: ") )== '\n')5850 printf( _("Boot file unchanged\n"));2889 if (read_maybe_empty("Please enter the name of the " 2890 "new boot file: ") == '\n') 2891 printf("Boot file unchanged\n"); 5851 2892 else 5852 2893 sgi_set_bootfile(line_ptr); 5853 } else5854 # endif5855 #ifdef CONFIG_FEATURE_OSF_LABEL 5856 bs elect();2894 } 2895 #if ENABLE_FEATURE_OSF_LABEL 2896 else 2897 bsd_select(); 5857 2898 #endif 5858 2899 break; 5859 2900 case 'c': 5860 if ( label_dos == current_label_type)2901 if (LABEL_IS_DOS) 5861 2902 toggle_dos_compatibility_flag(); 5862 #ifdef CONFIG_FEATURE_SUN_LABEL 5863 else if (label_sun == current_label_type) 2903 else if (LABEL_IS_SUN) 5864 2904 toggle_sunflags(get_partition(1, partitions), 5865 2905 0x10); 5866 #endif 5867 #ifdef CONFIG_FEATURE_SGI_LABEL 5868 else if (label_sgi == current_label_type) 2906 else if (LABEL_IS_SGI) 5869 2907 sgi_set_swappartition( 5870 2908 get_partition(1, partitions)); 5871 #endif5872 2909 else 5873 2910 unknown_command(c); … … 5876 2913 { 5877 2914 int j; 5878 #ifdef CONFIG_FEATURE_SGI_LABEL5879 2915 /* If sgi_label then don't use get_existing_partition, 5880 2916 let the user select a partition, since 5881 2917 get_existing_partition() only works for Linux-like 5882 2918 partition tables */ 5883 if ( label_sgi != current_label_type) {2919 if (!LABEL_IS_SGI) { 5884 2920 j = get_existing_partition(1, partitions); 5885 2921 } else { 5886 2922 j = get_partition(1, partitions); 5887 2923 } 5888 #else5889 j = get_existing_partition(1, partitions);5890 #endif5891 2924 if (j >= 0) 5892 2925 delete_partition(j); … … 5894 2927 break; 5895 2928 case 'i': 5896 #ifdef CONFIG_FEATURE_SGI_LABEL 5897 if (label_sgi == current_label_type) 2929 if (LABEL_IS_SGI) 5898 2930 create_sgiinfo(); 5899 2931 else 5900 #endif5901 2932 unknown_command(c); 5902 2933 case 'l': … … 5917 2948 case 'q': 5918 2949 close(fd); 5919 p rintf("\n");2950 puts(""); 5920 2951 return 0; 5921 2952 case 's': 5922 #if def CONFIG_FEATURE_SUN_LABEL2953 #if ENABLE_FEATURE_SUN_LABEL 5923 2954 create_sunlabel(); 5924 2955 #endif … … 5936 2967 write_table(); /* does not return */ 5937 2968 break; 5938 #if def CONFIG_FEATURE_FDISK_ADVANCED2969 #if ENABLE_FEATURE_FDISK_ADVANCED 5939 2970 case 'x': 5940 #ifdef CONFIG_FEATURE_SGI_LABEL 5941 if (label_sgi == current_label_type) { 5942 fprintf(stderr, 5943 _("\n\tSorry, no experts menu for SGI " 5944 "partition tables available.\n\n")); 2971 if (LABEL_IS_SGI) { 2972 printf("\n\tSorry, no experts menu for SGI " 2973 "partition tables available\n\n"); 5945 2974 } else 5946 #endif5947 5948 2975 xselect(); 5949 2976 break; … … 5955 2982 } 5956 2983 return 0; 5957 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */5958 } 2984 #endif /* FEATURE_FDISK_WRITABLE */ 2985 }
Note:
See TracChangeset
for help on using the changeset viewer.