Bug Summary

File:s/lib/dbm/src/hash.c
Warning:line 1105, column 13
Potential leak of memory pointed to by 'store'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hash.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/dbm/src -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/dbm/src -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D STDC_HEADERS -D HAVE_STRERROR -D HAVE_SNPRINTF -D MEMMOVE -D __DBINTERFACE_PRIVATE -I ../../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../../dist/public/dbm -I ../../../../dist/private/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c hash.c
1/*-
2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Margo Seltzer.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. ***REMOVED*** - see
17 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if defined(LIBC_SCCS) && !defined(lint)
36static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
37#endif /* LIBC_SCCS and not lint */
38
39#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
40#include <sys/param.h>
41#endif
42
43#if !defined(macintosh)
44#ifdef XP_OS2
45#include <sys/types.h>
46#endif
47#include <sys/stat.h>
48#endif
49
50#if defined(macintosh)
51#include <unix.h>
52#include <unistd.h>
53#endif
54
55#include <errno(*__errno_location ()).h>
56#include <fcntl.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60
61#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
62#include <unistd.h>
63#endif
64#if defined(_WIN32) || defined(_WINDOWS)
65#include <windows.h>
66#endif
67
68#include <assert.h>
69
70#include "mcom_db.h"
71#include "hash.h"
72#include "page.h"
73
74/*
75#include "extern.h"
76*/
77static int alloc_segs(HTAB *, int);
78static int flush_meta(HTAB *);
79static int hash_access(HTAB *, ACTION, DBT *, DBT *);
80static int hash_close(DB *);
81static int hash_delete(const DB *, const DBT *, uint);
82static int hash_fd(const DB *);
83static int hash_get(const DB *, const DBT *, DBT *, uint);
84static int hash_put(const DB *, DBT *, const DBT *, uint);
85static void *hash_realloc(SEGMENT **, size_t, size_t);
86static int hash_seq(const DB *, DBT *, DBT *, uint);
87static int hash_sync(const DB *, uint);
88static int hdestroy(HTAB *);
89static HTAB *init_hash(HTAB *, const char *, HASHINFO *);
90static int init_htab(HTAB *, int);
91#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
92static void swap_header(HTAB *);
93static void swap_header_copy(HASHHDR *, HASHHDR *);
94#endif
95
96/* Fast arithmetic, relying on powers of 2, */
97#define MOD(x, y)((x) & ((y)-1)) ((x) & ((y)-1))
98
99#define RETURN_ERROR(ERR, LOC){ save_errno = ERR; goto LOC; } \
100 { \
101 save_errno = ERR; \
102 goto LOC; \
103 }
104
105/* Return values */
106#define SUCCESS(0) (0)
107#define DBM_ERROR(-1) (-1)
108#define ABNORMAL(1) (1)
109
110#ifdef HASH_STATISTICS
111int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
112#endif
113
114/* A new Lou (montulli@mozilla.com) routine.
115 *
116 * The database is screwed.
117 *
118 * This closes the file, flushing buffers as appropriate.
119 */
120static void
121dbm_remove_database(DB *dbp)
122{
123 HTAB *hashp = (HTAB *)dbp->internal;
124
125 assert(0)((0) ? (void) (0) : __assert_fail ("0", "hash.c", 125, __extension__
__PRETTY_FUNCTION__))
;
126
127 if (!hashp)
128 return;
129 hdestroy(hashp);
130 dbp->internal = NULL((void*)0);
131}
132
133/************************** INTERFACE ROUTINES ***************************/
134/* OPEN/CLOSE */
135
136extern DB *
137dbm_hash_open(const char *file, int flags, int mode, const HASHINFO *info, int dflags)
138{
139 HTAB *hashp = NULL((void*)0);
140 struct stat statbuf;
141 DB *dbp;
142 int bpages, hdrsize, new_table, nsegs, save_errno;
143
144 if ((flags & O_ACCMODE0003) == O_WRONLY01) {
1
Assuming the condition is false
2
Taking false branch
145 errno(*__errno_location ()) = EINVAL22;
146 return NULL((void*)0);
147 }
148
149 /* zero the statbuffer so that
150 * we can check it for a non-zero
151 * date to see if stat succeeded
152 */
153 memset(&statbuf, 0, sizeof(struct stat));
154
155 if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) {
3
Assuming 'hashp' is non-null
4
Taking false branch
156 errno(*__errno_location ()) = ENOMEM12;
157 return NULL((void*)0);
158 }
159 hashp->fp = NO_FILE-1;
160 if (file)
5
Assuming 'file' is non-null
6
Taking true branch
161 hashp->filename = strdup(file);
162
163 /*
164 * Even if user wants write only, we need to be able to read
165 * the actual file, so we need to open it read/write. But, the
166 * field in the hashp structure needs to be accurate so that
167 * we can check accesses.
168 */
169 hashp->flags = flags;
170
171 new_table = 0;
172 if (!file
6.1
'file' is non-null
|| (flags & O_TRUNC01000) || (stat(file, &statbuf) && (errno(*__errno_location ()) == ENOENT2))) {
7
Assuming the condition is false
8
Assuming the condition is false
173 if (errno(*__errno_location ()) == ENOENT2)
174 errno(*__errno_location ()) = 0; /* Just in case someone looks at errno */
175 new_table = 1;
176 } else if (statbuf.st_mtimest_mtim.tv_sec && statbuf.st_size == 0) {
9
Assuming field 'tv_sec' is 0
177 /* check for a zero length file and delete it
178 * if it exists
179 */
180 new_table = 1;
181 }
182 hashp->file_size = statbuf.st_size;
183
184 if (file
9.1
'file' is non-null
) {
10
Taking true branch
185#if defined(_WIN32) || defined(_WINDOWS) || defined(macintosh) || defined(XP_OS2)
186 if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)open((file), (flags | O_BINARY), (mode))) == -1)
187 RETURN_ERROR(errno, error1){ save_errno = (*__errno_location ()); goto error1; };
188#else
189 if ((hashp->fp = open(file, flags, mode)) == -1)
11
Assuming the condition is false
12
Taking false branch
190 RETURN_ERROR(errno, error1){ save_errno = (*__errno_location ()); goto error1; };
191 (void)fcntl(hashp->fp, F_SETFD2, 1);
192#endif
193 }
194 if (new_table
12.1
'new_table' is 0
) {
195 if (!init_hash(hashp, file, (HASHINFO *)info))
196 RETURN_ERROR(errno, error1){ save_errno = (*__errno_location ()); goto error1; };
197 } else {
198 /* Table already exists */
199 if (info && info->hash)
13
Assuming 'info' is null
200 hashp->hash = info->hash;
201 else
202 hashp->hash = dbm_default_hash;
203
204 hdrsize = read(hashp->fp, (char *)&hashp->hdr, sizeof(HASHHDR));
205 if (hdrsize == -1)
14
Assuming the condition is false
15
Taking false branch
206 RETURN_ERROR(errno, error1){ save_errno = (*__errno_location ()); goto error1; };
207 if (hdrsize != sizeof(HASHHDR))
16
Assuming the condition is false
17
Taking false branch
208 RETURN_ERROR(EFTYPE, error1){ save_errno = 22; goto error1; };
209#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
210 swap_header(hashp);
211#endif
212 /* Verify file type, versions and hash function */
213 if (hashp->MAGIChdr.magic != HASHMAGIC0x061561)
18
Assuming field 'magic' is equal to HASHMAGIC
214 RETURN_ERROR(EFTYPE, error1){ save_errno = 22; goto error1; };
215#define OLDHASHVERSION1 1
216 if (hashp->VERSIONhdr.version != HASHVERSION2 &&
19
Assuming field 'version' is equal to HASHVERSION
217 hashp->VERSIONhdr.version != OLDHASHVERSION1)
218 RETURN_ERROR(EFTYPE, error1){ save_errno = 22; goto error1; };
219 if (hashp->hash(CHARKEY"%$sniglet^&", sizeof(CHARKEY"%$sniglet^&")) != hashp->H_CHARKEYhdr.h_charkey)
20
Assuming the condition is false
21
Taking false branch
220 RETURN_ERROR(EFTYPE, error1){ save_errno = 22; goto error1; };
221 if (hashp->NKEYShdr.nkeys < 0) /* Old bad database. */
22
Assuming field 'nkeys' is >= 0
23
Taking false branch
222 RETURN_ERROR(EFTYPE, error1){ save_errno = 22; goto error1; };
223
224 /*
225 * Figure out how many segments we need. Max_Bucket is the
226 * maximum bucket number, so the number of buckets is
227 * max_bucket + 1.
228 */
229 nsegs = (hashp->MAX_BUCKEThdr.max_bucket + 1 + hashp->SGSIZEhdr.ssize - 1) /
230 hashp->SGSIZEhdr.ssize;
231 hashp->nsegs = 0;
232 if (alloc_segs(hashp, nsegs))
24
Calling 'alloc_segs'
233 /* If alloc_segs fails, errno will have been set. */
234 RETURN_ERROR(errno, error1){ save_errno = (*__errno_location ()); goto error1; };
235 /* Read in bitmaps */
236 bpages = (hashp->SPAREShdr.spares[hashp->OVFL_POINThdr.ovfl_point] +
237 (hashp->BSIZEhdr.bsize << BYTE_SHIFT3) - 1) >>
238 (hashp->BSHIFThdr.bshift + BYTE_SHIFT3);
239
240 hashp->nmaps = bpages;
241 (void)memset(&hashp->mapp[0], 0, bpages * sizeof(uint32 *));
242 }
243
244 /* Initialize Buffer Manager */
245 if (info && info->cachesize)
246 dbm_buf_init(hashp, (int32)info->cachesize);
247 else
248 dbm_buf_init(hashp, DEF_BUFSIZE65536l);
249
250 hashp->new_file = new_table;
251#ifdef macintosh
252 hashp->save_file = file && !(hashp->flags & O_RDONLY00);
253#else
254 hashp->save_file = file && (hashp->flags & O_RDWR02);
255#endif
256 hashp->cbucket = -1;
257 if (!(dbp = (DB *)malloc(sizeof(DB)))) {
258 RETURN_ERROR(ENOMEM, error1){ save_errno = 12; goto error1; };
259 }
260 dbp->internal = hashp;
261 dbp->close = hash_close;
262 dbp->del = hash_delete;
263 dbp->fd = hash_fd;
264 dbp->get = hash_get;
265 dbp->put = hash_put;
266 dbp->seq = hash_seq;
267 dbp->sync = hash_sync;
268 dbp->type = DB_HASH;
269
270#ifdef HASH_STATISTICS
271 hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
272#endif
273 return (dbp);
274
275error1:
276 hdestroy(hashp);
277 errno(*__errno_location ()) = save_errno;
278 return (NULL((void*)0));
279}
280
281static int
282hash_close(DB *dbp)
283{
284 HTAB *hashp;
285 int retval;
286
287 if (!dbp)
288 return (DBM_ERROR(-1));
289
290 hashp = (HTAB *)dbp->internal;
291 if (!hashp)
292 return (DBM_ERROR(-1));
293
294 retval = hdestroy(hashp);
295 free(dbp);
296 return (retval);
297}
298
299static int
300hash_fd(const DB *dbp)
301{
302 HTAB *hashp;
303
304 if (!dbp)
305 return (DBM_ERROR(-1));
306
307 hashp = (HTAB *)dbp->internal;
308 if (!hashp)
309 return (DBM_ERROR(-1));
310
311 if (hashp->fp == -1) {
312 errno(*__errno_location ()) = ENOENT2;
313 return (-1);
314 }
315 return (hashp->fp);
316}
317
318/************************** LOCAL CREATION ROUTINES **********************/
319static HTAB *
320init_hash(HTAB *hashp, const char *file, HASHINFO *info)
321{
322 struct stat statbuf;
323 int nelem;
324
325 nelem = 1;
326 hashp->NKEYShdr.nkeys = 0;
327 hashp->LORDERhdr.lorder = BYTE_ORDER1234;
328 hashp->BSIZEhdr.bsize = DEF_BUCKET_SIZE4096;
329 hashp->BSHIFThdr.bshift = DEF_BUCKET_SHIFT12;
330 hashp->SGSIZEhdr.ssize = DEF_SEGSIZE256;
331 hashp->SSHIFThdr.sshift = DEF_SEGSIZE_SHIFT8;
332 hashp->DSIZEhdr.dsize = DEF_DIRSIZE256;
333 hashp->FFACTORhdr.ffactor = DEF_FFACTOR65536l;
334 hashp->hash = dbm_default_hash;
335 memset(hashp->SPAREShdr.spares, 0, sizeof(hashp->SPAREShdr.spares));
336 memset(hashp->BITMAPShdr.bitmaps, 0, sizeof(hashp->BITMAPShdr.bitmaps));
337
338 /* Fix bucket size to be optimal for file system */
339 if (file != NULL((void*)0)) {
340 if (stat(file, &statbuf))
341 return (NULL((void*)0));
342
343#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2)
344#if defined(__QNX__) && !defined(__QNXNTO__)
345 hashp->BSIZEhdr.bsize = 512; /* preferred blk size on qnx4 */
346#else
347 hashp->BSIZEhdr.bsize = statbuf.st_blksize;
348#endif
349
350 /* new code added by Lou to reduce block
351 * size down below MAX_BSIZE
352 */
353 if (hashp->BSIZEhdr.bsize > MAX_BSIZE32l * 1024l)
354 hashp->BSIZEhdr.bsize = MAX_BSIZE32l * 1024l;
355#endif
356 hashp->BSHIFThdr.bshift = dbm_log2((uint32)hashp->BSIZEhdr.bsize);
357 }
358
359 if (info) {
360 if (info->bsize) {
361 /* Round pagesize up to power of 2 */
362 hashp->BSHIFThdr.bshift = dbm_log2(info->bsize);
363 hashp->BSIZEhdr.bsize = 1 << hashp->BSHIFThdr.bshift;
364 if (hashp->BSIZEhdr.bsize > MAX_BSIZE32l * 1024l) {
365 errno(*__errno_location ()) = EINVAL22;
366 return (NULL((void*)0));
367 }
368 }
369 if (info->ffactor)
370 hashp->FFACTORhdr.ffactor = info->ffactor;
371 if (info->hash)
372 hashp->hash = info->hash;
373 if (info->nelem)
374 nelem = info->nelem;
375 if (info->lorder) {
376 if (info->lorder != BIG_ENDIAN4321 &&
377 info->lorder != LITTLE_ENDIAN1234) {
378 errno(*__errno_location ()) = EINVAL22;
379 return (NULL((void*)0));
380 }
381 hashp->LORDERhdr.lorder = info->lorder;
382 }
383 }
384 /* init_htab sets errno if it fails */
385 if (init_htab(hashp, nelem))
386 return (NULL((void*)0));
387 else
388 return (hashp);
389}
390/*
391 * This calls alloc_segs which may run out of memory. Alloc_segs will
392 * set errno, so we just pass the error information along.
393 *
394 * Returns 0 on No Error
395 */
396static int
397init_htab(HTAB *hashp, int nelem)
398{
399 register int nbuckets, nsegs;
400 int l2;
401
402 /*
403 * Divide number of elements by the fill factor and determine a
404 * desired number of buckets. Allocate space for the next greater
405 * power of two number of buckets.
406 */
407 nelem = (nelem - 1) / hashp->FFACTORhdr.ffactor + 1;
408
409 l2 = dbm_log2((uint32)PR_MAX(nelem, 2)((nelem)>(2)?(nelem):(2)));
410 nbuckets = 1 << l2;
411
412 hashp->SPAREShdr.spares[l2] = l2 + 1;
413 hashp->SPAREShdr.spares[l2 + 1] = l2 + 1;
414 hashp->OVFL_POINThdr.ovfl_point = l2;
415 hashp->LAST_FREEDhdr.last_freed = 2;
416
417 /* First bitmap page is at: splitpoint l2 page offset 1 */
418 if (dbm_ibitmap(hashp, (int)OADDR_OF(l2, 1)((uint32)((uint32)(l2) << 11) + (1)), l2 + 1, 0))
419 return (-1);
420
421 hashp->MAX_BUCKEThdr.max_bucket = hashp->LOW_MASKhdr.low_mask = nbuckets - 1;
422 hashp->HIGH_MASKhdr.high_mask = (nbuckets << 1) - 1;
423 hashp->HDRPAGEShdr.hdrpages = ((PR_MAX(sizeof(HASHHDR), MINHDRSIZE)((sizeof(HASHHDR))>(512)?(sizeof(HASHHDR)):(512)) - 1) >>
424 hashp->BSHIFThdr.bshift) +
425 1;
426
427 nsegs = (nbuckets - 1) / hashp->SGSIZEhdr.ssize + 1;
428 nsegs = 1 << dbm_log2((uint32)nsegs);
429
430 if (nsegs > hashp->DSIZEhdr.dsize)
431 hashp->DSIZEhdr.dsize = nsegs;
432 return (alloc_segs(hashp, nsegs));
433}
434
435/********************** DESTROY/CLOSE ROUTINES ************************/
436
437/*
438 * Flushes any changes to the file if necessary and destroys the hashp
439 * structure, freeing all allocated space.
440 */
441static int
442hdestroy(HTAB *hashp)
443{
444 int i, save_errno;
445
446 save_errno = 0;
447
448#ifdef HASH_STATISTICS
449 (void)fprintf(stderrstderr, "hdestroy: accesses %ld collisions %ld\n",
450 hash_accesses, hash_collisions);
451 (void)fprintf(stderrstderr, "hdestroy: expansions %ld\n",
452 hash_expansions);
453 (void)fprintf(stderrstderr, "hdestroy: overflows %ld\n",
454 hash_overflows);
455 (void)fprintf(stderrstderr, "keys %ld maxp %d segmentcount %d\n",
456 hashp->NKEYShdr.nkeys, hashp->MAX_BUCKEThdr.max_bucket, hashp->nsegs);
457
458 for (i = 0; i < NCACHED32; i++)
459 (void)fprintf(stderrstderr,
460 "spares[%d] = %d\n", i, hashp->SPAREShdr.spares[i]);
461#endif
462 /*
463 * Call on buffer manager to free buffers, and if required,
464 * write them to disk.
465 */
466 if (dbm_buf_free(hashp, 1, hashp->save_file))
467 save_errno = errno(*__errno_location ());
468 if (hashp->dir) {
469 free(*hashp->dir); /* Free initial segments */
470 /* Free extra segments */
471 while (hashp->exsegs--)
472 free(hashp->dir[--hashp->nsegs]);
473 free(hashp->dir);
474 }
475 if (flush_meta(hashp) && !save_errno)
476 save_errno = errno(*__errno_location ());
477 /* Free Bigmaps */
478 for (i = 0; i < hashp->nmaps; i++)
479 if (hashp->mapp[i])
480 free(hashp->mapp[i]);
481
482 if (hashp->fp != -1)
483 (void)close(hashp->fp);
484
485 if (hashp->filename) {
486#if defined(_WIN32) || defined(_WINDOWS) || defined(XP_OS2)
487 if (hashp->is_temp)
488 (void)unlink(hashp->filename);
489#endif
490 free(hashp->filename);
491 }
492 if (hashp->tmp_buf)
493 free(hashp->tmp_buf);
494 if (hashp->tmp_key)
495 free(hashp->tmp_key);
496 free(hashp);
497 if (save_errno) {
498 errno(*__errno_location ()) = save_errno;
499 return (DBM_ERROR(-1));
500 }
501 return (SUCCESS(0));
502}
503
504#if defined(_WIN32) || defined(_WINDOWS)
505/*
506 * Close and reopen file to force file length update on windows.
507 *
508 * Returns:
509 * 0 == OK
510 * -1 DBM_ERROR
511 */
512static int
513update_EOF(HTAB *hashp)
514{
515#if defined(DBM_REOPEN_ON_FLUSH)
516 char *file = hashp->filename;
517 off_t file_size;
518 int flags;
519 int mode = -1;
520 struct stat statbuf;
521
522 memset(&statbuf, 0, sizeof statbuf);
523
524 /* make sure we won't lose the file by closing it. */
525 if (!file || (stat(file, &statbuf) && (errno(*__errno_location ()) == ENOENT2))) {
526 /* pretend we did it. */
527 return 0;
528 }
529
530 (void)close(hashp->fp);
531
532 flags = hashp->flags & ~(O_TRUNC01000 | O_CREAT0100 | O_EXCL0200);
533
534 if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)open((file), (flags | O_BINARY), (mode))) == -1)
535 return -1;
536 file_size = lseek(hashp->fp, (off_t)0, SEEK_END2);
537 if (file_size == -1)
538 return -1;
539 hashp->file_size = file_size;
540 return 0;
541#else
542 int fd = hashp->fp;
543 off_t file_size = lseek(fd, (off_t)0, SEEK_END2);
544 HANDLE handle = (HANDLE)_get_osfhandle(fd);
545 BOOL cool = FlushFileBuffers(handle);
546#ifdef DEBUG3
547 if (!cool) {
548 DWORD err = GetLastError();
549 (void)fprintf(stderrstderr,
550 "FlushFileBuffers failed, last error = %d, 0x%08x\n",
551 err, err);
552 }
553#endif
554 if (file_size == -1)
555 return -1;
556 hashp->file_size = file_size;
557 return cool ? 0 : -1;
558#endif
559}
560#endif
561
562/*
563 * Write modified pages to disk
564 *
565 * Returns:
566 * 0 == OK
567 * -1 DBM_ERROR
568 */
569static int
570hash_sync(const DB *dbp, uint flags)
571{
572 HTAB *hashp;
573
574 if (flags != 0) {
575 errno(*__errno_location ()) = EINVAL22;
576 return (DBM_ERROR(-1));
577 }
578
579 if (!dbp)
580 return (DBM_ERROR(-1));
581
582 hashp = (HTAB *)dbp->internal;
583 if (!hashp)
584 return (DBM_ERROR(-1));
585
586 if (!hashp->save_file)
587 return (0);
588 if (dbm_buf_free(hashp, 0, 1) || flush_meta(hashp))
589 return (DBM_ERROR(-1));
590#if defined(_WIN32) || defined(_WINDOWS)
591 if (hashp->updateEOF && hashp->filename && !hashp->is_temp) {
592 int status = update_EOF(hashp);
593 hashp->updateEOF = 0;
594 if (status)
595 return status;
596 }
597#endif
598 hashp->new_file = 0;
599 return (0);
600}
601
602/*
603 * Returns:
604 * 0 == OK
605 * -1 indicates that errno should be set
606 */
607static int
608flush_meta(HTAB *hashp)
609{
610 HASHHDR *whdrp;
611#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
612 HASHHDR whdr;
613#endif
614 int fp, i, wsize;
615
616 if (!hashp->save_file)
617 return (0);
618 hashp->MAGIChdr.magic = HASHMAGIC0x061561;
619 hashp->VERSIONhdr.version = HASHVERSION2;
620 hashp->H_CHARKEYhdr.h_charkey = hashp->hash(CHARKEY"%$sniglet^&", sizeof(CHARKEY"%$sniglet^&"));
621
622 fp = hashp->fp;
623 whdrp = &hashp->hdr;
624#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
625 whdrp = &whdr;
626 swap_header_copy(&hashp->hdr, whdrp);
627#endif
628 if ((lseek(fp, (off_t)0, SEEK_SET0) == -1) ||
629 ((wsize = write(fp, (char *)whdrp, sizeof(HASHHDR))) == -1))
630 return (-1);
631 else if (wsize != sizeof(HASHHDR)) {
632 errno(*__errno_location ()) = EFTYPE22;
633 hashp->dbmerrno = errno(*__errno_location ());
634 return (-1);
635 }
636 for (i = 0; i < NCACHED32; i++)
637 if (hashp->mapp[i])
638 if (dbm_put_page(hashp, (char *)hashp->mapp[i],
639 hashp->BITMAPShdr.bitmaps[i], 0, 1))
640 return (-1);
641 return (0);
642}
643
644/*******************************SEARCH ROUTINES *****************************/
645/*
646 * All the access routines return
647 *
648 * Returns:
649 * 0 on SUCCESS
650 * 1 to indicate an external DBM_ERROR (i.e. key not found, etc)
651 * -1 to indicate an internal DBM_ERROR (i.e. out of memory, etc)
652 */
653static int
654hash_get(
655 const DB *dbp,
656 const DBT *key,
657 DBT *data,
658 uint flag)
659{
660 HTAB *hashp;
661 int rv;
662
663 hashp = (HTAB *)dbp->internal;
664 if (!hashp)
665 return (DBM_ERROR(-1));
666
667 if (flag) {
668 hashp->dbmerrno = errno(*__errno_location ()) = EINVAL22;
669 return (DBM_ERROR(-1));
670 }
671
672 rv = hash_access(hashp, HASH_GET, (DBT *)key, data);
673
674 if (rv == DATABASE_CORRUPTED_ERROR-999) {
675#if defined(unix) && defined(DEBUG1)
676 printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
677#endif
678 dbm_remove_database((DB *)dbp);
679 }
680
681 return (rv);
682}
683
684static int
685hash_put(
686 const DB *dbp,
687 DBT *key,
688 const DBT *data,
689 uint flag)
690{
691 HTAB *hashp;
692 int rv;
693
694 hashp = (HTAB *)dbp->internal;
695 if (!hashp)
696 return (DBM_ERROR(-1));
697
698 if (flag && flag != R_NOOVERWRITE8) {
699 hashp->dbmerrno = errno(*__errno_location ()) = EINVAL22;
700 return (DBM_ERROR(-1));
701 }
702 if ((hashp->flags & O_ACCMODE0003) == O_RDONLY00) {
703 hashp->dbmerrno = errno(*__errno_location ()) = EPERM1;
704 return (DBM_ERROR(-1));
705 }
706
707 rv = hash_access(hashp, flag == R_NOOVERWRITE8 ? HASH_PUTNEW : HASH_PUT,
708 (DBT *)key, (DBT *)data);
709
710 if (rv == DATABASE_CORRUPTED_ERROR-999) {
711#if defined(unix) && defined(DEBUG1)
712 printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
713#endif
714 dbm_remove_database((DB *)dbp);
715 }
716
717 return (rv);
718}
719
720static int
721hash_delete(
722 const DB *dbp,
723 const DBT *key,
724 uint flag) /* Ignored */
725{
726 HTAB *hashp;
727 int rv;
728
729 hashp = (HTAB *)dbp->internal;
730 if (!hashp)
731 return (DBM_ERROR(-1));
732
733 if (flag && flag != R_CURSOR1) {
734 hashp->dbmerrno = errno(*__errno_location ()) = EINVAL22;
735 return (DBM_ERROR(-1));
736 }
737 if ((hashp->flags & O_ACCMODE0003) == O_RDONLY00) {
738 hashp->dbmerrno = errno(*__errno_location ()) = EPERM1;
739 return (DBM_ERROR(-1));
740 }
741 rv = hash_access(hashp, HASH_DELETE, (DBT *)key, NULL((void*)0));
742
743 if (rv == DATABASE_CORRUPTED_ERROR-999) {
744#if defined(unix) && defined(DEBUG1)
745 printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
746#endif
747 dbm_remove_database((DB *)dbp);
748 }
749
750 return (rv);
751}
752
753#define MAX_OVERFLOW_HASH_ACCESS_LOOPS2000 2000
754/*
755 * Assume that hashp has been set in wrapper routine.
756 */
757static int
758hash_access(
759 HTAB *hashp,
760 ACTION action,
761 DBT *key, DBT *val)
762{
763 register BUFHEAD *rbufp;
764 BUFHEAD *bufp, *save_bufp;
765 register uint16 *bp;
766 register long n, ndx, off;
767 register size_t size;
768 register char *kp;
769 uint16 pageno;
770 uint32 ovfl_loop_count = 0;
771 int32 last_overflow_page_no = -1;
772
773#ifdef HASH_STATISTICS
774 hash_accesses++;
775#endif
776
777 off = hashp->BSIZEhdr.bsize;
778 size = key->size;
779 kp = (char *)key->data;
780 rbufp = dbm_get_buf(hashp, dbm_call_hash(hashp, kp, size), NULL((void*)0), 0);
781 if (!rbufp)
782 return (DATABASE_CORRUPTED_ERROR-999);
783 save_bufp = rbufp;
784
785 /* Pin the bucket chain */
786 rbufp->flags |= BUF_PIN0x0008;
787 for (bp = (uint16 *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) {
788
789 if (bp[1] >= REAL_KEY4) {
790 /* Real key/data pair */
791 if (size == (unsigned long)(off - *bp) &&
792 memcmp(kp, rbufp->page + *bp, size) == 0)
793 goto found;
794 off = bp[1];
795#ifdef HASH_STATISTICS
796 hash_collisions++;
797#endif
798 bp += 2;
799 ndx += 2;
800 } else if (bp[1] == OVFLPAGE0) {
801
802 /* database corruption: overflow loop detection */
803 if (last_overflow_page_no == (int32)*bp)
804 return (DATABASE_CORRUPTED_ERROR-999);
805
806 last_overflow_page_no = *bp;
807
808 rbufp = dbm_get_buf(hashp, *bp, rbufp, 0);
809 if (!rbufp) {
810 save_bufp->flags &= ~BUF_PIN0x0008;
811 return (DBM_ERROR(-1));
812 }
813
814 ovfl_loop_count++;
815 if (ovfl_loop_count > MAX_OVERFLOW_HASH_ACCESS_LOOPS2000)
816 return (DATABASE_CORRUPTED_ERROR-999);
817
818 /* FOR LOOP INIT */
819 bp = (uint16 *)rbufp->page;
820 n = *bp++;
821 ndx = 1;
822 off = hashp->BSIZEhdr.bsize;
823 } else if (bp[1] < REAL_KEY4) {
824 if ((ndx =
825 dbm_find_bigpair(hashp, rbufp, ndx, kp, (int)size)) > 0)
826 goto found;
827 if (ndx == -2) {
828 bufp = rbufp;
829 if (!(pageno =
830 dbm_find_last_page(hashp, &bufp))) {
831 ndx = 0;
832 rbufp = bufp;
833 break; /* FOR */
834 }
835 rbufp = dbm_get_buf(hashp, pageno, bufp, 0);
836 if (!rbufp) {
837 save_bufp->flags &= ~BUF_PIN0x0008;
838 return (DBM_ERROR(-1));
839 }
840 /* FOR LOOP INIT */
841 bp = (uint16 *)rbufp->page;
842 n = *bp++;
843 ndx = 1;
844 off = hashp->BSIZEhdr.bsize;
845 } else {
846 save_bufp->flags &= ~BUF_PIN0x0008;
847 return (DBM_ERROR(-1));
848 }
849 }
850 }
851
852 /* Not found */
853 switch (action) {
854 case HASH_PUT:
855 case HASH_PUTNEW:
856 if (dbm_addel(hashp, rbufp, key, val)) {
857 save_bufp->flags &= ~BUF_PIN0x0008;
858 return (DBM_ERROR(-1));
859 } else {
860 save_bufp->flags &= ~BUF_PIN0x0008;
861 return (SUCCESS(0));
862 }
863 case HASH_GET:
864 case HASH_DELETE:
865 default:
866 save_bufp->flags &= ~BUF_PIN0x0008;
867 return (ABNORMAL(1));
868 }
869
870found:
871 switch (action) {
872 case HASH_PUTNEW:
873 save_bufp->flags &= ~BUF_PIN0x0008;
874 return (ABNORMAL(1));
875 case HASH_GET:
876 bp = (uint16 *)rbufp->page;
877 if (bp[ndx + 1] < REAL_KEY4) {
878 if (dbm_big_return(hashp, rbufp, ndx, val, 0))
879 return (DBM_ERROR(-1));
880 } else {
881 val->data = (uint8 *)rbufp->page + (int)bp[ndx + 1];
882 val->size = bp[ndx] - bp[ndx + 1];
883 }
884 break;
885 case HASH_PUT:
886 if ((dbm_delpair(hashp, rbufp, ndx)) ||
887 (dbm_addel(hashp, rbufp, key, val))) {
888 save_bufp->flags &= ~BUF_PIN0x0008;
889 return (DBM_ERROR(-1));
890 }
891 break;
892 case HASH_DELETE:
893 if (dbm_delpair(hashp, rbufp, ndx))
894 return (DBM_ERROR(-1));
895 break;
896 default:
897 abort();
898 }
899 save_bufp->flags &= ~BUF_PIN0x0008;
900 return (SUCCESS(0));
901}
902
903static int
904hash_seq(
905 const DB *dbp,
906 DBT *key, DBT *data,
907 uint flag)
908{
909 register uint32 bucket;
910 register BUFHEAD *bufp = NULL((void*)0);
911 HTAB *hashp;
912 uint16 *bp, ndx;
913
914 hashp = (HTAB *)dbp->internal;
915 if (!hashp)
916 return (DBM_ERROR(-1));
917
918 if (flag && flag != R_FIRST3 && flag != R_NEXT7) {
919 hashp->dbmerrno = errno(*__errno_location ()) = EINVAL22;
920 return (DBM_ERROR(-1));
921 }
922#ifdef HASH_STATISTICS
923 hash_accesses++;
924#endif
925 if ((hashp->cbucket < 0) || (flag == R_FIRST3)) {
926 hashp->cbucket = 0;
927 hashp->cndx = 1;
928 hashp->cpage = NULL((void*)0);
929 }
930
931 for (bp = NULL((void*)0); !bp || !bp[0];) {
932 if (!(bufp = hashp->cpage)) {
933 for (bucket = hashp->cbucket;
934 bucket <= (uint32)hashp->MAX_BUCKEThdr.max_bucket;
935 bucket++, hashp->cndx = 1) {
936 bufp = dbm_get_buf(hashp, bucket, NULL((void*)0), 0);
937 if (!bufp)
938 return (DBM_ERROR(-1));
939 hashp->cpage = bufp;
940 bp = (uint16 *)bufp->page;
941 if (bp[0])
942 break;
943 }
944 hashp->cbucket = bucket;
945 if (hashp->cbucket > hashp->MAX_BUCKEThdr.max_bucket) {
946 hashp->cbucket = -1;
947 return (ABNORMAL(1));
948 }
949 } else
950 bp = (uint16 *)hashp->cpage->page;
951
952#ifdef DEBUG1
953 assert(bp)((bp) ? (void) (0) : __assert_fail ("bp", "hash.c", 953, __extension__
__PRETTY_FUNCTION__))
;
954 assert(bufp)((bufp) ? (void) (0) : __assert_fail ("bufp", "hash.c", 954, __extension__
__PRETTY_FUNCTION__))
;
955#endif
956 while (bp[hashp->cndx + 1] == OVFLPAGE0) {
957 bufp = hashp->cpage =
958 dbm_get_buf(hashp, bp[hashp->cndx], bufp, 0);
959 if (!bufp)
960 return (DBM_ERROR(-1));
961 bp = (uint16 *)(bufp->page);
962 hashp->cndx = 1;
963 }
964 if (!bp[0]) {
965 hashp->cpage = NULL((void*)0);
966 ++hashp->cbucket;
967 }
968 }
969 ndx = hashp->cndx;
970 if (bp[ndx + 1] < REAL_KEY4) {
971 if (dbm_big_keydata(hashp, bufp, key, data, 1))
972 return (DBM_ERROR(-1));
973 } else {
974 key->data = (uint8 *)hashp->cpage->page + bp[ndx];
975 key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZEhdr.bsize) - bp[ndx];
976 data->data = (uint8 *)hashp->cpage->page + bp[ndx + 1];
977 data->size = bp[ndx] - bp[ndx + 1];
978 ndx += 2;
979 if (ndx > bp[0]) {
980 hashp->cpage = NULL((void*)0);
981 hashp->cbucket++;
982 hashp->cndx = 1;
983 } else
984 hashp->cndx = ndx;
985 }
986 return (SUCCESS(0));
987}
988
989/********************************* UTILITIES ************************/
990
991/*
992 * Returns:
993 * 0 ==> OK
994 * -1 ==> Error
995 */
996extern int
997dbm_expand_table(HTAB *hashp)
998{
999 uint32 old_bucket, new_bucket;
1000 int new_segnum, spare_ndx;
1001 size_t dirsize;
1002
1003#ifdef HASH_STATISTICS
1004 hash_expansions++;
1005#endif
1006 new_bucket = ++hashp->MAX_BUCKEThdr.max_bucket;
1007 old_bucket = (hashp->MAX_BUCKEThdr.max_bucket & hashp->LOW_MASKhdr.low_mask);
1008
1009 new_segnum = new_bucket >> hashp->SSHIFThdr.sshift;
1010
1011 /* Check if we need a new segment */
1012 if (new_segnum >= hashp->nsegs) {
1013 /* Check if we need to expand directory */
1014 if (new_segnum >= hashp->DSIZEhdr.dsize) {
1015 /* Reallocate directory */
1016 dirsize = hashp->DSIZEhdr.dsize * sizeof(SEGMENT *);
1017 if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
1018 return (-1);
1019 hashp->DSIZEhdr.dsize = dirsize << 1;
1020 }
1021 if ((hashp->dir[new_segnum] =
1022 (SEGMENT)calloc((size_t)hashp->SGSIZEhdr.ssize, sizeof(BUFHEAD *))) == NULL((void*)0))
1023 return (-1);
1024 hashp->exsegs++;
1025 hashp->nsegs++;
1026 }
1027 /*
1028 * If the split point is increasing (MAX_BUCKET's log base 2
1029 * * increases), we need to copy the current contents of the spare
1030 * split bucket to the next bucket.
1031 */
1032 spare_ndx = dbm_log2((uint32)(hashp->MAX_BUCKEThdr.max_bucket + 1));
1033 if (spare_ndx > hashp->OVFL_POINThdr.ovfl_point) {
1034 hashp->SPAREShdr.spares[spare_ndx] = hashp->SPAREShdr.spares[hashp->OVFL_POINThdr.ovfl_point];
1035 hashp->OVFL_POINThdr.ovfl_point = spare_ndx;
1036 }
1037
1038 if (new_bucket > (uint32)hashp->HIGH_MASKhdr.high_mask) {
1039 /* Starting a new doubling */
1040 hashp->LOW_MASKhdr.low_mask = hashp->HIGH_MASKhdr.high_mask;
1041 hashp->HIGH_MASKhdr.high_mask = new_bucket | hashp->LOW_MASKhdr.low_mask;
1042 }
1043 /* Relocate records to the new bucket */
1044 return (dbm_split_page(hashp, old_bucket, new_bucket));
1045}
1046
1047/*
1048 * If realloc guarantees that the pointer is not destroyed if the realloc
1049 * fails, then this routine can go away.
1050 */
1051static void *
1052hash_realloc(
1053 SEGMENT **p_ptr,
1054 size_t oldsize, size_t newsize)
1055{
1056 register void *p;
1057
1058 if ((p = malloc(newsize))) {
1059 memmove(p, *p_ptr, oldsize);
1060 memset((char *)p + oldsize, 0, newsize - oldsize);
1061 free(*p_ptr);
1062 *p_ptr = (SEGMENT *)p;
1063 }
1064 return (p);
1065}
1066
1067extern uint32
1068dbm_call_hash(HTAB *hashp, char *k, size_t len)
1069{
1070 uint32 n, bucket;
1071
1072 n = hashp->hash(k, len);
1073 bucket = n & hashp->HIGH_MASKhdr.high_mask;
1074 if (bucket > (uint32)hashp->MAX_BUCKEThdr.max_bucket)
1075 bucket = bucket & hashp->LOW_MASKhdr.low_mask;
1076 return (bucket);
1077}
1078
1079/*
1080 * Allocate segment table. On error, set errno.
1081 *
1082 * Returns 0 on success
1083 */
1084static int
1085alloc_segs(
1086 HTAB *hashp,
1087 int nsegs)
1088{
1089 register int i;
1090 register SEGMENT store;
1091
1092 if ((hashp->dir =
25
Assuming the condition is false
26
Taking false branch
1093 (SEGMENT *)calloc((size_t)hashp->DSIZEhdr.dsize, sizeof(SEGMENT))) == NULL((void*)0)) {
1094 errno(*__errno_location ()) = ENOMEM12;
1095 return (-1);
1096 }
1097 /* Allocate segments */
1098 if ((store =
29
Assuming the condition is false
30
Taking false branch
1099 (SEGMENT)calloc((size_t)nsegs << hashp->SSHIFThdr.sshift, sizeof(BUFHEAD *))) == NULL((void*)0)) {
27
Assuming right operand of bit shift is non-negative but less than 64
28
Memory is allocated
1100 errno(*__errno_location ()) = ENOMEM12;
1101 return (-1);
1102 }
1103 for (i = 0; i < nsegs; i++, hashp->nsegs++)
31
Assuming 'i' is >= 'nsegs'
32
Loop condition is false. Execution continues on line 1105
1104 hashp->dir[i] = &store[i << hashp->SSHIFThdr.sshift];
1105 return (0);
33
Potential leak of memory pointed to by 'store'
1106}
1107
1108#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
1109/*
1110 * Hashp->hdr needs to be byteswapped.
1111 */
1112static void
1113swap_header_copy(
1114 HASHHDR *srcp, HASHHDR *destp)
1115{
1116 int i;
1117
1118 P_32_COPY(srcp->magic, destp->magic){ ((char *)&(destp->magic))[0] = ((char *)&(srcp->
magic))[3]; ((char *)&(destp->magic))[1] = ((char *)&
(srcp->magic))[2]; ((char *)&(destp->magic))[2] = (
(char *)&(srcp->magic))[1]; ((char *)&(destp->magic
))[3] = ((char *)&(srcp->magic))[0]; }
;
1119 P_32_COPY(srcp->version, destp->version){ ((char *)&(destp->version))[0] = ((char *)&(srcp
->version))[3]; ((char *)&(destp->version))[1] = ((
char *)&(srcp->version))[2]; ((char *)&(destp->
version))[2] = ((char *)&(srcp->version))[1]; ((char *
)&(destp->version))[3] = ((char *)&(srcp->version
))[0]; }
;
1120 P_32_COPY(srcp->lorder, destp->lorder){ ((char *)&(destp->lorder))[0] = ((char *)&(srcp->
lorder))[3]; ((char *)&(destp->lorder))[1] = ((char *)
&(srcp->lorder))[2]; ((char *)&(destp->lorder))
[2] = ((char *)&(srcp->lorder))[1]; ((char *)&(destp
->lorder))[3] = ((char *)&(srcp->lorder))[0]; }
;
1121 P_32_COPY(srcp->bsize, destp->bsize){ ((char *)&(destp->bsize))[0] = ((char *)&(srcp->
bsize))[3]; ((char *)&(destp->bsize))[1] = ((char *)&
(srcp->bsize))[2]; ((char *)&(destp->bsize))[2] = (
(char *)&(srcp->bsize))[1]; ((char *)&(destp->bsize
))[3] = ((char *)&(srcp->bsize))[0]; }
;
1122 P_32_COPY(srcp->bshift, destp->bshift){ ((char *)&(destp->bshift))[0] = ((char *)&(srcp->
bshift))[3]; ((char *)&(destp->bshift))[1] = ((char *)
&(srcp->bshift))[2]; ((char *)&(destp->bshift))
[2] = ((char *)&(srcp->bshift))[1]; ((char *)&(destp
->bshift))[3] = ((char *)&(srcp->bshift))[0]; }
;
1123 P_32_COPY(srcp->dsize, destp->dsize){ ((char *)&(destp->dsize))[0] = ((char *)&(srcp->
dsize))[3]; ((char *)&(destp->dsize))[1] = ((char *)&
(srcp->dsize))[2]; ((char *)&(destp->dsize))[2] = (
(char *)&(srcp->dsize))[1]; ((char *)&(destp->dsize
))[3] = ((char *)&(srcp->dsize))[0]; }
;
1124 P_32_COPY(srcp->ssize, destp->ssize){ ((char *)&(destp->ssize))[0] = ((char *)&(srcp->
ssize))[3]; ((char *)&(destp->ssize))[1] = ((char *)&
(srcp->ssize))[2]; ((char *)&(destp->ssize))[2] = (
(char *)&(srcp->ssize))[1]; ((char *)&(destp->ssize
))[3] = ((char *)&(srcp->ssize))[0]; }
;
1125 P_32_COPY(srcp->sshift, destp->sshift){ ((char *)&(destp->sshift))[0] = ((char *)&(srcp->
sshift))[3]; ((char *)&(destp->sshift))[1] = ((char *)
&(srcp->sshift))[2]; ((char *)&(destp->sshift))
[2] = ((char *)&(srcp->sshift))[1]; ((char *)&(destp
->sshift))[3] = ((char *)&(srcp->sshift))[0]; }
;
1126 P_32_COPY(srcp->ovfl_point, destp->ovfl_point){ ((char *)&(destp->ovfl_point))[0] = ((char *)&(srcp
->ovfl_point))[3]; ((char *)&(destp->ovfl_point))[1
] = ((char *)&(srcp->ovfl_point))[2]; ((char *)&(destp
->ovfl_point))[2] = ((char *)&(srcp->ovfl_point))[1
]; ((char *)&(destp->ovfl_point))[3] = ((char *)&(
srcp->ovfl_point))[0]; }
;
1127 P_32_COPY(srcp->last_freed, destp->last_freed){ ((char *)&(destp->last_freed))[0] = ((char *)&(srcp
->last_freed))[3]; ((char *)&(destp->last_freed))[1
] = ((char *)&(srcp->last_freed))[2]; ((char *)&(destp
->last_freed))[2] = ((char *)&(srcp->last_freed))[1
]; ((char *)&(destp->last_freed))[3] = ((char *)&(
srcp->last_freed))[0]; }
;
1128 P_32_COPY(srcp->max_bucket, destp->max_bucket){ ((char *)&(destp->max_bucket))[0] = ((char *)&(srcp
->max_bucket))[3]; ((char *)&(destp->max_bucket))[1
] = ((char *)&(srcp->max_bucket))[2]; ((char *)&(destp
->max_bucket))[2] = ((char *)&(srcp->max_bucket))[1
]; ((char *)&(destp->max_bucket))[3] = ((char *)&(
srcp->max_bucket))[0]; }
;
1129 P_32_COPY(srcp->high_mask, destp->high_mask){ ((char *)&(destp->high_mask))[0] = ((char *)&(srcp
->high_mask))[3]; ((char *)&(destp->high_mask))[1] =
((char *)&(srcp->high_mask))[2]; ((char *)&(destp
->high_mask))[2] = ((char *)&(srcp->high_mask))[1];
((char *)&(destp->high_mask))[3] = ((char *)&(srcp
->high_mask))[0]; }
;
1130 P_32_COPY(srcp->low_mask, destp->low_mask){ ((char *)&(destp->low_mask))[0] = ((char *)&(srcp
->low_mask))[3]; ((char *)&(destp->low_mask))[1] = (
(char *)&(srcp->low_mask))[2]; ((char *)&(destp->
low_mask))[2] = ((char *)&(srcp->low_mask))[1]; ((char
*)&(destp->low_mask))[3] = ((char *)&(srcp->low_mask
))[0]; }
;
1131 P_32_COPY(srcp->ffactor, destp->ffactor){ ((char *)&(destp->ffactor))[0] = ((char *)&(srcp
->ffactor))[3]; ((char *)&(destp->ffactor))[1] = ((
char *)&(srcp->ffactor))[2]; ((char *)&(destp->
ffactor))[2] = ((char *)&(srcp->ffactor))[1]; ((char *
)&(destp->ffactor))[3] = ((char *)&(srcp->ffactor
))[0]; }
;
1132 P_32_COPY(srcp->nkeys, destp->nkeys){ ((char *)&(destp->nkeys))[0] = ((char *)&(srcp->
nkeys))[3]; ((char *)&(destp->nkeys))[1] = ((char *)&
(srcp->nkeys))[2]; ((char *)&(destp->nkeys))[2] = (
(char *)&(srcp->nkeys))[1]; ((char *)&(destp->nkeys
))[3] = ((char *)&(srcp->nkeys))[0]; }
;
1133 P_32_COPY(srcp->hdrpages, destp->hdrpages){ ((char *)&(destp->hdrpages))[0] = ((char *)&(srcp
->hdrpages))[3]; ((char *)&(destp->hdrpages))[1] = (
(char *)&(srcp->hdrpages))[2]; ((char *)&(destp->
hdrpages))[2] = ((char *)&(srcp->hdrpages))[1]; ((char
*)&(destp->hdrpages))[3] = ((char *)&(srcp->hdrpages
))[0]; }
;
1134 P_32_COPY(srcp->h_charkey, destp->h_charkey){ ((char *)&(destp->h_charkey))[0] = ((char *)&(srcp
->h_charkey))[3]; ((char *)&(destp->h_charkey))[1] =
((char *)&(srcp->h_charkey))[2]; ((char *)&(destp
->h_charkey))[2] = ((char *)&(srcp->h_charkey))[1];
((char *)&(destp->h_charkey))[3] = ((char *)&(srcp
->h_charkey))[0]; }
;
1135 for (i = 0; i < NCACHED32; i++) {
1136 P_32_COPY(srcp->spares[i], destp->spares[i]){ ((char *)&(destp->spares[i]))[0] = ((char *)&(srcp
->spares[i]))[3]; ((char *)&(destp->spares[i]))[1] =
((char *)&(srcp->spares[i]))[2]; ((char *)&(destp
->spares[i]))[2] = ((char *)&(srcp->spares[i]))[1];
((char *)&(destp->spares[i]))[3] = ((char *)&(srcp
->spares[i]))[0]; }
;
1137 P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]){ ((char *)&(destp->bitmaps[i]))[0] = ((char *)&(srcp
->bitmaps[i]))[1]; ((char *)&(destp->bitmaps[i]))[1
] = ((char *)&(srcp->bitmaps[i]))[0]; }
;
1138 }
1139}
1140
1141static void
1142swap_header(HTAB *hashp)
1143{
1144 HASHHDR *hdrp;
1145 int i;
1146
1147 hdrp = &hashp->hdr;
1148
1149 M_32_SWAP(hdrp->magic){ uint32 _tmp = hdrp->magic; ((char *)&hdrp->magic)
[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->magic)[1
] = ((char *)&_tmp)[2]; ((char *)&hdrp->magic)[2] =
((char *)&_tmp)[1]; ((char *)&hdrp->magic)[3] = (
(char *)&_tmp)[0]; }
;
1150 M_32_SWAP(hdrp->version){ uint32 _tmp = hdrp->version; ((char *)&hdrp->version
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->version
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->version
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->version
)[3] = ((char *)&_tmp)[0]; }
;
1151 M_32_SWAP(hdrp->lorder){ uint32 _tmp = hdrp->lorder; ((char *)&hdrp->lorder
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->lorder)
[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->lorder)[
2] = ((char *)&_tmp)[1]; ((char *)&hdrp->lorder)[3
] = ((char *)&_tmp)[0]; }
;
1152 M_32_SWAP(hdrp->bsize){ uint32 _tmp = hdrp->bsize; ((char *)&hdrp->bsize)
[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->bsize)[1
] = ((char *)&_tmp)[2]; ((char *)&hdrp->bsize)[2] =
((char *)&_tmp)[1]; ((char *)&hdrp->bsize)[3] = (
(char *)&_tmp)[0]; }
;
1153 M_32_SWAP(hdrp->bshift){ uint32 _tmp = hdrp->bshift; ((char *)&hdrp->bshift
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->bshift)
[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->bshift)[
2] = ((char *)&_tmp)[1]; ((char *)&hdrp->bshift)[3
] = ((char *)&_tmp)[0]; }
;
1154 M_32_SWAP(hdrp->dsize){ uint32 _tmp = hdrp->dsize; ((char *)&hdrp->dsize)
[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->dsize)[1
] = ((char *)&_tmp)[2]; ((char *)&hdrp->dsize)[2] =
((char *)&_tmp)[1]; ((char *)&hdrp->dsize)[3] = (
(char *)&_tmp)[0]; }
;
1155 M_32_SWAP(hdrp->ssize){ uint32 _tmp = hdrp->ssize; ((char *)&hdrp->ssize)
[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->ssize)[1
] = ((char *)&_tmp)[2]; ((char *)&hdrp->ssize)[2] =
((char *)&_tmp)[1]; ((char *)&hdrp->ssize)[3] = (
(char *)&_tmp)[0]; }
;
1156 M_32_SWAP(hdrp->sshift){ uint32 _tmp = hdrp->sshift; ((char *)&hdrp->sshift
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->sshift)
[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->sshift)[
2] = ((char *)&_tmp)[1]; ((char *)&hdrp->sshift)[3
] = ((char *)&_tmp)[0]; }
;
1157 M_32_SWAP(hdrp->ovfl_point){ uint32 _tmp = hdrp->ovfl_point; ((char *)&hdrp->ovfl_point
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->ovfl_point
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->ovfl_point
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->ovfl_point
)[3] = ((char *)&_tmp)[0]; }
;
1158 M_32_SWAP(hdrp->last_freed){ uint32 _tmp = hdrp->last_freed; ((char *)&hdrp->last_freed
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->last_freed
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->last_freed
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->last_freed
)[3] = ((char *)&_tmp)[0]; }
;
1159 M_32_SWAP(hdrp->max_bucket){ uint32 _tmp = hdrp->max_bucket; ((char *)&hdrp->max_bucket
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->max_bucket
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->max_bucket
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->max_bucket
)[3] = ((char *)&_tmp)[0]; }
;
1160 M_32_SWAP(hdrp->high_mask){ uint32 _tmp = hdrp->high_mask; ((char *)&hdrp->high_mask
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->high_mask
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->high_mask
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->high_mask
)[3] = ((char *)&_tmp)[0]; }
;
1161 M_32_SWAP(hdrp->low_mask){ uint32 _tmp = hdrp->low_mask; ((char *)&hdrp->low_mask
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->low_mask
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->low_mask
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->low_mask
)[3] = ((char *)&_tmp)[0]; }
;
1162 M_32_SWAP(hdrp->ffactor){ uint32 _tmp = hdrp->ffactor; ((char *)&hdrp->ffactor
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->ffactor
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->ffactor
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->ffactor
)[3] = ((char *)&_tmp)[0]; }
;
1163 M_32_SWAP(hdrp->nkeys){ uint32 _tmp = hdrp->nkeys; ((char *)&hdrp->nkeys)
[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->nkeys)[1
] = ((char *)&_tmp)[2]; ((char *)&hdrp->nkeys)[2] =
((char *)&_tmp)[1]; ((char *)&hdrp->nkeys)[3] = (
(char *)&_tmp)[0]; }
;
1164 M_32_SWAP(hdrp->hdrpages){ uint32 _tmp = hdrp->hdrpages; ((char *)&hdrp->hdrpages
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->hdrpages
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->hdrpages
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->hdrpages
)[3] = ((char *)&_tmp)[0]; }
;
1165 M_32_SWAP(hdrp->h_charkey){ uint32 _tmp = hdrp->h_charkey; ((char *)&hdrp->h_charkey
)[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->h_charkey
)[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->h_charkey
)[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->h_charkey
)[3] = ((char *)&_tmp)[0]; }
;
1166 for (i = 0; i < NCACHED32; i++) {
1167 M_32_SWAP(hdrp->spares[i]){ uint32 _tmp = hdrp->spares[i]; ((char *)&hdrp->spares
[i])[0] = ((char *)&_tmp)[3]; ((char *)&hdrp->spares
[i])[1] = ((char *)&_tmp)[2]; ((char *)&hdrp->spares
[i])[2] = ((char *)&_tmp)[1]; ((char *)&hdrp->spares
[i])[3] = ((char *)&_tmp)[0]; }
;
1168 M_16_SWAP(hdrp->bitmaps[i]){ uint16 _tmp = hdrp->bitmaps[i]; ((char *)&hdrp->bitmaps
[i])[0] = ((char *)&_tmp)[1]; ((char *)&hdrp->bitmaps
[i])[1] = ((char *)&_tmp)[0]; }
;
1169 }
1170}
1171#endif