* Copyright (c) 1983, 1987 Regents of the University of California.
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)disklabel.c 5.13 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <sys/disklabel.h>
static struct disklabel disk
;
static char boot
[BUFSIZ
];
char *cp
, *cq
; /* can't be register */
register struct disklabel
*dp
= &disk
;
register struct partition
*pp
;
char p
, max
, psize
[3], pbsize
[3],
pfsize
[3], poffset
[3], ptype
[3];
if (dgetent(buf
, name
) <= 0)
return ((struct disklabel
*)0);
bzero((char *)&disk
, sizeof(disk
));
while (cq
< dp
->d_typename
+ sizeof(dp
->d_typename
) - 1 &&
(*cq
= *cp
) && *cq
!= '|' && *cq
!= ':')
* boot name (optional) xxboot, bootxx
dp
->d_boot0
= dgetstr("b0", &cp
);
dp
->d_boot1
= dgetstr("b1", &cp
);
if (cq
&& strcmp(cq
, "removable") == 0)
dp
->d_flags
|= D_REMOVABLE
;
else if (cq
&& strcmp(cq
, "simulated") == 0)
dp
->d_flags
|= D_RAMDISK
;
dp
->d_flags
|= D_BADSECT
;
#define getnumdflt(field, dname, dflt) \
{ int f = dgetnum(dname); \
(field) = f == -1 ? (dflt) : f; }
getnumdflt(dp
->d_secsize
, "se", DEV_BSIZE
);
dp
->d_ntracks
= dgetnum("nt");
dp
->d_nsectors
= dgetnum("ns");
dp
->d_ncylinders
= dgetnum("nc");
dp
->d_type
= gettype(cq
, dktypenames
);
getnumdflt(dp
->d_type
, "dt", 0);
getnumdflt(dp
->d_secpercyl
, "sc", dp
->d_nsectors
* dp
->d_ntracks
);
getnumdflt(dp
->d_secperunit
, "su", dp
->d_secpercyl
* dp
->d_ncylinders
);
getnumdflt(dp
->d_rpm
, "rm", 3600);
getnumdflt(dp
->d_interleave
, "il", 1);
getnumdflt(dp
->d_trackskew
, "sk", 0);
getnumdflt(dp
->d_cylskew
, "cs", 0);
getnumdflt(dp
->d_headswitch
, "hs", 0);
getnumdflt(dp
->d_trkseek
, "ts", 0);
getnumdflt(dp
->d_bbsize
, "bs", BBSIZE
);
getnumdflt(dp
->d_sbsize
, "sb", SBSIZE
);
pp
= &dp
->d_partitions
[0];
for (p
= 'a'; p
< 'a' + MAXPARTITIONS
; p
++, pp
++) {
psize
[1] = pbsize
[1] = pfsize
[1] = poffset
[1] = ptype
[1] = p
;
pp
->p_size
= dgetnum(psize
);
pp
->p_offset
= dgetnum(poffset
);
getnumdflt(pp
->p_fsize
, pfsize
, 0);
pp
->p_frag
= dgetnum(pbsize
) / pp
->p_fsize
;
getnumdflt(pp
->p_fstype
, ptype
, 0);
if (pp
->p_fstype
== 0 && (cq
= dgetstr(ptype
, &cp
)))
pp
->p_fstype
= gettype(cq
, fstypenames
);
dp
->d_npartitions
= max
+ 1 - 'a';
(void)strcpy(psize
, "dx");
for (p
= '0'; p
< '0' + NDDATA
; p
++, dx
++) {
getnumdflt(*dx
, psize
, 0);
dp
->d_magic2
= DISKMAGIC
;
* Get an entry for disk name in buffer bp,
* from the diskcap file. Parse is very rudimentary;
* we just notice escaped newlines.
register int i
= 0, cnt
= 0;
cnt
= read(tf
, ibuf
, BUFSIZ
);
if (cp
> bp
&& cp
[-1] == '\\'){
write(2,"Disktab entry too long\n", 23);
* The real work for the match.
* Dnamatch deals with name matching. The first field of the disktab
* entry is a sequence of names separated by |'s, so we compare
* against each such name. The normal : terminator after the last
* name (before the first field) stops us.
for (Np
= np
; *Np
&& *Bp
== *Np
; Bp
++, Np
++)
if (*Np
== 0 && (*Bp
== '|' || *Bp
== ':' || *Bp
== 0))
while (*Bp
&& *Bp
!= ':' && *Bp
!= '|')
if (*Bp
== 0 || *Bp
== ':')
* Skip to the next field. Notice that this is very dumb, not
* knowing about \: escapes or any such. If necessary, :'s can be put
* into the diskcap file in octal.
while (*bp
&& *bp
!= ':')
* Return the (numeric) option id.
* Numeric options look like
* i.e. the option string is separated from the numeric value by
* a # character. If the option is not found we return -1.
* Note that we handle octal numbers beginning with 0.
register char *bp
= tbuf
;
if (*bp
++ != id
[0] || *bp
== 0 || *bp
++ != id
[1])
i
*= base
, i
+= *bp
++ - '0';
* Flag options are given "naked", i.e. followed by a : or the end
* of the buffer. Return 1 if we find the option, or 0 if it is
register char *bp
= tbuf
;
if (*bp
++ == id
[0] && *bp
!= 0 && *bp
++ == id
[1]) {
* Get a string valued option.
* Much decoding is done on the strings, and the strings are
* placed in area, which is a ref parameter which is updated.
* No checking on area overflow.
register char *bp
= tbuf
;
if (*bp
++ != id
[0] || *bp
== 0 || *bp
++ != id
[1])
return (ddecode(bp
, area
));
* Tdecode does the grung work to decode the
* string capability escapes.
while ((c
= *str
++) && c
!= ':') {
dp
= "E\033^^\\\\::n\nr\rt\tb\bf\f";
c
<<= 3, c
|= *str
++ - '0';
while (--i
&& isdigit(*str
));
for (nm
= names
; *nm
; nm
++)
if (strcasecmp(t
, *nm
) == 0)
register struct disklabel
*lp
;
register u_short
*start
, *end
;
register u_short sum
= 0;
end
= (u_short
*)&lp
->d_partitions
[lp
->d_npartitions
];