📄 pfdisk.c
字号:
/*
* pfdisk - Partition a Fixed DISK
* by Gordon W. Ross, Jan. 1990
*
* See the file "pfdisk.doc" for user instructions.
*
* This program uses a simple, line-oriented interpreter,
* designed for both interactive and non-interactive use.
* To facilitate non-interactive use, the output from the
* 'L' (list partitions) command is carefully arranged so it
* can be used directly as command input. Neat trick, eh?
*/
char *versionString =
"# pfdisk version 1.2 by Gordon W. Ross Aug. 1990\n";
/* These don't really matter. The user is asked to set them. */
#define DEFAULT_CYLS 306
#define DEFAULT_HEADS 4
#define DEFAULT_SECTORS 17
#define PROMPT_STRING "pfdisk> "
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "sysdep.h"
#include "syscodes.h"
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
struct part { /* An entry in the partition table */
uchar active; /* active flag (0x80 or 0) */
uchar b_head; /* begin head */
uchar b_sec; /* sector */
uchar b_cyl; /* cylinder */
uchar sysid; /* system id (see sysid.c) */
uchar e_head; /* end head */
uchar e_sec; /* end sector */
uchar e_cyl; /* end cylinder */
/* These two are just longs, but this way is machine independent. */
uchar lsBeg[4]; /* logical sectors, beginning */
uchar lsLen[4]; /* logical sectors, length */
};
#define LOC_PT 0x1BE
#define LOC_NT 0x180
#define LOC_GWR 0x1A0
#define MAGIC_LOC 0x1FE
#define MAGIC_0 0x55
#define MAGIC_1 0xAA
#define MAX_LINE 80
char buffer[SECSIZE]; /* The boot block buffer */
int bufmod=0; /* buffer modified... */
/* (zero means buffer is unmodified) */
int useNTable; /* boot sector uses name table */
/* device parameters (force someone to set them!) */
unsigned cyls = DEFAULT_CYLS;
unsigned heads = DEFAULT_HEADS;
unsigned sectors = DEFAULT_SECTORS;
char *devname; /* device name */
char cmdline[MAX_LINE];
char filename[80]; /* used by r/w commands */
char *prompt; /* null if no tty input */
/* Some of these strings are used in more than one place.
* For consistency, I put a newline on all of them.
*/
char h_h[] = "? <enter> : Help summary\n";
char h_l[] = "L : List partition table\n";
char h_1[] = "1 id first last name : set partition 1\n";
char h_2[] = "2,3,4 ... (like 1) : set respective partition\n";
char h_a[] = "A n : Activate partition n\n";
char h_g[] = "G cyls heads sectors : set disk Geometry\n";
char h_i[] = "I : list known ID numbers\n";
char h_r[] = "R [optional-file] : Read device (or specified file)\n";
char h_w[] = "W [optional-file] : Write device (or specified file)\n";
char h_q[] = "Q[!] : Quit (! means force)\n";
char * helpTable[] = {
h_h, h_l, h_1, h_2, h_a, h_g, h_i, h_r, h_w, h_q,
"# (All command letters have lower-case equivalents.)\n",
(char *) 0 }; /* This MUST have a zero as the last element */
char *BadArg="Error: bad argument: %s\n";
char *WarnNotSaved =
"Warning, modified partition table not saved.\n";
help()
{
char ** p;
for (p = helpTable; *p; p++)
printf(*p);
}
/* forward declarations */
void checkValidity();
char * setPartition();
char * makeActive();
char * setGeometry();
ulong chs2long();
char * nameID();
int printIDs();
main(argc,argv)
int argc;
char *argv[];
{
char *cmdp; /* points to command word */
char *argp; /* points to command args */
/* check command line args (device name) */
if (argc != 2) {
usage(argv[0]); /* See s-sysname.c */
exit(1);
}
devname = argv[1];
/* Should we prompt? */
prompt = (isatty(fileno(stdin))) ? PROMPT_STRING : (char *) 0;
/* Print version name. */
fputs(versionString, stderr);
/* get disk parameters */
getGeometry(devname,&cyls,&heads,§ors);
/* Get the boot block. */
if (getBBlk(devname, buffer) < 0)
fprintf(stderr,"%s: read failed\n", devname);
checkValidity();
if (prompt) fprintf(stderr,"For help, enter: '?'\n");
/* Read and process commands a line at a time. */
while (1) {
if (prompt) fputs(prompt,stdout);
if (! fgets(cmdline, MAX_LINE, stdin)) break;
/* Find beginning of command word */
cmdp = cmdline;
while (isspace(*cmdp)) cmdp++;
/* find beginning of args */
argp = cmdp;
while (*argp && !isspace(*argp)) argp++;
while (isspace(*argp) || *argp=='=') argp++;
switch (*cmdp) {
case '\0': /* blank line */
case '#': /* line comment */
break;
case '?': case 'h': case 'H':
help();
break;
case '1': /* set partition entry */
case '2': case '3': case '4':
argp = setPartition(cmdp, argp);
if (argp) { /* arg list error */
fprintf(stderr,BadArg,argp);
fprintf(stderr,h_1);
fprintf(stderr,h_2);
break;
}
bufmod = 1;
break;
case 'a': case 'A': /* activate partition */
argp = makeActive(argp);
if (argp) {
fprintf(stderr,BadArg,argp);
fprintf(stderr,h_a);
break;
}
bufmod = 1;
break;
case 'g': case 'G': /* set disk parameters (Geometry) */
argp = setGeometry(argp);
if (argp) { /* arg list error */
fprintf(stderr,BadArg,argp);
fprintf(stderr,h_g);
}
break;
case 'i': case 'I': /* List known ID numbers */
printIDs();
break;
case 'l': case 'L': /* List the partition table */
listPTable();
break;
case 'q': case 'Q': /* Quit */
if (bufmod && (cmdp[1] != '!')) {
fprintf(stderr,"\007%s%s\n", WarnNotSaved,
"Use 'wq' or 'q!' (enter ? for help).");
break;
}
exit(0);
/*NOTREACHED*/
case 'r': case 'R': /* read from device or file */
if (sscanf(argp,"%80s",filename) == 1) {
/* Arg specified, read from filename */
if (getFile(filename, buffer, SECSIZE) < 0)
fprintf(stderr,"%s: read failed\n", filename);
bufmod = 1;
} else {
/* No arg, use device. */
if (getBBlk(devname, buffer) < 0)
fprintf(stderr,"%s: read failed\n", devname);
bufmod = 0;
}
checkValidity();
break;
case 'w': case 'W': /* Write to file or device */
if (sscanf(argp,"%80s",filename) == 1) {
/* Arg specified, write to filename */
if (putFile(filename, buffer, SECSIZE) < 0)
fprintf(stderr, "%s: write failed\n", filename);
} else { /* No arg, use device. */
if (putBBlk(devname, buffer) < 0)
fprintf(stderr, "%s: write failed\n", devname);
bufmod = 0;
}
if (cmdp[1] == 'q' || cmdp[1] == 'Q') exit(0);
break;
default:
fprintf(stderr,"'%c': unrecognized. Enter '?' for help.\n", *cmdp);
break;
} /* switch */
} /* while */
if (bufmod) fprintf(stderr, WarnNotSaved);
exit(0);
} /* main */
/* Check for valid boot block (magic number in last two bytes).
* Also, check for presence of partition name table.
*/
void checkValidity()
{
/* Check the magic number. */
if ((buffer[MAGIC_LOC] & 0xFF) != MAGIC_0 ||
(buffer[MAGIC_LOC+1] & 0xFF) != MAGIC_1 ) {
/* The boot sector is not valid -- Fix it. */
buffer[MAGIC_LOC] = MAGIC_0;
buffer[MAGIC_LOC+1] = MAGIC_1;
bufmod = 1;
fprintf(stderr,
"\n\tWarning: The boot sector has an invalid magic number.\n\
\tThe magic number has been fixed, but the other contents\n\
\tare probably garbage. Initialize using the command:\n\
\t\tR boot-program-file (i.e. bootmenu.bin)\n\
\tthen set each partition entry if necessary.\n");
}
/* Does it use a name table (for a boot menu)?
* My boot program does, and can be identified by
* finding my name in a particular (unused) area.
*/
useNTable = !strcmp(&buffer[LOC_GWR], "Gordon W. Ross");
}
char * setPartition(cmdp,argp) /* return string on error */
char *cmdp,*argp;
{
struct part *pp; /* partition entry */
char * np; /* name table pointer */
char * newname; /* name field */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -