⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pfdisk.c

📁 又一个选择启动分区的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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,&sectors);

  /* 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 + -