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