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
main(argc,argv)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
Perror(op)276 Perror(op)
277 char *op;
278 {
279
280 fprintf(stderr, "disklabel: "); /*perror(op);*/
281 exit(4);
282 }
283
284 #ifdef STANDALONE
getdev(prompt,buf)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
fprintf(a,b,c,d,e,f,g,h)298 fprintf(a,b,c,d,e,f,g,h) {
299 printf(b,c,d,e,f,g,h) ;
300 }
301 #endif
302