1 /* disk_io.c - implement abstract BIOS disk input and output */ 2 /* 3 * GRUB -- GRand Unified Bootloader 4 * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 22 #include <shared.h> 23 #include <filesys.h> 24 #include <gpt.h> 25 26 #ifdef SUPPORT_NETBOOT 27 # include <grub.h> 28 #endif 29 30 #ifdef GRUB_UTIL 31 # include <device.h> 32 #endif 33 34 /* instrumentation variables */ 35 void (*disk_read_hook) (unsigned int, int, int) = NULL; 36 void (*disk_read_func) (unsigned int, int, int) = NULL; 37 38 #ifndef STAGE1_5 39 int print_possibilities; 40 41 static int do_completion; 42 static int unique; 43 static char *unique_string; 44 45 #endif 46 47 int fsmax; 48 struct fsys_entry fsys_table[NUM_FSYS + 1] = 49 { 50 /* TFTP should come first because others don't handle net device. */ 51 # ifdef FSYS_TFTP 52 {"tftp", tftp_mount, tftp_read, tftp_dir, tftp_close, 0}, 53 # endif 54 # ifdef FSYS_FAT 55 {"fat", fat_mount, fat_read, fat_dir, 0, 0}, 56 # endif 57 # ifdef FSYS_EXT2FS 58 {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0}, 59 # endif 60 # ifdef FSYS_MINIX 61 {"minix", minix_mount, minix_read, minix_dir, 0, 0}, 62 # endif 63 # ifdef FSYS_REISERFS 64 {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed}, 65 # endif 66 # ifdef FSYS_VSTAFS 67 {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0}, 68 # endif 69 # ifdef FSYS_JFS 70 {"jfs", jfs_mount, jfs_read, jfs_dir, 0, jfs_embed}, 71 # endif 72 # ifdef FSYS_XFS 73 {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0}, 74 # endif 75 # ifdef FSYS_UFS 76 {"ufs", ufs_mount, ufs_read, ufs_dir, 0, ufs_embed}, 77 # endif 78 # ifdef FSYS_UFS2 79 {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed}, 80 # endif 81 # ifdef FSYS_ZFS 82 {"zfs", zfs_mount, zfs_read, zfs_open, 0, zfs_embed}, 83 # endif 84 # ifdef FSYS_ISO9660 85 {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0}, 86 # endif 87 /* XX FFS should come last as it's superblock is commonly crossing tracks 88 on floppies from track 1 to 2, while others only use 1. */ 89 # ifdef FSYS_FFS 90 {"ffs", ffs_mount, ffs_read, ffs_dir, 0, ffs_embed}, 91 # endif 92 {0, 0, 0, 0, 0, 0} 93 }; 94 95 96 /* These have the same format as "boot_drive" and "install_partition", but 97 are meant to be working values. */ 98 unsigned long current_drive = GRUB_INVALID_DRIVE; 99 unsigned long current_partition; 100 101 #ifndef STAGE1_5 102 /* The register ESI should contain the address of the partition to be 103 used for loading a chain-loader when chain-loading the loader. */ 104 unsigned long boot_part_addr = 0; 105 #endif 106 107 /* 108 * Global variables describing details of the filesystem 109 */ 110 111 /* FIXME: BSD evil hack */ 112 #include "freebsd.h" 113 int bsd_evil_hack; 114 115 /* filesystem type */ 116 int fsys_type = NUM_FSYS; 117 #ifndef NO_BLOCK_FILES 118 static int block_file = 0; 119 #endif /* NO_BLOCK_FILES */ 120 121 /* these are the translated numbers for the open partition */ 122 unsigned long part_start; 123 unsigned long part_length; 124 125 int current_slice; 126 127 /* ZFS root filesystem for booting */ 128 char current_rootpool[MAXNAMELEN]; 129 char current_bootfs[MAXNAMELEN]; 130 uint64_t current_bootfs_obj; 131 char current_bootpath[MAXPATHLEN]; 132 char current_devid[MAXPATHLEN]; 133 int is_zfs_mount; 134 unsigned long best_drive; 135 unsigned long best_part; 136 int find_best_root; 137 138 /* disk buffer parameters */ 139 int buf_drive = -1; 140 unsigned int buf_track; 141 struct geometry buf_geom; 142 143 /* filesystem common variables */ 144 int filepos; 145 int filemax; 146 147 static inline unsigned long 148 grub_log2 (unsigned long word) 149 { 150 asm volatile ("bsfl %1,%0" 151 : "=r" (word) 152 : "r" (word)); 153 return word; 154 } 155 #define log2 grub_log2 156 157 int 158 rawread(int drive, unsigned int sector, int byte_offset, int byte_len, 159 char *buf) 160 { 161 int slen, sectors_per_vtrack; 162 int sector_size_bits = log2 (buf_geom.sector_size); 163 164 if (byte_len <= 0) 165 return 1; 166 167 while (byte_len > 0 && !errnum) 168 { 169 int soff, num_sect, size = byte_len; 170 unsigned int track; 171 char *bufaddr; 172 173 /* 174 * Check track buffer. If it isn't valid or it is from the 175 * wrong disk, then reset the disk geometry. 176 */ 177 if (buf_drive != drive) 178 { 179 if (get_diskinfo (drive, &buf_geom)) 180 { 181 errnum = ERR_NO_DISK; 182 return 0; 183 } 184 buf_drive = drive; 185 buf_track = BUF_CACHE_INVALID; 186 sector_size_bits = log2 (buf_geom.sector_size); 187 } 188 189 slen = ((byte_offset + byte_len + buf_geom.sector_size - 1) 190 >> sector_size_bits); 191 192 /* Eliminate a buffer overflow. */ 193 if ((buf_geom.sectors << sector_size_bits) > BUFFERLEN) 194 sectors_per_vtrack = (BUFFERLEN >> sector_size_bits); 195 else 196 sectors_per_vtrack = buf_geom.sectors; 197 198 /* Get the first sector of track. */ 199 soff = sector % sectors_per_vtrack; 200 track = sector - soff; 201 num_sect = sectors_per_vtrack - soff; 202 bufaddr = ((char *) BUFFERADDR 203 + (soff << sector_size_bits) + byte_offset); 204 205 if (track != buf_track) 206 { 207 int bios_err, read_len = sectors_per_vtrack; 208 unsigned int read_start = track; 209 210 /* 211 * If there's more than one read in this entire loop, then 212 * only make the earlier reads for the portion needed. This 213 * saves filling the buffer with data that won't be used! 214 */ 215 if (slen > num_sect) 216 { 217 read_start = sector; 218 read_len = num_sect; 219 bufaddr = (char *) BUFFERADDR + byte_offset; 220 } 221 222 bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom, 223 read_start, read_len, BUFFERSEG); 224 if (bios_err) 225 { 226 buf_track = BUF_CACHE_INVALID; 227 228 if (bios_err == BIOSDISK_ERROR_GEOMETRY) 229 errnum = ERR_GEOM; 230 else 231 { 232 /* 233 * If there was an error, try to load only the 234 * required sector(s) rather than failing completely. 235 */ 236 if (slen > num_sect 237 || biosdisk (BIOSDISK_READ, drive, &buf_geom, 238 sector, slen, BUFFERSEG)) 239 errnum = ERR_READ; 240 241 bufaddr = (char *) BUFFERADDR + byte_offset; 242 } 243 } 244 else 245 buf_track = track; 246 247 if ((buf_track == 0 || sector == 0) 248 && (PC_SLICE_TYPE (BUFFERADDR, 0) == PC_SLICE_TYPE_EZD 249 || PC_SLICE_TYPE (BUFFERADDR, 1) == PC_SLICE_TYPE_EZD 250 || PC_SLICE_TYPE (BUFFERADDR, 2) == PC_SLICE_TYPE_EZD 251 || PC_SLICE_TYPE (BUFFERADDR, 3) == PC_SLICE_TYPE_EZD)) 252 { 253 /* This is a EZD disk map sector 0 to sector 1 */ 254 if (buf_track == 0 || slen >= 2) 255 { 256 /* We already read the sector 1, copy it to sector 0 */ 257 memmove ((char *) BUFFERADDR, 258 (char *) BUFFERADDR + buf_geom.sector_size, 259 buf_geom.sector_size); 260 } 261 else 262 { 263 if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 264 1, 1, BUFFERSEG)) 265 errnum = ERR_READ; 266 } 267 } 268 } 269 270 if (size > ((num_sect << sector_size_bits) - byte_offset)) 271 size = (num_sect << sector_size_bits) - byte_offset; 272 273 /* 274 * Instrumentation to tell which sectors were read and used. 275 */ 276 if (disk_read_func) 277 { 278 unsigned int sector_num = sector; 279 int length = buf_geom.sector_size - byte_offset; 280 if (length > size) 281 length = size; 282 (*disk_read_func) (sector_num++, byte_offset, length); 283 length = size - length; 284 if (length > 0) 285 { 286 while (length > buf_geom.sector_size) 287 { 288 (*disk_read_func) (sector_num++, 0, buf_geom.sector_size); 289 length -= buf_geom.sector_size; 290 } 291 (*disk_read_func) (sector_num, 0, length); 292 } 293 } 294 295 grub_memmove (buf, bufaddr, size); 296 297 buf += size; 298 byte_len -= size; 299 sector += num_sect; 300 byte_offset = 0; 301 } 302 303 return (!errnum); 304 } 305 306 307 int 308 devread(unsigned int sector, int byte_offset, int byte_len, char *buf) 309 { 310 /* 311 * Check partition boundaries 312 */ 313 if ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) 314 >= part_length) 315 { 316 errnum = ERR_OUTSIDE_PART; 317 return 0; 318 } 319 320 /* 321 * Get the read to the beginning of a partition. 322 */ 323 sector += byte_offset >> SECTOR_BITS; 324 byte_offset &= SECTOR_SIZE - 1; 325 326 #if !defined(STAGE1_5) 327 if (disk_read_hook && debug) 328 printf ("<%u, %d, %d>", sector, byte_offset, byte_len); 329 #endif /* !STAGE1_5 */ 330 331 /* 332 * Call RAWREAD, which is very similar, but: 333 * 334 * -- It takes an extra parameter, the drive number. 335 * -- It requires that "sector" is relative to the beginning 336 * of the disk. 337 * -- It doesn't handle offsets of more than 511 bytes into the 338 * sector. 339 */ 340 return rawread (current_drive, part_start + sector, byte_offset, 341 byte_len, buf); 342 } 343 344 #ifndef STAGE1_5 345 int 346 rawwrite(int drive, unsigned int sector, char *buf) 347 { 348 if (sector == 0) 349 { 350 if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 0, 1, SCRATCHSEG)) 351 { 352 errnum = ERR_WRITE; 353 return 0; 354 } 355 356 if (PC_SLICE_TYPE (SCRATCHADDR, 0) == PC_SLICE_TYPE_EZD 357 || PC_SLICE_TYPE (SCRATCHADDR, 1) == PC_SLICE_TYPE_EZD 358 || PC_SLICE_TYPE (SCRATCHADDR, 2) == PC_SLICE_TYPE_EZD 359 || PC_SLICE_TYPE (SCRATCHADDR, 3) == PC_SLICE_TYPE_EZD) 360 sector = 1; 361 } 362 363 memmove ((char *) SCRATCHADDR, buf, SECTOR_SIZE); 364 if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom, 365 sector, 1, SCRATCHSEG)) 366 { 367 errnum = ERR_WRITE; 368 return 0; 369 } 370 371 if (sector - sector % buf_geom.sectors == buf_track) 372 /* Clear the cache. */ 373 buf_track = BUF_CACHE_INVALID; 374 375 return 1; 376 } 377 378 int 379 devwrite(unsigned int sector, int sector_count, char *buf) 380 { 381 #if defined(GRUB_UTIL) && defined(__linux__) 382 if (current_partition != 0xFFFFFF 383 && is_disk_device (device_map, current_drive)) 384 { 385 /* If the grub shell is running under Linux and the user wants to 386 embed a Stage 1.5 into a partition instead of a MBR, use system 387 calls directly instead of biosdisk, because of the bug in 388 Linux. *sigh* */ 389 return write_to_partition (device_map, current_drive, current_partition, 390 sector, sector_count, buf); 391 } 392 else 393 #endif /* GRUB_UTIL && __linux__ */ 394 { 395 int i; 396 397 for (i = 0; i < sector_count; i++) 398 { 399 if (! rawwrite (current_drive, part_start + sector + i, 400 buf + (i << SECTOR_BITS))) 401 return 0; 402 403 } 404 return 1; 405 } 406 } 407 408 static int 409 sane_partition (void) 410 { 411 /* network drive */ 412 if (current_drive == NETWORK_DRIVE) 413 return 1; 414 415 if (!(current_partition & 0xFF000000uL) 416 && ((current_drive & 0xFFFFFF7F) < 8 417 || current_drive == cdrom_drive) 418 && (current_partition & 0xFF) == 0xFF 419 && ((current_partition & 0xFF00) == 0xFF00 420 || (current_partition & 0xFF00) < 0x1000) 421 && ((current_partition >> 16) == 0xFF 422 || (current_drive & 0x80))) 423 return 1; 424 425 errnum = ERR_DEV_VALUES; 426 return 0; 427 } 428 #endif /* ! STAGE1_5 */ 429 430 static void 431 attempt_mount (void) 432 { 433 #ifndef STAGE1_5 434 for (fsys_type = 0; fsys_type < NUM_FSYS; fsys_type++) 435 if ((fsys_table[fsys_type].mount_func) ()) 436 break; 437 438 if (fsys_type == NUM_FSYS && errnum == ERR_NONE) 439 errnum = ERR_FSYS_MOUNT; 440 #else 441 fsys_type = 0; 442 if ((*(fsys_table[fsys_type].mount_func)) () != 1) 443 { 444 fsys_type = NUM_FSYS; 445 errnum = ERR_FSYS_MOUNT; 446 } 447 #endif 448 } 449 450 451 #ifndef STAGE1_5 452 /* Turn on the active flag for the partition SAVED_PARTITION in the 453 drive SAVED_DRIVE. If an error occurs, return zero, otherwise return 454 non-zero. */ 455 int 456 make_saved_active (void) 457 { 458 char mbr[512]; 459 460 if (saved_drive & 0x80) 461 { 462 /* Hard disk */ 463 int part = saved_partition >> 16; 464 465 /* If the partition is not a primary partition, the active flag is 466 meaningless. (XXX: Really?) */ 467 if (part > 3) 468 { 469 errnum = ERR_DEV_VALUES; 470 return 0; 471 } 472 473 /* Read the MBR in the scratch space. */ 474 if (! rawread (saved_drive, 0, 0, SECTOR_SIZE, mbr)) 475 return 0; 476 477 /* If the partition is an extended partition, setting the active 478 flag violates the specification by IBM. */ 479 if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (mbr, part))) 480 { 481 errnum = ERR_DEV_VALUES; 482 return 0; 483 } 484 485 /* Check if the active flag is disabled. */ 486 if (PC_SLICE_FLAG (mbr, part) != PC_SLICE_FLAG_BOOTABLE) 487 { 488 int i; 489 490 /* Clear all the active flags in this table. */ 491 for (i = 0; i < 4; i++) 492 PC_SLICE_FLAG (mbr, i) = 0; 493 494 /* Set the flag. */ 495 PC_SLICE_FLAG (mbr, part) = PC_SLICE_FLAG_BOOTABLE; 496 497 /* Write back the MBR. */ 498 if (! rawwrite (saved_drive, 0, mbr)) 499 return 0; 500 } 501 } 502 else 503 { 504 /* If the drive is not a hard disk drive, you shouldn't call this 505 function. (XXX: Should I just ignore this error?) */ 506 errnum = ERR_DEV_VALUES; 507 return 0; 508 } 509 510 return 1; 511 } 512 513 /* Hide/Unhide CURRENT_PARTITION. */ 514 int 515 set_partition_hidden_flag (int hidden) 516 { 517 unsigned long part = 0xFFFFFF; 518 unsigned long start, len, offset, ext_offset, gpt_offset; 519 int entry, type, gpt_count, gpt_size; 520 char mbr[512]; 521 522 /* The drive must be a hard disk. */ 523 if (! (current_drive & 0x80)) 524 { 525 errnum = ERR_BAD_ARGUMENT; 526 return 1; 527 } 528 529 /* The partition must be a PC slice. */ 530 if ((current_partition >> 16) == 0xFF 531 || (current_partition & 0xFFFF) != 0xFFFF) 532 { 533 errnum = ERR_BAD_ARGUMENT; 534 return 1; 535 } 536 537 /* Look for the partition. */ 538 while (next_partition (current_drive, 0xFFFFFF, &part, &type, 539 &start, &len, &offset, &entry, 540 &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) 541 { 542 /* The partition may not be a GPT partition. */ 543 if (gpt_offset != 0) 544 { 545 errnum = ERR_BAD_ARGUMENT; 546 return 1; 547 } 548 549 if (part == current_partition) 550 { 551 /* Found. */ 552 if (hidden) 553 PC_SLICE_TYPE (mbr, entry) |= PC_SLICE_TYPE_HIDDEN_FLAG; 554 else 555 PC_SLICE_TYPE (mbr, entry) &= ~PC_SLICE_TYPE_HIDDEN_FLAG; 556 557 /* Write back the MBR to the disk. */ 558 buf_track = BUF_CACHE_INVALID; 559 if (! rawwrite (current_drive, offset, mbr)) 560 return 1; 561 562 /* Succeed. */ 563 return 0; 564 } 565 } 566 567 return 1; 568 } 569 570 571 static void 572 check_and_print_mount (void) 573 { 574 attempt_mount (); 575 if (errnum == ERR_FSYS_MOUNT) 576 errnum = ERR_NONE; 577 if (!errnum) 578 print_fsys_type (); 579 print_error (); 580 } 581 #endif /* STAGE1_5 */ 582 583 584 /* Get the information on next partition on the drive DRIVE. 585 The caller must not modify the contents of the arguments when 586 iterating this function. The partition representation in GRUB will 587 be stored in *PARTITION. Likewise, the partition type in *TYPE, the 588 start sector in *START, the length in *LEN, the offset of the 589 partition table in *OFFSET, the entry number in the table in *ENTRY, 590 the offset of the extended partition in *EXT_OFFSET. 591 BUF is used to store a MBR, the boot sector of a partition, or 592 a BSD label sector, and it must be at least 512 bytes length. 593 When calling this function first, *PARTITION must be initialized to 594 0xFFFFFF. The return value is zero if fails, otherwise non-zero. */ 595 int 596 next_partition (unsigned long drive, unsigned long dest, 597 unsigned long *partition, int *type, 598 unsigned long *start, unsigned long *len, 599 unsigned long *offset, int *entry, 600 unsigned long *ext_offset, 601 unsigned long *gpt_offset, int *gpt_count, 602 int *gpt_size, char *buf) 603 { 604 /* Forward declarations. */ 605 auto int next_bsd_partition (void); 606 auto int next_solaris_partition(void); 607 auto int next_pc_slice (void); 608 auto int next_gpt_slice(void); 609 610 /* Get next BSD partition in current PC slice. */ 611 int next_bsd_partition (void) 612 { 613 int i; 614 int bsd_part_no = (*partition & 0xFF00) >> 8; 615 616 /* If this is the first time... */ 617 if (bsd_part_no == 0xFF) 618 { 619 /* Check if the BSD label is within current PC slice. */ 620 if (*len < BSD_LABEL_SECTOR + 1) 621 { 622 errnum = ERR_BAD_PART_TABLE; 623 return 0; 624 } 625 626 /* Read the BSD label. */ 627 if (! rawread (drive, *start + BSD_LABEL_SECTOR, 628 0, SECTOR_SIZE, buf)) 629 return 0; 630 631 /* Check if it is valid. */ 632 if (! BSD_LABEL_CHECK_MAG (buf)) 633 { 634 errnum = ERR_BAD_PART_TABLE; 635 return 0; 636 } 637 638 bsd_part_no = -1; 639 } 640 641 /* Search next valid BSD partition. */ 642 for (i = bsd_part_no + 1; i < BSD_LABEL_NPARTS (buf); i++) 643 { 644 if (BSD_PART_TYPE (buf, i)) 645 { 646 /* Note that *TYPE and *PARTITION were set 647 for current PC slice. */ 648 *type = (BSD_PART_TYPE (buf, i) << 8) | (*type & 0xFF); 649 *start = BSD_PART_START (buf, i); 650 *len = BSD_PART_LENGTH (buf, i); 651 *partition = (*partition & 0xFF00FF) | (i << 8); 652 653 #ifndef STAGE1_5 654 /* XXX */ 655 if ((drive & 0x80) && BSD_LABEL_DTYPE (buf) == DTYPE_SCSI) 656 bsd_evil_hack = 4; 657 #endif /* ! STAGE1_5 */ 658 659 return 1; 660 } 661 } 662 663 errnum = ERR_NO_PART; 664 return 0; 665 } 666 667 /* Get next Solaris partition in current PC slice. */ 668 int next_solaris_partition (void) 669 { 670 static unsigned long pcs_start; 671 int i; 672 int sol_part_no = (*partition & 0xFF00) >> 8; 673 674 /* If this is the first time... */ 675 if (sol_part_no == 0xFF) 676 { 677 /* Check if the Solaris label is within current PC slice. */ 678 if (*len < SOL_LABEL_LOC + 1) 679 { 680 errnum = ERR_BAD_PART_TABLE; 681 return 0; 682 } 683 684 /* Read the Solaris label. */ 685 if (! rawread (drive, *start + SOL_LABEL_LOC, 0, SECTOR_SIZE, buf)) 686 return 0; 687 688 /* Check if it is valid. */ 689 if (! SOL_LABEL_CHECK_MAG (buf)) 690 { 691 errnum = ERR_BAD_PART_TABLE; 692 return 0; 693 } 694 695 sol_part_no = -1; 696 pcs_start = *start; /* save the start of pc slice */ 697 } 698 699 /* Search next valid Solaris partition. */ 700 for (i = sol_part_no + 1; i < SOL_LABEL_NPARTS; i++) 701 { 702 if (SOL_PART_EXISTS (buf, i)) 703 { 704 /* SOL_PART_START is relative to fdisk partition */ 705 *start = SOL_PART_START (buf, i) + pcs_start; 706 *len = SOL_PART_LENGTH (buf, i); 707 *partition = (*partition & 0xFF00FF) | (i << 8); 708 709 return 1; 710 } 711 } 712 713 errnum = ERR_NO_PART; 714 return 0; 715 } 716 717 /* Get next PC slice. Be careful of that this function may return 718 an empty PC slice (i.e. a partition whose type is zero) as well. */ 719 int next_pc_slice (void) 720 { 721 int pc_slice_no = (*partition & 0xFF0000) >> 16; 722 723 /* If this is the first time... */ 724 if (pc_slice_no == 0xFF) 725 { 726 *offset = 0; 727 *ext_offset = 0; 728 *entry = -1; 729 pc_slice_no = -1; 730 } 731 732 /* Read the MBR or the boot sector of the extended partition. */ 733 if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) 734 return 0; 735 736 /* Check if it is valid. */ 737 if (! PC_MBR_CHECK_SIG (buf)) 738 { 739 errnum = ERR_BAD_PART_TABLE; 740 return 0; 741 } 742 743 /* If this is a GPT partition table, read it as such. */ 744 if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT) 745 { 746 struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf; 747 748 /* Read in the GPT Partition table header. */ 749 if (! rawread (drive, 1, 0, SECTOR_SIZE, buf)) 750 return 0; 751 752 if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000) 753 { 754 /* Let gpt_offset point to the first entry in the GPT 755 partition table. This can also be used by callers of 756 next_partition to determine if a entry comes from a 757 GPT partition table or not. */ 758 *gpt_offset = hdr->partitions; 759 *gpt_count = hdr->maxpart; 760 *gpt_size = hdr->partentry_size; 761 762 return next_gpt_slice(); 763 } 764 else 765 { 766 /* This is not a valid header for a GPT partition table. 767 Re-read the MBR or the boot sector of the extended 768 partition. */ 769 if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) 770 return 0; 771 } 772 } 773 774 /* Not a GPT partition. */ 775 *gpt_offset = 0; 776 777 /* Increase the entry number. */ 778 (*entry)++; 779 780 /* If this is out of current partition table... */ 781 if (*entry == PC_SLICE_MAX) 782 { 783 int i; 784 785 /* Search the first extended partition in current table. */ 786 for (i = 0; i < PC_SLICE_MAX; i++) 787 { 788 if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (buf, i))) 789 { 790 /* Found. Set the new offset and the entry number, 791 and restart this function. */ 792 *offset = *ext_offset + PC_SLICE_START (buf, i); 793 if (! *ext_offset) 794 *ext_offset = *offset; 795 *entry = -1; 796 return next_pc_slice (); 797 } 798 } 799 800 errnum = ERR_NO_PART; 801 return 0; 802 } 803 804 *type = PC_SLICE_TYPE (buf, *entry); 805 *start = *offset + PC_SLICE_START (buf, *entry); 806 *len = PC_SLICE_LENGTH (buf, *entry); 807 808 /* The calculation of a PC slice number is complicated, because of 809 the rather odd definition of extended partitions. Even worse, 810 there is no guarantee that this is consistent with every 811 operating systems. Uggh. */ 812 if (pc_slice_no < PC_SLICE_MAX 813 || (! IS_PC_SLICE_TYPE_EXTENDED (*type) 814 && *type != PC_SLICE_TYPE_NONE)) 815 pc_slice_no++; 816 817 *partition = (pc_slice_no << 16) | 0xFFFF; 818 return 1; 819 } 820 821 /* Get the next GPT slice. */ 822 int next_gpt_slice (void) 823 { 824 struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf; 825 /* Make GPT partitions show up as PC slices. */ 826 int pc_slice_no = (*partition & 0xFF0000) >> 16; 827 828 /* If this is the first time... */ 829 if (pc_slice_no == 0xFF) 830 { 831 pc_slice_no = -1; 832 *entry = -1; 833 } 834 835 do { 836 (*entry)++; 837 838 if (*entry >= *gpt_count) 839 { 840 errnum = ERR_NO_PART; 841 return 0; 842 } 843 /* Read in the GPT Partition table entry. */ 844 if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf)) 845 return 0; 846 } while (! (gptentry->type1 && gptentry->type2)); 847 848 pc_slice_no++; 849 *start = gptentry->start; 850 *len = gptentry->end - gptentry->start + 1; 851 *type = PC_SLICE_TYPE_EXT2FS; 852 *entry = pc_slice_no; 853 *partition = (*entry << 16) | 0xFFFF; 854 855 return 1; 856 } 857 858 /* Start the body of this function. */ 859 860 #ifndef STAGE1_5 861 if (current_drive == NETWORK_DRIVE) 862 return 0; 863 #endif 864 865 /* check for Solaris partition */ 866 if (*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_SOLARIS (*type & 0xff)) 867 { 868 if (next_solaris_partition ()) 869 return 1; 870 errnum = ERR_NONE; 871 } 872 873 if (*partition != 0xFFFFFF && *gpt_offset != 0) 874 return next_gpt_slice (); 875 876 /* If previous partition is a BSD partition or a PC slice which 877 contains BSD partitions... */ 878 if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff)) 879 || ! (drive & 0x80)) 880 { 881 if (*type == PC_SLICE_TYPE_NONE) 882 *type = PC_SLICE_TYPE_FREEBSD; 883 884 /* Get next BSD partition, if any. */ 885 if (next_bsd_partition ()) 886 return 1; 887 888 /* If the destination partition is a BSD partition and current 889 BSD partition has any error, abort the operation. */ 890 if ((dest & 0xFF00) != 0xFF00 891 && ((dest & 0xFF0000) == 0xFF0000 892 || (dest & 0xFF0000) == (*partition & 0xFF0000))) 893 return 0; 894 895 /* Ignore the error. */ 896 errnum = ERR_NONE; 897 } 898 899 return next_pc_slice (); 900 } 901 902 #ifndef STAGE1_5 903 static unsigned long cur_part_offset; 904 static unsigned long cur_part_addr; 905 #endif 906 907 /* Open a partition. */ 908 int 909 real_open_partition (int flags) 910 { 911 unsigned long dest_partition = current_partition; 912 unsigned long part_offset; 913 unsigned long ext_offset; 914 unsigned long gpt_offset; 915 int gpt_count; 916 int gpt_size; 917 int entry; 918 char buf[SECTOR_SIZE]; 919 int unix_part, pc_slice; 920 921 /* For simplicity. */ 922 auto int next (void); 923 int next (void) 924 { 925 int ret = next_partition (current_drive, dest_partition, 926 ¤t_partition, ¤t_slice, 927 &part_start, &part_length, 928 &part_offset, &entry, &ext_offset, 929 &gpt_offset, &gpt_count, &gpt_size, buf); 930 unix_part = (current_partition >> 8) & 0xFF; 931 pc_slice = current_partition >> 16; 932 return ret; 933 } 934 935 #ifndef STAGE1_5 936 /* network drive */ 937 if (current_drive == NETWORK_DRIVE) 938 return 1; 939 940 if (! sane_partition ()) 941 return 0; 942 #endif 943 944 bsd_evil_hack = 0; 945 current_slice = 0; 946 part_start = 0; 947 948 /* Make sure that buf_geom is valid. */ 949 if (buf_drive != current_drive) 950 { 951 if (get_diskinfo (current_drive, &buf_geom)) 952 { 953 errnum = ERR_NO_DISK; 954 return 0; 955 } 956 buf_drive = current_drive; 957 buf_track = BUF_CACHE_INVALID; 958 } 959 part_length = 960 (buf_geom.total_sectors > MAXUINT) ? MAXUINT : buf_geom.total_sectors; 961 962 /* If this is the whole disk, return here. */ 963 if (! flags && current_partition == 0xFFFFFF) 964 return 1; 965 966 if (flags) 967 dest_partition = 0xFFFFFF; 968 969 /* Initialize CURRENT_PARTITION for next_partition. */ 970 current_partition = 0xFFFFFF; 971 972 while (next ()) 973 { 974 #ifndef STAGE1_5 975 loop_start: 976 977 cur_part_offset = part_offset; 978 cur_part_addr = BOOT_PART_TABLE + (entry << 4); 979 #endif /* ! STAGE1_5 */ 980 981 /* If this is a valid partition... */ 982 if (current_slice) 983 { 984 #ifndef STAGE1_5 985 /* Display partition information. */ 986 if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice)) 987 { 988 if (! do_completion) 989 { 990 if (current_drive & 0x80) 991 grub_printf (" Partition num: %d, ", 992 current_partition >> 16); 993 994 if (! IS_PC_SLICE_TYPE_BSD (current_slice) && 995 ! IS_PC_SLICE_TYPE_SOLARIS (current_slice)) 996 check_and_print_mount (); 997 else 998 { 999 int got_part = 0; 1000 int saved_slice = current_slice; 1001 1002 while (next ()) 1003 { 1004 if (unix_part == 0xFF) 1005 break; 1006 1007 if (! got_part) 1008 { 1009 grub_printf ("[BSD/SOLARIS sub-partitions immediately follow]\n"); 1010 got_part = 1; 1011 } 1012 1013 grub_printf (" BSD/SOLARIS Partition num: \'%c\', ", 1014 unix_part + 'a'); 1015 check_and_print_mount (); 1016 } 1017 1018 if (! got_part) 1019 grub_printf (" No BSD/SOLARIS sub-partition found, partition type 0x%x\n", 1020 saved_slice); 1021 1022 if (errnum) 1023 { 1024 errnum = ERR_NONE; 1025 break; 1026 } 1027 1028 goto loop_start; 1029 } 1030 } 1031 else 1032 { 1033 if (unix_part != 0xFF) 1034 { 1035 char str[16]; 1036 1037 if (! (current_drive & 0x80) 1038 || (dest_partition >> 16) == pc_slice) 1039 grub_sprintf (str, "%c)", unix_part + 'a'); 1040 else 1041 grub_sprintf (str, "%d,%c)", 1042 pc_slice, unix_part + 'a'); 1043 print_a_completion (str); 1044 } 1045 else if (! IS_PC_SLICE_TYPE_BSD (current_slice) && 1046 ! IS_PC_SLICE_TYPE_SOLARIS (current_slice)) 1047 { 1048 char str[8]; 1049 1050 grub_sprintf (str, "%d)", pc_slice); 1051 print_a_completion (str); 1052 } 1053 } 1054 } 1055 1056 errnum = ERR_NONE; 1057 #endif /* ! STAGE1_5 */ 1058 1059 /* Check if this is the destination partition. */ 1060 if (! flags 1061 && (dest_partition == current_partition 1062 || ((dest_partition >> 16) == 0xFF 1063 && ((dest_partition >> 8) & 0xFF) == unix_part))) 1064 return 1; 1065 } 1066 } 1067 1068 #ifndef STAGE1_5 1069 if (flags) 1070 { 1071 if (! (current_drive & 0x80)) 1072 { 1073 current_partition = 0xFFFFFF; 1074 check_and_print_mount (); 1075 } 1076 1077 errnum = ERR_NONE; 1078 return 1; 1079 } 1080 #endif /* ! STAGE1_5 */ 1081 1082 return 0; 1083 } 1084 1085 1086 int 1087 open_partition (void) 1088 { 1089 return real_open_partition (0); 1090 } 1091 1092 1093 #ifndef STAGE1_5 1094 /* XX used for device completion in 'set_device' and 'print_completions' */ 1095 static int incomplete, disk_choice; 1096 static enum 1097 { 1098 PART_UNSPECIFIED = 0, 1099 PART_DISK, 1100 PART_CHOSEN, 1101 } 1102 part_choice; 1103 #endif /* ! STAGE1_5 */ 1104 1105 char * 1106 set_device (char *device) 1107 { 1108 #ifdef STAGE1_5 1109 /* In Stage 1.5, the first 4 bytes of FILENAME has a device number. */ 1110 unsigned long dev = *((unsigned long *) device); 1111 int drive = (dev >> 24) & 0xFF; 1112 int partition = dev & 0xFFFFFF; 1113 1114 /* If DRIVE is disabled, use SAVED_DRIVE instead. */ 1115 if (drive == GRUB_INVALID_DRIVE) 1116 current_drive = saved_drive; 1117 else 1118 current_drive = drive; 1119 1120 /* The `partition' part must always have a valid number. */ 1121 current_partition = partition; 1122 1123 return device + sizeof (unsigned long); 1124 1125 #else /* ! STAGE1_5 */ 1126 1127 int result = 0; 1128 1129 incomplete = 0; 1130 disk_choice = 1; 1131 part_choice = PART_UNSPECIFIED; 1132 current_drive = saved_drive; 1133 current_partition = 0xFFFFFF; 1134 1135 if (*device == '(' && !*(device + 1)) 1136 /* user has given '(' only, let disk_choice handle what disks we have */ 1137 return device + 1; 1138 1139 if (*device == '(' && *(++device)) 1140 { 1141 if (*device != ',' && *device != ')') 1142 { 1143 char ch = *device; 1144 #ifdef SUPPORT_NETBOOT 1145 if (*device == 'f' || *device == 'h' 1146 || (*device == 'n' && network_ready) 1147 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1148 #else 1149 if (*device == 'f' || *device == 'h' 1150 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1151 #endif /* SUPPORT_NETBOOT */ 1152 { 1153 /* user has given '([fhn]', check for resp. add 'd' and 1154 let disk_choice handle what disks we have */ 1155 if (!*(device + 1)) 1156 { 1157 device++; 1158 *device++ = 'd'; 1159 *device = '\0'; 1160 return device; 1161 } 1162 else if (*(device + 1) == 'd' && !*(device + 2)) 1163 return device + 2; 1164 } 1165 1166 if ((*device == 'f' 1167 || *device == 'h' 1168 #ifdef SUPPORT_NETBOOT 1169 || (*device == 'n' && network_ready) 1170 #endif 1171 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1172 && (device += 2, (*(device - 1) != 'd'))) 1173 errnum = ERR_NUMBER_PARSING; 1174 1175 #ifdef SUPPORT_NETBOOT 1176 if (ch == 'n' && network_ready) 1177 current_drive = NETWORK_DRIVE; 1178 else 1179 #endif /* SUPPORT_NETBOOT */ 1180 { 1181 if (ch == 'c' && cdrom_drive != GRUB_INVALID_DRIVE) 1182 current_drive = cdrom_drive; 1183 else 1184 { 1185 safe_parse_maxint (&device, (int *) ¤t_drive); 1186 1187 disk_choice = 0; 1188 if (ch == 'h') 1189 current_drive += 0x80; 1190 } 1191 } 1192 } 1193 1194 if (errnum) 1195 return 0; 1196 1197 if (*device == ')') 1198 { 1199 part_choice = PART_CHOSEN; 1200 result = 1; 1201 } 1202 else if (*device == ',') 1203 { 1204 /* Either an absolute PC, BSD, or Solaris partition. */ 1205 disk_choice = 0; 1206 part_choice ++; 1207 device++; 1208 1209 if (*device >= '0' && *device <= '9') 1210 { 1211 part_choice ++; 1212 current_partition = 0; 1213 1214 if (!(current_drive & 0x80) 1215 || !safe_parse_maxint (&device, (int *) ¤t_partition) 1216 || current_partition > 254) 1217 { 1218 errnum = ERR_DEV_FORMAT; 1219 return 0; 1220 } 1221 1222 current_partition = (current_partition << 16) + 0xFFFF; 1223 1224 if (*device == ',') 1225 device++; 1226 1227 if (*device >= 'a' && *device <= 'p') 1228 { 1229 current_partition = (((*(device++) - 'a') << 8) 1230 | (current_partition & 0xFF00FF)); 1231 } 1232 } 1233 else if (*device >= 'a' && *device <= 'p') 1234 { 1235 part_choice ++; 1236 current_partition = ((*(device++) - 'a') << 8) | 0xFF00FF; 1237 } 1238 1239 if (*device == ')') 1240 { 1241 if (part_choice == PART_DISK) 1242 { 1243 current_partition = saved_partition; 1244 part_choice ++; 1245 } 1246 1247 result = 1; 1248 } 1249 } 1250 } 1251 1252 if (! sane_partition ()) 1253 return 0; 1254 1255 if (result) 1256 return device + 1; 1257 else 1258 { 1259 if (!*device) 1260 incomplete = 1; 1261 errnum = ERR_DEV_FORMAT; 1262 } 1263 1264 return 0; 1265 1266 #endif /* ! STAGE1_5 */ 1267 } 1268 1269 /* 1270 * This performs a "mount" on the current device, both drive and partition 1271 * number. 1272 */ 1273 1274 int 1275 open_device (void) 1276 { 1277 if (open_partition ()) 1278 attempt_mount (); 1279 1280 if (errnum != ERR_NONE) 1281 return 0; 1282 1283 return 1; 1284 } 1285 1286 1287 #ifndef STAGE1_5 1288 int 1289 set_bootdev (int hdbias) 1290 { 1291 int i, j; 1292 1293 /* Copy the boot partition information to 0x7be-0x7fd for chain-loading. */ 1294 if ((saved_drive & 0x80) && cur_part_addr) 1295 { 1296 if (rawread (saved_drive, cur_part_offset, 1297 0, SECTOR_SIZE, (char *) SCRATCHADDR)) 1298 { 1299 char *dst, *src; 1300 1301 /* Need only the partition table. 1302 XXX: We cannot use grub_memmove because BOOT_PART_TABLE 1303 (0x07be) is less than 0x1000. */ 1304 dst = (char *) BOOT_PART_TABLE; 1305 src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET; 1306 while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH) 1307 *dst++ = *src++; 1308 1309 /* Set the active flag of the booted partition. */ 1310 for (i = 0; i < 4; i++) 1311 PC_SLICE_FLAG (BOOT_PART_TABLE, i) = 0; 1312 1313 *((unsigned char *) cur_part_addr) = PC_SLICE_FLAG_BOOTABLE; 1314 boot_part_addr = cur_part_addr; 1315 } 1316 else 1317 return 0; 1318 } 1319 1320 /* 1321 * Set BSD boot device. 1322 */ 1323 i = (saved_partition >> 16) + 2; 1324 if (saved_partition == 0xFFFFFF) 1325 i = 1; 1326 else if ((saved_partition >> 16) == 0xFF) 1327 i = 0; 1328 1329 /* FIXME: extremely evil hack!!! */ 1330 j = 2; 1331 if (saved_drive & 0x80) 1332 j = bsd_evil_hack; 1333 1334 return MAKEBOOTDEV (j, (i >> 4), (i & 0xF), 1335 ((saved_drive - hdbias) & 0x7F), 1336 ((saved_partition >> 8) & 0xFF)); 1337 } 1338 #endif /* STAGE1_5 */ 1339 1340 1341 static char * 1342 setup_part (char *filename) 1343 { 1344 #ifdef STAGE1_5 1345 1346 if (! (filename = set_device (filename))) 1347 { 1348 current_drive = GRUB_INVALID_DRIVE; 1349 return 0; 1350 } 1351 1352 # ifndef NO_BLOCK_FILES 1353 if (*filename != '/') 1354 open_partition (); 1355 else 1356 # endif /* ! NO_BLOCK_FILES */ 1357 open_device (); 1358 1359 #else /* ! STAGE1_5 */ 1360 1361 if (*filename == '(') 1362 { 1363 if ((filename = set_device (filename)) == 0) 1364 { 1365 current_drive = GRUB_INVALID_DRIVE; 1366 return 0; 1367 } 1368 # ifndef NO_BLOCK_FILES 1369 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1370 open_partition (); 1371 else 1372 # endif /* ! NO_BLOCK_FILES */ 1373 open_device (); 1374 } 1375 else if (saved_drive != current_drive 1376 || saved_partition != current_partition 1377 || (*filename == '/' && fsys_type == NUM_FSYS) 1378 || buf_drive == -1) 1379 { 1380 current_drive = saved_drive; 1381 current_partition = saved_partition; 1382 /* allow for the error case of "no filesystem" after the partition 1383 is found. This makes block files work fine on no filesystem */ 1384 # ifndef NO_BLOCK_FILES 1385 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1386 open_partition (); 1387 else 1388 # endif /* ! NO_BLOCK_FILES */ 1389 open_device (); 1390 } 1391 1392 #endif /* ! STAGE1_5 */ 1393 1394 if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT)) 1395 return 0; 1396 else 1397 errnum = 0; 1398 1399 #ifndef STAGE1_5 1400 if (!sane_partition ()) 1401 return 0; 1402 #endif 1403 1404 return filename; 1405 } 1406 1407 1408 #ifndef STAGE1_5 1409 /* 1410 * This prints the filesystem type or gives relevant information. 1411 */ 1412 1413 void 1414 print_fsys_type (void) 1415 { 1416 if (! do_completion) 1417 { 1418 grub_printf (" Filesystem type "); 1419 1420 if (fsys_type != NUM_FSYS) 1421 grub_printf ("is %s, ", fsys_table[fsys_type].name); 1422 else 1423 grub_printf ("unknown, "); 1424 1425 if (current_partition == 0xFFFFFF) 1426 grub_printf ("using whole disk\n"); 1427 else 1428 grub_printf ("partition type 0x%x\n", current_slice & 0xFF); 1429 } 1430 } 1431 #endif /* STAGE1_5 */ 1432 1433 #ifndef STAGE1_5 1434 /* If DO_COMPLETION is true, just print NAME. Otherwise save the unique 1435 part into UNIQUE_STRING. */ 1436 void 1437 print_a_completion (char *name) 1438 { 1439 /* If NAME is "." or "..", do not count it. */ 1440 if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0) 1441 return; 1442 1443 if (do_completion) 1444 { 1445 char *buf = unique_string; 1446 1447 if (! unique) 1448 while ((*buf++ = *name++)) 1449 ; 1450 else 1451 { 1452 while (*buf && (*buf == *name)) 1453 { 1454 buf++; 1455 name++; 1456 } 1457 /* mismatch, strip it. */ 1458 *buf = '\0'; 1459 } 1460 } 1461 else 1462 grub_printf (" %s", name); 1463 1464 unique++; 1465 } 1466 1467 /* 1468 * This lists the possible completions of a device string, filename, or 1469 * any sane combination of the two. 1470 */ 1471 1472 int 1473 print_completions (int is_filename, int is_completion) 1474 { 1475 char *buf = (char *) COMPLETION_BUF; 1476 char *ptr = buf; 1477 1478 unique_string = (char *) UNIQUE_BUF; 1479 *unique_string = 0; 1480 unique = 0; 1481 do_completion = is_completion; 1482 1483 if (! is_filename) 1484 { 1485 /* Print the completions of builtin commands. */ 1486 struct builtin **builtin; 1487 1488 if (! is_completion) 1489 grub_printf (" Possible commands are:"); 1490 1491 for (builtin = builtin_table; (*builtin); builtin++) 1492 { 1493 /* If *BUILTIN cannot be run in the command-line, skip it. */ 1494 if (! ((*builtin)->flags & BUILTIN_CMDLINE)) 1495 continue; 1496 1497 if (substring (buf, (*builtin)->name) <= 0) 1498 print_a_completion ((*builtin)->name); 1499 } 1500 1501 if (is_completion && *unique_string) 1502 { 1503 if (unique == 1) 1504 { 1505 char *u = unique_string + grub_strlen (unique_string); 1506 1507 *u++ = ' '; 1508 *u = 0; 1509 } 1510 1511 grub_strcpy (buf, unique_string); 1512 } 1513 1514 if (! is_completion) 1515 grub_putchar ('\n'); 1516 1517 print_error (); 1518 do_completion = 0; 1519 if (errnum) 1520 return -1; 1521 else 1522 return unique - 1; 1523 } 1524 1525 if (*buf == '/' || (ptr = set_device (buf)) || incomplete) 1526 { 1527 errnum = 0; 1528 1529 if (*buf == '(' && (incomplete || ! *ptr)) 1530 { 1531 if (! part_choice) 1532 { 1533 /* disk completions */ 1534 int disk_no, i, j; 1535 struct geometry geom; 1536 1537 if (! is_completion) 1538 grub_printf (" Possible disks are: "); 1539 1540 if (!ptr 1541 || *(ptr-1) != 'd' 1542 #ifdef SUPPORT_NETBOOT 1543 || *(ptr-2) != 'n' 1544 #endif /* SUPPORT_NETBOOT */ 1545 || *(ptr-2) != 'c') 1546 { 1547 for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0); 1548 i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2); 1549 i++) 1550 { 1551 for (j = 0; j < 8; j++) 1552 { 1553 disk_no = (i * 0x80) + j; 1554 if ((disk_choice || disk_no == current_drive) 1555 && ! get_diskinfo (disk_no, &geom)) 1556 { 1557 char dev_name[8]; 1558 1559 grub_sprintf (dev_name, "%cd%d", i ? 'h':'f', j); 1560 print_a_completion (dev_name); 1561 } 1562 } 1563 } 1564 } 1565 1566 if (cdrom_drive != GRUB_INVALID_DRIVE 1567 && (disk_choice || cdrom_drive == current_drive) 1568 && (!ptr 1569 || *(ptr-1) == '(' 1570 || (*(ptr-1) == 'd' && *(ptr-2) == 'c'))) 1571 print_a_completion ("cd"); 1572 1573 # ifdef SUPPORT_NETBOOT 1574 if (network_ready 1575 && (disk_choice || NETWORK_DRIVE == current_drive) 1576 && (!ptr 1577 || *(ptr-1) == '(' 1578 || (*(ptr-1) == 'd' && *(ptr-2) == 'n'))) 1579 print_a_completion ("nd"); 1580 # endif /* SUPPORT_NETBOOT */ 1581 1582 if (is_completion && *unique_string) 1583 { 1584 ptr = buf; 1585 while (*ptr != '(') 1586 ptr--; 1587 ptr++; 1588 grub_strcpy (ptr, unique_string); 1589 if (unique == 1) 1590 { 1591 ptr += grub_strlen (ptr); 1592 if (*unique_string == 'h') 1593 { 1594 *ptr++ = ','; 1595 *ptr = 0; 1596 } 1597 else 1598 { 1599 *ptr++ = ')'; 1600 *ptr = 0; 1601 } 1602 } 1603 } 1604 1605 if (! is_completion) 1606 grub_putchar ('\n'); 1607 } 1608 else 1609 { 1610 /* partition completions */ 1611 if (part_choice == PART_CHOSEN 1612 && open_partition () 1613 && ! IS_PC_SLICE_TYPE_BSD (current_slice)) 1614 { 1615 unique = 1; 1616 ptr = buf + grub_strlen (buf); 1617 if (*(ptr - 1) != ')') 1618 { 1619 *ptr++ = ')'; 1620 *ptr = 0; 1621 } 1622 } 1623 else 1624 { 1625 if (! is_completion) 1626 grub_printf (" Possible partitions are:\n"); 1627 real_open_partition (1); 1628 1629 if (is_completion && *unique_string) 1630 { 1631 ptr = buf; 1632 while (*ptr++ != ',') 1633 ; 1634 grub_strcpy (ptr, unique_string); 1635 } 1636 } 1637 } 1638 } 1639 else if (ptr && *ptr == '/') 1640 { 1641 /* filename completions */ 1642 if (! is_completion) 1643 grub_printf (" Possible files are:"); 1644 1645 dir (buf); 1646 1647 if (is_completion && *unique_string) 1648 { 1649 ptr += grub_strlen (ptr); 1650 while (*ptr != '/') 1651 ptr--; 1652 ptr++; 1653 1654 grub_strcpy (ptr, unique_string); 1655 1656 if (unique == 1) 1657 { 1658 ptr += grub_strlen (unique_string); 1659 1660 /* Check if the file UNIQUE_STRING is a directory. */ 1661 *ptr = '/'; 1662 *(ptr + 1) = 0; 1663 1664 dir (buf); 1665 1666 /* Restore the original unique value. */ 1667 unique = 1; 1668 1669 if (errnum) 1670 { 1671 /* Regular file */ 1672 errnum = 0; 1673 *ptr = ' '; 1674 *(ptr + 1) = 0; 1675 } 1676 } 1677 } 1678 1679 if (! is_completion) 1680 grub_putchar ('\n'); 1681 } 1682 else 1683 errnum = ERR_BAD_FILENAME; 1684 } 1685 1686 print_error (); 1687 do_completion = 0; 1688 if (errnum) 1689 return -1; 1690 else 1691 return unique - 1; 1692 } 1693 #endif /* STAGE1_5 */ 1694 1695 1696 /* 1697 * This is the generic file open function. 1698 */ 1699 1700 int 1701 grub_open (char *filename) 1702 { 1703 #ifndef NO_DECOMPRESSION 1704 compressed_file = 0; 1705 #endif /* NO_DECOMPRESSION */ 1706 1707 /* if any "dir" function uses/sets filepos, it must 1708 set it to zero before returning if opening a file! */ 1709 filepos = 0; 1710 1711 if (!(filename = setup_part (filename))) 1712 return 0; 1713 1714 #ifndef NO_BLOCK_FILES 1715 block_file = 0; 1716 #endif /* NO_BLOCK_FILES */ 1717 1718 /* This accounts for partial filesystem implementations. */ 1719 fsmax = MAXINT; 1720 1721 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1722 { 1723 #ifndef NO_BLOCK_FILES 1724 char *ptr = filename; 1725 int tmp, list_addr = BLK_BLKLIST_START; 1726 filemax = 0; 1727 1728 while (list_addr < BLK_MAX_ADDR) 1729 { 1730 tmp = 0; 1731 safe_parse_maxint (&ptr, &tmp); 1732 errnum = 0; 1733 1734 if (*ptr != '+') 1735 { 1736 if ((*ptr && *ptr != '/' && !isspace (*ptr)) 1737 || tmp == 0 || tmp > filemax) 1738 errnum = ERR_BAD_FILENAME; 1739 else 1740 filemax = tmp; 1741 1742 break; 1743 } 1744 1745 /* since we use the same filesystem buffer, mark it to 1746 be remounted */ 1747 fsys_type = NUM_FSYS; 1748 1749 BLK_BLKSTART (list_addr) = tmp; 1750 ptr++; 1751 1752 if (!safe_parse_maxint (&ptr, &tmp) 1753 || tmp == 0 1754 || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr))) 1755 { 1756 errnum = ERR_BAD_FILENAME; 1757 break; 1758 } 1759 1760 BLK_BLKLENGTH (list_addr) = tmp; 1761 1762 filemax += (tmp * SECTOR_SIZE); 1763 list_addr += BLK_BLKLIST_INC_VAL; 1764 1765 if (*ptr != ',') 1766 break; 1767 1768 ptr++; 1769 } 1770 1771 if (list_addr < BLK_MAX_ADDR && ptr != filename && !errnum) 1772 { 1773 block_file = 1; 1774 BLK_CUR_FILEPOS = 0; 1775 BLK_CUR_BLKLIST = BLK_BLKLIST_START; 1776 BLK_CUR_BLKNUM = 0; 1777 1778 #ifndef NO_DECOMPRESSION 1779 return gunzip_test_header (); 1780 #else /* NO_DECOMPRESSION */ 1781 return 1; 1782 #endif /* NO_DECOMPRESSION */ 1783 } 1784 #else /* NO_BLOCK_FILES */ 1785 errnum = ERR_BAD_FILENAME; 1786 #endif /* NO_BLOCK_FILES */ 1787 } 1788 1789 if (!errnum && fsys_type == NUM_FSYS) 1790 errnum = ERR_FSYS_MOUNT; 1791 1792 # ifndef STAGE1_5 1793 /* set "dir" function to open a file */ 1794 print_possibilities = 0; 1795 # endif 1796 1797 if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename)) 1798 { 1799 #ifndef NO_DECOMPRESSION 1800 return gunzip_test_header (); 1801 #else /* NO_DECOMPRESSION */ 1802 return 1; 1803 #endif /* NO_DECOMPRESSION */ 1804 } 1805 1806 return 0; 1807 } 1808 1809 1810 int 1811 grub_read (char *buf, int len) 1812 { 1813 /* Make sure "filepos" is a sane value */ 1814 if ((filepos < 0) || (filepos > filemax)) 1815 filepos = filemax; 1816 1817 /* Make sure "len" is a sane value */ 1818 if ((len < 0) || (len > (filemax - filepos))) 1819 len = filemax - filepos; 1820 1821 /* if target file position is past the end of 1822 the supported/configured filesize, then 1823 there is an error */ 1824 if (filepos + len > fsmax) 1825 { 1826 errnum = ERR_FILELENGTH; 1827 return 0; 1828 } 1829 1830 #ifndef NO_DECOMPRESSION 1831 if (compressed_file) 1832 return gunzip_read (buf, len); 1833 #endif /* NO_DECOMPRESSION */ 1834 1835 #ifndef NO_BLOCK_FILES 1836 if (block_file) 1837 { 1838 int size, off, ret = 0; 1839 1840 while (len && !errnum) 1841 { 1842 /* we may need to look for the right block in the list(s) */ 1843 if (filepos < BLK_CUR_FILEPOS) 1844 { 1845 BLK_CUR_FILEPOS = 0; 1846 BLK_CUR_BLKLIST = BLK_BLKLIST_START; 1847 BLK_CUR_BLKNUM = 0; 1848 } 1849 1850 /* run BLK_CUR_FILEPOS up to filepos */ 1851 while (filepos > BLK_CUR_FILEPOS) 1852 { 1853 if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1))) 1854 >= SECTOR_SIZE) 1855 { 1856 BLK_CUR_FILEPOS += SECTOR_SIZE; 1857 BLK_CUR_BLKNUM++; 1858 1859 if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST)) 1860 { 1861 BLK_CUR_BLKLIST += BLK_BLKLIST_INC_VAL; 1862 BLK_CUR_BLKNUM = 0; 1863 } 1864 } 1865 else 1866 BLK_CUR_FILEPOS = filepos; 1867 } 1868 1869 off = filepos & (SECTOR_SIZE - 1); 1870 size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM) 1871 * SECTOR_SIZE) - off; 1872 if (size > len) 1873 size = len; 1874 1875 disk_read_func = disk_read_hook; 1876 1877 /* read current block and put it in the right place in memory */ 1878 devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM, 1879 off, size, buf); 1880 1881 disk_read_func = NULL; 1882 1883 len -= size; 1884 filepos += size; 1885 ret += size; 1886 buf += size; 1887 } 1888 1889 if (errnum) 1890 ret = 0; 1891 1892 return ret; 1893 } 1894 #endif /* NO_BLOCK_FILES */ 1895 1896 if (fsys_type == NUM_FSYS) 1897 { 1898 errnum = ERR_FSYS_MOUNT; 1899 return 0; 1900 } 1901 1902 return (*(fsys_table[fsys_type].read_func)) (buf, len); 1903 } 1904 1905 #ifndef STAGE1_5 1906 /* Reposition a file offset. */ 1907 int 1908 grub_seek (int offset) 1909 { 1910 if (offset > filemax || offset < 0) 1911 return -1; 1912 1913 filepos = offset; 1914 return offset; 1915 } 1916 1917 int 1918 dir (char *dirname) 1919 { 1920 #ifndef NO_DECOMPRESSION 1921 compressed_file = 0; 1922 #endif /* NO_DECOMPRESSION */ 1923 1924 if (!(dirname = setup_part (dirname))) 1925 return 0; 1926 1927 if (*dirname != '/') 1928 errnum = ERR_BAD_FILENAME; 1929 1930 if (fsys_type == NUM_FSYS) 1931 errnum = ERR_FSYS_MOUNT; 1932 1933 if (errnum) 1934 return 0; 1935 1936 /* set "dir" function to list completions */ 1937 print_possibilities = 1; 1938 1939 return (*(fsys_table[fsys_type].dir_func)) (dirname); 1940 } 1941 #endif /* STAGE1_5 */ 1942 1943 void 1944 grub_close (void) 1945 { 1946 #ifndef NO_BLOCK_FILES 1947 if (block_file) 1948 return; 1949 #endif /* NO_BLOCK_FILES */ 1950 1951 if (fsys_table[fsys_type].close_func != 0) 1952 (*(fsys_table[fsys_type].close_func)) (); 1953 } 1954