summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/stand/sgivol/sgivol.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sgi/stand/sgivol/sgivol.c')
-rw-r--r--sys/arch/sgi/stand/sgivol/sgivol.c607
1 files changed, 0 insertions, 607 deletions
diff --git a/sys/arch/sgi/stand/sgivol/sgivol.c b/sys/arch/sgi/stand/sgivol/sgivol.c
deleted file mode 100644
index 1066bf00eab..00000000000
--- a/sys/arch/sgi/stand/sgivol/sgivol.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/* $OpenBSD: sgivol.c,v 1.24 2017/09/08 05:36:52 deraadt Exp $ */
-/* $NetBSD: sgivol.c,v 1.8 2003/11/08 04:59:00 sekiya Exp $ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Michael Hitch and Hubert Feyrer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <unistd.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.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/dkio.h>
-
-/*
- * Some IRIX man pages refer to the size being a multiple of whole cylinders.
- * Later ones only refer to the size being "typically" 2MB. IRIX fx(1)
- * uses a default drive geometry if one can't be determined, suggesting
- * that "whole cylinder" multiples are not required.
- */
-
-#define SGI_SIZE_VOLHDR 3135 /* Can be overridden via -h parameter. */
-
-/*
- * Mode of operation can be one of:
- * -i Initialise volume header.
- * -r Read a file from volume header.
- * -w Write a file to volume header.
- * -l Link a file into the volume header.
- * -d Delete a file from the volume header.
- * -p Modify a partition.
- */
-
-char mode;
-int quiet;
-int fd;
-int partno, partfirst, partblocks, parttype;
-struct sgilabel *volhdr;
-int32_t checksum;
-
-/* Volume header size in sectors. */
-u_int32_t volhdr_size = SGI_SIZE_VOLHDR;
-
-const char *vfilename = "";
-const char *ufilename = "";
-
-struct disklabel lbl;
-
-unsigned char *buf;
-unsigned int bufsize;
-
-const char *sgi_types[] = {
- "Volume Header",
- "Repl Trks",
- "Repl Secs",
- "Raw",
- "BSD4.2",
- "SysV",
- "Volume",
- "EFS",
- "LVol",
- "RLVol",
- "XFS",
- "XSFLog",
- "XLV",
- "XVM"
-};
-
-void display_vol(void);
-void init_volhdr(void);
-void read_file(void);
-void write_file(void);
-void link_file(void);
-void delete_file(void);
-void modify_partition(void);
-void write_volhdr(void);
-int allocate_space(int);
-void checksum_vol(void);
-void usage(void);
-
-int
-main(int argc, char *argv[])
-{
- int ch, oflags;
- char fname[FILENAME_MAX];
- char *endp;
-
- quiet = 0;
- mode = ' ';
-
- while ((ch = getopt(argc, argv, "irwlpdqfh:")) != -1) {
- switch (ch) {
- case 'q':
- quiet = 1;
- break;
- case 'f':
- /* Legacy. Do nothing. */
- break;
- case 'i':
- mode = 'i';
- break;
- case 'h':
- volhdr_size = strtol(optarg, &endp, 0);
- if (*endp != '\0' || errno != 0)
- errx(1, "incorrect volume header size: %s",
- optarg);
- break;
- case 'r':
- mode = 'r';
- break;
- case 'w':
- mode = 'w';
- break;
- case 'l':
- mode = 'l';
- break;
- case 'd':
- mode = 'd';
- break;
- case 'p':
- mode = 'p';
- break;
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (mode == 'r' || mode == 'w' || mode == 'l') {
- if (argc != 3)
- usage();
- vfilename = argv[0];
- ufilename = argv[1];
- argc -= 2;
- argv += 2;
- } else if (mode == 'd') {
- if (argc != 2)
- usage();
- vfilename = argv[0];
- argc--;
- argv++;
- } else if (mode == 'p') {
- if (argc != 5)
- usage();
- 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;
- }
- if (argc != 1)
- usage();
-
- oflags = ((mode == 'i' || mode == 'w' || mode == 'l' || mode == 'd'
- || mode == 'p') ? O_RDWR : O_RDONLY);
-
- /* Open raw device. */
- if ((fd = open(argv[0], oflags)) < 0) {
- snprintf(fname, sizeof(fname), "/dev/r%s%c",
- argv[0], 'a' + getrawpartition());
- if ((fd = open(fname, oflags)) < 0)
- err(1, "open %s", fname);
- }
-
- /* Get disklabel for device. */
- if (ioctl(fd, DIOCGDINFO, &lbl) == -1)
- err(1, "ioctl DIOCGDINFO");
-
- /* Allocate a buffer that matches the device sector size. */
- bufsize = lbl.d_secsize;
- if (bufsize < sizeof(struct sgilabel))
- errx(1, "sector size is smaller than SGI volume header!\n");
- if ((buf = malloc(bufsize)) == NULL)
- err(1, "failed to allocate buffer");
-
- /* Read SGI volume header. */
- if (read(fd, buf, bufsize) != bufsize)
- err(1, "read volhdr");
- volhdr = (struct sgilabel *)buf;
-
- if (mode == 'i') {
- init_volhdr();
- exit(0);
- }
-
- if (betoh32(volhdr->magic) != SGILABEL_MAGIC)
- errx(2, "no Volume Header found, magic=%x. Use -i first.",
- betoh32(volhdr->magic));
-
- if (mode == 'r')
- read_file();
- else if (mode == 'w')
- write_file();
- else if (mode == 'l')
- link_file();
- else if (mode == 'd')
- delete_file();
- else if (mode == 'p')
- modify_partition();
- else if (!quiet)
- display_vol();
-
- exit (0);
-}
-
-void
-display_vol(void)
-{
- int32_t *l;
- int i;
-
- l = (int32_t *)buf;
- checksum = 0;
- for (i = 0; i < sizeof(struct sgilabel) / sizeof(int32_t); ++i)
- checksum += betoh32(l[i]);
-
- printf("disklabel shows %llu sectors with %u bytes per sector\n",
- DL_GETDSIZE(&lbl), lbl.d_secsize);
- printf("checksum: %08x%s\n", checksum, checksum == 0 ? "" : " *ERROR*");
- printf("root part: %d\n", betoh32(volhdr->root));
- printf("swap part: %d\n", betoh32(volhdr->swap));
- printf("bootfile: %s\n", volhdr->bootfile);
-
- /* volhdr->devparams[0..47] */
- printf("\nVolume header files:\n");
- 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),
- howmany(betoh32(volhdr->voldir[i].bytes),
- DEV_BSIZE));
- }
- }
-
- printf("\nSGI partitions:\n");
- for (i = 0; i < MAXPARTITIONS; ++i) {
- 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) >
- (sizeof(sgi_types) / sizeof(sgi_types[0])) ?
- "???" :
- sgi_types[betoh32(volhdr->partitions[i].type)]);
- }
- }
-}
-
-void
-init_volhdr(void)
-{
- memset(volhdr, 0, sizeof(struct sgilabel));
- volhdr->magic = htobe32(SGILABEL_MAGIC);
- volhdr->root = htobe16(0);
- volhdr->swap = htobe16(1);
- strlcpy(volhdr->bootfile, "/bsd", sizeof(volhdr->bootfile));
- volhdr->dp.dp_skew = 1; /* XXX */
- volhdr->dp.dp_gap1 = 1; /* XXX */
- volhdr->dp.dp_gap2 = 1; /* XXX */
- volhdr->dp.dp_cyls = htobe16(lbl.d_ncylinders);
- volhdr->dp.dp_shd0 = 0;
- volhdr->dp.dp_trks0 = htobe16(lbl.d_ntracks);
- volhdr->dp.dp_secs = htobe16(lbl.d_nsectors);
- volhdr->dp.dp_secbytes = htobe16(lbl.d_secsize);
- volhdr->dp.dp_interleave = 1;
- volhdr->dp.dp_nretries = htobe32(22);
- volhdr->partitions[10].blocks =
- htobe32(DL_SECTOBLK(&lbl, DL_GETDSIZE(&lbl)));
- volhdr->partitions[10].first = 0;
- volhdr->partitions[10].type = htobe32(SGI_PTYPE_VOLUME);
- volhdr->partitions[8].blocks = htobe32(DL_SECTOBLK(&lbl, volhdr_size));
- volhdr->partitions[8].first = 0;
- volhdr->partitions[8].type = htobe32(SGI_PTYPE_VOLHDR);
- volhdr->partitions[0].blocks =
- htobe32(DL_SECTOBLK(&lbl, DL_GETDSIZE(&lbl) - volhdr_size));
- volhdr->partitions[0].first = htobe32(DL_SECTOBLK(&lbl, volhdr_size));
- volhdr->partitions[0].type = htobe32(SGI_PTYPE_BSD);
- write_volhdr();
-}
-
-void
-read_file(void)
-{
- FILE *fp;
- int i;
-
- if (!quiet)
- printf("Reading file %s\n", vfilename);
- for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
- if (strncmp(vfilename, volhdr->voldir[i].name,
- strlen(volhdr->voldir[i].name)) == 0)
- break;
- }
- 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) * 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, bufsize) != bufsize)
- err(1, "read file");
- fwrite(buf, 1, i > bufsize ? bufsize : i, fp);
- i -= i > bufsize ? bufsize : i;
- }
- fclose(fp);
-}
-
-void
-write_file(void)
-{
- FILE *fp;
- int slot;
- int block, i, fsize, fbufsize;
- struct stat st;
- char *fbuf;
-
- if (!quiet)
- printf("Writing file %s\n", ufilename);
-
- if (stat(ufilename, &st) != 0)
- err(1, "stat %s", ufilename);
- if (st.st_size == 0)
- errx(1, "%s: file is empty", vfilename);
-
- if (!quiet)
- printf("File %s has %lld bytes\n", ufilename, st.st_size);
- slot = -1;
- 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) {
- slot = i;
- break;
- }
- }
- if (slot == -1)
- errx(1, "no more directory entries available");
- if (betoh32(volhdr->voldir[slot].block) > 0) {
- if (!quiet)
- printf("File %s exists, removing old file\n",
- vfilename);
- volhdr->voldir[slot].name[0] = 0;
- volhdr->voldir[slot].block = volhdr->voldir[slot].bytes = 0;
- }
- /* XXX assumes volume header starts at 0? */
- block = allocate_space((int)st.st_size);
- if (block < 0)
- errx(1, "no more space available");
-
- /*
- * Make sure the name in the volume header is max. 8 chars,
- * NOT including NUL.
- */
- if (strlen(vfilename) > sizeof(volhdr->voldir[slot].name))
- warnx("%s: filename is too long and will be truncated",
- vfilename);
- strncpy(volhdr->voldir[slot].name, vfilename,
- sizeof(volhdr->voldir[slot].name));
-
- volhdr->voldir[slot].block = htobe32(block);
- volhdr->voldir[slot].bytes = htobe32(st.st_size);
-
- write_volhdr();
-
- /* Write the file itself. */
- if (lseek(fd, block * DEV_BSIZE, SEEK_SET) == -1)
- err(1, "lseek write");
- fbufsize = volhdr->dp.dp_secbytes;
- if ((fbuf = malloc(fbufsize)) == NULL)
- err(1, "failed to allocate buffer");
- i = st.st_size;
- fp = fopen(ufilename, "r");
- while (i > 0) {
- bzero(fbuf, fbufsize);
- fsize = i > fbufsize ? fbufsize : i;
- if (fread(fbuf, 1, fsize, fp) != fsize)
- err(1, "reading file from disk");
- if (write(fd, fbuf, fbufsize) != fbufsize)
- err(1, "writing file to SGI volume header");
- i -= fsize;
- }
- fclose(fp);
- free(fbuf);
-}
-
-void
-link_file(void)
-{
- int slot, i;
- int32_t block, bytes;
-
- if (!quiet)
- printf("Linking file %s to %s\n", vfilename, ufilename);
- for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
- if (strncmp(vfilename, volhdr->voldir[i].name,
- strlen(volhdr->voldir[i].name)) == 0)
- break;
- }
- if (i >= SGI_SIZE_VOLDIR)
- errx(1, "%s: file not found", vfilename);
-
- block = volhdr->voldir[i].block;
- bytes = volhdr->voldir[i].bytes;
-
- slot = -1;
- for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
- if (volhdr->voldir[i].name[0] == '\0' && slot < 0)
- slot = i;
- if (strcmp(ufilename, volhdr->voldir[i].name) == 0) {
- slot = i;
- break;
- }
- }
- if (slot == -1)
- errx(1, "no more directory entries available");
-
- /*
- * Make sure the name in the volume header is max. 8 chars,
- * NOT including NUL.
- */
- if (strlen(ufilename) > sizeof(volhdr->voldir[slot].name))
- warnx("%s: filename is too long and will be truncated",
- ufilename);
- strncpy(volhdr->voldir[slot].name, ufilename,
- sizeof(volhdr->voldir[slot].name));
-
- volhdr->voldir[slot].block = block;
- volhdr->voldir[slot].bytes = bytes;
- write_volhdr();
-}
-
-void
-delete_file(void)
-{
- int i;
-
- for (i = 0; i < SGI_SIZE_VOLDIR; ++i) {
- if (strcmp(vfilename, volhdr->voldir[i].name) == 0) {
- break;
- }
- }
- 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';
- volhdr->voldir[i].block = volhdr->voldir[i].bytes = 0;
- write_volhdr();
-}
-
-void
-modify_partition(void)
-{
- if (!quiet)
- printf("Modify partition %d start %d length %d\n",
- partno, partfirst, partblocks);
- volhdr->partitions[partno].blocks = htobe32(partblocks);
- volhdr->partitions[partno].first = htobe32(partfirst);
- volhdr->partitions[partno].type = htobe32(parttype);
- write_volhdr();
-}
-
-void
-write_volhdr(void)
-{
- checksum_vol();
-
- if (!quiet)
- display_vol();
- if (lseek(fd, 0, SEEK_SET) == -1)
- err(1, "lseek 0");
- if (write(fd, buf, bufsize) != bufsize)
- err(1, "write volhdr");
-}
-
-int
-allocate_space(int size)
-{
- int n, blocks;
- int first;
-
- blocks = howmany(size, DEV_BSIZE);
- first = roundup(2 * DEV_BSIZE, volhdr->dp.dp_secbytes) / DEV_BSIZE;
-
- for (n = 0; n < SGI_SIZE_VOLDIR;) {
- if (volhdr->voldir[n].name[0]) {
- if (first < (betoh32(volhdr->voldir[n].block) +
- howmany(betoh32(volhdr->voldir[n].bytes),
- DEV_BSIZE)) &&
- (first + blocks) >
- betoh32(volhdr->voldir[n].block)) {
-
- first = roundup(
- betoh32(volhdr->voldir[n].block) +
- howmany(betoh32(volhdr->voldir[n].bytes),
- DEV_BSIZE),
- volhdr->dp.dp_secbytes / DEV_BSIZE);
-#if DEBUG
- 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 +
- howmany(volhdr->voldir[n].bytes,
- DEV_BSIZE));
-#endif
- n = 0;
- continue;
- }
- }
- ++n;
- }
- if (first + blocks > DL_GETDSIZE(&lbl))
- first = -1;
- /* XXX assumes volume header is partition 8 */
- /* XXX assumes volume header starts at 0? */
- if (first + blocks >= betoh32(volhdr->partitions[8].blocks))
- first = -1;
- return (first);
-}
-
-void
-checksum_vol(void)
-{
- int32_t *l;
- int i;
-
- volhdr->checksum = checksum = 0;
- l = (int32_t *)buf;
- for (i = 0; i < sizeof(struct sgilabel) / sizeof(int32_t); ++i)
- checksum += betoh32(l[i]);
- volhdr->checksum = htobe32(-checksum);
-}
-
-void
-usage(void)
-{
- extern char *__progname;
-
- fprintf(stderr,
- "usage: %s [-q] disk\n"
- " %s [-q] -d vhfilename disk\n"
- " %s [-q] -i [-h vhsize] disk\n"
- " %s [-q] -l vhfilename1 vhfilename2 disk\n"
- " %s [-q] -r vhfilename diskfilename disk\n"
- " %s [-q] -w vhfilename diskfilename disk\n",
- __progname, __progname, __progname, __progname, __progname,
- __progname);
-
- exit(1);
-}