121417Sdist /*
261111Sbostic * Copyright (c) 1983, 1987, 1993
361111Sbostic * The Regents of the University of California. All rights reserved.
435104Sbostic *
556242Selan * %sccs.include.redist.c%
621417Sdist */
710748Ssam
856242Selan #ifndef lint
9*69192Smckusick static char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 05/03/95";
1056242Selan #endif /* not lint */
1121417Sdist
1230420Skarels #include <sys/param.h>
1330420Skarels #define DKTYPENAMES
1430420Skarels #include <sys/disklabel.h>
15*69192Smckusick #include <ufs/ufs/dinode.h>
1651531Sbostic #include <ufs/ffs/fs.h>
1756409Sbostic
1856409Sbostic #include <errno.h>
1956409Sbostic #include <fcntl.h>
2010748Ssam #include <stdio.h>
2156409Sbostic #include <stdlib.h>
2242022Sbostic #include <string.h>
2346597Sdonn #include <unistd.h>
2410748Ssam
2556134Selan static int error __P((int));
2656134Selan static int gettype __P((char *, char **));
2710748Ssam
2830420Skarels struct disklabel *
getdiskbyname(name)2910748Ssam getdiskbyname(name)
3046597Sdonn const char *name;
3110748Ssam {
3233399Smarc static struct disklabel disk;
3330420Skarels register struct disklabel *dp = &disk;
3410760Ssam register struct partition *pp;
3556134Selan char *buf;
3656134Selan char *db_array[2] = { _PATH_DISKTAB, 0 };
3756134Selan char *cp, *cq; /* can't be register */
3833399Smarc char p, max, psize[3], pbsize[3],
3933399Smarc pfsize[3], poffset[3], ptype[3];
40*69192Smckusick u_int32_t *dx;
4110748Ssam
4256134Selan if (cgetent(&buf, db_array, (char *) name) < 0)
4356134Selan return NULL;
4456134Selan
4530420Skarels bzero((char *)&disk, sizeof(disk));
4633399Smarc /*
4733399Smarc * typename
4833399Smarc */
4930420Skarels cq = dp->d_typename;
5030420Skarels cp = buf;
5130420Skarels while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 &&
5230420Skarels (*cq = *cp) && *cq != '|' && *cq != ':')
5330420Skarels cq++, cp++;
5430420Skarels *cq = '\0';
5533399Smarc /*
5633399Smarc * boot name (optional) xxboot, bootxx
5733399Smarc */
5856134Selan cgetstr(buf, "b0", &dp->d_boot0);
5956134Selan cgetstr(buf, "b1", &dp->d_boot1);
6056134Selan
6156134Selan if (cgetstr(buf, "ty", &cq) > 0 && strcmp(cq, "removable") == 0)
6230420Skarels dp->d_flags |= D_REMOVABLE;
6330420Skarels else if (cq && strcmp(cq, "simulated") == 0)
6430420Skarels dp->d_flags |= D_RAMDISK;
6556134Selan if (cgetcap(buf, "sf", ':') != NULL)
6630420Skarels dp->d_flags |= D_BADSECT;
6733399Smarc
6830420Skarels #define getnumdflt(field, dname, dflt) \
6956134Selan { long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; }
7030420Skarels
7130420Skarels getnumdflt(dp->d_secsize, "se", DEV_BSIZE);
7256134Selan cgetnum(buf, "nt",(long *) &dp->d_ntracks);
7356134Selan cgetnum(buf, "ns",(long *) &dp->d_nsectors);
7456134Selan cgetnum(buf, "nc",(long *) &dp->d_ncylinders);
7556134Selan
7656134Selan if (cgetstr(buf, "dt", &cq) > 0)
7730420Skarels dp->d_type = gettype(cq, dktypenames);
7830420Skarels else
7930420Skarels getnumdflt(dp->d_type, "dt", 0);
8030420Skarels getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks);
8130420Skarels getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders);
8230420Skarels getnumdflt(dp->d_rpm, "rm", 3600);
8330420Skarels getnumdflt(dp->d_interleave, "il", 1);
8430420Skarels getnumdflt(dp->d_trackskew, "sk", 0);
8530420Skarels getnumdflt(dp->d_cylskew, "cs", 0);
8630420Skarels getnumdflt(dp->d_headswitch, "hs", 0);
8730420Skarels getnumdflt(dp->d_trkseek, "ts", 0);
8830420Skarels getnumdflt(dp->d_bbsize, "bs", BBSIZE);
8930420Skarels getnumdflt(dp->d_sbsize, "sb", SBSIZE);
9010760Ssam strcpy(psize, "px");
9110760Ssam strcpy(pbsize, "bx");
9210760Ssam strcpy(pfsize, "fx");
9330420Skarels strcpy(poffset, "ox");
9430420Skarels strcpy(ptype, "tx");
9530420Skarels max = 'a' - 1;
9630420Skarels pp = &dp->d_partitions[0];
9730420Skarels for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) {
9830420Skarels psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p;
9956134Selan if (cgetnum(buf, psize,(long *) &pp->p_size) == -1)
10030420Skarels pp->p_size = 0;
10130420Skarels else {
10256134Selan cgetnum(buf, poffset, (long *) &pp->p_offset);
10330420Skarels getnumdflt(pp->p_fsize, pfsize, 0);
10456134Selan if (pp->p_fsize) {
10556403Sralph long bsize;
10656403Sralph
10756403Sralph if (cgetnum(buf, pbsize, &bsize) == 0)
10856403Sralph pp->p_frag = bsize / pp->p_fsize;
10956403Sralph else
11056403Sralph pp->p_frag = 8;
11156134Selan }
11230420Skarels getnumdflt(pp->p_fstype, ptype, 0);
11356134Selan if (pp->p_fstype == 0 && cgetstr(buf, ptype, &cq) > 0)
11430420Skarels pp->p_fstype = gettype(cq, fstypenames);
11530420Skarels max = p;
11630420Skarels }
11710748Ssam }
11830420Skarels dp->d_npartitions = max + 1 - 'a';
11930681Sbostic (void)strcpy(psize, "dx");
12030420Skarels dx = dp->d_drivedata;
12130420Skarels for (p = '0'; p < '0' + NDDATA; p++, dx++) {
12230420Skarels psize[1] = p;
12330420Skarels getnumdflt(*dx, psize, 0);
12430420Skarels }
12530420Skarels dp->d_magic = DISKMAGIC;
12630420Skarels dp->d_magic2 = DISKMAGIC;
12756134Selan free(buf);
12810748Ssam return (dp);
12910748Ssam }
13010748Ssam
13156134Selan static int
gettype(t,names)13230420Skarels gettype(t, names)
13330420Skarels char *t;
13430420Skarels char **names;
13530420Skarels {
13630420Skarels register char **nm;
13730420Skarels
13830420Skarels for (nm = names; *nm; nm++)
13933261Smckusick if (strcasecmp(t, *nm) == 0)
14030420Skarels return (nm - names);
14130420Skarels if (isdigit(*t))
14230420Skarels return (atoi(t));
14330420Skarels return (0);
14430420Skarels }
14530420Skarels
14656134Selan static int
error(err)14745646Sbostic error(err)
14845646Sbostic int err;
14945646Sbostic {
15045646Sbostic char *p;
15145646Sbostic
15245646Sbostic (void)write(STDERR_FILENO, "disktab: ", 9);
15345646Sbostic (void)write(STDERR_FILENO, _PATH_DISKTAB, sizeof(_PATH_DISKTAB) - 1);
15453016Sbostic (void)write(STDERR_FILENO, ": ", 2);
15545646Sbostic p = strerror(err);
15645646Sbostic (void)write(STDERR_FILENO, p, strlen(p));
15745646Sbostic (void)write(STDERR_FILENO, "\n", 1);
15845646Sbostic }
159