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