/* * misc/bxmount.c * $Id: bxmount.c,v 1.0 2005/02/20 Mathis Exp $ * * Print partitions or mount a specific partition of a harddisk image. * */ #include #include #include #include #include #include #include #include #include "config.h" #include #define SECTOR_SIZE 512 const struct PartitionType { unsigned char number; char *name; } partition_type[]; extern const unsigned int partition_type_count; char *rcsid = "$Id: bxmount.c,v 1.0 2005/02/20 Mathis Exp $"; char *divider = "========================================================================"; /* stolen from main.cc */ void bx_center_print (FILE *file, char *line, int maxwidth) { int imax; int i; imax = (maxwidth - strlen(line)) >> 1; for (i=0; i> 1) / 1024; if(size > (4 * 1024)) fprintf(stderr, "%6uG\t", (size / 1024)); else fprintf(stderr, "%6uM\t", size); for(c = 0; c < partition_type_count; c++) if(partition_type[c].number == type) break; if(c >= partition_type_count) fprintf(stderr, "%02X (unknown)", type); else fprintf(stderr, "%s", partition_type[c].name); fprintf(stderr, "\n"); } return 0; } int dismount_partition(char *mount_directory) { char *argv[] = { "umount", mount_directory, NULL }; return execvp("umount", argv); } int mount_partition(char *filename, unsigned int partition_number, char *mount_directory) { FILE *image; size_t ret = 0; Bit8u data[SECTOR_SIZE]; char arg[50]; char *argv[] = { "mount", filename, mount_directory, "-o", arg, NULL }; image = fopen(filename, "rb"); if(image == NULL) { fprintf(stderr, "%s: %s.\n", filename, strerror(errno)); return -1; } ret = fread(data, SECTOR_SIZE, 1, image); if(ret != 1) { fprintf(stderr, "%s: %s.\n", filename, strerror(errno)); return -1; } fclose(image); if((data[0x1FE] != 0x55) && (data[0x1FE] != 0xAA)) { fprintf(stderr, "%s: No partition-table detected.\n", filename); return -2; } { // calculate byte offset of partition Bit8u *p = &data[0x1BE + (16 * partition_number)]; Bit32u start_sector = *((Bit32u *)&p[0x08]); unsigned int byte[8] = { 0, 0, 0, 0 }; char buffer[40000]; int n; if(start_sector == 0) { fprintf(stderr, "%s:%d: No partition entry. Aborted.\n", filename, partition_number); return -2; } for(n = 0; n < 8; n++) { byte[n] += ((start_sector & 0xFF) * SECTOR_SIZE); if(byte[n] > 0xFF) byte[n + 1] = (byte[n] >> 8); byte[n] &= 0xFF; start_sector >>= 8; } sprintf(arg, "loop=/dev/loop3,offset=0x"); for(n = 7; n >= 0; --n) { sprintf(buffer, "%02X", byte[n]); strcat(arg, buffer); } } return execvp("mount", argv); } int print_usage() { print_banner(); fprintf(stderr, "Usage:\n" "bxmount -p [filename]\n" "\tPrints the partition table of the harddisk image [filename].\n" "sudo bxmount -m [filename] [partition #1-4] [directory]\n" "\tMounts [partition #] of the harddisk image [filename] to [directory].\n" "sudo bxmount -u [directory]\n" "\tDismounts [directory].\n" "\n" "Example:\n" "sudo bxmount -m /path/to/harddisk.img 1 /mnt\n" "\tMounts partition #1 in harddisk image '/path/to/harddisk.img'\n" "\tto directory '/mnt'. If you are not logged in as root, you will be\n" "\tprompted for the superuser password.\n" "\n" "Note:\n" "\tYou must be logged in as root, because only the superuser can mount.\n" "\tOr use the prefix sudo.\n" ); return 0; } int main(int argc, char *argv[]) { if((argc == 3) && (strcmp(argv[1], "-p") == 0)) return print_partitiontable(argv[2]); else if((argc == 3) && (strcmp(argv[1], "-u") == 0)) return dismount_partition(argv[2]); else if((argc == 5) && (strcmp(argv[1], "-m") == 0)) { unsigned int n; sscanf(argv[3], "%d", &n); if(n == 0) return print_usage(); return mount_partition(argv[2], (n - 1), argv[4]); } else return print_usage(); return 0; } const struct PartitionType partition_type[] = { { 0x00, "Empty" }, { 0x01, "FAT12" }, { 0x02, "XENIX root" }, { 0x03, "XENIX usr" }, { 0x04, "FAT16 <32M" }, { 0x05, "Extended" }, { 0x06, "FAT16" }, { 0x07, "HPFS/NTFS" }, { 0x08, "AIX" }, { 0x09, "AIX bootable" }, { 0x0a, "OS/2 Boot Manager" }, { 0x0b, "W95 FAT32" }, { 0x0c, "W95 FAT32 (LBA)" }, { 0x0e, "W95 FAT16 (LBA)" }, { 0x0f, "W95 Ext'd (LBA)" }, { 0x10, "OPUS" }, { 0x11, "Hidden FAT12" }, { 0x12, "Compaq diagnostics" }, { 0x14, "Hidden FAT16 <3M" }, { 0x16, "Hidden FAT16" }, { 0x17, "Hidden HPFS/NTF" }, { 0x18, "AST SmartSleep" }, { 0x1b, "Hidden W95 FAT32" }, { 0x1c, "Hidden W95 FAT32" }, { 0x1e, "Hidden W95 FAT16" }, { 0x24, "NEC DOS" }, { 0x39, "Plan 9" }, { 0x3c, "PartitionMagic" }, { 0x40, "Venix 80286" }, { 0x41, "PPC PReP Boot" }, { 0x42, "SFS" }, { 0x4d, "QNX4.x" }, { 0x4e, "QNX4.x 2nd part" }, { 0x4f, "QNX4.x 3rd part" }, { 0x50, "OnTrack DM" }, { 0x51, "OnTrack DM6 Aux" }, { 0x52, "CP/M" }, { 0x53, "OnTrack DM6 Aux" }, { 0x54, "OnTrackDM6" }, { 0x55, "EZ-Drive" }, { 0x56, "Golden Bow" }, { 0x5c, "Priam Edisk" }, { 0x61, "SpeedStor" }, { 0x63, "GNU HURD or System V" }, { 0x64, "Novell Netware" }, { 0x65, "Novell Netware" }, { 0x70, "DiskSecure Multi-Boot" }, { 0x75, "PC/IX" }, { 0x80, "Old Minix" }, { 0x81, "Minix / old Linux" }, { 0x82, "Linux swap / Solaris" }, { 0x83, "Linux ext2/3" }, { 0x84, "OS/2 hidden C:" }, { 0x85, "Linux extended" }, { 0x86, "NTFS volume set" }, { 0x87, "NTFS volume set" }, { 0x8e, "Linux LVM" }, { 0x93, "Amoeba" }, { 0x94, "Amoeba BBT" }, { 0x9f, "BSD/OS" }, { 0xa0, "IBM Thinkpad high" }, { 0xa5, "FreeBSD" }, { 0xa6, "OpenBSD" }, { 0xa7, "NeXTSTEP" }, { 0xa8, "Darwin UFS" }, { 0xa9, "NetBSD" }, { 0xab, "Darwin boot" }, { 0xb7, "BSDI fs" }, { 0xb8, "BSDI swap" }, { 0xbb, "Boot Wizard hidden" }, { 0xbe, "Solaris boot" }, { 0xc1, "DRDOS/sec (FAT-12)" }, { 0xc4, "DRDOS/sec (FAT-16)" }, { 0xc6, "DRDOS/sec (FAT-32)" }, { 0xc7, "Syrinx" }, { 0xda, "Non-FS data" }, { 0xdb, "CP/M / CTOS" }, { 0xde, "Dell Utility" }, { 0xdf, "BootIt" }, { 0xe1, "DOS access" }, { 0xe3, "DOS R/O" }, { 0xe4, "SpeedStor" }, { 0xeb, "BeOS fs" }, { 0xee, "EFI GPT" }, { 0xef, "EFI (FAT-12/16/32)" }, { 0xf0, "Linux/PA-RISC boot" }, { 0xf1, "SpeedStor" }, { 0xf4, "SpeedStor" }, { 0xf2, "DOS secondary" }, { 0xfd, "Linux raid auto" }, { 0xfe, "LANstep" }, { 0xff, "BBT" } }; const unsigned int partition_type_count = (sizeof(partition_type) / sizeof(struct PartitionType));