summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/stand/sgivol
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2005-08-01 18:00:31 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2005-08-01 18:00:31 +0000
commit5b456408955576b0801bda69806de69270a22e13 (patch)
treec0f666f8e232c6bace38da0537d813991cc7985b /sys/arch/sgi/stand/sgivol
parent3d9eb73016ff4183587608afcad63a8502b2c130 (diff)
Add support for "hard links" in volume header.
ok miod@
Diffstat (limited to 'sys/arch/sgi/stand/sgivol')
-rw-r--r--sys/arch/sgi/stand/sgivol/sgivol.812
-rw-r--r--sys/arch/sgi/stand/sgivol/sgivol.c88
2 files changed, 83 insertions, 17 deletions
diff --git a/sys/arch/sgi/stand/sgivol/sgivol.8 b/sys/arch/sgi/stand/sgivol/sgivol.8
index 5e4dbf359bd..840a3cdcbe9 100644
--- a/sys/arch/sgi/stand/sgivol/sgivol.8
+++ b/sys/arch/sgi/stand/sgivol/sgivol.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sgivol.8,v 1.2 2005/04/28 10:03:34 jmc Exp $
+.\" $OpenBSD: sgivol.8,v 1.3 2005/08/01 18:00:30 kettenis Exp $
.\"
.\" Copyright (c) 2005 Theo de Raadt
.\" All rights reserved.
@@ -48,6 +48,10 @@
.Op Fl fq
.Op Fl w Ar vhfilename Ar diskfilename
.Ar disk
+.Nm sgivol
+.Op Fl fq
+.Op Fl l Ar vhfilename1 Ar vhfilename2
+.Ar disk
.Sh DESCRIPTION
.Nm
is used to initialize, and then add or remove programs from the
@@ -86,6 +90,12 @@ Copy the standard file
to the filesystem storage space in the volume header, placing
it there with the name
.Ar diskfilename .
+.It Fl l Ar vhfilename1 Ar vhfilename2
+Link the file
+.Ar vhfilename1
+to the file
+.Ar vhfilename2
+within the filesystem storage space in the volume header.
.It Ar disk
The name of the disk containing the partition in which the second-stage
boot program resides and the first-stage boot program is to be installed.
diff --git a/sys/arch/sgi/stand/sgivol/sgivol.c b/sys/arch/sgi/stand/sgivol/sgivol.c
index 0e492e7b67c..cca2fac652a 100644
--- a/sys/arch/sgi/stand/sgivol/sgivol.c
+++ b/sys/arch/sgi/stand/sgivol/sgivol.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sgivol.c,v 1.5 2005/04/28 10:03:35 jmc Exp $ */
+/* $OpenBSD: sgivol.c,v 1.6 2005/08/01 18:00:30 kettenis Exp $ */
/* $NetBSD: sgivol.c,v 1.8 2003/11/08 04:59:00 sekiya Exp $ */
/*-
@@ -127,6 +127,7 @@ int fd;
int opt_i; /* Initialize volume header */
int opt_r; /* Read a file from volume header */
int opt_w; /* Write a file to volume header */
+int opt_l; /* Link a file in volume header */
int opt_d; /* Delete a file from volume header */
int opt_p; /* Modify a partition */
int opt_q; /* quiet mode */
@@ -164,6 +165,7 @@ 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);
@@ -174,12 +176,12 @@ void usage(void);
int
main(int argc, char *argv[])
{
- int ch;
+ int ch, oflags;
char *endp;
- while ((ch = getopt(argc, argv, "irwpdqfh:")) != -1) {
+ while ((ch = getopt(argc, argv, "irwlpdqfh:")) != -1) {
switch (ch) {
- /* -i, -r, -w, -d and -p override each other */
+ /* -i, -r, -w, -l, -d and -p override each other */
/* -q implies -f */
case 'q':
++opt_q;
@@ -190,7 +192,7 @@ main(int argc, char *argv[])
break;
case 'i':
++opt_i;
- opt_r = opt_w = opt_d = opt_p = 0;
+ opt_r = opt_w = opt_l = opt_d = opt_p = 0;
break;
case 'h':
volhdr_size = strtol(optarg, &endp, 0);
@@ -200,19 +202,23 @@ main(int argc, char *argv[])
break;
case 'r':
++opt_r;
- opt_i = opt_w = opt_d = opt_p = 0;
+ opt_i = opt_w = opt_l = opt_d = opt_p = 0;
break;
case 'w':
++opt_w;
- opt_i = opt_r = opt_d = opt_p = 0;
+ opt_i = opt_r = opt_l = opt_d = opt_p = 0;
+ break;
+ case 'l':
+ ++opt_l;
+ opt_i = opt_r = opt_w = opt_d = opt_p = 0;
break;
case 'd':
++opt_d;
- opt_i = opt_r = opt_w = opt_p = 0;
+ opt_i = opt_r = opt_w = opt_l = opt_p = 0;
break;
case 'p':
++opt_p;
- opt_i = opt_r = opt_w = opt_d = 0;
+ opt_i = opt_r = opt_w = opt_l = opt_d = 0;
break;
default:
usage();
@@ -221,7 +227,7 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (opt_r || opt_w) {
+ if (opt_r || opt_w || opt_l) {
if (argc != 3)
usage();
vfilename = argv[0];
@@ -259,12 +265,11 @@ main(int argc, char *argv[])
if (argc != 1)
usage();
- fd = open(argv[0], (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY);
- if (fd < 0) {
+ oflags = ((opt_i | opt_w | opt_l | opt_d | opt_p) ? O_RDWR : O_RDONLY);
+ if ((fd = open(argv[0], oflags)) < 0) {
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)
+ if ((fd = open(buf, oflags)) < 0)
err(1, "open %s", buf);
}
if (read(fd, buf, sizeof(buf)) != sizeof(buf))
@@ -287,6 +292,10 @@ main(int argc, char *argv[])
write_file();
exit(0);
}
+ if (opt_l) {
+ link_file();
+ exit(0);
+ }
if (opt_d) {
delete_file();
exit(0);
@@ -473,6 +482,52 @@ write_file(void)
}
void
+link_file(void)
+{
+ int slot, i;
+ int32_t block, bytes;
+
+ if (!opt_q)
+ 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;
@@ -590,7 +645,8 @@ usage(void)
"usage: %s [-fq] [-d vhfilename] disk\n"
" %s [-fiq] [-h vhsize] disk\n"
" %s [-fq] [-r vhfilename diskfilename] disk\n"
- " %s [-fq] [-w vhfilename diskfilename] disk\n",
- __progname, __progname, __progname, __progname);
+ " %s [-fq] [-w vhfilename diskfilename] disk\n"
+ " %s [-fq] [-l vhfilename1 vhfilename2] disk\n",
+ __progname, __progname, __progname, __progname, __progname);
exit(1);
}