From owner-p4-projects Sun Feb 9 6:41:27 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5190737B406; Sun, 9 Feb 2003 06:41:19 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E11E437B405 for ; Sun, 9 Feb 2003 06:41:18 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9209043FBF for ; Sun, 9 Feb 2003 06:41:12 -0800 (PST) (envelope-from jmallett@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h19EfCbv060724 for ; Sun, 9 Feb 2003 06:41:12 -0800 (PST) (envelope-from jmallett@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h19EfBLG060712 for perforce@freebsd.org; Sun, 9 Feb 2003 06:41:11 -0800 (PST) Date: Sun, 9 Feb 2003 06:41:11 -0800 (PST) Message-Id: <200302091441.h19EfBLG060712@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jmallett@freebsd.org using -f From: Juli Mallett Subject: PERFORCE change 24895 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 #include #include +#include #include -/* - * 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