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