1*41074Swilliam /*-
2*41074Swilliam * Copyright (c) 1990 The Regents of the University of California.
3*41074Swilliam * All rights reserved.
4*41074Swilliam *
5*41074Swilliam * This code is derived from software contributed to Berkeley by
6*41074Swilliam * William Jolitz.
7*41074Swilliam *
8*41074Swilliam * %sccs.include.noredist.c%
9*41074Swilliam *
10*41074Swilliam * @(#)disklabel.c 7.1 (Berkeley) 04/24/90
11*41074Swilliam */
12*41074Swilliam
13*41074Swilliam #ifndef STANDALONE
14*41074Swilliam #include <stdio.h>
15*41074Swilliam #else
16*41074Swilliam #define stderr 0
17*41074Swilliam #define NULL 0
18*41074Swilliam #endif
19*41074Swilliam #include <disktab.h>
20*41074Swilliam #include <sys/types.h>
21*41074Swilliam #include <sys/ioctl.h>
22*41074Swilliam #include "disk.h"
23*41074Swilliam
24*41074Swilliam #define BOOTSIZE (8*1024) /* size of boot "block" */
25*41074Swilliam
26*41074Swilliam #define O_RDONLY 0
27*41074Swilliam #define O_WRONLY 1
28*41074Swilliam #define O_RDWR 2
29*41074Swilliam #define L_SET 0
30*41074Swilliam
31*41074Swilliam #ifdef STANDALONE
32*41074Swilliam #ifdef TP
33*41074Swilliam char *standdisk = "cst2d:" ;
34*41074Swilliam char *st506boot = "cst2e:"; /* ST506 boot block */
35*41074Swilliam char *scsiboot = "cst2f:"; /* SCSI boot block */
36*41074Swilliam #else
37*41074Swilliam char *standdisk = "/etc/disktab" ;
38*41074Swilliam char *st506boot = "/stand/bootwd"; /* ST506 boot block */
39*41074Swilliam char *scsiboot = "/stand/bootswd"; /* SCSI boot block */
40*41074Swilliam #endif
41*41074Swilliam #else
42*41074Swilliam char *st506boot = "/stand/bootwd"; /* ST506 boot block */
43*41074Swilliam char *scsiboot = "/stand/bootswd"; /* SCSI boot block */
44*41074Swilliam #endif
45*41074Swilliam
46*41074Swilliam char name[BOOTSIZE];
47*41074Swilliam union {
48*41074Swilliam char bootstrap[BOOTSIZE];
49*41074Swilliam struct {
50*41074Swilliam char pad[LABELOFFSET];
51*41074Swilliam struct disklabel lab;
52*41074Swilliam } b;
53*41074Swilliam } block0;
54*41074Swilliam
55*41074Swilliam #define MAXTYPES 4
56*41074Swilliam char *tnames[MAXTYPES] = {
57*41074Swilliam "type 0",
58*41074Swilliam "ST506",
59*41074Swilliam "floppy",
60*41074Swilliam "SCSI",
61*41074Swilliam };
62*41074Swilliam
main(argc,argv)63*41074Swilliam main(argc, argv)
64*41074Swilliam char *argv[];
65*41074Swilliam {
66*41074Swilliam register struct disklabel *lp = &block0.b.lab;
67*41074Swilliam register struct disktab *dp;
68*41074Swilliam register i;
69*41074Swilliam int f, b;
70*41074Swilliam char *boot ;
71*41074Swilliam char *p;
72*41074Swilliam #ifndef STANDALONE
73*41074Swilliam char *sprintf();
74*41074Swilliam
75*41074Swilliam if (argc < 2 || argc > 5) {
76*41074Swilliam fprintf(stderr, "usage: disklabel disk (to read label)\n");
77*41074Swilliam fprintf(stderr,
78*41074Swilliam "or disklabel disk type [ packid ] [ bootblock ] (to write label)\n");
79*41074Swilliam exit(1);
80*41074Swilliam }
81*41074Swilliam if (argv[1][0] != '/')
82*41074Swilliam sprintf(name, "/dev/r%sc", argv[1]);
83*41074Swilliam else
84*41074Swilliam strcpy(name, argv[1]);
85*41074Swilliam if (argc == 2) {
86*41074Swilliam f = open(name, O_RDONLY);
87*41074Swilliam if (f < 0 && argv[1][0] != '/') {
88*41074Swilliam sprintf(name, "/dev/r%s", argv[1]);
89*41074Swilliam f = open(name, O_RDONLY);
90*41074Swilliam }
91*41074Swilliam if (f < 0)
92*41074Swilliam Perror(name);
93*41074Swilliam #else
94*41074Swilliam char buf[80],c ;
95*41074Swilliam
96*41074Swilliam new_file:
97*41074Swilliam f = getdev("File", name) ;
98*41074Swilliam for(;;) {
99*41074Swilliam printf("R)ead, W)rite, F)ilename, or E)xit [RWFE] ? ") ;
100*41074Swilliam c = getchar() ;
101*41074Swilliam printf("\n") ;
102*41074Swilliam if (c == 'E') break ;
103*41074Swilliam if (c == 'W') goto wr_lab ;
104*41074Swilliam if (c == 'F') { close(f) ; goto new_file ; }
105*41074Swilliam if (c != 'R') continue ;
106*41074Swilliam #endif
107*41074Swilliam if (read(f, &block0, BOOTSIZE) < BOOTSIZE)
108*41074Swilliam Perror(name);
109*41074Swilliam if (lp->dk_magic != DISKMAGIC) {
110*41074Swilliam fprintf(stderr,
111*41074Swilliam "Bad pack magic number (pack is unlabeled)\n");
112*41074Swilliam #ifndef STANDALONE
113*41074Swilliam exit(1);
114*41074Swilliam #else
115*41074Swilliam continue ;
116*41074Swilliam #endif
117*41074Swilliam }
118*41074Swilliam #ifndef STANDALONE
119*41074Swilliam printf("%s (%.*s):\n", name, sizeof(lp->dk_name), lp->dk_name);
120*41074Swilliam #else
121*41074Swilliam printf("%s (%s):\n", name, lp->dk_name);
122*41074Swilliam #endif
123*41074Swilliam printf("%s, ", (unsigned) lp->dk_type < MAXTYPES?
124*41074Swilliam tnames[lp->dk_type] : "unknown type");
125*41074Swilliam if(lp->dk_type == DTYPE_SCSI) {
126*41074Swilliam printf("%d bytes/sector, %d sectors/drive, ",
127*41074Swilliam lp->dk_secsize, lp->dk_secperunit);
128*41074Swilliam printf("%d sectors/track,\n %d tracks/cylinder, ",
129*41074Swilliam lp->dk_secpercyl/lp->dk_ntracks,
130*41074Swilliam lp->dk_ntracks);
131*41074Swilliam printf ("%d sectors/cylinder, ", lp->dk_secpercyl) ;
132*41074Swilliam printf ("%s i/o mode\n", lp->dk_blind?"blind":"slow");
133*41074Swilliam } else {
134*41074Swilliam printf("%d bytes/sector, %d sectors/track, ",
135*41074Swilliam lp->dk_secsize, lp->dk_nsectors);
136*41074Swilliam printf("%d tracks/cylinder, %d cylinders\n",
137*41074Swilliam lp->dk_ntracks, lp->dk_ncylinders);
138*41074Swilliam if (lp->dk_secpercyl !=
139*41074Swilliam lp->dk_nsectors * lp->dk_ntracks)
140*41074Swilliam printf(
141*41074Swilliam "WARNING: sectors/cylinder field is wrong (%d instead of %d)\n",
142*41074Swilliam lp->dk_secpercyl,
143*41074Swilliam lp->dk_nsectors * lp->dk_ntracks);
144*41074Swilliam if (lp->dk_secperunit != lp->dk_nsectors *
145*41074Swilliam lp->dk_ntracks * lp->dk_ncylinders)
146*41074Swilliam printf(
147*41074Swilliam "WARNING: sectors/unit field is wrong (%d instead of %d)\n",
148*41074Swilliam lp->dk_secperunit,
149*41074Swilliam lp->dk_nsectors * lp->dk_ntracks *
150*41074Swilliam lp->dk_ncylinders);
151*41074Swilliam }
152*41074Swilliam #ifndef STANDALONE
153*41074Swilliam printf("partitions:\n");
154*41074Swilliam printf("\t size offset\n");
155*41074Swilliam #else
156*41074Swilliam printf("partition table:\n");
157*41074Swilliam #endif
158*41074Swilliam for (i = 0; i < 8; i++) {
159*41074Swilliam #ifndef STANDALONE
160*41074Swilliam printf("\t%c: %8d %8d", 'a' + i,
161*41074Swilliam #else
162*41074Swilliam printf("partition %c, size %d sectors, offset %d cylinders.", 'a' + i,
163*41074Swilliam #endif
164*41074Swilliam lp->dk_partition[i].nblocks, lp->dk_partition[i].cyloff);
165*41074Swilliam if (lp->dk_partition[i].nblocks){
166*41074Swilliam if (lp->dk_type != DTYPE_SCSI) {
167*41074Swilliam #ifndef STANDALONE
168*41074Swilliam printf("\t(Cyl. %d - %d",
169*41074Swilliam #else
170*41074Swilliam printf(" (from cyl %d to %d",
171*41074Swilliam #endif
172*41074Swilliam lp->dk_partition[i].cyloff,
173*41074Swilliam lp->dk_partition[i].cyloff +
174*41074Swilliam (lp->dk_partition[i].nblocks + lp->dk_secpercyl
175*41074Swilliam - 1) / lp->dk_secpercyl - 1);
176*41074Swilliam if (lp->dk_partition[i].nblocks % lp->dk_secpercyl)
177*41074Swilliam putchar('*');
178*41074Swilliam putchar(')');
179*41074Swilliam } else {
180*41074Swilliam }
181*41074Swilliam }
182*41074Swilliam printf("\n");
183*41074Swilliam }
184*41074Swilliam #ifdef STANDALONE
185*41074Swilliam continue ;
186*41074Swilliam wr_lab:
187*41074Swilliam printf("Type (e.g. miniscribe85...): ") ;
188*41074Swilliam gets(buf) ;
189*41074Swilliam dp = getdiskbyname(buf);
190*41074Swilliam if (dp == NULL) {
191*41074Swilliam printf("%s: unknown disk type\n", buf);
192*41074Swilliam #ifndef STANDALONE
193*41074Swilliam exit(1);
194*41074Swilliam #else
195*41074Swilliam continue ;
196*41074Swilliam #endif
197*41074Swilliam }
198*41074Swilliam #else
199*41074Swilliam exit(0);
200*41074Swilliam }
201*41074Swilliam dp = getdiskbyname(argv[2]);
202*41074Swilliam if (dp == NULL) {
203*41074Swilliam fprintf(stderr, "%s: unknown disk type\n", argv[2]);
204*41074Swilliam exit(1);
205*41074Swilliam }
206*41074Swilliam f = open(name, O_WRONLY);
207*41074Swilliam if (f < 0)
208*41074Swilliam Perror(name);
209*41074Swilliam #endif
210*41074Swilliam if (strcmp(dp->d_type, "scsi") == 0 || strcmp(dp->d_type, "SCSI") == 0)
211*41074Swilliam boot = scsiboot ; else boot = st506boot ;
212*41074Swilliam #ifndef STANDALONE
213*41074Swilliam if (argc > 4)
214*41074Swilliam boot = argv[4];
215*41074Swilliam #endif
216*41074Swilliam b = open(boot, O_RDONLY);
217*41074Swilliam if (b < 0)
218*41074Swilliam Perror(boot);
219*41074Swilliam if (read(b, &block0, BOOTSIZE) < 0)
220*41074Swilliam Perror(boot);
221*41074Swilliam close(b) ;
222*41074Swilliam for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++)
223*41074Swilliam if (*p) {
224*41074Swilliam fprintf(stderr,
225*41074Swilliam "Bootstrap doesn't leave room for disk label\n");
226*41074Swilliam exit(2);
227*41074Swilliam }
228*41074Swilliam lp->dk_magic = DISKMAGIC;
229*41074Swilliam if (strcmp(dp->d_type, "st506") == 0 ||
230*41074Swilliam strcmp(dp->d_type, "ST506") == 0) {
231*41074Swilliam lp->dk_type = DTYPE_ST506;
232*41074Swilliam lp->dk_precompcyl = dp->d_precomp;
233*41074Swilliam }
234*41074Swilliam if (strcmp(dp->d_type, "floppy") == 0)
235*41074Swilliam lp->dk_type = DTYPE_FLOPPY;
236*41074Swilliam if (strcmp(dp->d_type, "scsi") == 0)
237*41074Swilliam lp->dk_type = DTYPE_SCSI;
238*41074Swilliam
239*41074Swilliam if (strcmp(dp->d_type, "SCSI") == 0)
240*41074Swilliam lp->dk_type = DTYPE_SCSI;
241*41074Swilliam lp->dk_secsize = dp->d_secsize;
242*41074Swilliam lp->dk_nsectors = dp->d_nsectors;
243*41074Swilliam lp->dk_ntracks = dp->d_ntracks;
244*41074Swilliam lp->dk_ncylinders = dp->d_ncylinders;
245*41074Swilliam if (lp->dk_type == DTYPE_SCSI) {
246*41074Swilliam lp->dk_secpercyl = dp->d_secpercyl ;
247*41074Swilliam lp->dk_secperunit = dp->d_nsectors ;
248*41074Swilliam lp->dk_blind = dp->d_blind ;
249*41074Swilliam } else {
250*41074Swilliam lp->dk_secpercyl = dp->d_nsectors * dp->d_ntracks;
251*41074Swilliam lp->dk_secperunit = dp->d_nsectors * dp->d_ntracks
252*41074Swilliam * dp->d_ncylinders;
253*41074Swilliam }
254*41074Swilliam for (i = 0; i < 8; i++) {
255*41074Swilliam lp->dk_partition[i].nblocks = dp->d_partitions[i].p_size;
256*41074Swilliam if (lp->dk_partition[i].nblocks == -1)
257*41074Swilliam lp->dk_partition[i].nblocks = 0;
258*41074Swilliam lp->dk_partition[i].cyloff = dp->d_partitions[i].p_offset;
259*41074Swilliam if (lp->dk_partition[i].cyloff == -1)
260*41074Swilliam lp->dk_partition[i].cyloff = 0;
261*41074Swilliam }
262*41074Swilliam #ifndef STANDALONE
263*41074Swilliam if (argc > 3)
264*41074Swilliam strncpy(lp->dk_name, argv[3], sizeof(lp->dk_name));
265*41074Swilliam else
266*41074Swilliam #endif
267*41074Swilliam strncpy(lp->dk_name, dp->d_name, sizeof(lp->dk_name));
268*41074Swilliam if (write(f, &block0, BOOTSIZE) < BOOTSIZE)
269*41074Swilliam Perror("write");
270*41074Swilliam #ifdef STANDALONE
271*41074Swilliam }
272*41074Swilliam #endif
273*41074Swilliam exit(0);
274*41074Swilliam }
275*41074Swilliam
Perror(op)276*41074Swilliam Perror(op)
277*41074Swilliam char *op;
278*41074Swilliam {
279*41074Swilliam
280*41074Swilliam fprintf(stderr, "disklabel: "); /*perror(op);*/
281*41074Swilliam exit(4);
282*41074Swilliam }
283*41074Swilliam
284*41074Swilliam #ifdef STANDALONE
getdev(prompt,buf)285*41074Swilliam getdev(prompt, buf)
286*41074Swilliam char *buf ;
287*41074Swilliam {
288*41074Swilliam register int i;
289*41074Swilliam
290*41074Swilliam do {
291*41074Swilliam printf("%s: ", prompt);
292*41074Swilliam gets(buf);
293*41074Swilliam i = open(buf, 2);
294*41074Swilliam } while (i <= 0);
295*41074Swilliam return (i);
296*41074Swilliam }
297*41074Swilliam
fprintf(a,b,c,d,e,f,g,h)298*41074Swilliam fprintf(a,b,c,d,e,f,g,h) {
299*41074Swilliam printf(b,c,d,e,f,g,h) ;
300*41074Swilliam }
301*41074Swilliam #endif
302