17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5342440ecSPrasad Singamsetty * Common Development and Distribution License (the "License"). 6342440ecSPrasad Singamsetty * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*db92b35aSGary Mills * Copyright (c) 2011 Gary Mills 23*db92b35aSGary Mills * 24342440ecSPrasad Singamsetty * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25342440ecSPrasad Singamsetty * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * fsck_pcfs -- common.c 307c478bd9Sstevel@tonic-gate * All the routines in this file are being swiped directly from 317c478bd9Sstevel@tonic-gate * mkfs_pcfs. Eventually this file should only exist in one place 327c478bd9Sstevel@tonic-gate * and be part of a library that both mkfs and fsck link against. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 367c478bd9Sstevel@tonic-gate #include <unistd.h> 377c478bd9Sstevel@tonic-gate #include <stdlib.h> 387c478bd9Sstevel@tonic-gate #include <libintl.h> 397c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 407c478bd9Sstevel@tonic-gate #include <sys/types.h> 417c478bd9Sstevel@tonic-gate #include <sys/stat.h> 427c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 437c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 447c478bd9Sstevel@tonic-gate #include <sys/fs/pc_fs.h> 457c478bd9Sstevel@tonic-gate #include <sys/fs/pc_dir.h> 467c478bd9Sstevel@tonic-gate #include <sys/fs/pc_label.h> 477c478bd9Sstevel@tonic-gate #include "fsck_pcfs.h" 487c478bd9Sstevel@tonic-gate #include "pcfs_common.h" 497c478bd9Sstevel@tonic-gate #include "pcfs_bpb.h" 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * The assumption here is that _BIG_ENDIAN implies sparc, and 537c478bd9Sstevel@tonic-gate * so in addition to swapping bytes we also have to construct 547c478bd9Sstevel@tonic-gate * packed structures by hand to avoid bus errors due to improperly 557c478bd9Sstevel@tonic-gate * aligned pointers. 567c478bd9Sstevel@tonic-gate */ 577c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 587c478bd9Sstevel@tonic-gate void swap_pack_grab32bpb(bpb_t *wbpb, struct _boot_sector *bsp); 597c478bd9Sstevel@tonic-gate void swap_pack_grabbpb(bpb_t *wbpb, struct _boot_sector *bsp); 607c478bd9Sstevel@tonic-gate #endif /* _BIG_ENDIAN */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* 637c478bd9Sstevel@tonic-gate * Global variables related to input questions 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate extern int AlwaysYes; 667c478bd9Sstevel@tonic-gate extern int AlwaysNo; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * store_16_bits 707c478bd9Sstevel@tonic-gate * Save the lower 16 bits of a 32 bit value (v) into the provided 717c478bd9Sstevel@tonic-gate * buffer (pointed at by *bp), and increment the buffer pointer 727c478bd9Sstevel@tonic-gate * as well. This way the routine can be called multiple times in 737c478bd9Sstevel@tonic-gate * succession to fill buffers. The value is stored in little-endian 747c478bd9Sstevel@tonic-gate * order. 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate void 777c478bd9Sstevel@tonic-gate store_16_bits(uchar_t **bp, uint32_t v) 787c478bd9Sstevel@tonic-gate { 797c478bd9Sstevel@tonic-gate uchar_t *l = *bp; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate *l++ = v & 0xff; 827c478bd9Sstevel@tonic-gate *l = (v >> 8) & 0xff; 837c478bd9Sstevel@tonic-gate *bp += 2; 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate void 877c478bd9Sstevel@tonic-gate read_16_bits(uchar_t *bp, uint32_t *value) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate *value = *bp++; 907c478bd9Sstevel@tonic-gate *value += *bp << 8; 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate /* 947c478bd9Sstevel@tonic-gate * store_32_bits 957c478bd9Sstevel@tonic-gate * Save the 32 bit value (v) into the provided buffer (pointed 967c478bd9Sstevel@tonic-gate * at by *bp), and increment the buffer pointer as well. This way 977c478bd9Sstevel@tonic-gate * the routine can be called multiple times in succession to fill 987c478bd9Sstevel@tonic-gate * buffers. The value is stored in little-endian order. 997c478bd9Sstevel@tonic-gate */ 1007c478bd9Sstevel@tonic-gate void 1017c478bd9Sstevel@tonic-gate store_32_bits(uchar_t **bp, uint32_t v) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate uchar_t *l = *bp; 1047c478bd9Sstevel@tonic-gate int b; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate for (b = 0; b < 4; b++) { 1077c478bd9Sstevel@tonic-gate *l++ = v & 0xff; 1087c478bd9Sstevel@tonic-gate v = v >> 8; 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate *bp += 4; 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate void 1147c478bd9Sstevel@tonic-gate read_32_bits(uchar_t *bp, uint32_t *value) 1157c478bd9Sstevel@tonic-gate { 1167c478bd9Sstevel@tonic-gate *value = *bp++; 1177c478bd9Sstevel@tonic-gate *value += *bp++ << 8; 1187c478bd9Sstevel@tonic-gate *value += *bp++ << 16; 1197c478bd9Sstevel@tonic-gate *value += *bp++ << 24; 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * dump_bytes -- display bytes as hex numbers. 1247c478bd9Sstevel@tonic-gate * b is the pointer to the byte buffer 1257c478bd9Sstevel@tonic-gate * n is the number of bytes in the buffer 1267c478bd9Sstevel@tonic-gate */ 1277c478bd9Sstevel@tonic-gate /* Note: BPL = bytes to display per line */ 1287c478bd9Sstevel@tonic-gate #define BPL 16 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate void 1317c478bd9Sstevel@tonic-gate dump_bytes(uchar_t *buf, int n) 1327c478bd9Sstevel@tonic-gate { 1337c478bd9Sstevel@tonic-gate int printedCount; 1347c478bd9Sstevel@tonic-gate int countdown = n; 1357c478bd9Sstevel@tonic-gate int countup = 0; 1367c478bd9Sstevel@tonic-gate int offset = 0; 1377c478bd9Sstevel@tonic-gate int byte; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* Display offset, 16 bytes per line, and printable ascii version */ 1407c478bd9Sstevel@tonic-gate while (countdown > 0) { 1417c478bd9Sstevel@tonic-gate printedCount = 0; 1427c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n%06x: ", offset); 1437c478bd9Sstevel@tonic-gate /* 1447c478bd9Sstevel@tonic-gate * Print Hex value of characters in columns on left 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate for (byte = 0; byte < BPL; byte++) { 1477c478bd9Sstevel@tonic-gate if (countup + byte < n) { 1487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1497c478bd9Sstevel@tonic-gate "%02x ", (buf[countup + byte] & 0xff)); 1507c478bd9Sstevel@tonic-gate printedCount++; 1517c478bd9Sstevel@tonic-gate } else { 1527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, " "); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate /* 1567c478bd9Sstevel@tonic-gate * Right side has the printable character or '.' for 1577c478bd9Sstevel@tonic-gate * unprintable for each column of the left. 1587c478bd9Sstevel@tonic-gate */ 1597c478bd9Sstevel@tonic-gate for (byte = 0; byte < BPL; byte++) { 1607c478bd9Sstevel@tonic-gate if ((countup + byte < n) && 1617c478bd9Sstevel@tonic-gate ((buf[countup + byte] >= ' ') && 1627c478bd9Sstevel@tonic-gate (buf[countup + byte] <= '~'))) { 1637c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%c", 1647c478bd9Sstevel@tonic-gate buf[countup + byte]); 1657c478bd9Sstevel@tonic-gate } else { 1667c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "."); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate countup += printedCount; 1707c478bd9Sstevel@tonic-gate offset += printedCount; 1717c478bd9Sstevel@tonic-gate countdown -= printedCount; 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n\n"); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * header_for_dump -- display simple header over what will be output. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate void 1807c478bd9Sstevel@tonic-gate header_for_dump(void) 1817c478bd9Sstevel@tonic-gate { 1827c478bd9Sstevel@tonic-gate int byte; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n "); 1857c478bd9Sstevel@tonic-gate for (byte = 0; byte < BPL; byte++) 1867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%02x ", byte); 1877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n "); 1887c478bd9Sstevel@tonic-gate byte = 3*BPL; 1897c478bd9Sstevel@tonic-gate while (byte-- > 0) 1907c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "-"); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* 1947c478bd9Sstevel@tonic-gate * We are basically (incorrectly) assuming that if you aren't running 1957c478bd9Sstevel@tonic-gate * on x86 the BPB has to be packed by hand AND that the bytes must 1967c478bd9Sstevel@tonic-gate * be swapped. One or both of these assumptions may one day be invalid. 1977c478bd9Sstevel@tonic-gate * (if they aren't already :-)) 1987c478bd9Sstevel@tonic-gate */ 1997c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 2007c478bd9Sstevel@tonic-gate /* 2017c478bd9Sstevel@tonic-gate * swap_pack_grab{32}bpb 2027c478bd9Sstevel@tonic-gate * If not on an x86 we assume the structures making up the bpb 2037c478bd9Sstevel@tonic-gate * were not packed and that longs and shorts need to be byte swapped 2047c478bd9Sstevel@tonic-gate * (we've kept everything in host order up until now). A new architecture 2057c478bd9Sstevel@tonic-gate * might not need to swap or might not need to pack, in which case 2067c478bd9Sstevel@tonic-gate * new routines will have to be written. Of course if an architecture 2077c478bd9Sstevel@tonic-gate * supports both packing and little-endian host order, it can follow the 2087c478bd9Sstevel@tonic-gate * same path as the x86 code. 2097c478bd9Sstevel@tonic-gate */ 2107c478bd9Sstevel@tonic-gate void 2117c478bd9Sstevel@tonic-gate swap_pack_grabbpb(bpb_t *wbpb, struct _boot_sector *bsp) 2127c478bd9Sstevel@tonic-gate { 2137c478bd9Sstevel@tonic-gate uchar_t *grabp; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate grabp = (uchar_t *)&(bsp->bs_filler[ORIG_BPB_START_INDEX]); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.bytes_per_sector))[1] = *grabp++; 2187c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.bytes_per_sector))[0] = *grabp++; 2197c478bd9Sstevel@tonic-gate wbpb->bpb.sectors_per_cluster = *grabp++; 2207c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.resv_sectors))[1] = *grabp++; 2217c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.resv_sectors))[0] = *grabp++; 2227c478bd9Sstevel@tonic-gate wbpb->bpb.num_fats = *grabp++; 2237c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.num_root_entries))[1] = *grabp++; 2247c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.num_root_entries))[0] = *grabp++; 2257c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_volume))[1] = *grabp++; 2267c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_volume))[0] = *grabp++; 2277c478bd9Sstevel@tonic-gate wbpb->bpb.media = *grabp++; 2287c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_per_fat))[1] = *grabp++; 2297c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_per_fat))[0] = *grabp++; 2307c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_per_track))[1] = *grabp++; 2317c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_per_track))[0] = *grabp++; 2327c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.heads))[1] = *grabp++; 2337c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.heads))[0] = *grabp++; 2347c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.hidden_sectors))[3] = *grabp++; 2357c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.hidden_sectors))[2] = *grabp++; 2367c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.hidden_sectors))[1] = *grabp++; 2377c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.hidden_sectors))[0] = *grabp++; 2387c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_logical_volume))[3] = *grabp++; 2397c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_logical_volume))[2] = *grabp++; 2407c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_logical_volume))[1] = *grabp++; 2417c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb.sectors_in_logical_volume))[0] = *grabp++; 2427c478bd9Sstevel@tonic-gate wbpb->ebpb.phys_drive_num = *grabp++; 2437c478bd9Sstevel@tonic-gate wbpb->ebpb.reserved = *grabp++; 2447c478bd9Sstevel@tonic-gate wbpb->ebpb.ext_signature = *grabp++; 2457c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->ebpb.volume_id))[3] = *grabp++; 2467c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->ebpb.volume_id))[2] = *grabp++; 2477c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->ebpb.volume_id))[1] = *grabp++; 2487c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->ebpb.volume_id))[0] = *grabp++; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate (void) strncpy((char *)wbpb->ebpb.volume_label, (char *)grabp, 11); 2517c478bd9Sstevel@tonic-gate grabp += 11; 2527c478bd9Sstevel@tonic-gate (void) strncpy((char *)wbpb->ebpb.type, (char *)grabp, 8); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate void 2567c478bd9Sstevel@tonic-gate swap_pack_grab32bpb(bpb_t *wbpb, struct _boot_sector *bsp) 2577c478bd9Sstevel@tonic-gate { 2587c478bd9Sstevel@tonic-gate uchar_t *grabp; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate grabp = (uchar_t *)&(bsp->bs_filler[BPB_32_START_INDEX]); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.big_sectors_per_fat))[3] = *grabp++; 2637c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.big_sectors_per_fat))[2] = *grabp++; 2647c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.big_sectors_per_fat))[1] = *grabp++; 2657c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.big_sectors_per_fat))[0] = *grabp++; 2667c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.ext_flags))[1] = *grabp++; 2677c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.ext_flags))[0] = *grabp++; 2687c478bd9Sstevel@tonic-gate wbpb->bpb32.fs_vers_lo = *grabp++; 2697c478bd9Sstevel@tonic-gate wbpb->bpb32.fs_vers_hi = *grabp++; 2707c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.root_dir_clust))[3] = *grabp++; 2717c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.root_dir_clust))[2] = *grabp++; 2727c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.root_dir_clust))[1] = *grabp++; 2737c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.root_dir_clust))[0] = *grabp++; 2747c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.fsinfosec))[1] = *grabp++; 2757c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.fsinfosec))[0] = *grabp++; 2767c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.backupboot))[1] = *grabp++; 2777c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.backupboot))[0] = *grabp++; 2787c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[0]))[1] = *grabp++; 2797c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[0]))[0] = *grabp++; 2807c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[1]))[1] = *grabp++; 2817c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[1]))[0] = *grabp++; 2827c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[2]))[1] = *grabp++; 2837c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[2]))[0] = *grabp++; 2847c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[3]))[1] = *grabp++; 2857c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[3]))[0] = *grabp++; 2867c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[4]))[1] = *grabp++; 2877c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[4]))[0] = *grabp++; 2887c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[5]))[1] = *grabp++; 2897c478bd9Sstevel@tonic-gate ((uchar_t *)&(wbpb->bpb32.reserved[5]))[0] = *grabp++; 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate #endif /* _BIG_ENDIAN */ 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate int 2947c478bd9Sstevel@tonic-gate yes(void) 2957c478bd9Sstevel@tonic-gate { 2967c478bd9Sstevel@tonic-gate char *affirmative = gettext("yY"); 2977c478bd9Sstevel@tonic-gate char *a = affirmative; 2987c478bd9Sstevel@tonic-gate char input[80]; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if (AlwaysYes) { 3017c478bd9Sstevel@tonic-gate (void) printf("y\n"); 3027c478bd9Sstevel@tonic-gate return (1); 3037c478bd9Sstevel@tonic-gate } else if (AlwaysNo) { 3047c478bd9Sstevel@tonic-gate (void) printf("n\n"); 3057c478bd9Sstevel@tonic-gate return (0); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate if (fgets(input, sizeof (input), stdin) == NULL) { 3087c478bd9Sstevel@tonic-gate AlwaysNo = 1; 3097c478bd9Sstevel@tonic-gate (void) printf("n\n"); 3107c478bd9Sstevel@tonic-gate return (0); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate while (*a) { 3137c478bd9Sstevel@tonic-gate if (input[0] == (int)*a) 3147c478bd9Sstevel@tonic-gate break; 3157c478bd9Sstevel@tonic-gate a++; 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate return ((int)*a); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate char * 3217c478bd9Sstevel@tonic-gate stat_actual_disk(char *diskname, struct stat *info, char **suffix) 3227c478bd9Sstevel@tonic-gate { 3237c478bd9Sstevel@tonic-gate char *actualdisk; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate if (stat(diskname, info)) { 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Device named on command line doesn't exist. That 3287c478bd9Sstevel@tonic-gate * probably means there is a partition-specifying 3297c478bd9Sstevel@tonic-gate * suffix attached to the actual disk name. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate if ((actualdisk = strdup(diskname)) == NULL) { 3327c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3337c478bd9Sstevel@tonic-gate gettext("Out of memory for disk name.\n")); 3347c478bd9Sstevel@tonic-gate exit(2); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate if ((*suffix = strchr(actualdisk, ':')) != NULL) { 3377c478bd9Sstevel@tonic-gate **suffix = '\0'; 3387c478bd9Sstevel@tonic-gate (*suffix)++; 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate if (stat(actualdisk, info)) { 3427c478bd9Sstevel@tonic-gate perror(actualdisk); 3437c478bd9Sstevel@tonic-gate exit(2); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate } else { 3467c478bd9Sstevel@tonic-gate if ((actualdisk = strdup(diskname)) == NULL) { 3477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3487c478bd9Sstevel@tonic-gate gettext("Out of memory for disk name.\n")); 3497c478bd9Sstevel@tonic-gate exit(2); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate return (actualdisk); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate extern void usage(void); 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate void 3597c478bd9Sstevel@tonic-gate bad_arg(char *option) 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3627c478bd9Sstevel@tonic-gate gettext("Unrecognized option -o %s.\n"), option); 3637c478bd9Sstevel@tonic-gate usage(); 3647c478bd9Sstevel@tonic-gate exit(2); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate void 3687c478bd9Sstevel@tonic-gate missing_arg(char *option) 3697c478bd9Sstevel@tonic-gate { 3707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3717c478bd9Sstevel@tonic-gate gettext("Option %s requires a value.\n"), option); 3727c478bd9Sstevel@tonic-gate usage(); 3737c478bd9Sstevel@tonic-gate exit(3); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate static int 3777c478bd9Sstevel@tonic-gate parse_drvnum(char *pn) 3787c478bd9Sstevel@tonic-gate { 3797c478bd9Sstevel@tonic-gate int drvnum; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate /* 3827c478bd9Sstevel@tonic-gate * Determine logical drive to seek after. 3837c478bd9Sstevel@tonic-gate */ 3847c478bd9Sstevel@tonic-gate if ((strlen(pn) == 1) && ((*pn >= 'c') && (*pn <= 'z'))) { 3857c478bd9Sstevel@tonic-gate drvnum = *pn - 'c' + 1; 3867c478bd9Sstevel@tonic-gate } else if ((*pn >= '0') && (*pn <= '9')) { 3877c478bd9Sstevel@tonic-gate char *d; 3887c478bd9Sstevel@tonic-gate int v = 0; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate d = pn; 3917c478bd9Sstevel@tonic-gate while ((*d != '\0') && (*d >= '0') && (*d <= '9')) { 3927c478bd9Sstevel@tonic-gate v *= 10; 3937c478bd9Sstevel@tonic-gate v += *d - '0'; 3947c478bd9Sstevel@tonic-gate d++; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate if ((*d != '\0') || (v > 24)) { 3977c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3987c478bd9Sstevel@tonic-gate gettext("%s: bogus logical drive specification.\n"), 3997c478bd9Sstevel@tonic-gate pn); 4007c478bd9Sstevel@tonic-gate return (-1); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate drvnum = v; 4037c478bd9Sstevel@tonic-gate } else if (strcmp(pn, "boot") == 0) { 4047c478bd9Sstevel@tonic-gate drvnum = 99; 4057c478bd9Sstevel@tonic-gate } else { 4067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4077c478bd9Sstevel@tonic-gate gettext("%s: bogus logical drive specification.\n"), pn); 4087c478bd9Sstevel@tonic-gate return (-1); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate return (drvnum); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * isDosDrive() 4167c478bd9Sstevel@tonic-gate * Boolean function. Give it the systid field for an fdisk partition 4177c478bd9Sstevel@tonic-gate * and it decides if that's a systid that describes a DOS drive. We 4187c478bd9Sstevel@tonic-gate * use systid values defined in sys/dktp/fdisk.h. 4197c478bd9Sstevel@tonic-gate */ 4207c478bd9Sstevel@tonic-gate static int 4217c478bd9Sstevel@tonic-gate isDosDrive(uchar_t checkMe) 4227c478bd9Sstevel@tonic-gate { 4237c478bd9Sstevel@tonic-gate return ((checkMe == DOSOS12) || (checkMe == DOSOS16) || 4247c478bd9Sstevel@tonic-gate (checkMe == DOSHUGE) || (checkMe == FDISK_WINDOWS) || 4257c478bd9Sstevel@tonic-gate (checkMe == FDISK_EXT_WIN) || (checkMe == FDISK_FAT95) || 4267c478bd9Sstevel@tonic-gate (checkMe == DIAGPART)); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * isDosExtended() 4317c478bd9Sstevel@tonic-gate * Boolean function. Give it the systid field for an fdisk partition 4327c478bd9Sstevel@tonic-gate * and it decides if that's a systid that describes an extended DOS 4337c478bd9Sstevel@tonic-gate * partition. 4347c478bd9Sstevel@tonic-gate */ 4357c478bd9Sstevel@tonic-gate static int 4367c478bd9Sstevel@tonic-gate isDosExtended(uchar_t checkMe) 4377c478bd9Sstevel@tonic-gate { 4387c478bd9Sstevel@tonic-gate return ((checkMe == EXTDOS) || (checkMe == FDISK_EXTLBA)); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * isBootPart() 4437c478bd9Sstevel@tonic-gate * Boolean function. Give it the systid field for an fdisk partition 4447c478bd9Sstevel@tonic-gate * and it decides if that's a systid that describes a Solaris boot 4457c478bd9Sstevel@tonic-gate * partition. 4467c478bd9Sstevel@tonic-gate */ 4477c478bd9Sstevel@tonic-gate static int 4487c478bd9Sstevel@tonic-gate isBootPart(uchar_t checkMe) 4497c478bd9Sstevel@tonic-gate { 4507c478bd9Sstevel@tonic-gate return (checkMe == X86BOOT); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate off64_t 4547c478bd9Sstevel@tonic-gate findPartitionOffset(int fd, char *ldrive) 4557c478bd9Sstevel@tonic-gate { 4567c478bd9Sstevel@tonic-gate struct ipart part[FD_NUMPART]; 4577c478bd9Sstevel@tonic-gate struct mboot extmboot; 4587c478bd9Sstevel@tonic-gate struct mboot mb; 459342440ecSPrasad Singamsetty diskaddr_t xstartsect; 4607c478bd9Sstevel@tonic-gate off64_t nextseek = 0; 4617c478bd9Sstevel@tonic-gate off64_t lastseek = 0; 4627c478bd9Sstevel@tonic-gate off64_t found = 0; 4637c478bd9Sstevel@tonic-gate off64_t error = -1; 4647c478bd9Sstevel@tonic-gate int logicalDriveCount = 0; 4657c478bd9Sstevel@tonic-gate int extendedPart = -1; 4667c478bd9Sstevel@tonic-gate int primaryPart = -1; 4677c478bd9Sstevel@tonic-gate int bootPart = -1; 468342440ecSPrasad Singamsetty uint32_t xnumsect = 0; 4697c478bd9Sstevel@tonic-gate int drvnum; 4707c478bd9Sstevel@tonic-gate int driveIndex; 4717c478bd9Sstevel@tonic-gate int i; 4727c478bd9Sstevel@tonic-gate /* 4737c478bd9Sstevel@tonic-gate * Count of drives in the current extended partition's 4747c478bd9Sstevel@tonic-gate * FDISK table, and indexes of the drives themselves. 4757c478bd9Sstevel@tonic-gate */ 4767c478bd9Sstevel@tonic-gate int extndDrives[FD_NUMPART]; 4777c478bd9Sstevel@tonic-gate int numDrives = 0; 4787c478bd9Sstevel@tonic-gate /* 4797c478bd9Sstevel@tonic-gate * Count of drives (beyond primary) in master boot record's 4807c478bd9Sstevel@tonic-gate * FDISK table, and indexes of the drives themselves. 4817c478bd9Sstevel@tonic-gate */ 4827c478bd9Sstevel@tonic-gate int extraDrives[FD_NUMPART]; 4837c478bd9Sstevel@tonic-gate int numExtraDrives = 0; 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate if ((drvnum = parse_drvnum(ldrive)) < 0) 4867c478bd9Sstevel@tonic-gate return (error); 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate if (read(fd, &mb, sizeof (mb)) != sizeof (mb)) { 4897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4907c478bd9Sstevel@tonic-gate gettext("Couldn't read a Master Boot Record\n")); 4917c478bd9Sstevel@tonic-gate return (error); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate if (ltohs(mb.signature) != BOOTSECSIG) { 4957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4967c478bd9Sstevel@tonic-gate gettext("Bad signature on master boot record (%x)\n"), 4977c478bd9Sstevel@tonic-gate ltohs(mb.signature)); 4987c478bd9Sstevel@tonic-gate return (error); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /* 5027c478bd9Sstevel@tonic-gate * Copy partition table into memory 5037c478bd9Sstevel@tonic-gate */ 5047c478bd9Sstevel@tonic-gate (void) memcpy(part, mb.parts, sizeof (part)); 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * Get a summary of what is in the Master FDISK table. 5087c478bd9Sstevel@tonic-gate * Normally we expect to find one partition marked as a DOS drive. 5097c478bd9Sstevel@tonic-gate * This partition is the one Windows calls the primary dos partition. 5107c478bd9Sstevel@tonic-gate * If the machine has any logical drives then we also expect 5117c478bd9Sstevel@tonic-gate * to find a partition marked as an extended DOS partition. 5127c478bd9Sstevel@tonic-gate * 5137c478bd9Sstevel@tonic-gate * Sometimes we'll find multiple partitions marked as DOS drives. 5147c478bd9Sstevel@tonic-gate * The Solaris fdisk program allows these partitions 5157c478bd9Sstevel@tonic-gate * to be created, but Windows fdisk no longer does. We still need 5167c478bd9Sstevel@tonic-gate * to support these, though, since Windows does. We also need to fix 5177c478bd9Sstevel@tonic-gate * our fdisk to behave like the Windows version. 5187c478bd9Sstevel@tonic-gate * 5197c478bd9Sstevel@tonic-gate * It turns out that some off-the-shelf media have *only* an 5207c478bd9Sstevel@tonic-gate * Extended partition, so we need to deal with that case as 5217c478bd9Sstevel@tonic-gate * well. 5227c478bd9Sstevel@tonic-gate * 5237c478bd9Sstevel@tonic-gate * Only a single (the first) Extended or Boot Partition will 5247c478bd9Sstevel@tonic-gate * be recognized. Any others will be ignored. 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 5277c478bd9Sstevel@tonic-gate if (isDosDrive(part[i].systid)) { 5287c478bd9Sstevel@tonic-gate if (primaryPart < 0) { 5297c478bd9Sstevel@tonic-gate logicalDriveCount++; 5307c478bd9Sstevel@tonic-gate primaryPart = i; 5317c478bd9Sstevel@tonic-gate } else { 5327c478bd9Sstevel@tonic-gate extraDrives[numExtraDrives++] = i; 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate continue; 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate if ((extendedPart < 0) && isDosExtended(part[i].systid)) { 5377c478bd9Sstevel@tonic-gate extendedPart = i; 5387c478bd9Sstevel@tonic-gate continue; 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate if ((bootPart < 0) && isBootPart(part[i].systid)) { 5417c478bd9Sstevel@tonic-gate bootPart = i; 5427c478bd9Sstevel@tonic-gate continue; 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate if (drvnum == BOOT_PARTITION_DRIVE) { 5477c478bd9Sstevel@tonic-gate if (bootPart < 0) { 5487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5497c478bd9Sstevel@tonic-gate gettext("No boot partition found on drive\n")); 5507c478bd9Sstevel@tonic-gate return (error); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate found = ltohi(part[bootPart].relsect) * BPSEC; 5537c478bd9Sstevel@tonic-gate return (found); 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate if (drvnum == PRIMARY_DOS_DRIVE && primaryPart >= 0) { 5577c478bd9Sstevel@tonic-gate found = ltohi(part[primaryPart].relsect) * BPSEC; 5587c478bd9Sstevel@tonic-gate return (found); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate /* 5627c478bd9Sstevel@tonic-gate * We are not looking for the C: drive (or there was no primary 5637c478bd9Sstevel@tonic-gate * drive found), so we had better have an extended partition or 5647c478bd9Sstevel@tonic-gate * extra drives in the Master FDISK table. 5657c478bd9Sstevel@tonic-gate */ 5667c478bd9Sstevel@tonic-gate if ((extendedPart < 0) && (numExtraDrives == 0)) { 5677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5687c478bd9Sstevel@tonic-gate gettext("No such logical drive " 5697c478bd9Sstevel@tonic-gate "(missing extended partition entry)\n")); 5707c478bd9Sstevel@tonic-gate return (error); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate if (extendedPart >= 0) { 5747c478bd9Sstevel@tonic-gate nextseek = xstartsect = ltohi(part[extendedPart].relsect); 5757c478bd9Sstevel@tonic-gate xnumsect = ltohi(part[extendedPart].numsect); 5767c478bd9Sstevel@tonic-gate do { 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * If the seek would not cause us to change 5797c478bd9Sstevel@tonic-gate * position on the drive, then we're out of 5807c478bd9Sstevel@tonic-gate * extended partitions to examine. 5817c478bd9Sstevel@tonic-gate */ 5827c478bd9Sstevel@tonic-gate if (nextseek == lastseek) 5837c478bd9Sstevel@tonic-gate break; 5847c478bd9Sstevel@tonic-gate logicalDriveCount += numDrives; 5857c478bd9Sstevel@tonic-gate /* 5867c478bd9Sstevel@tonic-gate * Seek the next extended partition, and find 5877c478bd9Sstevel@tonic-gate * logical drives within it. 5887c478bd9Sstevel@tonic-gate */ 5897c478bd9Sstevel@tonic-gate if (lseek64(fd, nextseek * BPSEC, SEEK_SET) < 0 || 5907c478bd9Sstevel@tonic-gate read(fd, &extmboot, sizeof (extmboot)) != 5917c478bd9Sstevel@tonic-gate sizeof (extmboot)) { 5927c478bd9Sstevel@tonic-gate perror(gettext("Unable to read extended " 5937c478bd9Sstevel@tonic-gate "partition record")); 5947c478bd9Sstevel@tonic-gate return (error); 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate (void) memcpy(part, extmboot.parts, sizeof (part)); 5977c478bd9Sstevel@tonic-gate lastseek = nextseek; 5987c478bd9Sstevel@tonic-gate if (ltohs(extmboot.signature) != MBB_MAGIC) { 5997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6007c478bd9Sstevel@tonic-gate gettext("Bad signature on " 6017c478bd9Sstevel@tonic-gate "extended partition\n")); 6027c478bd9Sstevel@tonic-gate return (error); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate /* 6057c478bd9Sstevel@tonic-gate * Count up drives, and track where the next 6067c478bd9Sstevel@tonic-gate * extended partition is in case we need it. We 6077c478bd9Sstevel@tonic-gate * are expecting only one extended partition. If 6087c478bd9Sstevel@tonic-gate * there is more than one we'll only go to the 6097c478bd9Sstevel@tonic-gate * first one we see, but warn about ignoring. 6107c478bd9Sstevel@tonic-gate */ 6117c478bd9Sstevel@tonic-gate numDrives = 0; 6127c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 6137c478bd9Sstevel@tonic-gate if (isDosDrive(part[i].systid)) { 6147c478bd9Sstevel@tonic-gate extndDrives[numDrives++] = i; 6157c478bd9Sstevel@tonic-gate continue; 6167c478bd9Sstevel@tonic-gate } else if (isDosExtended(part[i].systid)) { 6177c478bd9Sstevel@tonic-gate if (nextseek != lastseek) { 6187c478bd9Sstevel@tonic-gate /* 6197c478bd9Sstevel@tonic-gate * Already found an extended 6207c478bd9Sstevel@tonic-gate * partition in this table. 6217c478bd9Sstevel@tonic-gate */ 6227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6237c478bd9Sstevel@tonic-gate gettext("WARNING: " 6247c478bd9Sstevel@tonic-gate "Ignoring unexpected " 6257c478bd9Sstevel@tonic-gate "additional extended " 6267c478bd9Sstevel@tonic-gate "partition")); 6277c478bd9Sstevel@tonic-gate continue; 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate nextseek = xstartsect + 6307c478bd9Sstevel@tonic-gate ltohi(part[i].relsect); 6317c478bd9Sstevel@tonic-gate continue; 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate } while (drvnum > logicalDriveCount + numDrives); 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate if (drvnum <= logicalDriveCount + numDrives) { 6377c478bd9Sstevel@tonic-gate /* 6387c478bd9Sstevel@tonic-gate * The number of logical drives we've found thus 6397c478bd9Sstevel@tonic-gate * far is enough to get us to the one we were 6407c478bd9Sstevel@tonic-gate * searching for. 6417c478bd9Sstevel@tonic-gate */ 6427c478bd9Sstevel@tonic-gate driveIndex = logicalDriveCount + numDrives - drvnum; 6437c478bd9Sstevel@tonic-gate found = 6447c478bd9Sstevel@tonic-gate ltohi(part[extndDrives[driveIndex]].relsect) + 6457c478bd9Sstevel@tonic-gate lastseek; 6467c478bd9Sstevel@tonic-gate if (found > (xstartsect + xnumsect)) { 6477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6487c478bd9Sstevel@tonic-gate gettext("Logical drive start sector (%d) " 6497c478bd9Sstevel@tonic-gate "is not within the partition!\n"), found); 6507c478bd9Sstevel@tonic-gate return (error); 6517c478bd9Sstevel@tonic-gate } else { 6527c478bd9Sstevel@tonic-gate found *= BPSEC; 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate return (found); 6557c478bd9Sstevel@tonic-gate } else { 6567c478bd9Sstevel@tonic-gate /* 6577c478bd9Sstevel@tonic-gate * We ran out of extended dos partition 6587c478bd9Sstevel@tonic-gate * drives. The only hope now is to go 6597c478bd9Sstevel@tonic-gate * back to extra drives defined in the master 6607c478bd9Sstevel@tonic-gate * fdisk table. But we overwrote that table 6617c478bd9Sstevel@tonic-gate * already, so we must load it in again. 6627c478bd9Sstevel@tonic-gate */ 6637c478bd9Sstevel@tonic-gate logicalDriveCount += numDrives; 6647c478bd9Sstevel@tonic-gate (void) memcpy(part, mb.parts, sizeof (part)); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate /* 6687c478bd9Sstevel@tonic-gate * Still haven't found the drive, is it an extra 6697c478bd9Sstevel@tonic-gate * drive defined in the main FDISK table? 6707c478bd9Sstevel@tonic-gate */ 6717c478bd9Sstevel@tonic-gate if (drvnum <= logicalDriveCount + numExtraDrives) { 6727c478bd9Sstevel@tonic-gate driveIndex = logicalDriveCount + numExtraDrives - drvnum; 6737c478bd9Sstevel@tonic-gate found = ltohi(part[extraDrives[driveIndex]].relsect) * BPSEC; 6747c478bd9Sstevel@tonic-gate return (found); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate return (error); 6777c478bd9Sstevel@tonic-gate } 678