/*
|
/*
|
* shpart.c -- show partitions on a disk
|
* shpart.c -- show partitions on a disk
|
*/
|
*/
|
|
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
#include <stdarg.h>
|
#include <stdarg.h>
|
|
|
|
|
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
|
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
|
#define DESCR_SIZE 20
|
#define DESCR_SIZE 20
|
|
|
|
|
typedef struct {
|
typedef struct {
|
unsigned long type;
|
unsigned int type;
|
unsigned long start;
|
unsigned int start;
|
unsigned long size;
|
unsigned int size;
|
char descr[DESCR_SIZE];
|
char descr[DESCR_SIZE];
|
} PartEntry;
|
} PartEntry;
|
|
|
PartEntry ptr[NPE];
|
PartEntry ptr[NPE];
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
void error(char *fmt, ...) {
|
void error(char *fmt, ...) {
|
va_list ap;
|
va_list ap;
|
|
|
va_start(ap, fmt);
|
va_start(ap, fmt);
|
printf("Error: ");
|
printf("Error: ");
|
vprintf(fmt, ap);
|
vprintf(fmt, ap);
|
printf("\n");
|
printf("\n");
|
va_end(ap);
|
va_end(ap);
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
unsigned long getNumber(unsigned char *p) {
|
unsigned int getNumber(unsigned char *p) {
|
return (unsigned long) *(p + 0) << 24 |
|
return (unsigned int) *(p + 0) << 24 |
|
(unsigned long) *(p + 1) << 16 |
|
(unsigned int) *(p + 1) << 16 |
|
(unsigned long) *(p + 2) << 8 |
|
(unsigned int) *(p + 2) << 8 |
|
(unsigned long) *(p + 3) << 0;
|
(unsigned int) *(p + 3) << 0;
|
}
|
}
|
|
|
|
|
void convertPartitionTable(PartEntry *e, int n) {
|
void convertPartitionTable(PartEntry *e, int n) {
|
int i;
|
int i;
|
unsigned char *p;
|
unsigned char *p;
|
|
|
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
p = (unsigned char *) &e[i];
|
p = (unsigned char *) &e[i];
|
e[i].type = getNumber(p + 0);
|
e[i].type = getNumber(p + 0);
|
e[i].start = getNumber(p + 4);
|
e[i].start = getNumber(p + 4);
|
e[i].size = getNumber(p + 8);
|
e[i].size = getNumber(p + 8);
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
char *diskName;
|
char *diskName;
|
FILE *disk;
|
FILE *disk;
|
unsigned long diskSize;
|
unsigned long diskSize;
|
unsigned long numSectors;
|
unsigned int numSectors;
|
unsigned long partLast;
|
unsigned int partLast;
|
int i, j;
|
int i, j;
|
char c;
|
char c;
|
|
|
/* check command line arguments */
|
/* check command line arguments */
|
if (argc != 2) {
|
if (argc != 2) {
|
printf("Usage: %s <disk image file>\n", argv[0]);
|
printf("Usage: %s <disk image file>\n", argv[0]);
|
exit(1);
|
exit(1);
|
}
|
}
|
diskName = argv[1];
|
diskName = argv[1];
|
/* determine disk size */
|
/* determine disk size */
|
disk = fopen(diskName, "rb");
|
disk = fopen(diskName, "rb");
|
if (disk == NULL) {
|
if (disk == NULL) {
|
error("cannot open disk image '%s'", diskName);
|
error("cannot open disk image '%s'", diskName);
|
}
|
}
|
fseek(disk, 0, SEEK_END);
|
fseek(disk, 0, SEEK_END);
|
diskSize = ftell(disk);
|
diskSize = ftell(disk);
|
numSectors = diskSize / SECTOR_SIZE;
|
numSectors = diskSize / SECTOR_SIZE;
|
fclose(disk);
|
fclose(disk);
|
printf("Disk '%s' has %lu (0x%lX) sectors.\n",
|
printf("Disk '%s' has %u (0x%X) sectors.\n",
|
diskName, numSectors, numSectors);
|
diskName, numSectors, numSectors);
|
if (numSectors < 32) {
|
if (numSectors < 32) {
|
error("disk is too small");
|
error("disk is too small");
|
}
|
}
|
if (diskSize % SECTOR_SIZE != 0) {
|
if (diskSize % SECTOR_SIZE != 0) {
|
printf("Warning: disk size is not a multiple of sector size!\n");
|
printf("Warning: disk size is not a multiple of sector size!\n");
|
}
|
}
|
/* read partition table record */
|
/* read partition table record */
|
disk = fopen(diskName, "rb");
|
disk = fopen(diskName, "rb");
|
if (disk == NULL) {
|
if (disk == NULL) {
|
error("cannot open disk image '%s'", diskName);
|
error("cannot open disk image '%s'", diskName);
|
}
|
}
|
fseek(disk, 1 * SECTOR_SIZE, SEEK_SET);
|
fseek(disk, 1 * SECTOR_SIZE, SEEK_SET);
|
if (fread(ptr, 1, SECTOR_SIZE, disk) != SECTOR_SIZE) {
|
if (fread(ptr, 1, SECTOR_SIZE, disk) != SECTOR_SIZE) {
|
error("cannot read partition table from disk image '%s'", diskName);
|
error("cannot read partition table from disk image '%s'", diskName);
|
}
|
}
|
fclose(disk);
|
fclose(disk);
|
convertPartitionTable(ptr, NPE);
|
convertPartitionTable(ptr, NPE);
|
/* show partition table */
|
/* show partition table */
|
printf("Partitions:\n");
|
printf("Partitions:\n");
|
printf(" # b type start last size description\n");
|
printf(" # b type start last size description\n");
|
for (i = 0; i < NPE; i++) {
|
for (i = 0; i < NPE; i++) {
|
if (ptr[i].type != 0) {
|
if (ptr[i].type != 0) {
|
partLast = ptr[i].start + ptr[i].size - 1;
|
partLast = ptr[i].start + ptr[i].size - 1;
|
} else {
|
} else {
|
partLast = 0;
|
partLast = 0;
|
}
|
}
|
printf("%2d %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX ",
|
printf("%2d %s 0x%08X 0x%08X 0x%08X 0x%08X ",
|
i,
|
i,
|
ptr[i].type & 0x80000000 ? "*" : " ",
|
ptr[i].type & 0x80000000 ? "*" : " ",
|
ptr[i].type & 0x7FFFFFFF,
|
ptr[i].type & 0x7FFFFFFF,
|
ptr[i].start,
|
ptr[i].start,
|
partLast,
|
partLast,
|
ptr[i].size);
|
ptr[i].size);
|
for (j = 0; j < DESCR_SIZE; j++) {
|
for (j = 0; j < DESCR_SIZE; j++) {
|
c = ptr[i].descr[j];
|
c = ptr[i].descr[j];
|
if (c == '\0') {
|
if (c == '\0') {
|
break;
|
break;
|
}
|
}
|
if (c >= 0x20 && c < 0x7F) {
|
if (c >= 0x20 && c < 0x7F) {
|
printf("%c", c);
|
printf("%c", c);
|
} else {
|
} else {
|
printf(".");
|
printf(".");
|
}
|
}
|
}
|
}
|
printf("\n");
|
printf("\n");
|
}
|
}
|
/* done */
|
/* done */
|
return 0;
|
return 0;
|
}
|
}
|
|
|