rules.c revision 8160
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.2 1995/04/29 04:00:56 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
100/*
101 * Rule#2:
102 *	Max one 'fat' as child of 'whole'
103 */
104void
105Rule_002(struct disk *d, struct chunk *c, char *msg)
106{
107	int i;
108	struct chunk *c1;
109
110	if (c->type != whole)
111		return;
112	for (i=0, c1=c->part; c1; c1=c1->next) {
113		if (c1->type != fat)
114			continue;
115		i++;
116	}
117	if (i > 1) {
118		sprintf(msg+strlen(msg),
119		    "Max one 'fat' allowed as child of 'whole'\n");
120	}
121}
122
123/*
124 * Rule#3:
125 *	Max one extended as child of 'whole'
126 */
127void
128Rule_003(struct disk *d, struct chunk *c, char *msg)
129{
130	int i;
131	struct chunk *c1;
132
133	if (c->type != whole)
134		return;
135	for (i=0, c1=c->part; c1; c1=c1->next) {
136		if (c1->type != extended)
137			continue;
138		i++;
139	}
140	if (i > 1) {
141		sprintf(msg+strlen(msg),
142		    "Max one 'extended' allowed as child of 'whole'\n");
143	}
144}
145
146void
147Check_Chunk(struct disk *d, struct chunk *c, char *msg)
148{
149	Rule_000(d,c,msg);
150	Rule_001(d,c,msg);
151	Rule_002(d,c,msg);
152	Rule_003(d,c,msg);
153	if (c->part)
154		Check_Chunk(d,c->part,msg);
155	if (c->next)
156		Check_Chunk(d,c->next,msg);
157	return;
158}
159
160char *
161CheckRules(struct disk *d)
162{
163	char msg[BUFSIZ];
164
165	*msg = '\0';
166	Check_Chunk(d,d->chunks,msg);
167	if (*msg)
168		return strdup(msg);
169	return 0;
170}
171