Home | History | Annotate | Line # | Download | only in sgivol
sgivol.c revision 1.3.2.3
      1  1.3.2.3  jdolecek /*	$NetBSD: sgivol.c,v 1.3.2.3 2002/03/16 15:59:34 jdolecek Exp $	*/
      2  1.3.2.2   thorpej 
      3  1.3.2.2   thorpej /*-
      4  1.3.2.2   thorpej  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  1.3.2.2   thorpej  * All rights reserved.
      6  1.3.2.2   thorpej  *
      7  1.3.2.2   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8  1.3.2.2   thorpej  * by Michael Hitch and Hubert Feyrer.
      9  1.3.2.2   thorpej  *
     10  1.3.2.2   thorpej  * Redistribution and use in source and binary forms, with or without
     11  1.3.2.2   thorpej  * modification, are permitted provided that the following conditions
     12  1.3.2.2   thorpej  * are met:
     13  1.3.2.2   thorpej  * 1. Redistributions of source code must retain the above copyright
     14  1.3.2.2   thorpej  *    notice, this list of conditions and the following disclaimer.
     15  1.3.2.2   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.3.2.2   thorpej  *    notice, this list of conditions and the following disclaimer in the
     17  1.3.2.2   thorpej  *    documentation and/or other materials provided with the distribution.
     18  1.3.2.2   thorpej  * 3. All advertising materials mentioning features or use of this software
     19  1.3.2.2   thorpej  *    must display the following acknowledgement:
     20  1.3.2.2   thorpej  *        This product includes software developed by the NetBSD
     21  1.3.2.2   thorpej  *        Foundation, Inc. and its contributors.
     22  1.3.2.2   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.3.2.2   thorpej  *    contributors may be used to endorse or promote products derived
     24  1.3.2.2   thorpej  *    from this software without specific prior written permission.
     25  1.3.2.2   thorpej  *
     26  1.3.2.2   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.3.2.2   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.3.2.2   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.3.2.2   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.3.2.2   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.3.2.2   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.3.2.2   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.3.2.2   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.3.2.2   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.3.2.2   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.3.2.2   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     37  1.3.2.2   thorpej  */
     38  1.3.2.2   thorpej 
     39  1.3.2.2   thorpej #include <sys/types.h>
     40  1.3.2.2   thorpej #include <sys/ioctl.h>
     41  1.3.2.2   thorpej #include <sys/disklabel.h>
     42  1.3.2.2   thorpej #include <sys/stat.h>
     43  1.3.2.2   thorpej 
     44  1.3.2.2   thorpej #include <stdio.h>
     45  1.3.2.2   thorpej #include <stdlib.h>
     46  1.3.2.2   thorpej #include <unistd.h>
     47  1.3.2.2   thorpej #include <string.h>
     48  1.3.2.2   thorpej #include <fcntl.h>
     49  1.3.2.2   thorpej #include <util.h>
     50  1.3.2.2   thorpej 
     51  1.3.2.2   thorpej #define SGI_SIZE_VOLHDR	3135	/* XXX Irix: 2592, NetBSD: 3753 */
     52  1.3.2.2   thorpej 
     53  1.3.2.2   thorpej int	fd;
     54  1.3.2.2   thorpej int	opt_i;			/* Initialize volume header */
     55  1.3.2.2   thorpej int	opt_r;			/* Read a file from volume header */
     56  1.3.2.2   thorpej int	opt_w;			/* Write a file to volume header */
     57  1.3.2.2   thorpej int	opt_d;			/* Delete a file from volume header */
     58  1.3.2.2   thorpej int	opt_p;			/* Modify a partition */
     59  1.3.2.2   thorpej int	partno, partfirst, partblocks, parttype;
     60  1.3.2.2   thorpej struct sgilabel *volhdr;
     61  1.3.2.2   thorpej int32_t	checksum;
     62  1.3.2.2   thorpej 
     63  1.3.2.2   thorpej const char *vfilename = "";
     64  1.3.2.2   thorpej const char *ufilename = "";
     65  1.3.2.2   thorpej 
     66  1.3.2.2   thorpej struct disklabel lbl;
     67  1.3.2.2   thorpej 
     68  1.3.2.2   thorpej unsigned char buf[512];
     69  1.3.2.2   thorpej 
     70  1.3.2.2   thorpej const char *sgi_types[] = {
     71  1.3.2.2   thorpej 	"Volume Header",
     72  1.3.2.2   thorpej 	"Repl Trks",
     73  1.3.2.2   thorpej 	"Repl Secs",
     74  1.3.2.2   thorpej 	"Raw",
     75  1.3.2.2   thorpej 	"BSD4.2",
     76  1.3.2.2   thorpej 	"SysV",
     77  1.3.2.2   thorpej 	"Volume",
     78  1.3.2.2   thorpej 	"EFS",
     79  1.3.2.2   thorpej 	"LVol",
     80  1.3.2.2   thorpej 	"RLVol",
     81  1.3.2.2   thorpej 	"XFS",
     82  1.3.2.2   thorpej 	"XSFLog",
     83  1.3.2.2   thorpej 	"XLV",
     84  1.3.2.2   thorpej 	"XVM"
     85  1.3.2.2   thorpej };
     86  1.3.2.2   thorpej 
     87  1.3.2.2   thorpej int	main(int, char *[]);
     88  1.3.2.2   thorpej 
     89  1.3.2.2   thorpej void	display_vol(void);
     90  1.3.2.2   thorpej void	init_volhdr(void);
     91  1.3.2.2   thorpej void	read_file(void);
     92  1.3.2.2   thorpej void	write_file(void);
     93  1.3.2.2   thorpej void	delete_file(void);
     94  1.3.2.2   thorpej void	modify_partition(void);
     95  1.3.2.2   thorpej void	write_volhdr(void);
     96  1.3.2.2   thorpej int	allocate_space(int);
     97  1.3.2.2   thorpej void	checksum_vol(void);
     98  1.3.2.2   thorpej void	usage(void);
     99  1.3.2.2   thorpej 
    100  1.3.2.2   thorpej int
    101  1.3.2.2   thorpej main(int argc, char *argv[])
    102  1.3.2.2   thorpej {
    103  1.3.2.2   thorpej 	if (argc < 2)
    104  1.3.2.2   thorpej 		usage();
    105  1.3.2.2   thorpej 
    106  1.3.2.2   thorpej 	if (argv[1][0] == '-') {
    107  1.3.2.2   thorpej 		switch(argv[1][1]) {
    108  1.3.2.2   thorpej 		case 'i':
    109  1.3.2.2   thorpej 			++opt_i;
    110  1.3.2.2   thorpej 			argv++;
    111  1.3.2.2   thorpej 			argc--;
    112  1.3.2.2   thorpej 			break;
    113  1.3.2.2   thorpej 		case 'r':
    114  1.3.2.2   thorpej 		case 'w':
    115  1.3.2.2   thorpej 			if (argc < 4)
    116  1.3.2.2   thorpej 				usage();
    117  1.3.2.2   thorpej 			if (argv[1][1] == 'r')
    118  1.3.2.2   thorpej 				++opt_r;
    119  1.3.2.2   thorpej 			else
    120  1.3.2.2   thorpej 				++opt_w;
    121  1.3.2.2   thorpej 			vfilename = argv[2];
    122  1.3.2.2   thorpej 			ufilename = argv[3];
    123  1.3.2.2   thorpej 			argv += 3;
    124  1.3.2.2   thorpej 			argc -= 3;
    125  1.3.2.2   thorpej 			break;
    126  1.3.2.2   thorpej 		case 'd':
    127  1.3.2.2   thorpej 			if (argc < 3)
    128  1.3.2.2   thorpej 				usage();
    129  1.3.2.2   thorpej 			++opt_d;
    130  1.3.2.2   thorpej 			vfilename = argv[2];
    131  1.3.2.2   thorpej 			argv += 2;
    132  1.3.2.2   thorpej 			argc -= 2;
    133  1.3.2.2   thorpej 				break;
    134  1.3.2.2   thorpej 		case 'p':
    135  1.3.2.2   thorpej 			if (argc < 6)
    136  1.3.2.2   thorpej 				usage();
    137  1.3.2.2   thorpej 			++opt_p;
    138  1.3.2.2   thorpej 			partno = atoi(argv[2]);
    139  1.3.2.2   thorpej 			partfirst = atoi(argv[3]);
    140  1.3.2.2   thorpej 			partblocks = atoi(argv[4]);
    141  1.3.2.2   thorpej 			parttype = atoi(argv[5]);
    142  1.3.2.2   thorpej 			argv += 5;
    143  1.3.2.2   thorpej 			argc -= 5;
    144  1.3.2.2   thorpej 			break;
    145  1.3.2.2   thorpej 		default:
    146  1.3.2.2   thorpej 			printf("-%c Invalid\n", argv[1][1]);
    147  1.3.2.2   thorpej 			usage();
    148  1.3.2.2   thorpej 		}
    149  1.3.2.2   thorpej 	}
    150  1.3.2.2   thorpej 
    151  1.3.2.2   thorpej 	if (argc < 2)
    152  1.3.2.2   thorpej 		usage();
    153  1.3.2.2   thorpej 
    154  1.3.2.2   thorpej 	fd = open(argv[1], (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY);
    155  1.3.2.2   thorpej 	if (fd < 0) {
    156  1.3.2.2   thorpej 		sprintf(buf, "/dev/r%s%c", argv[1], 'a' + getrawpartition());
    157  1.3.2.2   thorpej 		fd = open(buf,
    158  1.3.2.2   thorpej 		    (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY);
    159  1.3.2.2   thorpej 		if (fd < 0) {
    160  1.3.2.2   thorpej 			perror("open");
    161  1.3.2.2   thorpej 			exit(1);
    162  1.3.2.2   thorpej 		}
    163  1.3.2.2   thorpej 	}
    164  1.3.2.2   thorpej 	if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
    165  1.3.2.2   thorpej 		perror("read volhdr");
    166  1.3.2.2   thorpej 		exit(1);
    167  1.3.2.2   thorpej 	}
    168  1.3.2.2   thorpej 	if (ioctl(fd, DIOCGDINFO, &lbl) < 0) {
    169  1.3.2.2   thorpej 		perror("DIOCGDINFO");
    170  1.3.2.2   thorpej 		exit(1);
    171  1.3.2.2   thorpej 	}
    172  1.3.2.2   thorpej 	volhdr = (struct sgilabel *)buf;
    173  1.3.2.2   thorpej 	if (opt_i) {
    174  1.3.2.2   thorpej 		init_volhdr();
    175  1.3.2.2   thorpej 		exit(0);
    176  1.3.2.2   thorpej 	}
    177  1.3.2.2   thorpej 	if (volhdr->magic != SGILABEL_MAGIC) {
    178  1.3.2.2   thorpej 		printf("No SGI volume header found, magic=%x\n", volhdr->magic);
    179  1.3.2.2   thorpej 		exit(1);
    180  1.3.2.2   thorpej 	}
    181  1.3.2.2   thorpej 	if (opt_r) {
    182  1.3.2.2   thorpej 		read_file();
    183  1.3.2.2   thorpej 		exit(0);
    184  1.3.2.2   thorpej 	}
    185  1.3.2.2   thorpej 	if (opt_w) {
    186  1.3.2.2   thorpej 		write_file();
    187  1.3.2.2   thorpej 		exit(0);
    188  1.3.2.2   thorpej 	}
    189  1.3.2.2   thorpej 	if (opt_d) {
    190  1.3.2.2   thorpej 		delete_file();
    191  1.3.2.2   thorpej 		exit(0);
    192  1.3.2.2   thorpej 	}
    193  1.3.2.2   thorpej 	if (opt_p) {
    194  1.3.2.2   thorpej 		modify_partition();
    195  1.3.2.2   thorpej 		exit(0);
    196  1.3.2.2   thorpej 	}
    197  1.3.2.2   thorpej 	display_vol();
    198  1.3.2.2   thorpej 
    199  1.3.2.2   thorpej 	return 0;
    200  1.3.2.2   thorpej }
    201  1.3.2.2   thorpej 
    202  1.3.2.2   thorpej void
    203  1.3.2.2   thorpej display_vol(void)
    204  1.3.2.2   thorpej {
    205  1.3.2.2   thorpej 	int32_t *l;
    206  1.3.2.2   thorpej 	int i;
    207  1.3.2.2   thorpej 
    208  1.3.2.2   thorpej 	printf("disklabel shows %d sectors\n", lbl.d_secperunit);
    209  1.3.2.2   thorpej 	l = (int32_t *)buf;
    210  1.3.2.2   thorpej 	checksum = 0;
    211  1.3.2.2   thorpej 	for (i = 0; i < 512 / 4; ++i)
    212  1.3.2.2   thorpej 		checksum += l[i];
    213  1.3.2.2   thorpej 	printf("checksum: %08x%s\n", checksum, checksum == 0 ? "" : " *ERROR*");
    214  1.3.2.2   thorpej 	printf("root part: %d\n", volhdr->root);
    215  1.3.2.2   thorpej 	printf("swap part: %d\n", volhdr->swap);
    216  1.3.2.2   thorpej 	printf("bootfile: %s\n", volhdr->bootfile);
    217  1.3.2.2   thorpej 	/* volhdr->devparams[0..47] */
    218  1.3.2.2   thorpej 	printf("\nVolume header files:\n");
    219  1.3.2.2   thorpej 	for (i = 0; i < 15; ++i)
    220  1.3.2.2   thorpej 		if (volhdr->voldir[i].name[0])
    221  1.3.2.2   thorpej 			printf("%-8s offset %4d blocks, length %8d bytes (%d blocks)\n",
    222  1.3.2.2   thorpej 			    volhdr->voldir[i].name, volhdr->voldir[i].block,
    223  1.3.2.2   thorpej 			    volhdr->voldir[i].bytes, (volhdr->voldir[i].bytes + 511 ) / 512);
    224  1.3.2.2   thorpej 	printf("\nSGI partitions:\n");
    225  1.3.2.2   thorpej 	for (i = 0; i < MAXPARTITIONS; ++i) {
    226  1.3.2.2   thorpej 		if (volhdr->partitions[i].blocks) {
    227  1.3.2.2   thorpej 			printf("%2d:%c blocks %8d first %8d type %2d (%s)\n",
    228  1.3.2.2   thorpej 			    i, i + 'a', volhdr->partitions[i].blocks,
    229  1.3.2.2   thorpej 			    volhdr->partitions[i].first,
    230  1.3.2.2   thorpej 			    volhdr->partitions[i].type,
    231  1.3.2.2   thorpej 			    volhdr->partitions[i].type > 13 ? "???" :
    232  1.3.2.2   thorpej 			    sgi_types[volhdr->partitions[i].type]);
    233  1.3.2.2   thorpej 		}
    234  1.3.2.2   thorpej 	}
    235  1.3.2.2   thorpej }
    236  1.3.2.2   thorpej 
    237  1.3.2.2   thorpej void
    238  1.3.2.2   thorpej init_volhdr(void)
    239  1.3.2.2   thorpej {
    240  1.3.2.2   thorpej 	memset(buf, 0, sizeof(buf));
    241  1.3.2.2   thorpej 	volhdr->magic = SGILABEL_MAGIC;
    242  1.3.2.2   thorpej 	volhdr->root = 0;
    243  1.3.2.2   thorpej 	volhdr->swap = 1;
    244  1.3.2.2   thorpej 	strcpy(volhdr->bootfile, "/netbsd");
    245  1.3.2.3  jdolecek 	volhdr->dp.dp_skew = lbl.d_trackskew;
    246  1.3.2.3  jdolecek 	volhdr->dp.dp_gap1 = 1; /* XXX */
    247  1.3.2.3  jdolecek 	volhdr->dp.dp_gap2 = 1; /* XXX */
    248  1.3.2.3  jdolecek 	volhdr->dp.dp_cyls = lbl.d_ncylinders;
    249  1.3.2.3  jdolecek 	volhdr->dp.dp_shd0 = 0;
    250  1.3.2.3  jdolecek 	volhdr->dp.dp_trks0 = lbl.d_ntracks;
    251  1.3.2.3  jdolecek 	volhdr->dp.dp_secs = lbl.d_nsectors;
    252  1.3.2.3  jdolecek 	volhdr->dp.dp_secbytes = lbl.d_secsize;
    253  1.3.2.3  jdolecek 	volhdr->dp.dp_interleave = lbl.d_interleave;
    254  1.3.2.3  jdolecek 	volhdr->dp.dp_nretries = 22;
    255  1.3.2.2   thorpej 	volhdr->partitions[10].blocks = lbl.d_secperunit;
    256  1.3.2.2   thorpej 	volhdr->partitions[10].first = 0;
    257  1.3.2.2   thorpej 	volhdr->partitions[10].type = SGI_PTYPE_VOLUME;
    258  1.3.2.2   thorpej 	volhdr->partitions[8].blocks = SGI_SIZE_VOLHDR;
    259  1.3.2.2   thorpej 	volhdr->partitions[8].first = 0;
    260  1.3.2.2   thorpej 	volhdr->partitions[8].type = SGI_PTYPE_VOLHDR;
    261  1.3.2.2   thorpej 	volhdr->partitions[0].blocks = lbl.d_secperunit - SGI_SIZE_VOLHDR;
    262  1.3.2.2   thorpej 	volhdr->partitions[0].first = SGI_SIZE_VOLHDR;
    263  1.3.2.2   thorpej 	volhdr->partitions[0].type = SGI_PTYPE_BSD;
    264  1.3.2.2   thorpej 	write_volhdr();
    265  1.3.2.2   thorpej }
    266  1.3.2.2   thorpej 
    267  1.3.2.2   thorpej void
    268  1.3.2.2   thorpej read_file(void)
    269  1.3.2.2   thorpej {
    270  1.3.2.2   thorpej 	FILE *fp;
    271  1.3.2.2   thorpej 	int i;
    272  1.3.2.2   thorpej 
    273  1.3.2.2   thorpej 	printf("Reading file %s\n", vfilename);
    274  1.3.2.2   thorpej 	for (i = 0; i < 15; ++i) {
    275  1.3.2.2   thorpej 		if (strncmp(vfilename, volhdr->voldir[i].name,
    276  1.3.2.2   thorpej 		    sizeof(volhdr->voldir[i].name)) == NULL)
    277  1.3.2.2   thorpej 			break;
    278  1.3.2.2   thorpej 	}
    279  1.3.2.2   thorpej 	if (i >= 15) {
    280  1.3.2.2   thorpej 		printf("file %s not found\n", vfilename);
    281  1.3.2.2   thorpej 		exit(1);
    282  1.3.2.2   thorpej 	}
    283  1.3.2.2   thorpej 	/* XXX assumes volume header starts at 0? */
    284  1.3.2.2   thorpej 	lseek(fd, volhdr->voldir[i].block * 512, SEEK_SET);
    285  1.3.2.2   thorpej 	fp = fopen(ufilename, "w");
    286  1.3.2.2   thorpej 	if (fp == NULL) {
    287  1.3.2.2   thorpej 		perror("open write");
    288  1.3.2.2   thorpej 		exit(1);
    289  1.3.2.2   thorpej 	}
    290  1.3.2.2   thorpej 	i = volhdr->voldir[i].bytes;
    291  1.3.2.2   thorpej 	while (i > 0) {
    292  1.3.2.2   thorpej 		if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
    293  1.3.2.2   thorpej 			perror("read file");
    294  1.3.2.2   thorpej 			exit(1);
    295  1.3.2.2   thorpej 		}
    296  1.3.2.2   thorpej 		fwrite(buf, 1, i > sizeof(buf) ? sizeof(buf) : i, fp);
    297  1.3.2.2   thorpej 		i -= i > sizeof(buf) ? sizeof(buf) : i;
    298  1.3.2.2   thorpej 	}
    299  1.3.2.2   thorpej 	fclose(fp);
    300  1.3.2.2   thorpej }
    301  1.3.2.2   thorpej 
    302  1.3.2.2   thorpej void
    303  1.3.2.2   thorpej write_file(void)
    304  1.3.2.2   thorpej {
    305  1.3.2.2   thorpej 	FILE *fp;
    306  1.3.2.2   thorpej 	int slot;
    307  1.3.2.2   thorpej 	size_t namelen;
    308  1.3.2.2   thorpej 	int block, i;
    309  1.3.2.2   thorpej 	struct stat st;
    310  1.3.2.2   thorpej 	char fbuf[512];
    311  1.3.2.2   thorpej 
    312  1.3.2.2   thorpej 	printf("Writing file %s\n", ufilename);
    313  1.3.2.2   thorpej 	if (stat(ufilename, &st) < 0) {
    314  1.3.2.2   thorpej 		perror("stat");
    315  1.3.2.2   thorpej 		exit(1);
    316  1.3.2.2   thorpej 	}
    317  1.3.2.2   thorpej 	printf("File %s has %lld bytes\n", ufilename, st.st_size);
    318  1.3.2.2   thorpej 	slot = -1;
    319  1.3.2.2   thorpej 	for (i = 0; i < 15; ++i) {
    320  1.3.2.2   thorpej 		if (volhdr->voldir[i].name[0] == '\0' && slot < 0)
    321  1.3.2.2   thorpej 			slot = i;
    322  1.3.2.2   thorpej 		if (strcmp(vfilename, volhdr->voldir[i].name) == 0) {
    323  1.3.2.2   thorpej 			slot = i;
    324  1.3.2.2   thorpej 			break;
    325  1.3.2.2   thorpej 		}
    326  1.3.2.2   thorpej 	}
    327  1.3.2.2   thorpej 	if (slot == -1) {
    328  1.3.2.2   thorpej 		printf("No directory space for file %s\n", vfilename);
    329  1.3.2.2   thorpej 		exit(1);
    330  1.3.2.2   thorpej 	}
    331  1.3.2.2   thorpej 	/* -w can overwrite, -a won't overwrite */
    332  1.3.2.2   thorpej 	if (volhdr->voldir[slot].block > 0) {
    333  1.3.2.2   thorpej 		printf("File %s exists, removing old file\n", vfilename);
    334  1.3.2.2   thorpej 		volhdr->voldir[slot].name[0] = 0;
    335  1.3.2.2   thorpej 		volhdr->voldir[slot].block = volhdr->voldir[slot].bytes = 0;
    336  1.3.2.2   thorpej 	}
    337  1.3.2.2   thorpej 	if (st.st_size == 0) {
    338  1.3.2.2   thorpej 		printf("bad file size?\n");
    339  1.3.2.2   thorpej 		exit(1);
    340  1.3.2.2   thorpej 	}
    341  1.3.2.2   thorpej 	/* XXX assumes volume header starts at 0? */
    342  1.3.2.2   thorpej 	block = allocate_space((int)st.st_size);
    343  1.3.2.2   thorpej 	if (block < 0) {
    344  1.3.2.2   thorpej 		printf("No space for file\n");
    345  1.3.2.2   thorpej 		exit(1);
    346  1.3.2.2   thorpej 	}
    347  1.3.2.2   thorpej 
    348  1.3.2.2   thorpej 	/*
    349  1.3.2.2   thorpej 	 * Make sure the name in the volume header is max. 8 chars,
    350  1.3.2.2   thorpej 	 * NOT including NUL.
    351  1.3.2.2   thorpej 	 */
    352  1.3.2.2   thorpej 	namelen = strlen(vfilename);
    353  1.3.2.2   thorpej 	if (namelen > sizeof(volhdr->voldir[slot].name)) {
    354  1.3.2.2   thorpej 		printf("Warning: '%s' is too long for volume header, ",
    355  1.3.2.2   thorpej 		       vfilename);
    356  1.3.2.2   thorpej 		namelen = sizeof(volhdr->voldir[slot].name);
    357  1.3.2.2   thorpej 		printf("truncating to '%-8s'\n", vfilename);
    358  1.3.2.2   thorpej 	}
    359  1.3.2.3  jdolecek 
    360  1.3.2.2   thorpej 	/* Populate it w/ NULs */
    361  1.3.2.2   thorpej 	memset(volhdr->voldir[slot].name, 0,
    362  1.3.2.2   thorpej 	    sizeof(volhdr->voldir[slot].name));
    363  1.3.2.2   thorpej 	/* Then copy the name */
    364  1.3.2.2   thorpej 	memcpy(volhdr->voldir[slot].name, vfilename, namelen);
    365  1.3.2.2   thorpej 
    366  1.3.2.2   thorpej 	volhdr->voldir[slot].block = block;
    367  1.3.2.2   thorpej 	volhdr->voldir[slot].bytes = st.st_size;
    368  1.3.2.2   thorpej 
    369  1.3.2.2   thorpej 	write_volhdr();
    370  1.3.2.2   thorpej 
    371  1.3.2.2   thorpej 	/* write the file itself */
    372  1.3.2.2   thorpej 	i = lseek(fd, block * 512, SEEK_SET);
    373  1.3.2.2   thorpej 	if (i < 0) {
    374  1.3.2.2   thorpej 		perror("lseek write");
    375  1.3.2.2   thorpej 		exit(1);
    376  1.3.2.2   thorpej 	}
    377  1.3.2.2   thorpej 	i = st.st_size;
    378  1.3.2.2   thorpej 	fp = fopen(ufilename, "r");
    379  1.3.2.2   thorpej 	while (i > 0) {
    380  1.3.2.2   thorpej 		fread(fbuf, 1, i > 512 ? 512 : i, fp);
    381  1.3.2.2   thorpej 		if (write(fd, fbuf, 512) != 512) {
    382  1.3.2.2   thorpej 			perror("write file");
    383  1.3.2.2   thorpej 			exit(1);
    384  1.3.2.2   thorpej 		}
    385  1.3.2.2   thorpej 		i -= i > 512 ? 512 : i;
    386  1.3.2.2   thorpej 	}
    387  1.3.2.2   thorpej }
    388  1.3.2.2   thorpej 
    389  1.3.2.2   thorpej void
    390  1.3.2.2   thorpej delete_file(void)
    391  1.3.2.2   thorpej {
    392  1.3.2.2   thorpej 	int i;
    393  1.3.2.2   thorpej 
    394  1.3.2.2   thorpej 	for (i = 0; i < 15; ++i) {
    395  1.3.2.2   thorpej 		if (strcmp(vfilename, volhdr->voldir[i].name) == NULL) {
    396  1.3.2.2   thorpej 			break;
    397  1.3.2.2   thorpej 		}
    398  1.3.2.2   thorpej 	}
    399  1.3.2.2   thorpej 	if (i >= 15) {
    400  1.3.2.2   thorpej 		printf("File %s not found\n", vfilename);
    401  1.3.2.2   thorpej 		exit(1);
    402  1.3.2.2   thorpej 	}
    403  1.3.2.2   thorpej 	volhdr->voldir[i].name[0] = '\0';
    404  1.3.2.2   thorpej 	volhdr->voldir[i].block = volhdr->voldir[i].bytes = 0;
    405  1.3.2.2   thorpej 	write_volhdr();
    406  1.3.2.2   thorpej }
    407  1.3.2.2   thorpej 
    408  1.3.2.2   thorpej void
    409  1.3.2.2   thorpej modify_partition(void)
    410  1.3.2.2   thorpej {
    411  1.3.2.2   thorpej 	printf("Modify partition %d start %d length %d\n", partno, partfirst,
    412  1.3.2.2   thorpej 	    partblocks);
    413  1.3.2.2   thorpej 	if (partno < 0 || partno > 15) {
    414  1.3.2.2   thorpej 		printf("Invalue partition number: %d\n", partno);
    415  1.3.2.2   thorpej 		exit(1);
    416  1.3.2.2   thorpej 	}
    417  1.3.2.2   thorpej 	volhdr->partitions[partno].blocks = partblocks;
    418  1.3.2.2   thorpej 	volhdr->partitions[partno].first = partfirst;
    419  1.3.2.2   thorpej 	volhdr->partitions[partno].type = parttype;
    420  1.3.2.2   thorpej 	write_volhdr();
    421  1.3.2.2   thorpej }
    422  1.3.2.2   thorpej 
    423  1.3.2.2   thorpej void
    424  1.3.2.2   thorpej write_volhdr(void)
    425  1.3.2.2   thorpej {
    426  1.3.2.2   thorpej 	int i;
    427  1.3.2.2   thorpej 
    428  1.3.2.2   thorpej 	checksum_vol();
    429  1.3.2.2   thorpej 	display_vol();
    430  1.3.2.2   thorpej 	printf("\nDo you want to update volume (y/n)? ");
    431  1.3.2.2   thorpej 	i = getchar();
    432  1.3.2.2   thorpej 	if (i != 'Y' && i != 'y')
    433  1.3.2.2   thorpej 		exit(1);
    434  1.3.2.2   thorpej 	i = lseek(fd, 0 , SEEK_SET);
    435  1.3.2.2   thorpej 	if (i < 0) {
    436  1.3.2.2   thorpej 		perror("lseek 0");
    437  1.3.2.2   thorpej 		exit(1);
    438  1.3.2.2   thorpej 	}
    439  1.3.2.2   thorpej 	i = write(fd, buf, 512);
    440  1.3.2.2   thorpej 	if (i < 0)
    441  1.3.2.2   thorpej 		perror("write volhdr");
    442  1.3.2.2   thorpej }
    443  1.3.2.2   thorpej 
    444  1.3.2.2   thorpej int
    445  1.3.2.2   thorpej allocate_space(int size)
    446  1.3.2.2   thorpej {
    447  1.3.2.2   thorpej 	int n, blocks;
    448  1.3.2.2   thorpej 	int first;
    449  1.3.2.2   thorpej 
    450  1.3.2.2   thorpej 	blocks = (size + 511) / 512;
    451  1.3.2.2   thorpej 	first = 2;
    452  1.3.2.2   thorpej 	n = 0;
    453  1.3.2.2   thorpej 	while (n < 15) {
    454  1.3.2.2   thorpej 		if (volhdr->voldir[n].name[0]) {
    455  1.3.2.2   thorpej 			if (first < (volhdr->voldir[n].block +
    456  1.3.2.2   thorpej 			    (volhdr->voldir[n].bytes + 511) / 512) &&
    457  1.3.2.2   thorpej 			    (first + blocks) >= volhdr->voldir[n].block) {
    458  1.3.2.2   thorpej 				first = volhdr->voldir[n].block +
    459  1.3.2.2   thorpej 				    (volhdr->voldir[n].bytes + 511) / 512;
    460  1.3.2.2   thorpej #if 0
    461  1.3.2.2   thorpej printf("allocate: n=%d first=%d blocks=%d size=%d\n", n, first, blocks, size);
    462  1.3.2.2   thorpej printf("%s %d %d\n", volhdr->voldir[n].name, volhdr->voldir[n].block, volhdr->voldir[n].bytes);
    463  1.3.2.2   thorpej printf("first=%d block=%d last=%d end=%d\n", first, volhdr->voldir[n].block,
    464  1.3.2.2   thorpej     first + blocks - 1, volhdr->voldir[n].block + (volhdr->voldir[n].bytes + 511)/512);
    465  1.3.2.2   thorpej #endif
    466  1.3.2.2   thorpej 				n = 0;
    467  1.3.2.2   thorpej 				continue;
    468  1.3.2.2   thorpej 			}
    469  1.3.2.2   thorpej 		}
    470  1.3.2.2   thorpej 		++n;
    471  1.3.2.2   thorpej 	}
    472  1.3.2.2   thorpej 	if (first + blocks > lbl.d_secperunit)
    473  1.3.2.2   thorpej 		first = -1;
    474  1.3.2.2   thorpej 	/* XXX assumes volume header is partition 8 */
    475  1.3.2.2   thorpej 	/* XXX assumes volume header starts at 0? */
    476  1.3.2.2   thorpej 	if (first + blocks >= volhdr->partitions[8].blocks)
    477  1.3.2.2   thorpej 		first = -1;
    478  1.3.2.2   thorpej 	return(first);
    479  1.3.2.2   thorpej }
    480  1.3.2.2   thorpej 
    481  1.3.2.2   thorpej void
    482  1.3.2.2   thorpej checksum_vol(void)
    483  1.3.2.2   thorpej {
    484  1.3.2.2   thorpej 	int32_t *l;
    485  1.3.2.2   thorpej 	int i;
    486  1.3.2.2   thorpej 
    487  1.3.2.2   thorpej 	volhdr->checksum = checksum = 0;
    488  1.3.2.2   thorpej 	l = (int32_t *)buf;
    489  1.3.2.2   thorpej 	for (i = 0; i < 512 / 4; ++i)
    490  1.3.2.2   thorpej 		checksum += l[i];
    491  1.3.2.2   thorpej 	volhdr->checksum = -checksum;
    492  1.3.2.2   thorpej }
    493  1.3.2.2   thorpej 
    494  1.3.2.2   thorpej void
    495  1.3.2.2   thorpej usage(void)
    496  1.3.2.2   thorpej {
    497  1.3.2.3  jdolecek 	printf("Usage:	sgivol [-i] device\n"
    498  1.3.2.3  jdolecek 	       "	sgivol [-r vhfilename diskfilename] device\n"
    499  1.3.2.3  jdolecek 	       "	sgivol [-w vhfilename diskfilename] device\n"
    500  1.3.2.3  jdolecek 	       "	sgivol [-d vhfilename] device\n"
    501  1.3.2.2   thorpej 	       );
    502  1.3.2.2   thorpej 	exit(0);
    503  1.3.2.2   thorpej }
    504