Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Feb 2003 06:41:11 -0800 (PST)
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 24895 for review
Message-ID:  <200302091441.h19EfBLG060712@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=24895

Change 24895 by jmallett@jmallett_dalek on 2003/02/09 06:40:46

	Fix late-night-code braindeath.  Add a flag to initialise a new
	header on a disk.

Affected files ...

.. //depot/projects/mips/sbin/fxlabel/fxlabel.c#2 edit

Differences ...

==== //depot/projects/mips/sbin/fxlabel/fxlabel.c#2 (text+ko) ====

@@ -35,28 +35,25 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
-/*
- * Note that this file makes a habit of possibly swapping fields only when
- * needed, rather than reversing the byte order of the entire label as a
- * buffer.
- */
-
 struct volhdr	label;
+static int	needswap;
 
 /*
  * Boolean returns here indicate true on error.
  */
-static int	dkopen(const char *);
+static int	dkopen(const char *, int);
 static void	dirlist(struct volhdr *);
-static bool	dirswap(struct voldir *);
 static bool	goodlabel(struct volhdr *, const char **);
-static void	labelswap(struct volhdr *);
-static bool	partswap(struct volpart *);
+static void	newlabel(struct volhdr *);
 static void	printlabel(struct volhdr *);
 static bool	readlabel(int);
-static void	strnswapbetoh(char *, size_t);
+static void	sumlabel(struct volhdr *);
+static void	swaplabel(struct volhdr *);
+static bool	writelabel(int);
+
 static void	usage(void);
 
 const char *srch[] = {
@@ -70,11 +67,25 @@
 main(int argc, char *argv[])
 {
 	const char *disk, *error;
+	bool pflag, wflag;
 	int ch;
 	int fd;
 
-	while ((ch = getopt(argc, argv, "")) != -1) {
+	pflag = wflag = false;
+	needswap = be16toh(0x1234) != 0x1234;
+
+	while ((ch = getopt(argc, argv, "pw")) != -1) {
 		switch (ch) {
+		case 'p':
+			if (wflag)
+				usage();
+			pflag = true;
+			break;
+		case 'w':
+			if (pflag)
+				usage();
+			wflag = true;
+			break;
 		case '?':
 		default:
 			usage();
@@ -83,24 +94,42 @@
 	argc -= optind;
 	argv += optind;
 
+	if (!pflag && !wflag)
+		pflag = true;
+
 	while ((disk = *argv++) != NULL) {
-		fd = dkopen(disk);
-		if (fd == -1)
-			err(1, "%s (open)", disk);
-		if (readlabel(fd))
-			err(1, "%s (label read)", disk);
-		if (goodlabel(&label, &error))
-			errx(1, "%s (label check): %s", disk, error);
-		labelswap(&label);
-		printlabel(&label);
-		close(fd);
+		if (pflag) {
+			fd = dkopen(disk, O_RDONLY);
+			if (fd == -1)
+				err(1, "%s (open)", disk);
+			if (readlabel(fd))
+				err(1, "%s (label read)", disk);
+			if (goodlabel(&label, &error))
+				errx(1, "%s (label check): %s", disk, error);
+			swaplabel(&label);
+			printlabel(&label);
+			close(fd);
+			continue;
+		}
+		if (wflag) {
+			fd = dkopen(disk, O_WRONLY);
+			if (fd == -1)
+				err(1, "%s (open)", disk);
+			newlabel(&label);
+			sumlabel(&label);
+			swaplabel(&label);
+			if (writelabel(fd))
+				err(1, "%s (label write)", disk);
+			close(fd);
+			continue;
+		}
 	}
 
 	return (0);
 }
 
 static int
-dkopen(const char *disk)
+dkopen(const char *disk, int flags)
 {
 	char path[MAXPATHLEN];
 	const char **prefix;
@@ -109,7 +138,7 @@
 	prefix = srch;
 	do {
 		snprintf(path, sizeof path, "%s%s", *prefix, disk);
-		fd = open(path, O_RDONLY);
+		fd = open(path, flags);
 	} while (*prefix++ != NULL && fd == -1);
 
 	return (fd);
@@ -124,27 +153,14 @@
 	printf("directory listing\n");
 	for (i = 0; i < FX_DIRSIZE; i++) {
 		dp = &vp->vh_dir[i];
-		if (dirswap(dp))
+		if (!dp->vd_size)
 			continue;
-		printf("\t%-8s\tsize %d, addr %d\n",
+		printf("\t%-8.8s\tsize %d, addr %d\n",
 		       dp->vd_name, dp->vd_size, dp->vd_addr);
 	}
 }
 
 static bool
-dirswap(struct voldir *vp)
-{
-	vp->vd_size = be32toh(vp->vd_size);
-	if (!vp->vd_size) {
-		return (true);
-	}
-	vp->vd_addr = be32toh(vp->vd_size);
-	strnswapbetoh(vp->vd_name, sizeof vp->vd_name);
-	
-	return (false);
-}
-
-static bool
 goodlabel(struct volhdr *vp, const char **errorp)
 {
 	int32_t *words;
@@ -158,8 +174,8 @@
 		*errorp = "bad magic";
 		return (true);
 	}
-	for (i = 0; i < 512 / sizeof *words; i++)
-		sum += be32toh(words[i]);
+	for (i = 0; i < sizeof *vp / sizeof *words; i++)
+		sum -= htobe32(words[i]);
 	if (sum != 0) {
 		*errorp = "bad checksum";
 		return (true);
@@ -168,27 +184,12 @@
 }
 
 static void
-labelswap(struct volhdr *vp)
+newlabel(struct volhdr *vp)
 {
-	vp->vh_magic = be32toh(vp->vh_magic);
-	vp->vh_root = be16toh(vp->vh_root);
-	vp->vh_swap = be16toh(vp->vh_swap);
-	strnswapbetoh(vp->vh_kernel, sizeof vp->vh_kernel);
+	memset(vp, 0, sizeof *vp);
+	vp->vh_magic = FX_LABEL_MAGIC;
 }
 
-static bool
-partswap(struct volpart *vp)
-{
-	vp->vp_size = be32toh(vp->vp_size);
-	if (!vp->vp_size) {
-		return (true);
-	}
-	vp->vp_begin = be32toh(vp->vp_size);
-	vp->vp_type = be32toh(vp->vp_type);
-	
-	return (false);
-}
-
 static const char *
 parttype(struct volpart *vp)
 {
@@ -209,11 +210,12 @@
 	nparts = 0;
 	for (i = 0; i < FX_NPARTS; i++) {
 		part = &vp->vh_part[i];
-		if (partswap(part))
+		if (!part->vp_size)
 			continue;
 		nparts++;
-		printf("found partition %c, type %d (%s)\n",
-		       'a' + i, part->vp_type, parttype(part));
+		printf("found partition %c, type %d (%s) %d-%d\n",
+		       'a' + i, part->vp_type, parttype(part), part->vp_begin,
+		       part->vp_size);
 	}
 	printf("found %d partitions\n", nparts);
 	printf("root at %c\n", 'a' + vp->vh_root);
@@ -238,16 +240,69 @@
 	}
 }
 
+/*
+ * This takes a new label which is already converted to big endian.
+ */
 static void
-strnswapbetoh(char *str, size_t len)
+sumlabel(struct volhdr *vp)
+{
+	int32_t *words;
+	int32_t sum;
+	int i;
+
+	words = (int32_t *)vp;
+	sum = 0;
+	vp->vh_csum = 0;
+
+	for (i = 0; i < sizeof *vp / sizeof *words; i++)
+		sum += words[i];
+	vp->vh_csum = -sum;
+}
+
+#define	swap16(x)	(x) = bswap32((x))
+#define	swap32(x)	(x) = bswap32((x))
+
+/*
+ * Swaps all the fields to and from network byte order, unless
+ * we're running in network byte order.
+ */
+static void
+swaplabel(struct volhdr *vp)
 {
-	u_int32_t *wordp;
 	int i;
 
-	while (i < len) {
-		wordp = (u_int32_t *)&str[len];
-		*wordp = be32toh(*wordp);
-		i += 2;
+	if (!needswap)
+		return;
+
+	swap32(vp->vh_magic);
+	swap16(vp->vh_root);
+	swap16(vp->vh_swap);
+	/* kernel */
+	/* ... dparms ... XXX unused */
+	for (i = 0; i < FX_DIRSIZE; i++) {
+		/* name */
+		swap32(vp->vh_dir[i].vd_addr);
+		swap32(vp->vh_dir[i].vd_size);
+	}
+	for (i = 0; i < FX_NPARTS; i++) {
+		swap32(vp->vh_part[i].vp_size);
+		swap32(vp->vh_part[i].vp_begin);
+		swap32(vp->vh_part[i].vp_type);
+	}
+	swap32(vp->vh_csum);
+	/* unused */
+}
+
+static bool
+writelabel(int fd)
+{
+	ssize_t cnt;
+
+	cnt = pwrite(fd, &label, sizeof label, 0);
+	if (cnt < 0 || (size_t)cnt != sizeof label) {
+		return (true);
+	} else {
+		return (false);
 	}
 }
 
@@ -255,6 +310,7 @@
 usage(void)
 {
 	fprintf(stderr,
-"usage: fxlabel disk\n");
+"usage: fxlabel [-p] disk [...]\n"
+"usage: fxlabel [-w] disk [...]\n");
 	exit(-1);
 }

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302091441.h19EfBLG060712>