| File: | ptserver/db_verify.c |
| Location: | line 408, column 2 |
| Description: | Value stored to 'sghead' is never read |
| 1 | /* |
| 2 | * Copyright 2000, International Business Machines Corporation and others. |
| 3 | * All Rights Reserved. |
| 4 | * |
| 5 | * This software has been released under the terms of the IBM Public |
| 6 | * License. For details, see the LICENSE file in the top-level source |
| 7 | * directory or online at http://www.openafs.org/dl/license10.html |
| 8 | */ |
| 9 | |
| 10 | #include <afsconfig.h> |
| 11 | #include <afs/param.h> |
| 12 | #include <afs/stds.h> |
| 13 | |
| 14 | #include <roken.h> |
| 15 | |
| 16 | /* |
| 17 | * (3) Define a structure, idused, instead of an |
| 18 | * array of long integers, idmap, to count group |
| 19 | * memberships. These structures are on a linked |
| 20 | * list, with each structure containing IDCOUNT |
| 21 | * slots for id's. |
| 22 | * (4) Add new functions to processs the structure |
| 23 | * described above: |
| 24 | * zeromap(), idcount(), inccount(). |
| 25 | * (5) Add code, primarily in WalkNextChain(): |
| 26 | * 1. Test id's, allowing groups within groups. |
| 27 | * 2. Count the membership list for supergroups, |
| 28 | * and follow the continuation chain for |
| 29 | * supergroups. |
| 30 | * (6) Add fprintf statements for various error |
| 31 | * conditions. |
| 32 | */ |
| 33 | |
| 34 | |
| 35 | #ifdef AFS_NT40_ENV |
| 36 | #include <WINNT/afsevent.h> |
| 37 | #else |
| 38 | #include <sys/file.h> |
| 39 | #endif |
| 40 | |
| 41 | #include <afs/cellconfig.h> |
| 42 | #include <afs/afsutil.h> |
| 43 | #include <ubik.h> |
| 44 | #include <afs/cmd.h> |
| 45 | #include <afs/com_err.h> |
| 46 | |
| 47 | #include "ptint.h" |
| 48 | #include "pterror.h" |
| 49 | #include "ptserver.h" |
| 50 | #include "ptuser.h" |
| 51 | #include "display.h" |
| 52 | |
| 53 | struct prheader cheader; |
| 54 | int fd; |
| 55 | const char *pr_dbaseName; |
| 56 | char *whoami = "db_verify"; |
| 57 | #define UBIK_HEADERSIZE64 64 |
| 58 | |
| 59 | afs_int32 |
| 60 | printheader(struct prheader *h) |
| 61 | { |
| 62 | printf("Version = %d\n", ntohl(h->version)(__builtin_constant_p(h->version) ? ((((__uint32_t)(h-> version)) >> 24) | ((((__uint32_t)(h->version)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->version )) & (0xff << 8)) << 8) | (((__uint32_t)(h-> version)) << 24)) : __bswap32_var(h->version))); |
| 63 | printf("Header Size = %d\n", ntohl(h->headerSize)(__builtin_constant_p(h->headerSize) ? ((((__uint32_t)(h-> headerSize)) >> 24) | ((((__uint32_t)(h->headerSize) ) & (0xff << 16)) >> 8) | ((((__uint32_t)(h-> headerSize)) & (0xff << 8)) << 8) | (((__uint32_t )(h->headerSize)) << 24)) : __bswap32_var(h->headerSize ))); |
| 64 | printf("Free Ptr = 0x%x\n", ntohl(h->freePtr)(__builtin_constant_p(h->freePtr) ? ((((__uint32_t)(h-> freePtr)) >> 24) | ((((__uint32_t)(h->freePtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->freePtr )) & (0xff << 8)) << 8) | (((__uint32_t)(h-> freePtr)) << 24)) : __bswap32_var(h->freePtr))); |
| 65 | printf("EOF Ptr = 0x%x\n", ntohl(h->eofPtr)(__builtin_constant_p(h->eofPtr) ? ((((__uint32_t)(h->eofPtr )) >> 24) | ((((__uint32_t)(h->eofPtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->eofPtr)) & (0xff << 8)) << 8) | (((__uint32_t)(h->eofPtr)) << 24)) : __bswap32_var(h->eofPtr))); |
| 66 | printf("Max Group ID = %d\n", ntohl(h->maxGroup)(__builtin_constant_p(h->maxGroup) ? ((((__uint32_t)(h-> maxGroup)) >> 24) | ((((__uint32_t)(h->maxGroup)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->maxGroup )) & (0xff << 8)) << 8) | (((__uint32_t)(h-> maxGroup)) << 24)) : __bswap32_var(h->maxGroup))); |
| 67 | printf("Max User ID = %d\n", ntohl(h->maxID)(__builtin_constant_p(h->maxID) ? ((((__uint32_t)(h->maxID )) >> 24) | ((((__uint32_t)(h->maxID)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->maxID)) & (0xff << 8)) << 8) | (((__uint32_t)(h->maxID)) << 24)) : __bswap32_var(h->maxID))); |
| 68 | printf("Max Foreign ID = %d\n", ntohl(h->maxForeign)(__builtin_constant_p(h->maxForeign) ? ((((__uint32_t)(h-> maxForeign)) >> 24) | ((((__uint32_t)(h->maxForeign) ) & (0xff << 16)) >> 8) | ((((__uint32_t)(h-> maxForeign)) & (0xff << 8)) << 8) | (((__uint32_t )(h->maxForeign)) << 24)) : __bswap32_var(h->maxForeign ))); |
| 69 | /* printf("Max Sub/Super ID = %d\n", ntohl(h->maxInst)); */ |
| 70 | printf("Orphaned groups = %d\n", ntohl(h->orphan)(__builtin_constant_p(h->orphan) ? ((((__uint32_t)(h->orphan )) >> 24) | ((((__uint32_t)(h->orphan)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->orphan)) & (0xff << 8)) << 8) | (((__uint32_t)(h->orphan)) << 24)) : __bswap32_var(h->orphan))); |
| 71 | printf("User Count = %d\n", ntohl(h->usercount)(__builtin_constant_p(h->usercount) ? ((((__uint32_t)(h-> usercount)) >> 24) | ((((__uint32_t)(h->usercount)) & (0xff << 16)) >> 8) | ((((__uint32_t)(h->usercount )) & (0xff << 8)) << 8) | (((__uint32_t)(h-> usercount)) << 24)) : __bswap32_var(h->usercount))); |
| 72 | printf("Group Count = %d\n", ntohl(h->groupcount)(__builtin_constant_p(h->groupcount) ? ((((__uint32_t)(h-> groupcount)) >> 24) | ((((__uint32_t)(h->groupcount) ) & (0xff << 16)) >> 8) | ((((__uint32_t)(h-> groupcount)) & (0xff << 8)) << 8) | (((__uint32_t )(h->groupcount)) << 24)) : __bswap32_var(h->groupcount ))); |
| 73 | /* printf("Foreign Count = %d\n", ntohl(h->foreigncount)); NYI */ |
| 74 | /* printf("Sub/super Count = %d\n", ntohl(h->instcount)); NYI */ |
| 75 | printf("Name Hash = %d buckets\n", HASHSIZE8191); |
| 76 | printf("ID Hash = %d buckets\n", HASHSIZE8191); |
| 77 | return 0; |
| 78 | } |
| 79 | |
| 80 | static afs_int32 |
| 81 | pr_Read(afs_int32 pos, void *buff, afs_int32 len) |
| 82 | { |
| 83 | afs_int32 code; |
| 84 | |
| 85 | code = lseek(fd, UBIK_HEADERSIZE64 + pos, 0); |
| 86 | if (code == -1) |
| 87 | return errno(* __error()); |
| 88 | |
| 89 | code = read(fd, buff, len); |
| 90 | if (code != len) |
| 91 | return -1; |
| 92 | if (code == -1) |
| 93 | return errno(* __error()); |
| 94 | |
| 95 | return 0; |
| 96 | } |
| 97 | |
| 98 | /* InitDB () |
| 99 | * Initializes the a transaction on the database and reads the header into |
| 100 | * the static variable cheader. If successful it returns a read-locked |
| 101 | * transaction. If ubik reports that cached database info should be up to date |
| 102 | * the cheader structure is not re-read from the ubik. |
| 103 | */ |
| 104 | |
| 105 | afs_int32 |
| 106 | ReadHeader(void) |
| 107 | { |
| 108 | afs_int32 code; |
| 109 | |
| 110 | code = pr_Read(0, (char *)&cheader, sizeof(cheader)); |
| 111 | if (code) { |
| 112 | afs_com_err(whoami, code, "couldn't read header"); |
| 113 | return code; |
| 114 | } |
| 115 | /* Check and see if database exists and is approximately OK. */ |
| 116 | if (ntohl(cheader.headerSize)(__builtin_constant_p(cheader.headerSize) ? ((((__uint32_t)(cheader .headerSize)) >> 24) | ((((__uint32_t)(cheader.headerSize )) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .headerSize)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.headerSize)) << 24)) : __bswap32_var(cheader. headerSize)) != sizeof(cheader) |
| 117 | || ntohl(cheader.eofPtr)(__builtin_constant_p(cheader.eofPtr) ? ((((__uint32_t)(cheader .eofPtr)) >> 24) | ((((__uint32_t)(cheader.eofPtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.eofPtr )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .eofPtr)) << 24)) : __bswap32_var(cheader.eofPtr)) == 0) { |
| 118 | if (code) |
| 119 | return code; |
| 120 | afs_com_err(whoami, PRDBBAD(267275L), "header is bad"); |
| 121 | return PRDBBAD(267275L); |
| 122 | } |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | static afs_int32 |
| 127 | IDHash(afs_int32 x) |
| 128 | { |
| 129 | /* returns hash bucket for x */ |
| 130 | return ((abs(x)) % HASHSIZE8191); |
| 131 | } |
| 132 | |
| 133 | static afs_int32 |
| 134 | NameHash(char *aname) |
| 135 | { |
| 136 | /* returns hash bucket for aname */ |
| 137 | unsigned int hash = 0; |
| 138 | int i; |
| 139 | /* stolen directly from the HashString function in the vol package */ |
| 140 | for (i = strlen(aname), aname += i - 1; i--; aname--) |
| 141 | hash = (hash * 31) + (*(unsigned char *)aname - 31); |
| 142 | return (hash % HASHSIZE8191); |
| 143 | } |
| 144 | |
| 145 | #define MAP_NAMEHASH1 1 |
| 146 | #define MAP_IDHASH2 2 |
| 147 | #define MAP_HASHES(1 | 2) (MAP_NAMEHASH1 | MAP_IDHASH2) |
| 148 | #define MAP_CONT4 4 |
| 149 | #define MAP_FREE8 8 |
| 150 | #define MAP_OWNED0x10 0x10 |
| 151 | #define MAP_RECREATE0x20 0x20 |
| 152 | |
| 153 | struct misc_data { |
| 154 | int nEntries; /* number of database entries */ |
| 155 | int anon; /* found anonymous Id */ |
| 156 | afs_int32 maxId; /* user */ |
| 157 | afs_int32 minId; /* group */ |
| 158 | afs_int32 maxForId; /* foreign user id */ |
| 159 | #if defined(SUPERGROUPS1) |
| 160 | #define IDCOUNT512 512 |
| 161 | struct idused { |
| 162 | int idstart; |
| 163 | afs_int32 idcount[IDCOUNT512]; |
| 164 | struct idused *idnext; |
| 165 | } *idmap; |
| 166 | #else |
| 167 | int idRange; /* number of ids in map */ |
| 168 | afs_int32 *idmap; /* map of all id's: midId is origin */ |
| 169 | #endif /* SUPERGROUPS */ |
| 170 | int nusers; /* counts of each type */ |
| 171 | int ngroups; |
| 172 | int nforeigns; |
| 173 | int ninsts; |
| 174 | int ncells; |
| 175 | int maxOwnerLength; /* longest owner chain */ |
| 176 | int maxContLength; /* longest chain of cont. blks */ |
| 177 | int orphanLength; /* length of orphan list */ |
| 178 | int freeLength; /* length of free list */ |
| 179 | int verbose; |
| 180 | int listuheader; |
| 181 | int listpheader; |
| 182 | int listentries; |
| 183 | FILE *recreate; /* stream for recreate instructions */ |
| 184 | }; |
| 185 | |
| 186 | #if defined(SUPERGROUPS1) |
| 187 | void zeromap(struct idused *idmap); |
| 188 | void inccount(struct idused **idmapp, int id); |
| 189 | int idcount(struct idused **idmapp, int id); |
| 190 | #endif |
| 191 | |
| 192 | int |
| 193 | readUbikHeader(struct misc_data *misc) |
| 194 | { |
| 195 | int offset, r; |
| 196 | struct ubik_hdr uheader; |
| 197 | |
| 198 | offset = lseek(fd, 0, 0); |
| 199 | if (offset != 0) { |
| 200 | printf("error: lseek to 0 failed: %d %d\n", offset, errno(* __error())); |
| 201 | return (-1); |
| 202 | } |
| 203 | |
| 204 | /* now read the info */ |
| 205 | r = read(fd, &uheader, sizeof(uheader)); |
| 206 | if (r != sizeof(uheader)) { |
| 207 | printf("error: read of %" AFS_SIZET_FMT"zu" " bytes failed: %d %d\n", |
| 208 | sizeof(uheader), r, errno(* __error())); |
| 209 | return (-1); |
| 210 | } |
| 211 | |
| 212 | uheader.magic = ntohl(uheader.magic)(__builtin_constant_p(uheader.magic) ? ((((__uint32_t)(uheader .magic)) >> 24) | ((((__uint32_t)(uheader.magic)) & (0xff << 16)) >> 8) | ((((__uint32_t)(uheader.magic )) & (0xff << 8)) << 8) | (((__uint32_t)(uheader .magic)) << 24)) : __bswap32_var(uheader.magic)); |
| 213 | uheader.size = ntohl(uheader.size)(__builtin_constant_p(uheader.size) ? ((((__uint32_t)(uheader .size)) >> 24) | ((((__uint32_t)(uheader.size)) & ( 0xff << 16)) >> 8) | ((((__uint32_t)(uheader.size )) & (0xff << 8)) << 8) | (((__uint32_t)(uheader .size)) << 24)) : __bswap32_var(uheader.size)); |
| 214 | uheader.version.epoch = ntohl(uheader.version.epoch)(__builtin_constant_p(uheader.version.epoch) ? ((((__uint32_t )(uheader.version.epoch)) >> 24) | ((((__uint32_t)(uheader .version.epoch)) & (0xff << 16)) >> 8) | (((( __uint32_t)(uheader.version.epoch)) & (0xff << 8)) << 8) | (((__uint32_t)(uheader.version.epoch)) << 24)) : __bswap32_var (uheader.version.epoch)); |
| 215 | uheader.version.counter = ntohl(uheader.version.counter)(__builtin_constant_p(uheader.version.counter) ? ((((__uint32_t )(uheader.version.counter)) >> 24) | ((((__uint32_t)(uheader .version.counter)) & (0xff << 16)) >> 8) | (( ((__uint32_t)(uheader.version.counter)) & (0xff << 8 )) << 8) | (((__uint32_t)(uheader.version.counter)) << 24)) : __bswap32_var(uheader.version.counter)); |
| 216 | |
| 217 | if (misc->listuheader) { |
| 218 | printf("Ubik Header\n"); |
| 219 | printf(" Magic = 0x%x\n", uheader.magic); |
| 220 | printf(" Size = %u\n", uheader.size); |
| 221 | printf(" Version.epoch = %u\n", uheader.version.epoch); |
| 222 | printf(" Version.counter = %u\n", uheader.version.counter); |
| 223 | } |
| 224 | |
| 225 | if (uheader.size != UBIK_HEADERSIZE64) |
| 226 | printf("Ubik header size is %u (should be %u)\n", uheader.size, |
| 227 | UBIK_HEADERSIZE64); |
| 228 | if (uheader.magic != UBIK_MAGIC0x354545) |
| 229 | printf("Ubik header magic is 0x%x (should be 0x%x)\n", uheader.magic, |
| 230 | UBIK_MAGIC0x354545); |
| 231 | |
| 232 | return (0); |
| 233 | } |
| 234 | |
| 235 | afs_int32 |
| 236 | ConvertDiskAddress(afs_uint32 ea, int *eiP) |
| 237 | { |
| 238 | int i; |
| 239 | |
| 240 | *eiP = -1; |
| 241 | |
| 242 | if (ea < sizeof(cheader)) |
| 243 | return PRDBADDR(267278L); |
| 244 | if (ea >= ntohl(cheader.eofPtr)(__builtin_constant_p(cheader.eofPtr) ? ((((__uint32_t)(cheader .eofPtr)) >> 24) | ((((__uint32_t)(cheader.eofPtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.eofPtr )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .eofPtr)) << 24)) : __bswap32_var(cheader.eofPtr))) |
| 245 | return PRDBADDR(267278L); |
| 246 | ea -= sizeof(cheader); |
| 247 | i = ea / sizeof(struct prentry); |
| 248 | if (i * sizeof(struct prentry) != ea) |
| 249 | return PRDBADDR(267278L); |
| 250 | /* if ((i < 0) || (i >= misc->nEntries)) return PRDBADDR; */ |
| 251 | *eiP = i; |
| 252 | return 0; |
| 253 | } |
| 254 | |
| 255 | int |
| 256 | PrintEntryError(struct misc_data *misc, afs_int32 ea, struct prentry *e, int indent) |
| 257 | { |
| 258 | |
| 259 | pr_PrintEntry(stderr__stderrp, /*net order */ 0, ea, e, indent); |
| 260 | return 0; |
| 261 | } |
| 262 | |
| 263 | afs_int32 |
| 264 | WalkHashTable(afs_int32 hashtable[], /* hash table to walk */ |
| 265 | int hashType, /* hash function to use */ |
| 266 | char map[], /* one byte per db entry */ |
| 267 | struct misc_data *misc) /* stuff to keep track of */ |
| 268 | { |
| 269 | afs_int32 code; |
| 270 | int hi; /* index in hash table */ |
| 271 | afs_int32 ea; /* entry's db addr */ |
| 272 | int ei; /* entry's index */ |
| 273 | char bit; /* bits to check for in map */ |
| 274 | struct prentry e; |
| 275 | afs_int32 next_ea; |
| 276 | afs_int32 id; |
| 277 | afs_int32 flags; |
| 278 | afs_int32 hash; |
| 279 | |
| 280 | bit = hashType; |
| 281 | |
| 282 | for (hi = 0; hi < HASHSIZE8191; hi++) { |
| 283 | ea = 0; |
| 284 | next_ea = ntohl(hashtable[hi])(__builtin_constant_p(hashtable[hi]) ? ((((__uint32_t)(hashtable [hi])) >> 24) | ((((__uint32_t)(hashtable[hi])) & ( 0xff << 16)) >> 8) | ((((__uint32_t)(hashtable[hi ])) & (0xff << 8)) << 8) | (((__uint32_t)(hashtable [hi])) << 24)) : __bswap32_var(hashtable[hi])); |
| 285 | while (next_ea) { |
| 286 | code = ConvertDiskAddress(next_ea, &ei); |
| 287 | if (code) { |
| 288 | fprintf(stderr__stderrp, "Bad chain address %d\n", next_ea); |
| 289 | if (ea) { |
| 290 | fprintf(stderr__stderrp, "Last entry in chain:\n"); |
| 291 | if (PrintEntryError(misc, ea, &e, 2)) |
| 292 | return PRDBBAD(267275L); |
| 293 | } |
| 294 | fprintf(stderr__stderrp, "Skipping remainder of hash bucket %d\n", hi); |
| 295 | break; |
| 296 | } |
| 297 | ea = next_ea; |
| 298 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 299 | if (code) |
| 300 | return code; |
| 301 | |
| 302 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 303 | |
| 304 | if (((e.flags & htonl((PRGRP | PRINST))(__builtin_constant_p((2 | 32)) ? ((((__uint32_t)((2 | 32))) >> 24) | ((((__uint32_t)((2 | 32))) & (0xff << 16)) >> 8) | ((((__uint32_t)((2 | 32))) & (0xff << 8)) << 8) | (((__uint32_t)((2 | 32))) << 24)) : __bswap32_var ((2 | 32)))) == 0) |
| 305 | && (strchr(e.name, '@'))) { |
| 306 | /* Foreign user */ |
| 307 | if (id > misc->maxForId) |
| 308 | misc->maxForId = id; |
| 309 | } else { |
| 310 | if (id == ANONYMOUSID32766) |
| 311 | misc->anon++; |
| 312 | else if (id > misc->maxId) |
| 313 | misc->maxId = id; |
| 314 | if (id < misc->minId) |
| 315 | misc->minId = id; |
| 316 | } |
| 317 | |
| 318 | switch (hashType) { |
| 319 | case MAP_NAMEHASH1: |
| 320 | next_ea = ntohl(e.nextName)(__builtin_constant_p(e.nextName) ? ((((__uint32_t)(e.nextName )) >> 24) | ((((__uint32_t)(e.nextName)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.nextName)) & (0xff << 8)) << 8) | (((__uint32_t)(e.nextName)) << 24)) : __bswap32_var(e.nextName)); |
| 321 | hash = NameHash(e.name); |
| 322 | break; |
| 323 | case MAP_IDHASH2: |
| 324 | next_ea = ntohl(e.nextID)(__builtin_constant_p(e.nextID) ? ((((__uint32_t)(e.nextID)) >> 24) | ((((__uint32_t)(e.nextID)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.nextID)) & (0xff << 8)) << 8) | (((__uint32_t)(e.nextID)) << 24)) : __bswap32_var (e.nextID)); |
| 325 | hash = IDHash(id); |
| 326 | break; |
| 327 | default: |
| 328 | fprintf(stderr__stderrp, "unknown hash table type %d\n", hashType); |
| 329 | return PRBADARG(267273L); |
| 330 | } |
| 331 | |
| 332 | if (map[ei] & bit) { |
| 333 | fprintf(stderr__stderrp, |
| 334 | "Entry found twice in hash table: bucket %d\n", hi); |
| 335 | if (hi != hash) |
| 336 | fprintf(stderr__stderrp, "also in wrong bucket: should be in %d\n", |
| 337 | hash); |
| 338 | if (PrintEntryError(misc, ea, &e, 2)) |
| 339 | return PRDBBAD(267275L); |
| 340 | break; |
| 341 | } |
| 342 | map[ei] |= bit; |
| 343 | |
| 344 | flags = ntohl(e.flags)(__builtin_constant_p(e.flags) ? ((((__uint32_t)(e.flags)) >> 24) | ((((__uint32_t)(e.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.flags)) & (0xff << 8)) << 8) | (((__uint32_t)(e.flags)) << 24)) : __bswap32_var( e.flags)); |
| 345 | switch (flags & PRTYPE0x3f) { |
| 346 | case PRFREE1: |
| 347 | fprintf(stderr__stderrp, "ENTRY IS FREE"); |
| 348 | goto abort; |
| 349 | case PRCONT4: |
| 350 | fprintf(stderr__stderrp, "ENTRY IS CONTINUATION"); |
| 351 | goto abort; |
| 352 | case PRGRP2: |
| 353 | case PRUSER0: |
| 354 | break; |
| 355 | case PRCELL8: |
| 356 | case PRFOREIGN16: |
| 357 | case PRINST32: |
| 358 | fprintf(stderr__stderrp, "ENTRY IS unexpected type (flags=0x%x)\n", |
| 359 | flags); |
| 360 | break; |
| 361 | default: |
| 362 | fprintf(stderr__stderrp, "ENTRY IS OF unknown type (flags=0x%x)\n", |
| 363 | flags); |
| 364 | goto abort; |
| 365 | } |
| 366 | |
| 367 | if (hash != hi) { |
| 368 | fprintf(stderr__stderrp, "entry hashed in bucket %d should be %d\n", |
| 369 | hi, hash); |
| 370 | abort: |
| 371 | if (PrintEntryError(misc, ea, &e, 2)) |
| 372 | return PRDBBAD(267275L); |
| 373 | continue; |
| 374 | } |
| 375 | } |
| 376 | } |
| 377 | return 0; |
| 378 | } |
| 379 | |
| 380 | afs_int32 |
| 381 | WalkNextChain(char map[], /* one byte per db entry */ |
| 382 | struct misc_data *misc, /* stuff to keep track of */ |
| 383 | afs_int32 ea, struct prentry *e) |
| 384 | { |
| 385 | afs_int32 head; |
| 386 | int bit; |
| 387 | afs_int32 code; |
| 388 | struct prentry c; /* continuation entry */ |
| 389 | afs_int32 na; /* next thread */ |
| 390 | int ni; |
| 391 | afs_int32 eid = 0; |
| 392 | int count = 0; /* number of members, set to > 9999 if */ |
| 393 | /* list ends early */ |
| 394 | int i; |
| 395 | int noErrors = 1; |
| 396 | int length; /* length of chain */ |
| 397 | #if defined(SUPERGROUPS1) |
| 398 | int sgcount = 0; /* number of sgentrys */ |
| 399 | afs_int32 sghead; |
| 400 | #define g (((struct prentryg *)e)) |
| 401 | #endif |
| 402 | |
| 403 | if (e) { |
| 404 | head = ntohl(e->next)(__builtin_constant_p(e->next) ? ((((__uint32_t)(e->next )) >> 24) | ((((__uint32_t)(e->next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->next)) & (0xff << 8)) << 8) | (((__uint32_t)(e->next)) << 24)) : __bswap32_var(e->next)); |
| 405 | eid = ntohl(e->id)(__builtin_constant_p(e->id) ? ((((__uint32_t)(e->id)) >> 24) | ((((__uint32_t)(e->id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->id)) & (0xff << 8)) << 8) | (((__uint32_t)(e->id)) << 24)) : __bswap32_var (e->id)); |
| 406 | bit = MAP_CONT4; |
| 407 | #if defined(SUPERGROUPS1) |
| 408 | sghead = ntohl(g->next)(__builtin_constant_p(g->next) ? ((((__uint32_t)(g->next )) >> 24) | ((((__uint32_t)(g->next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(g->next)) & (0xff << 8)) << 8) | (((__uint32_t)(g->next)) << 24)) : __bswap32_var(g->next)); |
Value stored to 'sghead' is never read | |
| 409 | #endif |
| 410 | for (i = 0; i < PRSIZE10; i++) { |
| 411 | afs_int32 id = ntohl(e->entries[i])(__builtin_constant_p(e->entries[i]) ? ((((__uint32_t)(e-> entries[i])) >> 24) | ((((__uint32_t)(e->entries[i]) ) & (0xff << 16)) >> 8) | ((((__uint32_t)(e-> entries[i])) & (0xff << 8)) << 8) | (((__uint32_t )(e->entries[i])) << 24)) : __bswap32_var(e->entries [i])); |
| 412 | if (id == PRBADID0x80000000) |
| 413 | continue; |
| 414 | else if (id) { |
| 415 | int eid_s, id_s; |
| 416 | count++; |
| 417 | /* in case the ids are large, convert to pure sign. */ |
| 418 | if (id > 0) |
| 419 | id_s = 1; |
| 420 | else |
| 421 | id_s = -1; |
| 422 | if (eid > 0) |
| 423 | eid_s = 1; |
| 424 | else |
| 425 | eid_s = -1; |
| 426 | #if defined(SUPERGROUPS1) |
| 427 | if (id_s > 0 && eid_s > 0) { |
| 428 | fprintf(stderr__stderrp, |
| 429 | "User can't be member of user in membership list\n"); |
| 430 | if (PrintEntryError(misc, ea, e, 2)) |
| 431 | return PRDBBAD(267275L); |
| 432 | noErrors = 0; |
| 433 | } |
| 434 | #else |
| 435 | if (id_s * eid_s > 0) { /* sign should be different */ |
| 436 | fprintf(stderr__stderrp, |
| 437 | "Bad user/group dicotomy in membership list\n"); |
| 438 | if (PrintEntryError(misc, ea, e, 2)) |
| 439 | return PRDBBAD(267275L); |
| 440 | noErrors = 0; |
| 441 | } |
| 442 | #endif /* SUPERGROUPS */ |
| 443 | /* count each user as a group, and each group a user is in */ |
| 444 | #if defined(SUPERGROUPS1) |
| 445 | if (!(id < 0 && eid < 0) && (id != ANONYMOUSID32766)) |
| 446 | inccount(&misc->idmap, id); |
| 447 | #else |
| 448 | if ((id >= misc->minId) && (id <= misc->maxId) |
| 449 | && (id != ANONYMOUSID32766)) |
| 450 | misc->idmap[id - misc->minId]++; |
| 451 | #endif /* SUPERGROUPS */ |
| 452 | } else if (head) |
| 453 | count = 9999; |
| 454 | else |
| 455 | break; |
| 456 | } |
| 457 | #if defined(SUPERGROUPS1) |
| 458 | sghead = ntohl(g->nextsg)(__builtin_constant_p(g->nextsg) ? ((((__uint32_t)(g->nextsg )) >> 24) | ((((__uint32_t)(g->nextsg)) & (0xff << 16)) >> 8) | ((((__uint32_t)(g->nextsg)) & (0xff << 8)) << 8) | (((__uint32_t)(g->nextsg)) << 24)) : __bswap32_var(g->nextsg)); |
| 459 | if ((e->flags & htonl(PRGRP)(__builtin_constant_p(2) ? ((((__uint32_t)(2)) >> 24) | ((((__uint32_t)(2)) & (0xff << 16)) >> 8) | ( (((__uint32_t)(2)) & (0xff << 8)) << 8) | ((( __uint32_t)(2)) << 24)) : __bswap32_var(2)))) { |
| 460 | for (i = 0; i < SGSIZE2; ++i) { |
| 461 | afs_int32 id = ntohl(g->supergroup[i])(__builtin_constant_p(g->supergroup[i]) ? ((((__uint32_t)( g->supergroup[i])) >> 24) | ((((__uint32_t)(g->supergroup [i])) & (0xff << 16)) >> 8) | ((((__uint32_t) (g->supergroup[i])) & (0xff << 8)) << 8) | (((__uint32_t)(g->supergroup[i])) << 24)) : __bswap32_var (g->supergroup[i])); |
| 462 | if (id == PRBADID0x80000000) |
| 463 | continue; |
| 464 | else if (id) { |
| 465 | if (id > 0) { |
| 466 | fprintf(stderr__stderrp, |
| 467 | "User can't be member of supergroup list\n"); |
| 468 | if (PrintEntryError(misc, ea, e, 2)) |
| 469 | return PRDBBAD(267275L); |
| 470 | noErrors = 0; |
| 471 | } |
| 472 | sgcount++; |
| 473 | inccount(&misc->idmap, id); |
| 474 | } |
| 475 | } |
| 476 | } |
| 477 | #endif /* SUPERGROUPS */ |
| 478 | } else { |
| 479 | head = ntohl(cheader.freePtr)(__builtin_constant_p(cheader.freePtr) ? ((((__uint32_t)(cheader .freePtr)) >> 24) | ((((__uint32_t)(cheader.freePtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.freePtr )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .freePtr)) << 24)) : __bswap32_var(cheader.freePtr)); |
| 480 | #if defined(SUPERGROUPS1) |
| 481 | sghead = 0; |
| 482 | #endif |
| 483 | bit = MAP_FREE8; |
| 484 | } |
| 485 | |
| 486 | #if defined(SUPERGROUPS1) |
| 487 | length = 0; |
| 488 | for (na = sghead; na; na = ntohl(c.next)(__builtin_constant_p(c.next) ? ((((__uint32_t)(c.next)) >> 24) | ((((__uint32_t)(c.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.next)) & (0xff << 8)) << 8) | (((__uint32_t)(c.next)) << 24)) : __bswap32_var(c .next))) { |
| 489 | code = ConvertDiskAddress(na, &ni); |
| 490 | if (code) { |
| 491 | fprintf(stderr__stderrp, "Bad SGcontinuation ptr %d", na); |
| 492 | if (PrintEntryError(misc, ea, e, 2)) |
| 493 | return PRDBBAD(267275L); |
| 494 | if (na != sghead) { |
| 495 | fprintf(stderr__stderrp, "last block: \n"); |
| 496 | if (PrintEntryError(misc, na, &c, 4)) |
| 497 | return PRDBBAD(267275L); |
| 498 | } |
| 499 | return 0; |
| 500 | } |
| 501 | code = pr_Read(na, (char *)&c, sizeof(c)); |
| 502 | if (code) |
| 503 | return code; |
| 504 | length++; |
| 505 | |
| 506 | if (map[ni]) { |
| 507 | fprintf(stderr__stderrp, "Continuation entry reused\n"); |
| 508 | if (PrintEntryError(misc, ea, e, 2)) |
| 509 | return PRDBBAD(267275L); |
| 510 | if (PrintEntryError(misc, na, &c, 4)) |
| 511 | return PRDBBAD(267275L); |
| 512 | noErrors = 0; |
| 513 | break; |
| 514 | } |
| 515 | map[ni] |= bit; |
| 516 | if ((ntohl(c.id)(__builtin_constant_p(c.id) ? ((((__uint32_t)(c.id)) >> 24) | ((((__uint32_t)(c.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.id)) & (0xff << 8)) << 8) | (((__uint32_t)(c.id)) << 24)) : __bswap32_var(c.id )) != eid)) { |
| 517 | fprintf(stderr__stderrp, "Continuation id mismatch\n"); |
| 518 | if (PrintEntryError(misc, ea, e, 2)) |
| 519 | return PRDBBAD(267275L); |
| 520 | if (PrintEntryError(misc, na, &c, 4)) |
| 521 | return PRDBBAD(267275L); |
| 522 | noErrors = 0; |
| 523 | continue; |
| 524 | } |
| 525 | |
| 526 | /* update membership count */ |
| 527 | for (i = 0; i < COSIZE39; i++) { |
| 528 | afs_int32 id = ntohl(c.entries[i])(__builtin_constant_p(c.entries[i]) ? ((((__uint32_t)(c.entries [i])) >> 24) | ((((__uint32_t)(c.entries[i])) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.entries[i])) & (0xff << 8)) << 8) | (((__uint32_t)(c.entries[i] )) << 24)) : __bswap32_var(c.entries[i])); |
| 529 | if (id == PRBADID0x80000000) |
| 530 | continue; |
| 531 | else if (id) { |
| 532 | int eid_s, id_s; |
| 533 | sgcount++; |
| 534 | /* in case the ids are large, convert to pure sign. */ |
| 535 | if (id > 0) |
| 536 | id_s = 1; |
| 537 | else |
| 538 | id_s = -1; |
| 539 | if (eid > 0) |
| 540 | eid_s = 1; |
| 541 | else |
| 542 | eid_s = -1; |
| 543 | if (id_s > 0) { |
| 544 | fprintf(stderr__stderrp, |
| 545 | "User can't be member of supergroup list\n"); |
| 546 | if (PrintEntryError(misc, ea, e, 2)) |
| 547 | return PRDBBAD(267275L); |
| 548 | if (PrintEntryError(misc, na, &c, 4)) |
| 549 | return PRDBBAD(267275L); |
| 550 | noErrors = 0; |
| 551 | } |
| 552 | /* count each user as a group, and each group a user is in */ |
| 553 | if ((id != ANONYMOUSID32766)) |
| 554 | inccount(&misc->idmap, id); |
| 555 | } else if (c.next) |
| 556 | count = 9999; |
| 557 | else |
| 558 | break; |
| 559 | } |
| 560 | } |
| 561 | if (length > misc->maxContLength) |
| 562 | misc->maxContLength = length; |
| 563 | #endif /* SUPERGROUPS */ |
| 564 | length = 0; |
| 565 | for (na = head; na; na = ntohl(c.next)(__builtin_constant_p(c.next) ? ((((__uint32_t)(c.next)) >> 24) | ((((__uint32_t)(c.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.next)) & (0xff << 8)) << 8) | (((__uint32_t)(c.next)) << 24)) : __bswap32_var(c .next))) { |
| 566 | code = ConvertDiskAddress(na, &ni); |
| 567 | if (code) { |
| 568 | fprintf(stderr__stderrp, "Bad continuation ptr %d", na); |
| 569 | if (e == 0) |
| 570 | fprintf(stderr__stderrp, "walking free list"); |
| 571 | else if (PrintEntryError(misc, ea, e, 2)) |
| 572 | return PRDBBAD(267275L); |
| 573 | if (na != head) { |
| 574 | fprintf(stderr__stderrp, "last block: \n"); |
| 575 | if (PrintEntryError(misc, na, &c, 4)) |
| 576 | return PRDBBAD(267275L); |
| 577 | } |
| 578 | return 0; |
| 579 | } |
| 580 | code = pr_Read(na, (char *)&c, sizeof(c)); |
| 581 | if (code) |
| 582 | return code; |
| 583 | length++; |
| 584 | |
| 585 | if (map[ni]) { |
| 586 | fprintf(stderr__stderrp, "Continuation entry reused\n"); |
| 587 | if (e == 0) |
| 588 | fprintf(stderr__stderrp, "walking free list"); |
| 589 | else if (PrintEntryError(misc, ea, e, 2)) |
| 590 | return PRDBBAD(267275L); |
| 591 | if (PrintEntryError(misc, na, &c, 4)) |
| 592 | return PRDBBAD(267275L); |
| 593 | noErrors = 0; |
| 594 | break; |
| 595 | } |
| 596 | map[ni] |= bit; |
| 597 | if (e && (ntohl(c.id)(__builtin_constant_p(c.id) ? ((((__uint32_t)(c.id)) >> 24) | ((((__uint32_t)(c.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.id)) & (0xff << 8)) << 8) | (((__uint32_t)(c.id)) << 24)) : __bswap32_var(c.id )) != eid)) { |
| 598 | fprintf(stderr__stderrp, "Continuation id mismatch\n"); |
| 599 | if (e == 0) |
| 600 | fprintf(stderr__stderrp, "walking free list"); |
| 601 | else if (PrintEntryError(misc, ea, e, 2)) |
| 602 | return PRDBBAD(267275L); |
| 603 | if (PrintEntryError(misc, na, &c, 4)) |
| 604 | return PRDBBAD(267275L); |
| 605 | noErrors = 0; |
| 606 | continue; |
| 607 | } |
| 608 | |
| 609 | /* update membership count */ |
| 610 | if (e) |
| 611 | for (i = 0; i < COSIZE39; i++) { |
| 612 | afs_int32 id = ntohl(c.entries[i])(__builtin_constant_p(c.entries[i]) ? ((((__uint32_t)(c.entries [i])) >> 24) | ((((__uint32_t)(c.entries[i])) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.entries[i])) & (0xff << 8)) << 8) | (((__uint32_t)(c.entries[i] )) << 24)) : __bswap32_var(c.entries[i])); |
| 613 | if (id == PRBADID0x80000000) |
| 614 | continue; |
| 615 | else if (id) { |
| 616 | int eid_s, id_s; |
| 617 | count++; |
| 618 | /* in case the ids are large, convert to pure sign. */ |
| 619 | if (id > 0) |
| 620 | id_s = 1; |
| 621 | else |
| 622 | id_s = -1; |
| 623 | if (eid > 0) |
| 624 | eid_s = 1; |
| 625 | else |
| 626 | eid_s = -1; |
| 627 | #if defined(SUPERGROUPS1) |
| 628 | if (id_s > 0 && eid_s > 0) { |
| 629 | fprintf(stderr__stderrp, |
| 630 | "User can't be member of user in membership list\n"); |
| 631 | if (PrintEntryError(misc, ea, e, 2)) |
| 632 | return PRDBBAD(267275L); |
| 633 | if (PrintEntryError(misc, na, &c, 4)) |
| 634 | return PRDBBAD(267275L); |
| 635 | noErrors = 0; |
| 636 | } |
| 637 | #else |
| 638 | if (id_s * eid_s > 0) { /* sign should be different */ |
| 639 | fprintf(stderr__stderrp, |
| 640 | "Bad user/group dicotomy in membership list\n"); |
| 641 | if (PrintEntryError(misc, ea, e, 2)) |
| 642 | return PRDBBAD(267275L); |
| 643 | if (PrintEntryError(misc, na, &c, 4)) |
| 644 | return PRDBBAD(267275L); |
| 645 | noErrors = 0; |
| 646 | } |
| 647 | #endif /* SUPERGROUPS */ |
| 648 | /* count each user as a group, and each group a user is in */ |
| 649 | #if defined(SUPERGROUPS1) |
| 650 | if (!(id < 0 && eid < 0) && (id != ANONYMOUSID32766)) |
| 651 | inccount(&misc->idmap, id); |
| 652 | #else |
| 653 | if ((id >= misc->minId) && (id <= misc->maxId) |
| 654 | && (id != ANONYMOUSID32766)) |
| 655 | misc->idmap[id - misc->minId]++; |
| 656 | #endif /* SUPERGROUPS */ |
| 657 | } else if (c.next) |
| 658 | count = 9999; |
| 659 | else |
| 660 | break; |
| 661 | } |
| 662 | } |
| 663 | if (e && noErrors && (count != ntohl(e->count)(__builtin_constant_p(e->count) ? ((((__uint32_t)(e->count )) >> 24) | ((((__uint32_t)(e->count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->count)) & (0xff << 8)) << 8) | (((__uint32_t)(e->count)) << 24)) : __bswap32_var(e->count)))) { |
| 664 | #if defined(SUPERGROUPS1) |
| 665 | if (count >= 9999) |
| 666 | fprintf(stderr__stderrp, "Membership list ends early\n"); |
| 667 | #else |
| 668 | if (count > 9999) |
| 669 | fprintf(stderr__stderrp, "Membership list ends early\n"); |
| 670 | #endif /* SUPERGROUPS */ |
| 671 | fprintf(stderr__stderrp, "Count was %d should be %d\n", count, |
| 672 | ntohl(e->count)(__builtin_constant_p(e->count) ? ((((__uint32_t)(e->count )) >> 24) | ((((__uint32_t)(e->count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->count)) & (0xff << 8)) << 8) | (((__uint32_t)(e->count)) << 24)) : __bswap32_var(e->count))); |
| 673 | if (PrintEntryError(misc, ea, e, 2)) |
| 674 | return PRDBBAD(267275L); |
| 675 | #if defined(SUPERGROUPS1) |
| 676 | noErrors = 0; |
| 677 | } |
| 678 | if (e && (e->flags & htonl(PRGRP)(__builtin_constant_p(2) ? ((((__uint32_t)(2)) >> 24) | ((((__uint32_t)(2)) & (0xff << 16)) >> 8) | ( (((__uint32_t)(2)) & (0xff << 8)) << 8) | ((( __uint32_t)(2)) << 24)) : __bswap32_var(2))) && (sgcount != ntohl(g->countsg)(__builtin_constant_p(g->countsg) ? ((((__uint32_t)(g-> countsg)) >> 24) | ((((__uint32_t)(g->countsg)) & (0xff << 16)) >> 8) | ((((__uint32_t)(g->countsg )) & (0xff << 8)) << 8) | (((__uint32_t)(g-> countsg)) << 24)) : __bswap32_var(g->countsg)))) { |
| 679 | fprintf(stderr__stderrp, "SGCount was %d should be %d\n", sgcount, |
| 680 | ntohl(g->countsg)(__builtin_constant_p(g->countsg) ? ((((__uint32_t)(g-> countsg)) >> 24) | ((((__uint32_t)(g->countsg)) & (0xff << 16)) >> 8) | ((((__uint32_t)(g->countsg )) & (0xff << 8)) << 8) | (((__uint32_t)(g-> countsg)) << 24)) : __bswap32_var(g->countsg))); |
| 681 | if (PrintEntryError(misc, ea, e, 2)) |
| 682 | return PRDBBAD(267275L); |
| 683 | #endif |
| 684 | } |
| 685 | |
| 686 | if (e) { |
| 687 | if (length > misc->maxContLength) |
| 688 | misc->maxContLength = length; |
| 689 | } else |
| 690 | misc->freeLength = length; |
| 691 | |
| 692 | return 0; |
| 693 | #if defined(SUPERGROUPS1) |
| 694 | #undef g |
| 695 | #endif |
| 696 | } |
| 697 | |
| 698 | afs_int32 |
| 699 | WalkOwnedChain(char map[], /* one byte per db entry */ |
| 700 | struct misc_data *misc, /* stuff to keep track of */ |
| 701 | afs_int32 ea, struct prentry *e) |
| 702 | { |
| 703 | afs_int32 head; |
| 704 | afs_int32 code; |
| 705 | struct prentry c; /* continuation entry */ |
| 706 | afs_int32 na; /* next thread */ |
| 707 | int ni; |
| 708 | afs_int32 eid = 0; |
| 709 | int length; /* length of chain */ |
| 710 | |
| 711 | if (e) { |
| 712 | head = ntohl(e->owned)(__builtin_constant_p(e->owned) ? ((((__uint32_t)(e->owned )) >> 24) | ((((__uint32_t)(e->owned)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->owned)) & (0xff << 8)) << 8) | (((__uint32_t)(e->owned)) << 24)) : __bswap32_var(e->owned)); |
| 713 | eid = ntohl(e->id)(__builtin_constant_p(e->id) ? ((((__uint32_t)(e->id)) >> 24) | ((((__uint32_t)(e->id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e->id)) & (0xff << 8)) << 8) | (((__uint32_t)(e->id)) << 24)) : __bswap32_var (e->id)); |
| 714 | } else |
| 715 | head = ntohl(cheader.orphan)(__builtin_constant_p(cheader.orphan) ? ((((__uint32_t)(cheader .orphan)) >> 24) | ((((__uint32_t)(cheader.orphan)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.orphan )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .orphan)) << 24)) : __bswap32_var(cheader.orphan)); |
| 716 | |
| 717 | length = 0; |
| 718 | for (na = head; na; na = ntohl(c.nextOwned)(__builtin_constant_p(c.nextOwned) ? ((((__uint32_t)(c.nextOwned )) >> 24) | ((((__uint32_t)(c.nextOwned)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.nextOwned)) & (0xff << 8)) << 8) | (((__uint32_t)(c.nextOwned)) << 24)) : __bswap32_var(c.nextOwned))) { |
| 719 | code = ConvertDiskAddress(na, &ni); |
| 720 | if (code) { |
| 721 | fprintf(stderr__stderrp, "Bad owned list ptr %d", na); |
| 722 | if (e == 0) |
| 723 | fprintf(stderr__stderrp, "walking orphan list"); |
| 724 | else if (PrintEntryError(misc, ea, e, 2)) |
| 725 | return PRDBBAD(267275L); |
| 726 | if (na != head) { |
| 727 | fprintf(stderr__stderrp, "last block: \n"); |
| 728 | if (PrintEntryError(misc, na, &c, 4)) |
| 729 | return PRDBBAD(267275L); |
| 730 | } |
| 731 | return 0; |
| 732 | } |
| 733 | code = pr_Read(na, (char *)&c, sizeof(c)); |
| 734 | if (code) |
| 735 | return code; |
| 736 | length++; |
| 737 | |
| 738 | if (map[ni] & MAP_OWNED0x10) { |
| 739 | fprintf(stderr__stderrp, "Entry on multiple owner chains\n"); |
| 740 | if (e == 0) |
| 741 | fprintf(stderr__stderrp, "walking orphan list"); |
| 742 | else if (PrintEntryError(misc, ea, e, 2)) |
| 743 | return PRDBBAD(267275L); |
| 744 | if (PrintEntryError(misc, na, &c, 4)) |
| 745 | return PRDBBAD(267275L); |
| 746 | break; |
| 747 | } |
| 748 | map[ni] |= MAP_OWNED0x10; |
| 749 | if ((map[ni] & MAP_HASHES(1 | 2)) != MAP_HASHES(1 | 2)) { |
| 750 | fprintf(stderr__stderrp, "Owned entry not hashed properly\n"); |
| 751 | abort: |
| 752 | if (e == 0) |
| 753 | fprintf(stderr__stderrp, "walking orphan list"); |
| 754 | else if (PrintEntryError(misc, ea, e, 2)) |
| 755 | return PRDBBAD(267275L); |
| 756 | if (PrintEntryError(misc, na, &c, 4)) |
| 757 | return PRDBBAD(267275L); |
| 758 | continue; |
| 759 | } |
| 760 | if (e) { |
| 761 | if (ntohl(c.owner)(__builtin_constant_p(c.owner) ? ((((__uint32_t)(c.owner)) >> 24) | ((((__uint32_t)(c.owner)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.owner)) & (0xff << 8)) << 8) | (((__uint32_t)(c.owner)) << 24)) : __bswap32_var( c.owner)) != eid) { |
| 762 | fprintf(stderr__stderrp, "Owner id mismatch\n"); |
| 763 | goto abort; |
| 764 | } |
| 765 | } else /* orphan */ if (c.owner) { |
| 766 | fprintf(stderr__stderrp, "Orphan group owner not zero\n"); |
| 767 | goto abort; |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | if (e) { |
| 772 | if (length > misc->maxOwnerLength) |
| 773 | misc->maxOwnerLength = length; |
| 774 | } else |
| 775 | misc->orphanLength = length; |
| 776 | |
| 777 | return 0; |
| 778 | } |
| 779 | |
| 780 | afs_int32 |
| 781 | WalkChains(char map[], /* one byte per db entry */ |
| 782 | struct misc_data *misc) /* stuff to keep track of */ |
| 783 | { |
| 784 | afs_int32 code; |
| 785 | int ei; |
| 786 | afs_int32 ea; /* entry's db addr */ |
| 787 | struct prentry e; |
| 788 | afs_int32 id; |
| 789 | int type; |
| 790 | |
| 791 | /* check all entries found in hash table walks */ |
| 792 | for (ei = 0; ei < misc->nEntries; ei++) |
| 793 | if (map[ei] & MAP_HASHES(1 | 2)) { |
| 794 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 795 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 796 | if (code) |
| 797 | return code; |
| 798 | |
| 799 | if ((map[ei] & MAP_HASHES(1 | 2)) != MAP_HASHES(1 | 2)) { |
| 800 | fprintf(stderr__stderrp, "entry not in both hashtables\n"); |
| 801 | if ((map[ei] & MAP_NAMEHASH1) != MAP_NAMEHASH1) |
| 802 | fprintf(stderr__stderrp, "--> entry not in Name hashtable\n"); |
| 803 | if ((map[ei] & MAP_IDHASH2) != MAP_IDHASH2) |
| 804 | fprintf(stderr__stderrp, "--> entry not in ID hashtable\n"); |
| 805 | |
| 806 | abort: |
| 807 | if (PrintEntryError(misc, ea, &e, 2)) |
| 808 | return PRDBBAD(267275L); |
| 809 | continue; |
| 810 | } |
| 811 | |
| 812 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 813 | |
| 814 | type = ntohl(e.flags)(__builtin_constant_p(e.flags) ? ((((__uint32_t)(e.flags)) >> 24) | ((((__uint32_t)(e.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.flags)) & (0xff << 8)) << 8) | (((__uint32_t)(e.flags)) << 24)) : __bswap32_var( e.flags)) & PRTYPE0x3f; |
| 815 | switch (type) { |
| 816 | case PRGRP2: |
| 817 | if (id >= 0) { |
| 818 | fprintf(stderr__stderrp, "Group id not negative\n"); |
| 819 | goto abort; |
| 820 | } |
| 821 | /* special case sysadmin: it owns itself */ |
| 822 | if (id == SYSADMINID-204) { |
| 823 | if (ntohl(e.owner)(__builtin_constant_p(e.owner) ? ((((__uint32_t)(e.owner)) >> 24) | ((((__uint32_t)(e.owner)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.owner)) & (0xff << 8)) << 8) | (((__uint32_t)(e.owner)) << 24)) : __bswap32_var( e.owner)) != SYSADMINID-204) { |
| 824 | fprintf(stderr__stderrp, |
| 825 | "System:administrators doesn't own itself\n"); |
| 826 | goto abort; |
| 827 | } |
| 828 | } |
| 829 | code = WalkOwnedChain(map, misc, ea, &e); |
| 830 | if (code) |
| 831 | return code; |
| 832 | code = WalkNextChain(map, misc, ea, &e); |
| 833 | if (code) |
| 834 | return code; |
| 835 | misc->ngroups++; |
| 836 | break; |
| 837 | case PRUSER0: |
| 838 | if (id <= 0) { |
| 839 | #if defined(SUPERGROUPS1) |
| 840 | fprintf(stderr__stderrp, "User id not positive\n"); |
| 841 | #else |
| 842 | fprintf(stderr__stderrp, "User id negative\n"); |
| 843 | #endif |
| 844 | goto abort; |
| 845 | } |
| 846 | |
| 847 | /* Users are owned by sysadmin, but sysadmin doesn't have an owner |
| 848 | * chain. Check this then set the owned bit. */ |
| 849 | if (ntohl(e.owner)(__builtin_constant_p(e.owner) ? ((((__uint32_t)(e.owner)) >> 24) | ((((__uint32_t)(e.owner)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.owner)) & (0xff << 8)) << 8) | (((__uint32_t)(e.owner)) << 24)) : __bswap32_var( e.owner)) != SYSADMINID-204) { |
| 850 | fprintf(stderr__stderrp, |
| 851 | "User not owned by system:administrators\n"); |
| 852 | goto abort; |
| 853 | } |
| 854 | if (e.nextOwned) { |
| 855 | fprintf(stderr__stderrp, "User has owned pointer\n"); |
| 856 | goto abort; |
| 857 | } |
| 858 | map[ei] |= MAP_OWNED0x10; |
| 859 | |
| 860 | code = WalkOwnedChain(map, misc, ea, &e); |
| 861 | if (code) |
| 862 | return code; |
| 863 | code = WalkNextChain(map, misc, ea, &e); |
| 864 | if (code) |
| 865 | return code; |
| 866 | if (strchr(e.name, '@') == 0) { |
| 867 | misc->nusers++; /* Not a foreign user */ |
| 868 | } else { |
| 869 | misc->nforeigns++; /* A foreign user */ |
| 870 | } |
| 871 | break; |
| 872 | case PRFREE1: |
| 873 | case PRCONT4: |
| 874 | case PRCELL8: |
| 875 | misc->ncells++; |
| 876 | break; |
| 877 | case PRFOREIGN16: |
| 878 | fprintf(stderr__stderrp, |
| 879 | "ENTRY IS unexpected type [PRFOREIGN] (flags=0x%x)\n", |
| 880 | ntohl(e.flags)(__builtin_constant_p(e.flags) ? ((((__uint32_t)(e.flags)) >> 24) | ((((__uint32_t)(e.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.flags)) & (0xff << 8)) << 8) | (((__uint32_t)(e.flags)) << 24)) : __bswap32_var( e.flags))); |
| 881 | break; |
| 882 | case PRINST32: |
| 883 | misc->ninsts++; |
| 884 | break; |
| 885 | default: |
| 886 | fprintf(stderr__stderrp, "entry with unexpected type"); |
| 887 | goto abort; |
| 888 | } |
| 889 | } |
| 890 | |
| 891 | return 0; |
| 892 | } |
| 893 | |
| 894 | afs_int32 |
| 895 | GC(char map[], struct misc_data *misc) |
| 896 | { |
| 897 | afs_int32 code; |
| 898 | int ei; |
| 899 | afs_int32 ea; |
| 900 | struct prentry e; |
| 901 | char m; |
| 902 | |
| 903 | for (ei = 0; ei < misc->nEntries; ei++) { |
| 904 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 905 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 906 | if (code) |
| 907 | return code; |
| 908 | m = map[ei]; |
| 909 | if (m == 0) { |
| 910 | fprintf(stderr__stderrp, "Unreferenced entry:"); |
| 911 | if (PrintEntryError(misc, ea, &e, 2)) |
| 912 | return PRDBBAD(267275L); |
| 913 | } |
| 914 | /* all users and groups should be owned, and their membership counts |
| 915 | * should be okay */ |
| 916 | else if ((m & MAP_HASHES(1 | 2)) == MAP_HASHES(1 | 2)) { |
| 917 | afs_int32 id; |
| 918 | int refCount; |
| 919 | if (!(m & MAP_OWNED0x10)) { |
| 920 | fprintf(stderr__stderrp, "Entry not on any owner chain:\n"); |
| 921 | if (PrintEntryError(misc, ea, &e, 2)) |
| 922 | return PRDBBAD(267275L); |
| 923 | } |
| 924 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 925 | #if defined(SUPERGROUPS1) |
| 926 | if ((id != ANONYMOUSID32766) |
| 927 | && ((refCount = idcount(&misc->idmap, id)) != ntohl(e.count)(__builtin_constant_p(e.count) ? ((((__uint32_t)(e.count)) >> 24) | ((((__uint32_t)(e.count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.count)) & (0xff << 8)) << 8) | (((__uint32_t)(e.count)) << 24)) : __bswap32_var( e.count)))) |
| 928 | #else |
| 929 | if ((id >= misc->minId) && (id <= misc->maxId) |
| 930 | && (id != ANONYMOUSID32766) |
| 931 | && ((refCount = misc->idmap[id - misc->minId]) != |
| 932 | ntohl(e.count)(__builtin_constant_p(e.count) ? ((((__uint32_t)(e.count)) >> 24) | ((((__uint32_t)(e.count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.count)) & (0xff << 8)) << 8) | (((__uint32_t)(e.count)) << 24)) : __bswap32_var( e.count)))) |
| 933 | #endif /* SUPERGROUPS */ |
| 934 | { |
| 935 | afs_int32 na; |
| 936 | fprintf(stderr__stderrp, |
| 937 | "Entry membership count is inconsistent: %d entries refer to this one\n", |
| 938 | refCount); |
| 939 | if (PrintEntryError(misc, ea, &e, 2)) |
| 940 | return PRDBBAD(267275L); |
| 941 | |
| 942 | /* get continuation blocks too */ |
| 943 | for (na = ntohl(e.next)(__builtin_constant_p(e.next) ? ((((__uint32_t)(e.next)) >> 24) | ((((__uint32_t)(e.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.next)) & (0xff << 8)) << 8) | (((__uint32_t)(e.next)) << 24)) : __bswap32_var(e .next)); na; na = ntohl(e.next)(__builtin_constant_p(e.next) ? ((((__uint32_t)(e.next)) >> 24) | ((((__uint32_t)(e.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.next)) & (0xff << 8)) << 8) | (((__uint32_t)(e.next)) << 24)) : __bswap32_var(e .next))) { |
| 944 | int ni; |
| 945 | code = ConvertDiskAddress(na, &ni); |
| 946 | if (code) |
| 947 | return code; |
| 948 | code = pr_Read(na, (char *)&e, sizeof(e)); |
| 949 | if (code) |
| 950 | return code; |
| 951 | if (PrintEntryError(misc, na, &e, 4)) |
| 952 | return PRDBBAD(267275L); |
| 953 | } |
| 954 | } |
| 955 | } |
| 956 | } |
| 957 | return 0; |
| 958 | } |
| 959 | |
| 960 | char * |
| 961 | QuoteName(char *s) |
| 962 | { |
| 963 | char *qs; |
| 964 | if (strpbrk(s, " \t")) { |
| 965 | qs = (char *)malloc(strlen(s) + 3); |
| 966 | strcpy(qs, "\""); |
| 967 | strcat(qs, s); |
| 968 | strcat(qs, "\""); |
| 969 | } else |
| 970 | qs = s; |
| 971 | return qs; |
| 972 | } |
| 973 | |
| 974 | afs_int32 |
| 975 | DumpRecreate(char map[], struct misc_data *misc) |
| 976 | { |
| 977 | afs_int32 code; |
| 978 | int ei; |
| 979 | afs_int32 ea; |
| 980 | struct prentry e; |
| 981 | afs_int32 id; |
| 982 | afs_int32 flags; |
| 983 | afs_int32 owner; |
| 984 | char *name; |
| 985 | int builtinUsers = 0; |
| 986 | int createLow = 0; /* users uncreate from here */ |
| 987 | #if defined(SUPERGROUPS1) |
| 988 | struct idused *idmap; /* map of all id's */ |
| 989 | #else |
| 990 | afs_int32 *idmap; /* map of all id's */ |
| 991 | #endif |
| 992 | int found; |
| 993 | FILE *rc; |
| 994 | |
| 995 | rc = misc->recreate; |
| 996 | idmap = misc->idmap; |
| 997 | #if defined(SUPERGROUPS1) |
| 998 | zeromap(idmap); |
| 999 | #else |
| 1000 | memset(idmap, 0, misc->idRange * sizeof(misc->idmap[0])); |
| 1001 | #endif |
| 1002 | do { |
| 1003 | found = 0; |
| 1004 | for (ei = createLow; ei < misc->nEntries; ei++) { |
| 1005 | if ((map[ei] & MAP_HASHES(1 | 2)) && (map[ei] & MAP_RECREATE0x20) == 0) { |
| 1006 | afs_int32 mask; |
| 1007 | afs_int32 access; |
| 1008 | int gq, uq; |
| 1009 | |
| 1010 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 1011 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 1012 | if (code) |
| 1013 | return code; |
| 1014 | |
| 1015 | if (misc->listentries) |
| 1016 | pr_PrintEntry(stdout__stdoutp, 0 /*not in host order */ , ea, &e, |
| 1017 | 0); |
| 1018 | |
| 1019 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 1020 | flags = ntohl(e.flags)(__builtin_constant_p(e.flags) ? ((((__uint32_t)(e.flags)) >> 24) | ((((__uint32_t)(e.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.flags)) & (0xff << 8)) << 8) | (((__uint32_t)(e.flags)) << 24)) : __bswap32_var( e.flags)); |
| 1021 | owner = ntohl(e.owner)(__builtin_constant_p(e.owner) ? ((((__uint32_t)(e.owner)) >> 24) | ((((__uint32_t)(e.owner)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.owner)) & (0xff << 8)) << 8) | (((__uint32_t)(e.owner)) << 24)) : __bswap32_var( e.owner)); |
| 1022 | name = QuoteName(e.name); |
| 1023 | |
| 1024 | if (!strcmp(e.name, "system:administrators") |
| 1025 | || !strcmp(e.name, "system:anyuser") |
| 1026 | || !strcmp(e.name, "system:authuser") |
| 1027 | || !strcmp(e.name, "system:backup") |
| 1028 | || !strcmp(e.name, "anonymous")) { |
| 1029 | builtinUsers++; |
| 1030 | goto user_done; |
| 1031 | } |
| 1032 | |
| 1033 | /* check for duplicate id. This may still lead to duplicate |
| 1034 | * names. */ |
| 1035 | #if defined(SUPERGROUPS1) |
| 1036 | if (idcount(&idmap, id)) |
| 1037 | #else |
| 1038 | if (idmap[id - misc->minId]) |
| 1039 | #endif |
| 1040 | { |
| 1041 | fprintf(stderr__stderrp, "Skipping entry with duplicate id %di\n", |
| 1042 | id); |
| 1043 | goto user_done; |
| 1044 | } |
| 1045 | |
| 1046 | /* If owner doesn't exist skip for now, unless we're our own |
| 1047 | * owner. If so, a special case allows a group to own itself |
| 1048 | * if caller is sysadmin. This leaves only owner cycles to |
| 1049 | * deal with. */ |
| 1050 | |
| 1051 | if ((owner < misc->minId) || (owner > misc->maxId)) { |
| 1052 | if (owner == ANONYMOUSID32766) |
| 1053 | fprintf(stderr__stderrp, |
| 1054 | "Warning: id %di is owned by ANONYMOUS; using sysadmin instead\n", |
| 1055 | id); |
| 1056 | else |
| 1057 | fprintf(stderr__stderrp, |
| 1058 | "Bogus owner (%d) of id %di; using sysadmin instead\n", |
| 1059 | owner, id); |
| 1060 | owner = SYSADMINID-204; |
| 1061 | } |
| 1062 | if (id == owner) { |
| 1063 | fprintf(stderr__stderrp, "Warning: group %s is self owning\n", |
| 1064 | name); |
| 1065 | } else if (owner == 0) { |
| 1066 | fprintf(stderr__stderrp, |
| 1067 | "Warning: orphan group %s will become self owning.\n", |
| 1068 | name); |
| 1069 | owner = id; |
| 1070 | } |
| 1071 | #if defined(SUPERGROUPS1) |
| 1072 | else if (!idcount(&idmap, owner)) |
| 1073 | goto user_skip; |
| 1074 | #else |
| 1075 | else if (idmap[owner - misc->minId] == 0) |
| 1076 | goto user_skip; |
| 1077 | #endif |
| 1078 | |
| 1079 | if (rc) |
| 1080 | fprintf(rc, "cr %s %d %d\n", name, id, owner); |
| 1081 | |
| 1082 | gq = uq = access = mask = 0; |
| 1083 | if (flags & PRACCESS(1<<6)) { |
| 1084 | access = (flags >> PRIVATE_SHIFT16); |
| 1085 | mask |= PR_SF_ALLBITS0xff; |
| 1086 | } |
| 1087 | if (flags & PRQUOTA(1<<7)) { |
| 1088 | gq = ntohl(e.ngroups)(__builtin_constant_p(e.ngroups) ? ((((__uint32_t)(e.ngroups) ) >> 24) | ((((__uint32_t)(e.ngroups)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.ngroups)) & (0xff << 8)) << 8) | (((__uint32_t)(e.ngroups)) << 24)) : __bswap32_var(e.ngroups)); |
| 1089 | uq = ntohl(e.nusers)(__builtin_constant_p(e.nusers) ? ((((__uint32_t)(e.nusers)) >> 24) | ((((__uint32_t)(e.nusers)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.nusers)) & (0xff << 8)) << 8) | (((__uint32_t)(e.nusers)) << 24)) : __bswap32_var (e.nusers)); |
| 1090 | mask |= PR_SF_NGROUPS(1<<31) | PR_SF_NUSERS(1<<30); |
| 1091 | } |
| 1092 | if (mask && rc) { |
| 1093 | fprintf(rc, "sf %d %x %x %d %d\n", id, mask, access, gq, |
| 1094 | uq); |
| 1095 | } |
| 1096 | user_done: |
| 1097 | map[ei] |= MAP_RECREATE0x20; |
| 1098 | #if defined(SUPERGROUPS1) |
| 1099 | if (id != ANONYMOUSID32766) |
| 1100 | inccount(&idmap, id); |
| 1101 | #else |
| 1102 | if (id != ANONYMOUSID32766) |
| 1103 | idmap[id - misc->minId]++; |
| 1104 | #endif |
| 1105 | found++; |
| 1106 | } |
| 1107 | /* bump low water mark if possible */ |
| 1108 | if (ei == createLow) |
| 1109 | createLow++; |
| 1110 | user_skip:; |
| 1111 | } |
| 1112 | misc->verbose = 0; |
| 1113 | } while (found); |
| 1114 | |
| 1115 | /* Now create the entries with circular owner dependencies and make them |
| 1116 | * own themselves. This is the only way to create them with the correct |
| 1117 | * names. */ |
| 1118 | for (ei = 0; ei < misc->nEntries; ei++) |
| 1119 | if (((map[ei] & MAP_HASHES(1 | 2)) == MAP_HASHES(1 | 2)) |
| 1120 | && (map[ei] & MAP_RECREATE0x20) == 0) { |
| 1121 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 1122 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 1123 | if (code) |
| 1124 | return code; |
| 1125 | |
| 1126 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 1127 | name = QuoteName(e.name); |
| 1128 | fprintf(stderr__stderrp, "Warning: group %s in self owning cycle\n", name); |
| 1129 | if (rc) |
| 1130 | fprintf(rc, "cr %s %d %d\n", name, id, id); |
| 1131 | #if defined(SUPERGROUPS1) |
| 1132 | inccount(&idmap, id); |
| 1133 | #else |
| 1134 | idmap[id - misc->minId]++; |
| 1135 | #endif |
| 1136 | } |
| 1137 | for (ei = 0; ei < misc->nEntries; ei++) |
| 1138 | if (((map[ei] & MAP_HASHES(1 | 2)) == MAP_HASHES(1 | 2)) |
| 1139 | && (map[ei] & MAP_RECREATE0x20) == 0) { |
| 1140 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 1141 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 1142 | if (code) |
| 1143 | return code; |
| 1144 | |
| 1145 | owner = ntohl(e.owner)(__builtin_constant_p(e.owner) ? ((((__uint32_t)(e.owner)) >> 24) | ((((__uint32_t)(e.owner)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.owner)) & (0xff << 8)) << 8) | (((__uint32_t)(e.owner)) << 24)) : __bswap32_var( e.owner)); |
| 1146 | #if defined(SUPERGROUPS1) |
| 1147 | if (!idcount(&idmap, owner)) |
| 1148 | #else |
| 1149 | if (idmap[owner - misc->minId] == 0) |
| 1150 | #endif |
| 1151 | { |
| 1152 | fprintf(stderr__stderrp, |
| 1153 | "Skipping chown of '%s' to non-existant owner %di\n", |
| 1154 | e.name, owner); |
| 1155 | } else if (rc) |
| 1156 | fprintf(rc, "ce %d \"\" %d 0\n", ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )), e.owner); |
| 1157 | } |
| 1158 | |
| 1159 | if (rc == 0) |
| 1160 | return 0; |
| 1161 | |
| 1162 | /* Reconstruct membership information based on the groups' user lists. */ |
| 1163 | for (ei = 0; ei < misc->nEntries; ei++) { |
| 1164 | if ((map[ei] & MAP_HASHES(1 | 2)) == MAP_HASHES(1 | 2)) { |
| 1165 | ea = ei * sizeof(struct prentry) + sizeof(cheader); |
| 1166 | code = pr_Read(ea, (char *)&e, sizeof(e)); |
| 1167 | if (code) |
| 1168 | return code; |
| 1169 | |
| 1170 | id = ntohl(e.id)(__builtin_constant_p(e.id) ? ((((__uint32_t)(e.id)) >> 24) | ((((__uint32_t)(e.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.id)) & (0xff << 8)) << 8) | (((__uint32_t)(e.id)) << 24)) : __bswap32_var(e.id )); |
| 1171 | flags = ntohl(e.flags)(__builtin_constant_p(e.flags) ? ((((__uint32_t)(e.flags)) >> 24) | ((((__uint32_t)(e.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.flags)) & (0xff << 8)) << 8) | (((__uint32_t)(e.flags)) << 24)) : __bswap32_var( e.flags)); |
| 1172 | |
| 1173 | if ((id < 0) && (flags & PRGRP2)) { |
| 1174 | int count = 0; |
| 1175 | afs_int32 na; |
| 1176 | int i; |
| 1177 | for (i = 0; i < PRSIZE10; i++) { |
| 1178 | afs_int32 uid = ntohl(e.entries[i])(__builtin_constant_p(e.entries[i]) ? ((((__uint32_t)(e.entries [i])) >> 24) | ((((__uint32_t)(e.entries[i])) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.entries[i])) & (0xff << 8)) << 8) | (((__uint32_t)(e.entries[i] )) << 24)) : __bswap32_var(e.entries[i])); |
| 1179 | if (uid == 0) |
| 1180 | break; |
| 1181 | if (uid == PRBADID0x80000000) |
| 1182 | continue; |
| 1183 | #if !defined(SUPERGROUPS1) |
| 1184 | if (uid > 0) { |
| 1185 | #endif |
| 1186 | fprintf(rc, "au %d %d\n", uid, id); |
| 1187 | count++; |
| 1188 | #if !defined(SUPERGROUPS1) |
| 1189 | } else |
| 1190 | fprintf(stderr__stderrp, "Skipping %di in group %di\n", uid, |
| 1191 | id); |
| 1192 | #endif |
| 1193 | } |
| 1194 | na = ntohl(e.next)(__builtin_constant_p(e.next) ? ((((__uint32_t)(e.next)) >> 24) | ((((__uint32_t)(e.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.next)) & (0xff << 8)) << 8) | (((__uint32_t)(e.next)) << 24)) : __bswap32_var(e .next)); |
| 1195 | while (na) { |
| 1196 | struct prentry c; |
| 1197 | code = pr_Read(na, (char *)&c, sizeof(c)); |
| 1198 | if (code) |
| 1199 | return code; |
| 1200 | |
| 1201 | if ((id == ntohl(c.id)(__builtin_constant_p(c.id) ? ((((__uint32_t)(c.id)) >> 24) | ((((__uint32_t)(c.id)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.id)) & (0xff << 8)) << 8) | (((__uint32_t)(c.id)) << 24)) : __bswap32_var(c.id ))) && (c.flags & htonl(PRCONT)(__builtin_constant_p(4) ? ((((__uint32_t)(4)) >> 24) | ((((__uint32_t)(4)) & (0xff << 16)) >> 8) | ( (((__uint32_t)(4)) & (0xff << 8)) << 8) | ((( __uint32_t)(4)) << 24)) : __bswap32_var(4)))) { |
| 1202 | for (i = 0; i < COSIZE39; i++) { |
| 1203 | afs_int32 uid = ntohl(c.entries[i])(__builtin_constant_p(c.entries[i]) ? ((((__uint32_t)(c.entries [i])) >> 24) | ((((__uint32_t)(c.entries[i])) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.entries[i])) & (0xff << 8)) << 8) | (((__uint32_t)(c.entries[i] )) << 24)) : __bswap32_var(c.entries[i])); |
| 1204 | if (uid == 0) |
| 1205 | break; |
| 1206 | if (uid == PRBADID0x80000000) |
| 1207 | continue; |
| 1208 | #if !defined(SUPERGROUPS1) |
| 1209 | if (uid > 0) { |
| 1210 | #endif |
| 1211 | fprintf(rc, "au %d %d\n", uid, id); |
| 1212 | count++; |
| 1213 | #if !defined(SUPERGROUPS1) |
| 1214 | } else |
| 1215 | fprintf(stderr__stderrp, "Skipping %di in group %di\n", |
| 1216 | uid, id); |
| 1217 | #endif |
| 1218 | } |
| 1219 | } else { |
| 1220 | fprintf(stderr__stderrp, "Skipping continuation block at %d\n", |
| 1221 | na); |
| 1222 | break; |
| 1223 | } |
| 1224 | na = ntohl(c.next)(__builtin_constant_p(c.next) ? ((((__uint32_t)(c.next)) >> 24) | ((((__uint32_t)(c.next)) & (0xff << 16)) >> 8) | ((((__uint32_t)(c.next)) & (0xff << 8)) << 8) | (((__uint32_t)(c.next)) << 24)) : __bswap32_var(c .next)); |
| 1225 | } |
| 1226 | if (count != ntohl(e.count)(__builtin_constant_p(e.count) ? ((((__uint32_t)(e.count)) >> 24) | ((((__uint32_t)(e.count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.count)) & (0xff << 8)) << 8) | (((__uint32_t)(e.count)) << 24)) : __bswap32_var( e.count))) |
| 1227 | fprintf(stderr__stderrp, |
| 1228 | "Group membership count problem found %d should be %d\n", |
| 1229 | count, ntohl(e.count)(__builtin_constant_p(e.count) ? ((((__uint32_t)(e.count)) >> 24) | ((((__uint32_t)(e.count)) & (0xff << 16)) >> 8) | ((((__uint32_t)(e.count)) & (0xff << 8)) << 8) | (((__uint32_t)(e.count)) << 24)) : __bswap32_var( e.count))); |
| 1230 | } else if ((id < 0) || (flags & PRGRP2)) { |
| 1231 | fprintf(stderr__stderrp, "Skipping group %di\n", id); |
| 1232 | } |
| 1233 | } |
| 1234 | } |
| 1235 | return 0; |
| 1236 | } |
| 1237 | |
| 1238 | afs_int32 |
| 1239 | CheckPrDatabase(struct misc_data *misc) /* info & statistics */ |
| 1240 | { |
| 1241 | afs_int32 code; |
| 1242 | afs_int32 eof; |
| 1243 | int n; |
| 1244 | char *map; /* map of each entry in db */ |
| 1245 | |
| 1246 | eof = ntohl(cheader.eofPtr)(__builtin_constant_p(cheader.eofPtr) ? ((((__uint32_t)(cheader .eofPtr)) >> 24) | ((((__uint32_t)(cheader.eofPtr)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.eofPtr )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .eofPtr)) << 24)) : __bswap32_var(cheader.eofPtr)); |
| 1247 | eof -= sizeof(cheader); |
| 1248 | n = eof / sizeof(struct prentry); |
| 1249 | if ((eof < 0) || (n * sizeof(struct prentry) != eof)) { |
| 1250 | code = PRDBBAD(267275L); |
| 1251 | afs_com_err(whoami, code, |
| 1252 | "eof ptr no good: eof=%d, sizeof(prentry)=%" AFS_SIZET_FMT"zu", |
| 1253 | eof, sizeof(struct prentry)); |
| 1254 | abort: |
| 1255 | return code; |
| 1256 | } |
| 1257 | if (misc->verbose) |
| 1258 | printf("Database has %d entries\n", n); |
| 1259 | map = (char *)malloc(n); |
| 1260 | memset(map, 0, n); |
| 1261 | misc->nEntries = n; |
| 1262 | |
| 1263 | if (misc->verbose) { |
| 1264 | printf("\nChecking name hash table\n"); |
| 1265 | fflush(stdout__stdoutp); |
| 1266 | } |
| 1267 | code = WalkHashTable(cheader.nameHash, MAP_NAMEHASH1, map, misc); |
| 1268 | if (code) { |
| 1269 | afs_com_err(whoami, code, "walking name hash"); |
| 1270 | goto abort; |
| 1271 | } |
| 1272 | if (misc->verbose) { |
| 1273 | printf("\nChecking id hash table\n"); |
| 1274 | fflush(stdout__stdoutp); |
| 1275 | } |
| 1276 | code = WalkHashTable(cheader.idHash, MAP_IDHASH2, map, misc); |
| 1277 | if (code) { |
| 1278 | afs_com_err(whoami, code, "walking id hash"); |
| 1279 | goto abort; |
| 1280 | } |
| 1281 | |
| 1282 | /* hash walk calculates min and max id */ |
| 1283 | #if defined(SUPERGROUPS1) |
| 1284 | misc->idmap = 0; |
| 1285 | #else |
| 1286 | n = ((misc->maxId > misc->maxForId) ? misc->maxId : misc->maxForId); |
| 1287 | misc->idRange = n - misc->minId + 1; |
| 1288 | misc->idmap = (afs_int32 *) malloc(misc->idRange * sizeof(afs_int32)); |
| 1289 | if (!misc->idmap) { |
| 1290 | afs_com_err(whoami, 0, "Unable to malloc space for max ids of %d", |
| 1291 | misc->idRange); |
| 1292 | code = -1; |
| 1293 | goto abort; |
| 1294 | } |
| 1295 | memset(misc->idmap, 0, misc->idRange * sizeof(misc->idmap[0])); |
| 1296 | #endif /* SUPERGROUPS */ |
| 1297 | |
| 1298 | if (misc->verbose) { |
| 1299 | printf("\nChecking entry chains\n"); |
| 1300 | fflush(stdout__stdoutp); |
| 1301 | } |
| 1302 | code = WalkChains(map, misc); |
| 1303 | if (code) { |
| 1304 | afs_com_err(whoami, code, "walking chains"); |
| 1305 | goto abort; |
| 1306 | } |
| 1307 | if (misc->verbose) { |
| 1308 | printf("\nChecking free list\n"); |
| 1309 | fflush(stdout__stdoutp); |
| 1310 | } |
| 1311 | code = WalkNextChain(map, misc, 0, 0); |
| 1312 | if (code) { |
| 1313 | afs_com_err(whoami, code, "walking free list"); |
| 1314 | goto abort; |
| 1315 | } |
| 1316 | if (misc->verbose) { |
| 1317 | printf("\nChecking orphans list\n"); |
| 1318 | fflush(stdout__stdoutp); |
| 1319 | } |
| 1320 | code = WalkOwnedChain(map, misc, 0, 0); |
| 1321 | if (code) { |
| 1322 | afs_com_err(whoami, code, "walking orphan list"); |
| 1323 | goto abort; |
| 1324 | } |
| 1325 | |
| 1326 | if (misc->verbose) { |
| 1327 | printf("\nChecking for unreferenced entries\n"); |
| 1328 | fflush(stdout__stdoutp); |
| 1329 | } |
| 1330 | code = GC(map, misc); |
| 1331 | if (code) { |
| 1332 | afs_com_err(whoami, code, "looking for unreferenced entries"); |
| 1333 | goto abort; |
| 1334 | } |
| 1335 | |
| 1336 | DumpRecreate(map, misc); /* check for owner cycles */ |
| 1337 | if (misc->recreate) |
| 1338 | fclose(misc->recreate); |
| 1339 | |
| 1340 | if (misc->anon != 2) /* once for each hash table */ |
| 1341 | fprintf(stderr__stderrp, "Problems with ANON=%d\n", misc->anon); |
| 1342 | if (misc->ncells || misc->ninsts) |
| 1343 | fprintf(stderr__stderrp, "Unexpected entry type\n"); |
| 1344 | if (misc->nusers != ntohl(cheader.usercount)(__builtin_constant_p(cheader.usercount) ? ((((__uint32_t)(cheader .usercount)) >> 24) | ((((__uint32_t)(cheader.usercount )) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .usercount)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.usercount)) << 24)) : __bswap32_var(cheader.usercount ))) { |
| 1345 | fprintf(stderr__stderrp, |
| 1346 | "User count inconsistent: should be %d, header claims: %d\n", |
| 1347 | misc->nusers, ntohl(cheader.usercount)(__builtin_constant_p(cheader.usercount) ? ((((__uint32_t)(cheader .usercount)) >> 24) | ((((__uint32_t)(cheader.usercount )) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .usercount)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.usercount)) << 24)) : __bswap32_var(cheader.usercount ))); |
| 1348 | } |
| 1349 | if (misc->ngroups != ntohl(cheader.groupcount)(__builtin_constant_p(cheader.groupcount) ? ((((__uint32_t)(cheader .groupcount)) >> 24) | ((((__uint32_t)(cheader.groupcount )) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .groupcount)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.groupcount)) << 24)) : __bswap32_var(cheader. groupcount))) { |
| 1350 | fprintf(stderr__stderrp, |
| 1351 | "Group count inconsistent: should be %d, header claims: %d\n", |
| 1352 | misc->ngroups, ntohl(cheader.groupcount)(__builtin_constant_p(cheader.groupcount) ? ((((__uint32_t)(cheader .groupcount)) >> 24) | ((((__uint32_t)(cheader.groupcount )) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .groupcount)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.groupcount)) << 24)) : __bswap32_var(cheader. groupcount))); |
| 1353 | } |
| 1354 | if (misc->maxId > ntohl(cheader.maxID)(__builtin_constant_p(cheader.maxID) ? ((((__uint32_t)(cheader .maxID)) >> 24) | ((((__uint32_t)(cheader.maxID)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.maxID )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .maxID)) << 24)) : __bswap32_var(cheader.maxID))) |
| 1355 | fprintf(stderr__stderrp, |
| 1356 | "Database's max user Id (%d) is smaller than largest user's Id (%d).\n", |
| 1357 | ntohl(cheader.maxID)(__builtin_constant_p(cheader.maxID) ? ((((__uint32_t)(cheader .maxID)) >> 24) | ((((__uint32_t)(cheader.maxID)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader.maxID )) & (0xff << 8)) << 8) | (((__uint32_t)(cheader .maxID)) << 24)) : __bswap32_var(cheader.maxID)), misc->maxId); |
| 1358 | if (misc->minId < ntohl(cheader.maxGroup)(__builtin_constant_p(cheader.maxGroup) ? ((((__uint32_t)(cheader .maxGroup)) >> 24) | ((((__uint32_t)(cheader.maxGroup)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .maxGroup)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.maxGroup)) << 24)) : __bswap32_var(cheader.maxGroup ))) |
| 1359 | fprintf(stderr__stderrp, |
| 1360 | "Database's max group Id (%d) is smaller than largest group's Id (%d).\n", |
| 1361 | ntohl(cheader.maxGroup)(__builtin_constant_p(cheader.maxGroup) ? ((((__uint32_t)(cheader .maxGroup)) >> 24) | ((((__uint32_t)(cheader.maxGroup)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader .maxGroup)) & (0xff << 8)) << 8) | (((__uint32_t )(cheader.maxGroup)) << 24)) : __bswap32_var(cheader.maxGroup )), misc->minId); |
| 1362 | |
| 1363 | if (misc->verbose) { |
| 1364 | printf("\nMaxId = %d, MinId = %d, MaxForeignId = %d\n", misc->maxId, |
| 1365 | misc->minId, misc->maxForId); |
| 1366 | printf |
| 1367 | ("Free list is %d entries in length, %d groups on orphan list\n", |
| 1368 | misc->freeLength, misc->orphanLength); |
| 1369 | printf |
| 1370 | ("The longest owner list is %d, the longest continuation block chain is %d\n", |
| 1371 | misc->maxOwnerLength, misc->maxContLength); |
| 1372 | printf("%d users ; %d foreign users ; and %d groups\n", misc->nusers, |
| 1373 | misc->nforeigns, misc->ngroups); |
| 1374 | } |
| 1375 | |
| 1376 | free(map); |
| 1377 | return code; |
| 1378 | } |
| 1379 | |
| 1380 | #include "AFS_component_version_number.c" |
| 1381 | |
| 1382 | int |
| 1383 | WorkerBee(struct cmd_syndesc *as, void *arock) |
| 1384 | { |
| 1385 | afs_int32 code; |
| 1386 | char *recreateFile; |
| 1387 | struct misc_data misc; /* info & statistics */ |
| 1388 | |
| 1389 | initialize_PT_error_table(); |
| 1390 | initialize_U_error_table(); |
| 1391 | |
| 1392 | pr_dbaseName = AFSDIR_SERVER_PRDB_FILEPATHgetDirPath(AFSDIR_SERVER_PRDB_FILEPATH_ID); |
| 1393 | memset(&misc, 0, sizeof(misc)); |
| 1394 | |
| 1395 | pr_dbaseName = as->parms[0].items->data; /* -database */ |
| 1396 | misc.listuheader = (as->parms[1].items ? 1 : 0); /* -uheader */ |
| 1397 | misc.listpheader = (as->parms[2].items ? 1 : 0); /* -pheader */ |
| 1398 | misc.listentries = (as->parms[3].items ? 1 : 0); /* -entries */ |
| 1399 | misc.verbose = (as->parms[4].items ? 1 : 0); /* -verbose */ |
| 1400 | recreateFile = (as->parms[5].items ? as->parms[5].items->data : NULL((void *)0)); /* -rebuild */ |
| 1401 | |
| 1402 | fd = open(pr_dbaseName, O_RDONLY0x0000, 0); |
| 1403 | if (fd == -1) { |
| 1404 | afs_com_err(whoami, errno(* __error()), "Open failed on db %s", pr_dbaseName); |
| 1405 | exit(2); |
| 1406 | } |
| 1407 | |
| 1408 | /* Read the ubik header */ |
| 1409 | if (misc.listuheader) { |
| 1410 | readUbikHeader(&misc); |
| 1411 | } |
| 1412 | |
| 1413 | code = ReadHeader(); |
| 1414 | if (code) |
| 1415 | return code; |
| 1416 | if (misc.listpheader) |
| 1417 | printheader(&cheader); |
| 1418 | |
| 1419 | if (recreateFile) { |
| 1420 | misc.recreate = fopen(recreateFile, "w"); |
| 1421 | if (misc.recreate == 0) { |
| 1422 | afs_com_err(whoami, errno(* __error()), |
| 1423 | "can't create file for recreation instructions: %s", |
| 1424 | recreateFile); |
| 1425 | exit(4); |
| 1426 | } |
| 1427 | } |
| 1428 | code = CheckPrDatabase(&misc); |
| 1429 | if (code) { |
| 1430 | afs_com_err(whoami, code, "Checking prserver database"); |
| 1431 | exit(3); |
| 1432 | } |
| 1433 | exit(0); |
| 1434 | } |
| 1435 | |
| 1436 | int |
| 1437 | main(int argc, char *argv[]) |
| 1438 | { |
| 1439 | struct cmd_syndesc *ts; |
| 1440 | |
| 1441 | setlinebuf(stdout__stdoutp); |
| 1442 | |
| 1443 | ts = cmd_CreateSyntax(NULL((void *)0), WorkerBee, NULL((void *)0), "PRDB check"); |
| 1444 | cmd_AddParm(ts, "-database", CMD_SINGLE2, CMD_REQUIRED0, "ptdb_file"); |
| 1445 | cmd_AddParm(ts, "-uheader", CMD_FLAG1, CMD_OPTIONAL1, |
| 1446 | "Display UBIK header"); |
| 1447 | cmd_AddParm(ts, "-pheader", CMD_FLAG1, CMD_OPTIONAL1, |
| 1448 | "Display KADB header"); |
| 1449 | cmd_AddParm(ts, "-entries", CMD_FLAG1, CMD_OPTIONAL1, "Display entries"); |
| 1450 | cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, "verbose"); |
| 1451 | cmd_AddParm(ts, "-rebuild", CMD_SINGLE2, CMD_OPTIONAL1 | CMD_HIDE4, |
| 1452 | "out_file"); |
| 1453 | |
| 1454 | return cmd_Dispatch(argc, argv); |
| 1455 | } |
| 1456 | |
| 1457 | |
| 1458 | #if defined(SUPERGROUPS1) |
| 1459 | |
| 1460 | /* new routines to deal with very large ID numbers */ |
| 1461 | |
| 1462 | void |
| 1463 | zeromap(struct idused *idmap) |
| 1464 | { |
| 1465 | while (idmap) { |
| 1466 | memset(idmap->idcount, 0, sizeof idmap->idcount); |
| 1467 | idmap = idmap->idnext; |
| 1468 | } |
| 1469 | } |
| 1470 | |
| 1471 | void |
| 1472 | inccount(struct idused **idmapp, int id) |
| 1473 | { |
| 1474 | struct idused *idmap; |
| 1475 | |
| 1476 | if (IDCOUNT512 & (IDCOUNT512 - 1)) { |
| 1477 | fprintf(stderr__stderrp, "IDCOUNT must be power of 2!\n"); |
| 1478 | exit(1); |
| 1479 | } |
| 1480 | while ((idmap = *idmapp) != NULL((void *)0)) { |
| 1481 | if (idmap->idstart == (id & ~(IDCOUNT512 - 1))) |
| 1482 | break; |
| 1483 | idmapp = &idmap->idnext; |
| 1484 | } |
| 1485 | if (!idmap) { |
| 1486 | idmap = (struct idused *)malloc(sizeof *idmap); |
| 1487 | if (!idmap) { |
| 1488 | perror("idmap"); |
| 1489 | exit(1); |
| 1490 | } |
| 1491 | memset(idmap, 0, sizeof idmap); |
| 1492 | idmap->idstart = id & ~(IDCOUNT512 - 1); |
| 1493 | idmap->idnext = *idmapp; |
| 1494 | *idmapp = idmap; |
| 1495 | } |
| 1496 | ++idmap->idcount[id & (IDCOUNT512 - 1)]; |
| 1497 | } |
| 1498 | |
| 1499 | int |
| 1500 | idcount(struct idused **idmapp, int id) |
| 1501 | { |
| 1502 | struct idused *idmap; |
| 1503 | |
| 1504 | if (IDCOUNT512 & (IDCOUNT512 - 1)) { |
| 1505 | fprintf(stderr__stderrp, "IDCOUNT must be power of 2!\n"); |
| 1506 | exit(1); |
| 1507 | } |
| 1508 | while ((idmap = *idmapp) != NULL((void *)0)) { |
| 1509 | if (idmap->idstart == (id & ~(IDCOUNT512 - 1))) { |
| 1510 | return idmap->idcount[id & (IDCOUNT512 - 1)]; |
| 1511 | } |
| 1512 | idmapp = &idmap->idnext; |
| 1513 | } |
| 1514 | return 0; |
| 1515 | } |
| 1516 | #endif /* SUPERGROUPS */ |