From: Alan Cox Date: Sun, 28 Dec 2014 23:54:12 +0000 (+0000) Subject: fdisk: Now we are doing PC style partition tables import an fdisk tool X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=b8c3d2ce071a0a5c65ad4a87a5b71f079a20bfc5;p=FUZIX.git fdisk: Now we are doing PC style partition tables import an fdisk tool --- diff --git a/Applications/util/Makefile b/Applications/util/Makefile index f96f5a96..78723255 100644 --- a/Applications/util/Makefile +++ b/Applications/util/Makefile @@ -32,6 +32,7 @@ SRCS = basename.c \ echo.c \ ed.c \ false.c \ + fdisk.c \ fsck.c \ grep.c \ id.c \ diff --git a/Applications/util/fdisk.c b/Applications/util/fdisk.c new file mode 100644 index 00000000..4f384796 --- /dev/null +++ b/Applications/util/fdisk.c @@ -0,0 +1,449 @@ +/* + * fdisk.c Disk partitioning program. + * Copyright (C) 1997 David Murn + * + * This program is distributed under the GNU General Public Licence, and + * as such, may be freely distributed. + * + */ + +#include +#include +#include +#include +#include + +#include "fdisk.h" + +#define isxdigit(x) ( ((x)>='0' && (x)<='9') || ((x)>='A' && (x)<='F') \ + || ((x)>='a' && (x)<='f') ) + +#define die { printf("Usage %s [-l] \n",argv[0]); fflush(stdout); exit(1); } +#define spc ((unsigned long)(geometry.heads*geometry.sectors)) + +static Funcs funcs[] = { + { 'a',"Add partion", add_part }, + { 'b',"Set bootable flag", set_boot }, + { 'd',"Delete partition", del_part }, + { 'l',"List partition types", list_types }, + { 'p',"Print partition table", list_part }, + { 'q',"Quit fdisk", quit }, + { 't',"Set partition type", set_type }, + { 'w',"Write partition table", write_out }, + { '?',"Help", help }, + { 0, NULL, NULL } +}; + +/* Table indexing the valid partition types. + * + * Any value of 'Y' indicates a valid partition type, and + * any other value says otherwise. + * + * The types in this list are those recognised by the fdisk + * command that is distributed with Red Hat Linux 6.2. + */ + +const char partOK[257] = /* '0123456789ABCDEF' */ + + "YYYYYYYYYYYYY.YY" /* 0x */ + "YYY.Y.YYY..YY.Y." /* 1x */ + "....Y..........." /* 2x */ + "............Y..." /* 3x */ + "YYY..........YYY" /* 4x */ + "YYYYYYY.....Y..." /* 5x */ + ".Y.YYY.........." /* 6x */ + "Y....Y.........." /* 7x */ + "YYYYYYYY........" /* 8x */ + "...YY..........." /* 9x */ + "Y....YYY........" /* Ax */ + ".......YY......." /* Bx */ + ".Y..Y.YY........" /* Cx */ + "...........Y...." /* Dx */ + ".Y.YY......Y...." /* Ex */ + ".YY.Y........YYY" /* Fx */ +; + +#define valid(n) (partOK[n] == 'Y') + +void list_types(void) /* FIXME - Should make this more flexible */ +{ + printf( + " 0 Empty 3c PartitionMagic recovery 85 Linux extended\n" + " 1 FAT12 40 Venix 80286 86 NTFS volume set\n" + " 2 XENIX root 41 PPC PReP Boot 87 NTFS volume set\n" + " 3 XENIX usr 42 SFS 93 Amoeba\n" + " 4 FAT16 <32M 4d QNX4.x 94 Amoeba BBT\n" + " 5 Extended 4e QNX4.x 2nd part a0 IBM Thinkpad hibernate\n" + " 6 FAT16 4f QNX4.x 3rd part a5 BSD/386\n" + " 7 HPFS/NTFS 50 OnTrack DM a6 OpenBSD\n" + " 8 AIX 51 OnTrack DM6 Aux1 a7 NeXTSTEP\n" + " 9 AIX bootable 52 CP/M b7 BSDI fs\n" + " a OS/2 Boot Manager 53 OnTrack DM6 Aux3 b8 BSDI swap\n" + " b Win9x FAT32 54 OnTrack DM6 c1 DR-DOS/sec FAT-12\n" + " c Win9x FAT32 (LBA) 55 EZ-Drive c4 DR-DOS/sec FAT-16 <32M\n" + " e Win9x FAT16 (LBA) 56 Golden Bow c6 DR-DOS/sec FAT-16\n" + " f Win9x Extended (LBA) 5c Priam Edisk c7 Syrinx\n" + "10 OPUS 61 SpeedStor db CP/M / CTOS / ...\n" + "11 Hide FAT12 63 GNU HURD or SysV e1 DOS access\n" + "12 Compaq diagnostics 64 Novell Netware 286 e3 DOS R/O\n" + "14 Hide FAT16 <32M 65 Novell Netware 386 e4 SpeedStor\n" + "16 Hide FAT16 70 DiskSecure Multi-Boot eb BeOS fs\n" + "17 Hide HPFS/NTFS 75 PC/IX f1 SpeedStor\n" + "18 AST Windows swapfile 80 ELKS / Old Minix f2 DOS secondary\n" + "1b Hide Win9x FAT32 81 New Minix / Old Linux f4 SpeedStor\n" + "1c Hide Win9x FAT32 (LBA) 82 Linux swap fd Linux raid autodetect\n" + "1e Hide Win9x FAT16 (LBA) 83 New Linux fe LANstep\n" + "24 NEC DOS 84 OS/2 Hide C: ff BBT\n" + ); + fflush(stdout); +} + +void quit(void) +{ + exit(1); +} + +void list_part(void) +{ + if(*dev!=0) + list_partition(NULL); +} + +void add_part(void) +{ + unsigned char pentry[16]; + char buf[8]; + unsigned long tmp; + unsigned char *oset; + int part, scyl, ecyl; + + pentry[0]=0; + printf("Add partition:\n\n"); + for (part=0;part<1 || part>4;) { + printf("Which partition to add(1-4): "); + fflush(stdout); + fgets(buf,8,stdin); + part=atoi(buf); + if (*buf=='\n') + return; + } + + oset=partitiontable+(0x1be)+((part-1)*16); + + printf("geo.cyl=%d\n",geometry.cylinders); + for (scyl=geometry.cylinders+1;scyl<0 || scyl>geometry.cylinders;) { + printf("First cylinder(%d-%d):",0,geometry.cylinders); + fflush(stdout); + fgets(buf,8,stdin); + scyl=atoi(buf); + if (*buf=='\n') + return; + } + + pentry[1]=scyl==0?1:0; + pentry[2]=1+((scyl >> 2) & 0xc0); + pentry[3]=(scyl&0xff); + +#ifdef PART_TYPE + pentry[4]=PART_TYPE; +#else + pentry[4]=0x80; +#endif + + for (ecyl=geometry.cylinders+1;ecylgeometry.cylinders;) { + printf("Ending cylinder(%d-%d):",0,geometry.cylinders); + fflush(stdout); + fgets(buf,8,stdin); + ecyl=atoi(buf); + if(*buf=='\n') + return; + } + + pentry[5]=geometry.heads-1; + pentry[6]=geometry.sectors+((ecyl >> 2) & 0xc0); + pentry[7]=(ecyl&0xff); + + tmp=spc*(unsigned long)scyl; + if (scyl==0) + tmp=(unsigned long)geometry.sectors; + + pentry[11]=(unsigned char)((tmp>>24uL)&0x000000ffuL); + pentry[10]=(unsigned char)((tmp>>16uL)&0x000000ffuL); + pentry[ 9]=(unsigned char)((tmp>> 8uL)&0x000000ffuL); + pentry[ 8]=(unsigned char)((tmp )&0x000000fful); + + tmp=spc*(unsigned long)(ecyl-scyl+1); + if (scyl==0) + tmp-=(unsigned long)geometry.sectors; + + pentry[15]=(unsigned char)((tmp>>24uL)&0x000000ffuL); + pentry[14]=(unsigned char)((tmp>>16uL)&0x000000ffuL); + pentry[13]=(unsigned char)((tmp>> 8uL)&0x000000ffuL); + pentry[12]=(unsigned char)((tmp )&0x000000ffuL); + + printf("Adding partition"); + memcpy(oset,pentry,16); + printf("\n"); + fflush(stdout); +} + +void set_boot(void) +{ + char buf[8]; + int part, a; + + printf("Toggle bootable flag:\n\n"); + for(part=0;part<1 || part>4;) { + printf("Which partition to toggle(1-4): "); + fflush(stdout); + fgets(buf,8,stdin); + part=atoi(buf); + if (*buf=='\n') + return; + } + + a=(0x1ae)+(part*16); + partitiontable[a]=(partitiontable[a]==0x00?0x80:0x00); +} + +int atohex(char *s) +{ + int n, r; + + n = 0; + if (!isxdigit(*s)) + return 256; + while (*s) { + if (*s >= '0' && *s <= '9') + r = *s - '0'; + else if (*s >= 'A' && *s <= 'F') + r = *s - 'A' + 10; + else if (*s >= 'a' && *s <= 'f') + r = *s - 'a' + 10; + else + break; + n = 16 * n + r; + s++; + } + return n; +} + +void set_type(void) /* FIXME - Should make this more flexible */ +{ + char buf[8]; + int part, type, a; + + printf("Set partition type:\n\n"); + for (part=0;part<1 || part>4;) { + printf("Which partition to toggle(1-4): "); + fflush(stdout); + fgets(buf,8,stdin); + part=atoi(buf); + if (*buf=='\n') + return; + } + a=(0x1ae)+(part*16)+4; + type=256; + while (!valid(type)) { + printf("Set partition type (l for list, q to quit): "); + fflush(stdout); + fgets(buf,8,stdin); + if (isxdigit(*buf)) + type=atohex(buf) % 256; + else + switch (*buf) { + + case 'l': + list_types(); + break; + + case 'q': + return; + + default: + printf("Invalid: %c\n", *buf); + break; + } + } + partitiontable[a]=type; +} + +void del_part(void) +{ + char buf[8]; + int part; + + printf("Delete partition:\n\n"); + for (part=0;part<1 || part>4;) { + printf("Which partition to delete(1-4): "); + fflush(stdout); + fgets(buf,8,stdin); + part=atoi(buf); + if (*buf=='\n') + return; + } + printf("Deleting partition %d...",part); + memset(partitiontable+(0x1be)+((part-1)*16),0,16); + printf("Done\n"); + fflush(stdout); +} + +void write_out(void) +{ + int i; + + if (lseek(pFd,0L,SEEK_SET)!=0) + printf("ERROR! Cannot seek to offset 0.\n"); + else { + partitiontable[510] = 0x55; + partitiontable[511] = 0xAA; + if ((i=write(pFd,partitiontable,512))!=512) { + printf("ERROR! Only wrote %d of 512 bytes to the partition table.\n",i); + printf(" Table possibly corrupted.\n"); + } else + printf("Successfully wrote %d bytes to %s\n",i,dev); + } + fflush(stdout); +} + +void help(void) +{ + Funcs *tmp; + + printf("Key Description\n"); + for (tmp=funcs;tmp->cmd;tmp++) + printf("%c %s\n",tmp->cmd,tmp->help); + fflush(stdout); +} + +void list_partition(char *devname) +{ + unsigned char ptbl[512],*partition; + unsigned long seccnt; + int i; + + if (devname!=NULL) { + if ((pFd=open(devname,O_RDONLY))==-1) { + printf("Error opening %s (%d)\n",devname,-pFd); + exit(1); + } + if ((i=read(pFd,ptbl,512))!=512) { + printf("Unable to read first 512 bytes from %s, only read %d bytes\n", + devname,i); + exit(1); + } + } else + memcpy(ptbl,partitiontable,512); + printf(" START END\n"); + printf("Device Boot Head Sector Cylinder Head Sector Cylinder Type Sector count\n\n"); + for (i=0x1be;i<0x1fe;i+=16) { + partition=ptbl+i; /* FIXME /--- gotta be a better way to do this ---\ */ + seccnt= ((unsigned long) partition[15] << 24uL) + \ + ((unsigned long) partition[14] << 16uL) + \ + ((unsigned long) partition[13] << 8uL) + \ + (unsigned long) partition[12]; + if (partition[5]) + printf("%s%d %c %2d %3d %5d %2d %3d %5d %2x %10ld\n", + devname==NULL?dev:devname,1+((i-0x1be)/16), + partition[0]==0?' ':(partition[0]==0x80?'*':'?'), + partition[1], /* Start head */ + partition[2] & 0x3f, /* Start sector */ + partition[3] | ((partition[2] & 0xc0) << 2), /* Start cylinder */ + partition[5], /* End head */ + partition[6] & 0x3f, /* End sector */ + partition[7] | ((partition[6] & 0xc0) << 2), /* End cylinder */ + partition[4], /* Partition type */ + seccnt); /* Sector count */ + } + if (devname!=NULL) + close(pFd); + fflush(stdout); +} + +int main(int argc,char *argv[]) +{ + int i, mode=MODE_EDIT; + + dev[0]=0; + for (i=1;icmd; tmp++) + if (*buf==tmp->cmd) { + tmp->func(); + break; + } + } + } + } + exit(0); +} diff --git a/Applications/util/fdisk.h b/Applications/util/fdisk.h new file mode 100644 index 00000000..6a2177a4 --- /dev/null +++ b/Applications/util/fdisk.h @@ -0,0 +1,33 @@ +#define MODE_EDIT 0 +#define MODE_LIST 1 +#define MODE_SIZE 2 + +#define CMDLEN 8 + +#define DEFAULT_DEV "/dev/hda" + +void quit(void); +void list_part(void); +void del_part(void); +void add_part(void); +void help(void); +void write_out(void); +void list_types(void); +void list_part(void); +void set_boot(void); +void set_type(void); + +void list_partition(char *dev); + +char dev[256]; /* FIXME - should be a #define'd number from header file */ +int pFd; +unsigned char partitiontable[512]; + +typedef struct { + int cmd; + char *help; + void (*func)(); +} Funcs; + +struct hd_geometry geometry; +