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