/* * * (c) 2004 Laurent Vivier * */ #include #include #include #include #include #include #include #include #include #include "libemile.h" #define EMILE_MAX_DISK 16 #define EMILE_MAX_DEVNAME 16 typedef char device_name_t[EMILE_MAX_DEVNAME]; extern int verbose; static void print_size(int nb_blocks, int block_size) { int B, GB, MB, kB; B = (nb_blocks * block_size) % 1024; if (block_size > 1024) kB = nb_blocks * (block_size / 1024); else kB = nb_blocks / (1024 / block_size); MB = kB / 1024; kB = kB % 1024; GB = MB / 1024; MB = MB % 1024; if (GB) printf("%d.%03d GB", GB, MB * 1000 / 1024); else if (MB) printf("%d.%03d MB", MB, kB * 1000 / 1024); else printf("%d.%03d kB", kB, B * 1000 / 1024); } static int emile_scanbus(device_name_t devices[EMILE_MAX_DISK]) { int i,j; int fd; device_name_t dev; j = 0; /* scan SCSI disks */ for(i = 0; (i < EMILE_MAX_DISK) && (j < EMILE_MAX_DISK); i++) { sprintf(dev, "/dev/sd%c", 'a' + i); fd = open(dev, O_RDONLY); if (fd == -1) break; close(fd); strncpy(devices[j++], dev, EMILE_MAX_DEVNAME); } /* scan ATA disks: EMILE doesn't manage them, but this * allows to have all information on all disks */ for(i = 0; (i < EMILE_MAX_DISK) && (j < EMILE_MAX_DISK); i++) { sprintf(dev, "/dev/hd%c", 'a' + i); fd = open(dev, O_RDONLY); if (fd == -1) break; close(fd); strncpy(devices[j++], dev, EMILE_MAX_DEVNAME); } return j; } void scanbus(void) { emile_map_t* map; device_name_t devices[EMILE_MAX_DISK]; int count; int i; int j; int boottype; char bootblock[BOOTBLOCK_SIZE]; count = emile_scanbus(devices); if (count == 0) { if (errno == EACCES) { fprintf(stderr, "ERROR: cannot access to devices (you should try as root...)\n"); return; } printf("No disk found\n"); } for (i = 0; i < count; i++) { int block_size, block_count; printf("%s:", devices[i]); map = emile_map_open(devices[i], O_RDONLY); emile_map_geometry(map, &block_size, &block_count); if (verbose) { printf(" block size: %d, blocks number: %d (", block_size, block_count); print_size(block_count, block_size); printf(")\n"); } else putchar('\n'); if (map == NULL) { printf("\t\n"); continue; } if (!emile_map_is_valid(map)) { printf("\t\n"); continue; } if (emile_map_get_driver_number(map) > 0) printf(" Drivers\n"); for (j = 0; j < emile_map_get_driver_number(map); j++) { int block, size, type, part; emile_map_get_driver_info(map, j, &block, &size, &type); printf(" %d: base: %d size: %d type: %d", j, block * block_size / 512, size * block_size / 512 , type); part = emile_map_seek_driver_partition(map, block * block_size / 512 ); if (part == -1) printf(" \n"); else { emile_map_read(map, part); printf(" <%d: %s [%s]>\n", part + 1, emile_map_get_partition_name(map), emile_map_get_partition_type(map)); } } printf(" Partitions\n"); for (j = 0; j < emile_map_get_number(map); j++) { emile_map_read(map, j); if (emile_map_partition_is_startup(map)) printf(" --> "); else printf(" "); printf("%s%-2d: ", devices[i], j + 1); printf("%16s [%-16s] ", emile_map_get_partition_name(map), emile_map_get_partition_type(map)); emile_map_bootblock_read(map, bootblock); boottype = emile_map_bootblock_get_type(bootblock); switch(boottype) { case INVALID_BOOTBLOCK: break; case APPLE_BOOTBLOCK: printf(" "); break; case EMILE_BOOTBLOCK: printf(" "); break; default: printf(" "); break; } if (emile_map_partition_is_bootable(map)) printf(" *\n"); else putchar('\n'); if (verbose) { int start, count; emile_map_get_partition_geometry(map, &start, &count); printf(" base: %d, count: %d (", start, count); print_size(count, block_size); printf(")\n"); printf(" flags: 0x%08x\n", emile_map_partition_get_flags(map)); } } emile_map_close(map); } }