/* * blockdev.c --- Do various simple block device ioctls from the command line * aeb, 991028 */ #include "blockdata.h" int getsize(int fd, long long *sectors) { int err; long sz; long long b; err = ioctl (fd, BLKGETSIZE, &sz); if (err) return err; err = ioctl(fd, BLKGETSIZE64, &b); if (err || b == 0 || b == sz) *sectors = sz; else *sectors = (b >> 9); return 0; } int get_device_data(char *device, int *blocksize, int *startsector) { int fd; int sizesect, blksize; long long bytes; struct hd_geometry g; fd = open(device, O_RDONLY | O_NONBLOCK); if (fd < 0) { fprintf(stderr, "ERROR: cannot open device '%s'\n", device); return -1; } sizesect = blksize = 0; g.start = 0; int get_geometry = ioctl (fd, HDIO_GETGEO, &g); // FIXME fail silently; valid behavior? if( get_geometry != 0 ) { //fprintf(stderr, "ioctl error on device %s; probably loopback? error=%d\n", device, get_geometry); //do nothing } int ret = -1; if( ioctl (fd, BLKBSZGET, &blksize) == 0 && getsize (fd, &bytes) == 0) { *startsector = g.start; *blocksize = blksize; ret = 0; } else { *startsector = g.start; *blocksize = blksize; ret = -1; } if(fd > 0) close(fd); return ret; } /* * Guillaume Cottenceau (gc@mandrakesoft.com) * * Copyright 2000 Mandrakesoft * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * Portions from Erik Troan (ewt@redhat.com) * * Copyright 1996 Red Hat Software * */ int seek_and_compare(int fd, struct partition_detection_anchor anch) { char buf[500]; size_t count; if (lseek(fd, anch.offset, SEEK_SET) == (off_t)-1) { fprintf(stderr, "seek failed"); return -1; } count = read(fd, buf, strlen(anch.anchor)); if (count != strlen(anch.anchor)) { fprintf(stderr, "read failed"); return -1; } buf[count] = '\0'; if (strcmp(anch.anchor, buf)) return 1; return 0; } char * detect_partition_type(char * dev) { struct partition_detection_info { const char * name; struct partition_detection_anchor anchor0; struct partition_detection_anchor anchor1; struct partition_detection_anchor anchor2; }; struct partition_detection_info partitions_signatures[] = { { "Linux Swap", { 4086, "SWAP-SPACE" }, { 0, NULL }, { 0, NULL } }, { "Linux Swap", { 4086, "SWAPSPACE2" }, { 0, NULL }, { 0, NULL } }, { "Ext3", { 0x45c, "\x0000004" }, { 0, NULL }, { 0, NULL } }, { "Ext2", { 0x438, "\x53\xEF" }, { 0, NULL }, { 0, NULL } }, { "ReiserFS", { 0x10034, "ReIsErFs" }, { 0, NULL }, { 0, NULL } }, { "ReiserFS", { 0x10034, "ReIsEr2Fs" }, { 0, NULL }, { 0, NULL } }, { "XFS", { 0, "XFSB" }, { 0x200, "XAGF" }, { 0x400, "XAGI" } }, { "JFS", { 0x8000, "JFS1" }, { 0, NULL }, { 0, NULL } }, { "NTFS", { 0x1FE, "\x55\xAA" }, { 0x3, "NTFS" }, { 0, NULL } }, { "FAT32", { 0x1FE, "\x55\xAA" }, { 0x52, "FAT32" }, { 0, NULL } }, { "FAT", { 0x1FE, "\x55\xAA" }, { 0x36, "FAT" }, { 0, NULL } }, { "x86 boot sector", { 0x1FE, "\x55\xAA" }, { 0, NULL }, { 0, NULL } }, { "Linux LVM", { 0, "HM\1\0" }, { 0, NULL }, { 0, NULL } } }; int partitions_signatures_nb = sizeof(partitions_signatures) / sizeof(struct partition_detection_info); int i; int fd; char *part_type = NULL; //check it exists /*struct stat statbuf; if (!stat(dev, &statbuf)){ fprintf(stderr, "device does not exist\n"); return NULL; }*/ if ((fd = open(dev, O_RDONLY, 0)) < 0) { fprintf(stderr, "device open failed\n"); return NULL; } for (i=0; i