summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sgi/stand/sgivol/sgivol.c267
1 files changed, 121 insertions, 146 deletions
diff --git a/sys/arch/sgi/stand/sgivol/sgivol.c b/sys/arch/sgi/stand/sgivol/sgivol.c
index 4d4604741c0..d2d2f640ee0 100644
--- a/sys/arch/sgi/stand/sgivol/sgivol.c
+++ b/sys/arch/sgi/stand/sgivol/sgivol.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: sgivol.c,v 1.3 2004/11/08 21:24:46 miod Exp $ */
/* $NetBSD: sgivol.c,v 1.8 2003/11/08 04:59:00 sekiya Exp $ */
/*-
@@ -36,19 +37,21 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/disklabel.h>
-
+#include <unistd.h>
+#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-#include <fcntl.h>
#include <util.h>
+
+#include <sys/disklabel.h>
#include <sys/endian.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
/*
* Some IRIX man pages refer to the size being a multiple of whole cylinders.
@@ -83,7 +86,9 @@ struct local_devparms {
u_int16_t dp_xgap2;
u_int16_t dp_xrgate;
u_int16_t dp_xwcont;
-} __attribute__((__packed__));
+} __packed;
+
+#define SGI_SIZE_VOLDIR 15
struct local_sgilabel {
#define SGILABEL_MAGIC 0xbe5a941
@@ -96,7 +101,7 @@ struct local_sgilabel {
char name[8];
int32_t block;
int32_t bytes;
- } voldir[15];
+ } voldir[SGI_SIZE_VOLDIR];
struct {
int32_t blocks;
int32_t first;
@@ -104,7 +109,7 @@ struct local_sgilabel {
} partitions[MAXPARTITIONS];
int32_t checksum;
int32_t _pad;
-} __attribute__((__packed__));
+} __packed;
#define SGI_PTYPE_VOLHDR 0
#define SGI_PTYPE_RAW 3
@@ -136,7 +141,7 @@ const char *ufilename = "";
struct disklabel lbl;
-unsigned char buf[512];
+unsigned char buf[DEV_BSIZE];
const char *sgi_types[] = {
"Volume Header",
@@ -155,8 +160,6 @@ const char *sgi_types[] = {
"XVM"
};
-int main(int, char *[]);
-
void display_vol(void);
void init_volhdr(void);
void read_file(void);
@@ -172,6 +175,8 @@ int
main(int argc, char *argv[])
{
int ch;
+ char *endp;
+
while ((ch = getopt(argc, argv, "irwpdqfh:")) != -1) {
switch (ch) {
/* -i, -r, -w, -d and -p override each other */
@@ -188,7 +193,10 @@ main(int argc, char *argv[])
opt_r = opt_w = opt_d = opt_p = 0;
break;
case 'h':
- volhdr_size = atoi(optarg);
+ volhdr_size = strtol(optarg, &endp, 0);
+ if (*endp != '\0' || errno != 0)
+ errx(1, "incorrect volume header size: %s",
+ optarg);
break;
case 'r':
++opt_r;
@@ -205,12 +213,7 @@ main(int argc, char *argv[])
case 'p':
++opt_p;
opt_i = opt_r = opt_w = opt_d = 0;
- partno = atoi(argv[0]);
- partfirst = atoi(argv[1]);
- partblocks = atoi(argv[2]);
- parttype = atoi(argv[3]);
break;
- case '?':
default:
usage();
}
@@ -237,10 +240,19 @@ main(int argc, char *argv[])
if (opt_p) {
if (argc != 5)
usage();
- partno = atoi(argv[0]);
- partfirst = atoi(argv[1]);
- partblocks = atoi(argv[2]);
- parttype = atoi(argv[3]);
+ partno = strtol(argv[0], &endp, 0);
+ if (*endp != '\0' || errno != 0 ||
+ partno < 0 || partno > SGI_SIZE_VOLDIR)
+ errx(1, "invalid partition number: %s", argv[0]);
+ partfirst = strtol(argv[1], &endp, 0);
+ if (*endp != '\0' || errno != 0)
+ errx(1, "invalid partition start: %s", argv[1]);
+ partblocks = strtol(argv[2], &endp, 0);
+ if (*endp != '\0' || errno != 0)
+ errx(1, "invalid partition size: %s", argv[2]);
+ parttype = strtol(argv[3], &endp, 0);
+ if (*endp != '\0' || errno != 0)
+ errx(1, "invalid partition type: %s", argv[3]);
argc -= 4;
argv += 4;
}
@@ -249,33 +261,24 @@ main(int argc, char *argv[])
fd = open(argv[0], (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY);
if (fd < 0) {
- sprintf(buf, "/dev/r%s%c", argv[0], 'a' + getrawpartition());
- fd = open(buf, (opt_i | opt_w | opt_d | opt_p)
- ? O_RDWR : O_RDONLY);
- if (fd < 0) {
- printf("Error opening device %s: %s\n",
- argv[0], strerror(errno));
- exit(1);
- }
- }
- if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
- perror("read volhdr");
- exit(1);
- }
- if (ioctl(fd, DIOCGDINFO, &lbl) < 0) {
- perror("DIOCGDINFO");
- exit(1);
- }
- volhdr = (struct local_sgilabel *) buf;
+ snprintf(buf, sizeof(buf), "/dev/r%s%c",
+ argv[0], 'a' + getrawpartition());
+ if ((fd = open(buf,
+ (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY)) < 0)
+ err(1, "open %s", buf);
+ }
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "read volhdr");
+ if (ioctl(fd, DIOCGDINFO, &lbl) == -1)
+ err(1, "ioctl DIOCGDINFO");
+ volhdr = (struct local_sgilabel *)buf;
if (opt_i) {
init_volhdr();
exit(0);
}
- if (betoh32(volhdr->magic) != SGILABEL_MAGIC) {
- printf("No Volume Header found, magic=%x. Use -i first.\n",
- betoh32(volhdr->magic));
- exit(2);
- }
+ if (betoh32(volhdr->magic) != SGILABEL_MAGIC)
+ errx(2, "no Volume Header found, magic=%x. Use -i first.",
+ betoh32(volhdr->magic));
if (opt_r) {
read_file();
exit(0);
@@ -296,7 +299,7 @@ main(int argc, char *argv[])
if (!opt_q)
display_vol();
- return 0;
+ exit (0);
}
void
@@ -308,7 +311,7 @@ display_vol(void)
printf("disklabel shows %d sectors\n", lbl.d_secperunit);
l = (int32_t *)buf;
checksum = 0;
- for (i = 0; i < 512 / 4; ++i)
+ for (i = 0; i < sizeof(buf) / sizeof(int32_t); ++i)
checksum += betoh32(l[i]);
printf("checksum: %08x%s\n", checksum, checksum == 0 ? "" : " *ERROR*");
printf("root part: %d\n", betoh32(volhdr->root));
@@ -316,20 +319,27 @@ display_vol(void)
printf("bootfile: %s\n", volhdr->bootfile);
/* volhdr->devparams[0..47] */
printf("\nVolume header files:\n");
- for (i = 0; i < 15; ++i)
- if (volhdr->voldir[i].name[0])
+ for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
+ if (volhdr->voldir[i].name[0] != '\0') {
printf("%-8s offset %4d blocks, length %8d bytes (%d blocks)\n",
- volhdr->voldir[i].name, betoh32(volhdr->voldir[i].block),
- betoh32(volhdr->voldir[i].bytes), (betoh32(volhdr->voldir[i].bytes) + 511) / 512);
+ volhdr->voldir[i].name,
+ betoh32(volhdr->voldir[i].block),
+ betoh32(volhdr->voldir[i].bytes),
+ howmany(betoh32(volhdr->voldir[i].bytes),
+ DEV_BSIZE));
+ }
+ }
printf("\nSGI partitions:\n");
for (i = 0; i < MAXPARTITIONS; ++i) {
- if (betoh32(volhdr->partitions[i].blocks)) {
+ if (betoh32(volhdr->partitions[i].blocks) != 0) {
printf("%2d:%c blocks %8d first %8d type %2d (%s)\n",
- i, i + 'a', betoh32(volhdr->partitions[i].blocks),
- betoh32(volhdr->partitions[i].first),
- betoh32(volhdr->partitions[i].type),
- betoh32(volhdr->partitions[i].type) > 13 ? "???" :
- sgi_types[betoh32(volhdr->partitions[i].type)]);
+ i, i + 'a', betoh32(volhdr->partitions[i].blocks),
+ betoh32(volhdr->partitions[i].first),
+ betoh32(volhdr->partitions[i].type),
+ betoh32(volhdr->partitions[i].type) >
+ (sizeof(sgi_types) / sizeof(sgi_types[0])) ?
+ "???" :
+ sgi_types[betoh32(volhdr->partitions[i].type)]);
}
}
}
@@ -341,7 +351,7 @@ init_volhdr(void)
volhdr->magic = htobe32(SGILABEL_MAGIC);
volhdr->root = htobe16(0);
volhdr->swap = htobe16(1);
- strcpy(volhdr->bootfile, "/bsd");
+ strlcpy(volhdr->bootfile, "/bsd", sizeof(volhdr->bootfile));
volhdr->dp.dp_skew = lbl.d_trackskew;
volhdr->dp.dp_gap1 = 1; /* XXX */
volhdr->dp.dp_gap2 = 1; /* XXX */
@@ -372,28 +382,21 @@ read_file(void)
if (!opt_q)
printf("Reading file %s\n", vfilename);
- for (i = 0; i < 15; ++i) {
+ for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
if (strncmp(vfilename, volhdr->voldir[i].name,
strlen(volhdr->voldir[i].name)) == 0)
break;
}
- if (i >= 15) {
- printf("file %s not found\n", vfilename);
- exit(1);
- }
+ if (i >= SGI_SIZE_VOLDIR)
+ errx(1, "%s: file not found", vfilename);
/* XXX assumes volume header starts at 0? */
- lseek(fd, betoh32(volhdr->voldir[i].block) * 512, SEEK_SET);
- fp = fopen(ufilename, "w");
- if (fp == NULL) {
- perror("open write");
- exit(1);
- }
+ lseek(fd, betoh32(volhdr->voldir[i].block) * DEV_BSIZE, SEEK_SET);
+ if ((fp = fopen(ufilename, "w")) == NULL)
+ err(1, "open %s", ufilename);
i = betoh32(volhdr->voldir[i].bytes);
while (i > 0) {
- if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
- perror("read file");
- exit(1);
- }
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "read file");
fwrite(buf, 1, i > sizeof(buf) ? sizeof(buf) : i, fp);
i -= i > sizeof(buf) ? sizeof(buf) : i;
}
@@ -405,21 +408,20 @@ write_file(void)
{
FILE *fp;
int slot;
- size_t namelen;
int block, i;
struct stat st;
- char fbuf[512];
+ char fbuf[DEV_BSIZE];
if (!opt_q)
printf("Writing file %s\n", ufilename);
- if (stat(ufilename, &st) < 0) {
- perror("stat");
- exit(1);
- }
+ if (stat(ufilename, &st) != 0)
+ err(1, "stat %s", ufilename);
+ if (st.st_size == 0)
+ errx(1, "%s: file is empty", vfilename);
if (!opt_q)
printf("File %s has %lld bytes\n", ufilename, st.st_size);
slot = -1;
- for (i = 0; i < 15; ++i) {
+ for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
if (volhdr->voldir[i].name[0] == '\0' && slot < 0)
slot = i;
if (strcmp(vfilename, volhdr->voldir[i].name) == 0) {
@@ -427,10 +429,8 @@ write_file(void)
break;
}
}
- if (slot == -1) {
- printf("No directory space for file %s\n", vfilename);
- exit(1);
- }
+ if (slot == -1)
+ errx(1, "no more directory entries available");
/* -w can overwrite, -a won't overwrite */
if (betoh32(volhdr->voldir[slot].block) > 0) {
if (!opt_q)
@@ -439,34 +439,20 @@ write_file(void)
volhdr->voldir[slot].name[0] = 0;
volhdr->voldir[slot].block = volhdr->voldir[slot].bytes = 0;
}
- if (st.st_size == 0) {
- printf("bad file size\n");
- exit(1);
- }
/* XXX assumes volume header starts at 0? */
block = allocate_space((int)st.st_size);
- if (block < 0) {
- printf("No space for file\n");
- exit(1);
- }
+ if (block < 0)
+ errx(1, "no more space available");
/*
* Make sure the name in the volume header is max. 8 chars,
* NOT including NUL.
*/
- namelen = strlen(vfilename);
- if (namelen > sizeof(volhdr->voldir[slot].name)) {
- printf("Warning: '%s' is too long for volume header, ",
+ if (strlen(vfilename) > sizeof(volhdr->voldir[slot].name))
+ warnx("%s: filename is too long and will be truncated",
vfilename);
- namelen = sizeof(volhdr->voldir[slot].name);
- printf("truncating to '%-8s'\n", vfilename);
- }
-
- /* Populate it w/ NULs */
- memset(volhdr->voldir[slot].name, 0,
+ strncpy(volhdr->voldir[slot].name, vfilename,
sizeof(volhdr->voldir[slot].name));
- /* Then copy the name */
- memcpy(volhdr->voldir[slot].name, vfilename, namelen);
volhdr->voldir[slot].block = htobe32(block);
volhdr->voldir[slot].bytes = htobe32(st.st_size);
@@ -474,20 +460,15 @@ write_file(void)
write_volhdr();
/* write the file itself */
- i = lseek(fd, block * 512, SEEK_SET);
- if (i < 0) {
- perror("lseek write");
- exit(1);
- }
+ if (lseek(fd, block * DEV_BSIZE, SEEK_SET) == -1)
+ err(1, "lseek write");
i = st.st_size;
fp = fopen(ufilename, "r");
while (i > 0) {
- fread(fbuf, 1, i > 512 ? 512 : i, fp);
- if (write(fd, fbuf, 512) != 512) {
- perror("write file");
- exit(1);
- }
- i -= i > 512 ? 512 : i;
+ fread(fbuf, 1, i > sizeof(fbuf) ? sizeof(fbuf) : i, fp);
+ if (write(fd, fbuf, sizeof(fbuf)) != sizeof(fbuf))
+ err(1, "write file");
+ i -= i > sizeof(fbuf) ? sizeof(fbuf) : i;
}
}
@@ -496,15 +477,13 @@ delete_file(void)
{
int i;
- for (i = 0; i < 15; ++i) {
+ for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
if (strcmp(vfilename, volhdr->voldir[i].name) == 0) {
break;
}
}
- if (i >= 15) {
- printf("File %s not found\n", vfilename);
- exit(1);
- }
+ if (i >= SGI_SIZE_VOLDIR)
+ errx(1, "%s: file not found", vfilename);
/* XXX: we don't compact the file space, so get fragmentation */
volhdr->voldir[i].name[0] = '\0';
@@ -517,11 +496,7 @@ modify_partition(void)
{
if (!opt_q)
printf("Modify partition %d start %d length %d\n",
- partno, partfirst, partblocks);
- if (partno < 0 || partno > 15) {
- printf("Invalid partition number: %d\n", partno);
- exit(1);
- }
+ partno, partfirst, partblocks);
volhdr->partitions[partno].blocks = htobe32(partblocks);
volhdr->partitions[partno].first = htobe32(partfirst);
volhdr->partitions[partno].type = htobe32(parttype);
@@ -543,14 +518,10 @@ write_volhdr(void)
if (i != 'Y' && i != 'y')
exit(1);
}
- i = lseek(fd, 0, SEEK_SET);
- if (i < 0) {
- perror("lseek 0");
- exit(1);
- }
- i = write(fd, buf, 512);
- if (i < 0)
- perror("write volhdr");
+ if (lseek(fd, 0, SEEK_SET) == -1)
+ err(1, "lseek 0");
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "write volhdr");
}
int
@@ -559,21 +530,22 @@ allocate_space(int size)
int n, blocks;
int first;
- blocks = (size + 511) / 512;
+ blocks = howmany(size, DEV_BSIZE);
first = 2;
- n = 0;
- while (n < 15) {
+ for (n = 0; n < SGI_SIZE_VOLDIR;) {
if (volhdr->voldir[n].name[0]) {
if (first < (betoh32(volhdr->voldir[n].block) +
- (betoh32(volhdr->voldir[n].bytes) + 511) / 512) &&
+ howmany(betoh32(volhdr->voldir[n].bytes),
+ DEV_BSIZE)) &&
(first + blocks) > betoh32(volhdr->voldir[n].block)) {
first = betoh32(volhdr->voldir[n].block) +
- (betoh32(volhdr->voldir[n].bytes) + 511) / 512;
+ howmany(betoh32(volhdr->voldir[n].bytes),
+ DEV_BSIZE);
#if 0
printf("allocate: n=%d first=%d blocks=%d size=%d\n", n, first, blocks, size);
printf("%s %d %d\n", volhdr->voldir[n].name, volhdr->voldir[n].block, volhdr->voldir[n].bytes);
printf("first=%d block=%d last=%d end=%d\n", first, volhdr->voldir[n].block,
- first + blocks - 1, volhdr->voldir[n].block + (volhdr->voldir[n].bytes + 511) / 512);
+ first + blocks - 1, volhdr->voldir[n].block + howmany(volhdr->voldir[n].bytes, DEV_BSIZE));
#endif
n = 0;
continue;
@@ -598,7 +570,7 @@ checksum_vol(void)
volhdr->checksum = checksum = 0;
l = (int32_t *)buf;
- for (i = 0; i < 512 / 4; ++i)
+ for (i = 0; i < sizeof(buf) / sizeof(int32_t); ++i)
checksum += betoh32(l[i]);
volhdr->checksum = htobe32(-checksum);
}
@@ -606,10 +578,13 @@ checksum_vol(void)
void
usage(void)
{
- printf("Usage: sgivol [-qf] [-i] [-h vhsize] device\n"
- " sgivol [-qf] [-r vhfilename diskfilename] device\n"
- " sgivol [-qf] [-w vhfilename diskfilename] device\n"
- " sgivol [-qf] [-d vhfilename] device\n"
- );
- exit(0);
+ extern char *__progname;
+
+ fprintf(stderr,
+ "usage: %s [-qf] [-i] [-h vhsize] device\n"
+ " %s [-qf] [-r vhfilename diskfilename] device\n"
+ " %s [-qf] [-w vhfilename diskfilename] device\n"
+ " %s [-qf] [-d vhfilename] device\n",
+ __progname, __progname, __progname, __progname);
+ exit(1);
}