rules.c revision 8157
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 *
9 * $Id: rules.c,v 1.1 1995/04/29 01:55:24 phk Exp $
10 *
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <string.h>
17#include <sys/types.h>
18#include <sys/diskslice.h>
19#include <sys/disklabel.h>
20#include <err.h>
21#include "libdisk.h"
22
23int
24Aligned(struct disk *d, u_long offset)
25{
26	if (!d->bios_sect)
27		return 1;
28	if (offset % d->bios_sect)
29		return 0;
30	return 1;
31}
32
33u_long
34Prev_Aligned(struct disk *d, u_long offset)
35{
36	if (!d->bios_sect)
37		return offset;
38	return (offset / d->bios_sect) * d->bios_sect;
39}
40
41u_long
42Next_Aligned(struct disk *d, u_long offset)
43{
44	if (!d->bios_sect)
45		return offset;
46	return Prev_Aligned(d,offset + d->bios_sect);
47}
48
49/*
50 *  Rule#0:
51 *	Chunks of type 'whole' can have max NDOSPART children.
52 */
53void
54Rule_000(struct disk *d, struct chunk *c, char *msg)
55{
56	int i;
57	struct chunk *c1;
58
59	if (c->type != whole)
60		return;
61	for (i=0, c1=c->part; c1; c1=c1->next)
62		if (c1->type != unused)
63			i++;
64	if (i <= NDOSPART)
65		return;
66	sprintf(msg+strlen(msg),
67		"%d is too many children of the 'whole' chunk.  Max is %d\n",
68		i, NDOSPART);
69}
70
71/*
72 * Rule#1:
73 *	All children of 'whole' must be track-aligned.
74 *	Exception: the end can be unaligned if it matches the end of 'whole'
75 */
76void
77Rule_001(struct disk *d, struct chunk *c, char *msg)
78{
79	int i;
80	struct chunk *c1;
81
82	if (c->type != whole)
83		return;
84	for (i=0, c1=c->part; c1; c1=c1->next) {
85		if (c1->type == reserved)
86			continue;
87		if (c1->type == unused)
88			continue;
89		if (!Aligned(d,c1->offset))
90			sprintf(msg+strlen(msg),
91		    "chunk '%s' [%ld..%ld] does not start on a track boundary\n",
92				c1->name,c1->offset,c1->end);
93		if (c->end != c1->end && !Aligned(d,c1->end+1))
94			sprintf(msg+strlen(msg),
95		    "chunk '%s' [%ld..%ld] does not end on a track boundary\n",
96				c1->name,c1->offset,c1->end);
97	}
98}
99
100void
101Check_Chunk(struct disk *d, struct chunk *c, char *msg)
102{
103	Rule_000(d,c,msg);
104	Rule_001(d,c,msg);
105	if (c->part)
106		Check_Chunk(d,c->part,msg);
107	if (c->next)
108		Check_Chunk(d,c->next,msg);
109	return;
110}
111
112char *
113CheckRules(struct disk *d)
114{
115	char msg[BUFSIZ];
116
117	*msg = '\0';
118	Check_Chunk(d,d->chunks,msg);
119	if (*msg)
120		return strdup(msg);
121	return 0;
122}
123