📄 fdisk.c
字号:
/* * fdisk version 3.0 - aeb - 950813 * rewrited by netboy <zhonghua.wu@sw-linux.com> - 2003-06-23 * * Copyright (C) 1995 Andries E. Brouwer (aeb@cwi.nl) * * This program is free software. You can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation: either Version 1 * or (at your option) any later version. * */#include <stdio.h>#include <stdlib.h> /* atoi, free */#include <unistd.h> /* read, write */#include <fcntl.h> /* O_RDWR */#include <errno.h> /* ERANGE */#include <string.h> /* index() */#include <ctype.h>#include <sys/ioctl.h>#include <linux/unistd.h> /* _syscall */#include <linux/hdreg.h> /* HDIO_GETGEO */#include "autousb.h"/* * A. About seeking *//* * sseek: seek to specified sector - return 0 on failure * * For >4GB disks lseek needs a > 32bit arg, and we have to use llseek. * On the other hand, a 32 bit sector number is OK until 2TB. * The routines _llseek and sseek below are the only ones that * know about the loff_t type. */static _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);int sseek(char *dev, unsigned int fd, unsigned long s) { loff_t in, out; in = ((loff_t) s << 9); out = 1; if (_llseek (fd, in>>32, in & 0xffffffff, &out, SEEK_SET) != 0) { DBG("seek error on %s - cannot seek to %lu\n", dev, s); return 0; } if (in != out) { DBG("seek error: wanted 0x%08x%08x, got 0x%08x%08x\n", (uint)(in>>32), (uint)(in & 0xffffffff), (uint)(out>>32), (uint)(out & 0xffffffff)); return 0; } return 1;}/* * B. About sectors *//* * We preserve all sectors read in a chain - some of these will * have to be modified and written back. */struct sector { struct sector *next; unsigned long sectornumber; int to_be_written; char data[512];} *sectorhead;void free_sectors(void) { struct sector *s; while (sectorhead) { s = sectorhead; sectorhead = s->next; free(s); }}struct sector *get_sector(char *dev, int fd, unsigned long sno) { struct sector *s; //sectorhead = (struct sector *)malloc(sizeof(struct sector)); for(s = sectorhead; s; s = s->next) if(s->sectornumber == sno) return s; if (!sseek(dev, fd, sno)) return 0; if (!(s = (struct sector *) malloc(sizeof(struct sector)))) DBG("out of memory - giving up\n"); if (read(fd, s->data, sizeof(s->data)) != sizeof(s->data)) { DBG("read error on %s - cannot read sector %lu\n", dev, sno); free(s); return 0; } s->next = sectorhead; sectorhead = s; s->sectornumber = sno; s->to_be_written = 0; return s;}#if 1int msdos_signature (struct sector *s) { if (*(unsigned short *) (s->data + 0x1fe) != 0xaa55) { DBG("ERROR: sector %lu does not have an msdos signature\n", s->sectornumber); return 0; } return 1;}#endiftypedef struct { unsigned char h,s,c; } chs; /* has some c bits in s *//* * D. About system Ids */#define EMPTY_PARTITION 0#define EXTENDED_PARTITION 5#define EXT_PAR_LBA 15#define DM6_PARTITION 0x54#define EZD_PARTITION 0x55#define DM6_AUX1PARTITION 0x51#define DM6_AUX3PARTITION 0x53#define LINUX_SWAP 0x82#define LINUX_NATIVE 0x83#define LINUX_EXTENDED 0x85int is_extended(unsigned char type){ return (type == EXTENDED_PARTITION || type == LINUX_EXTENDED || type == EXT_PAR_LBA);}struct partition { unsigned char bootable; /* 0 or 0x80 */ chs begin_chs; unsigned char sys_type; chs end_chs; unsigned int start_sect; /* starting sector counting from 0 */ unsigned int nr_sects; /* nr of sectors in partition */};struct part_desc { unsigned long start; unsigned long size; unsigned long sector, offset; /* disk location of this info */ struct partition p; struct part_desc *ep; /* extended partition containing this one */};struct disk_desc { struct part_desc partitions[128]; int partno;} oldp;/* find Linux name of this partition, assuming that it will have a name */int index_to_linux(int pno, struct disk_desc *z) { int i, ct = 1; struct part_desc *p = &(z->partitions[0]); for (i=0; i<pno; i++,p++) if(i < 4 || (p->size > 0 && !is_extended(p->p.sys_type))) ct++; return ct;}int linux_to_index(int lpno, struct disk_desc *z) { int i, ct = 0; struct part_desc *p = &(z->partitions[0]); for (i=0; i<z->partno && ct < lpno; i++,p++) if((i < 4 || (p->size > 0 && !is_extended(p->p.sys_type))) && ++ct == lpno) return i; return -1;}static void out_partitions(char *dev, struct disk_desc *z, struct par_info *pi){ int pno, pno1, lpno; struct part_desc *p = NULL; if (z->partno == 0){ DBG("No partitions found\n"); pi[0].type = 0; } else { for(pno=0; pno < z->partno; pno++) { p = &(z->partitions[pno]); if (p->p.sys_type == 0) continue; pno1 = p - &(z->partitions[0]); /* our index */ lpno = index_to_linux(pno1, z); /* name of next one that has a name */ if(pno1 == linux_to_index(lpno, z)){ /* was that us? */ sprintf(pi->dev, "%8s%d", dev, lpno); pi->type = p->p.sys_type; DBG("pi->dev: %s %x\n", pi->dev, pi->type); pi++; } } (pi)->type = 0; } DBG("%s %d\n", __FUNCTION__, __LINE__);}static void extended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) { struct partition *p; struct sector *s; unsigned long start, here, next; int i, moretodo = 1; struct part_desc *partitions = &(z->partitions[0]); int pno = z->partno; here = start = ep->start; while (moretodo) { moretodo = 0; if (!(s = get_sector(dev, fd, here))) break; if (!msdos_signature(s)) break; p = (struct partition *) (s->data + 0x1be); if (pno+4 >= SIZE(z->partitions)) { DBG("too many partitions - ignoring those past nr (%d)\n", pno-1); break; } next = 0; for (i=0; i<4; i++,p++) { partitions[pno].sector = here; partitions[pno].offset = ((char *) p) - s->data; partitions[pno].ep = ep; if (is_extended(p->sys_type)) { if (next) DBG("tree of partitions?\n"); partitions[pno].start = next = start + p->start_sect; moretodo = 1; } else { partitions[pno].start = here + p->start_sect; } partitions[pno].size = p->nr_sects; partitions[pno++].p = *p; } here = next; } z->partno = pno;}static void get_partitions(char *dev, int fd, struct disk_desc *z){ int i; struct partition *pt; struct sector *s; struct part_desc *partitions = &(z->partitions[0]); int pno = z->partno; int start = 0; z->partno = 0; if (!(s = get_sector(dev, fd, start))) return; if (!msdos_signature(s)) return; pt = (struct partition *) (s->data + 0x1be); for (pno=0; pno<4; pno++) { partitions[pno].sector = start; partitions[pno].offset = ((char *) pt) - s->data; partitions[pno].start = start + pt->start_sect; partitions[pno].size = pt->nr_sects; partitions[pno].ep = 0; partitions[pno].p = *pt++; } z->partno = pno; for (i=0; i<4; i++){ if (is_extended(partitions[i].p.sys_type)) { if (!partitions[i].size) { DBG("strange..., an extended partition of size 0?\n"); continue; } extended_partition(dev, fd, &partitions[i], z); } }}int get_par(char *dev, struct par_info *p){ int fd; struct disk_desc *z; //struct par_info *tmp; //tmp = p; free_sectors(); z = (struct disk_desc *) malloc(sizeof(struct disk_desc)); DBG("DEV: %s\n", dev); fd = open(dev, O_RDONLY); if (fd < 0) return (-1); get_partitions(dev, fd, z); out_partitions(dev, z, p); free(z); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -