Print this page
10078 smatch fixes for UCB
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/ucblib/libdbm/dbm.c
+++ new/usr/src/ucblib/libdbm/dbm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 29 /*
30 30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 31 * under license from the Regents of the University of California.
32 32 */
33 33
34 +/*
35 + * Copyright (c) 2018, Joyent, Inc.
36 + */
37 +
34 38 /*LINTLIBRARY*/
35 39
36 40 #include <sys/types.h>
37 41 #include <stdio.h>
38 42 #include <unistd.h>
39 43 #include <stdlib.h>
40 44 #include <strings.h>
41 45 #include <malloc.h>
42 46 #include <sys/stat.h>
43 47 #include <sys/fcntl.h>
44 48 #include <dbm.h>
45 49 #include <errno.h>
46 50
47 51 /* forward declarations */
48 52 /* could be all static if not were for older *.a releases */
49 53 void chkblk(char buf[PBLKSIZ]);
50 54 void delitem(char buf[PBLKSIZ], int n);
51 55 void dbm_access(long hash);
52 56 int getbit(void);
53 57 int setbit(void);
54 58 int additem(char buf[PBLKSIZ], datum item);
55 59 int cmpdatum(datum d1, datum d2);
56 60
57 61 int
58 62 dbminit(char *file)
59 63 {
60 64 struct stat64 statb;
61 65
62 66 dbrdonly = 0;
63 67 if (strlcpy(pagbuf, file, sizeof (pagbuf)) >= sizeof (pagbuf) ||
64 68 strlcat(pagbuf, ".pag", sizeof (pagbuf)) >= sizeof (pagbuf)) {
65 69 /*
66 70 * file.pag does not fit into pagbuf.
67 71 * fails with ENAMETOOLONG.
68 72 */
69 73 errno = ENAMETOOLONG;
70 74 return (-1);
71 75 }
72 76 pagf = open(pagbuf, 2);
73 77 if (pagf < 0) {
74 78 pagf = open(pagbuf, 0);
75 79 dbrdonly = 1;
76 80 }
77 81
78 82 /*
79 83 * We know this won't overflow so it is safe to ignore the
80 84 * return value; we use strl* to prevent false hits in
81 85 * code sweeps.
82 86 */
83 87 (void) strlcpy(pagbuf, file, sizeof (pagbuf));
84 88 (void) strlcat(pagbuf, ".dir", sizeof (pagbuf));
85 89 dirf = open(pagbuf, 2);
86 90 if (dirf < 0) {
87 91 dirf = open(pagbuf, 0);
88 92 dbrdonly = 1;
89 93 }
90 94 if (pagf < 0 || dirf < 0) {
91 95 (void) printf("cannot open database %s\n", file);
92 96 return (-1);
93 97 }
94 98 /* Guards against large inodes */
95 99 (void) fstat64(dirf, &statb);
96 100 maxbno = (off_t)statb.st_size * BYTESIZ - 1;
97 101 return (0);
98 102 }
99 103
100 104 static long oldb1 = -1L;
101 105 static long oldb2 = -1L;
102 106
103 107 /* Avoid using cached data for subsequent accesses. */
104 108 int
105 109 dbmflush(void)
106 110 {
107 111 oldb1 = -1L;
108 112 oldb2 = -1L;
109 113 return (0);
110 114 }
111 115
112 116 /* Clean up after ourself. */
113 117 int
114 118 dbmclose(void)
115 119 {
116 120 (void) close(pagf);
117 121 (void) close(dirf);
118 122 bitno = 0;
119 123 maxbno = 0;
120 124 blkno = 0;
121 125 hmask = 0;
122 126 oldb1 = -1L;
123 127 oldb2 = -1L;
124 128 return (0);
125 129 }
126 130
127 131 long
128 132 forder(datum key)
129 133 {
130 134 long hash;
131 135
132 136 hash = calchash(key);
133 137 for (hmask = 0; ; hmask = (hmask<<1)+1) {
134 138 blkno = hash & hmask;
135 139 bitno = blkno + hmask;
136 140 if (getbit() == 0)
137 141 break;
138 142 }
139 143 return (blkno);
140 144 }
141 145
142 146 datum
143 147 fetch(datum key)
144 148 {
145 149 int i;
146 150 datum item;
147 151
148 152 dbm_access(calchash(key));
149 153 for (i = 0; ; i += 2) {
150 154 item = makdatum(pagbuf, i);
151 155 if (item.dptr == NULL)
152 156 return (item);
153 157 if (cmpdatum(key, item) == 0) {
154 158 item = makdatum(pagbuf, i+1);
155 159 if (item.dptr == NULL)
156 160 (void) printf("items not in pairs\n");
157 161 return (item);
158 162 }
159 163 }
160 164 }
161 165
162 166 int
163 167 delete(datum key)
164 168 {
165 169 int i;
166 170 datum item;
167 171
168 172 if (dbrdonly)
169 173 return (-1);
170 174 dbm_access(calchash(key));
171 175 for (i = 0; ; i += 2) {
172 176 item = makdatum(pagbuf, i);
173 177 if (item.dptr == NULL)
174 178 return (-1);
175 179 if (cmpdatum(key, item) == 0) {
176 180 delitem(pagbuf, i);
177 181 delitem(pagbuf, i);
178 182 break;
179 183 }
180 184 }
181 185 (void) lseek(pagf, blkno*PBLKSIZ, 0);
182 186 (void) write(pagf, pagbuf, PBLKSIZ);
183 187 return (0);
184 188 }
185 189
186 190 int
187 191 store(datum key, datum dat)
188 192 {
189 193 int i;
190 194 datum item;
191 195 char ovfbuf[PBLKSIZ];
192 196 datum Sentry;
193 197 int Oneflag;
194 198
195 199 Sentry.dsize = 0;
196 200 Sentry.dptr = NULL;
197 201
198 202 if (dbrdonly)
199 203 return (-1);
200 204 loop:
201 205 dbm_access(calchash(key));
202 206 for (i = 0; ; i += 2) {
203 207 item = makdatum(pagbuf, i);
204 208 if (item.dptr == NULL)
205 209 break;
206 210 if (cmpdatum(key, item) == 0) {
207 211 delitem(pagbuf, i);
208 212 delitem(pagbuf, i);
209 213 break;
210 214 }
211 215 }
212 216 i = additem(pagbuf, key);
213 217 if (i < 0)
214 218 goto split;
215 219 if (additem(pagbuf, dat) < 0) {
216 220 delitem(pagbuf, i);
217 221 goto split;
218 222 }
219 223 (void) lseek(pagf, blkno*PBLKSIZ, 0);
220 224 (void) write(pagf, pagbuf, PBLKSIZ);
221 225 return (0);
222 226 split:
223 227 if (key.dsize+dat.dsize+3*sizeof (short) >= PBLKSIZ) {
224 228 (void) printf("entry too big\n");
225 229 return (-1);
226 230 }
227 231 bzero(ovfbuf, PBLKSIZ);
228 232 Oneflag = 0;
229 233 for (i = 0; ; ) {
230 234 item = makdatum(pagbuf, i);
231 235 Oneflag++;
232 236 if (item.dptr == NULL) {
233 237 if ((Sentry.dsize == key.dsize) &&
234 238 (strncmp(Sentry.dptr, key.dptr, key.dsize) == 0))
235 239 return (-1);
236 240 if (Oneflag == 2) {
237 241 Sentry.dsize = key.dsize;
238 242 Sentry.dptr = malloc(strlen(key.dptr)+1);
239 243 (void) strncpy(Sentry.dptr, key.dptr,
240 244 key.dsize);
241 245 }
242 246 break;
243 247 }
244 248 if (calchash(item) & (hmask+1)) {
245 249 (void) additem(ovfbuf, item);
246 250 delitem(pagbuf, i);
247 251 item = makdatum(pagbuf, i);
248 252 if (item.dptr == NULL) {
249 253 (void) printf("split not paired\n");
250 254 break;
251 255 }
252 256 (void) additem(ovfbuf, item);
253 257 delitem(pagbuf, i);
254 258 continue;
255 259 }
256 260 i += 2;
257 261 }
258 262 (void) lseek(pagf, blkno*PBLKSIZ, 0);
259 263 if (write(pagf, pagbuf, PBLKSIZ) < 0)
260 264 return (-1);
261 265 (void) lseek(pagf, (blkno+hmask+1)*PBLKSIZ, 0);
262 266 if (write(pagf, ovfbuf, PBLKSIZ) < 0)
263 267 return (-1);
264 268 if (setbit() < 0)
265 269 return (-1);
266 270 goto loop;
267 271 }
268 272
269 273 datum
270 274 firstkey(void)
271 275 {
272 276 return (firsthash(0L));
273 277 }
274 278
275 279 datum
276 280 nextkey(datum key)
277 281 {
278 282 int i;
279 283 datum item, bitem;
280 284 long hash;
281 285 int f;
282 286
283 287 hash = calchash(key);
284 288 dbm_access(hash);
285 289 f = 1;
286 290 for (i = 0; ; i += 2) {
287 291 item = makdatum(pagbuf, i);
288 292 if (item.dptr == NULL)
289 293 break;
290 294 if (cmpdatum(key, item) <= 0)
291 295 continue;
292 296 if (f || cmpdatum(bitem, item) < 0) {
293 297 bitem = item;
294 298 f = 0;
295 299 }
296 300 }
297 301 if (f == 0)
298 302 return (bitem);
299 303 hash = hashinc(hash);
300 304 if (hash == 0)
301 305 return (item);
302 306 return (firsthash(hash));
303 307 }
304 308
305 309 datum
306 310 firsthash(long hash)
307 311 {
308 312 int i;
309 313 datum item, bitem;
310 314
311 315 loop:
312 316 dbm_access(hash);
313 317 bitem = makdatum(pagbuf, 0);
314 318 for (i = 2; ; i += 2) {
315 319 item = makdatum(pagbuf, i);
316 320 if (item.dptr == NULL)
317 321 break;
318 322 if (cmpdatum(bitem, item) < 0)
319 323 bitem = item;
320 324 }
321 325 if (bitem.dptr != NULL)
322 326 return (bitem);
323 327 hash = hashinc(hash);
324 328 if (hash == 0)
325 329 return (item);
326 330 goto loop;
327 331 }
328 332
329 333 void
330 334 dbm_access(long hash)
331 335 {
332 336 ssize_t readsize;
333 337
334 338 for (hmask = 0; ; hmask = (hmask<<1)+1) {
335 339 blkno = hash & hmask;
336 340 bitno = blkno + hmask;
337 341 if (getbit() == 0)
338 342 break;
339 343 }
340 344 if (blkno != oldb1) {
341 345 (void) lseek(pagf, blkno*PBLKSIZ, 0);
342 346 readsize = read(pagf, pagbuf, PBLKSIZ);
343 347 if (readsize != PBLKSIZ) {
344 348 if (readsize < 0) readsize = 0;
345 349 bzero(pagbuf+readsize, PBLKSIZ-readsize);
346 350 }
347 351 chkblk(pagbuf);
348 352 oldb1 = blkno;
349 353 }
350 354 }
351 355
352 356 int
353 357 getbit(void)
354 358 {
355 359 long bn;
356 360 ssize_t readsize;
357 361 long b, i, n;
358 362
359 363 if (bitno > maxbno)
360 364 return (0);
361 365 n = bitno % BYTESIZ;
362 366 bn = bitno / BYTESIZ;
363 367 i = bn % DBLKSIZ;
364 368 b = bn / DBLKSIZ;
365 369 if (b != oldb2) {
366 370 (void) lseek(dirf, (long)b*DBLKSIZ, 0);
367 371 readsize = read(dirf, dirbuf, DBLKSIZ);
368 372 if (readsize != DBLKSIZ) {
369 373 if (readsize < 0) readsize = 0;
370 374 bzero(dirbuf+readsize, DBLKSIZ-readsize);
371 375 }
372 376 oldb2 = b;
373 377 }
374 378 if (dirbuf[i] & (1<<n))
375 379 return (1);
376 380 return (0);
377 381 }
378 382
379 383 int
380 384 setbit(void)
381 385 {
382 386 long bn;
383 387 long i, n, b;
384 388
385 389 if (dbrdonly)
386 390 return (-1);
387 391 if (bitno > maxbno) {
388 392 maxbno = bitno;
389 393 (void) getbit();
390 394 }
391 395 n = bitno % BYTESIZ;
392 396 bn = bitno / BYTESIZ;
393 397 i = bn % DBLKSIZ;
394 398 b = bn / DBLKSIZ;
395 399 dirbuf[i] |= 1<<n;
396 400 (void) lseek(dirf, (long)b*DBLKSIZ, 0);
397 401 if (write(dirf, dirbuf, DBLKSIZ) < 0)
398 402 return (-1);
399 403 return (0);
400 404 }
401 405
402 406 datum
403 407 makdatum(char buf[PBLKSIZ], int n)
404 408 {
405 409 short *sp;
406 410 int t;
407 411 datum item;
408 412
409 413 sp = (short *)buf;
410 414 if (n < 0 || n >= sp[0])
411 415 goto null;
412 416 t = PBLKSIZ;
413 417 if (n > 0)
414 418 t = sp[n+1-1];
415 419 item.dptr = buf+sp[n+1];
416 420 item.dsize = t - sp[n+1];
417 421 return (item);
418 422
419 423 null:
420 424 item.dptr = NULL;
421 425 item.dsize = 0;
422 426 return (item);
423 427 }
424 428
425 429 int
426 430 cmpdatum(datum d1, datum d2)
427 431 {
428 432 int n;
429 433 char *p1, *p2;
430 434
431 435 n = d1.dsize;
432 436 if (n != d2.dsize)
433 437 return (n - d2.dsize);
434 438 if (n == 0)
435 439 return (0);
436 440 p1 = d1.dptr;
437 441 p2 = d2.dptr;
438 442 do
439 443 if (*p1++ != *p2++)
440 444 return (*--p1 - *--p2);
441 445 while (--n);
442 446 return (0);
443 447 }
444 448
445 449 int hitab[16]
446 450 /*
447 451 * ken's
448 452 * {
449 453 * 055,043,036,054,063,014,004,005,
450 454 * 010,064,077,000,035,027,025,071,
451 455 * };
452 456 */
453 457 = { 61, 57, 53, 49, 45, 41, 37, 33,
454 458 29, 25, 21, 17, 13, 9, 5, 1,
455 459 };
456 460 long hltab[64] = {
457 461 06100151277L, 06106161736L, 06452611562L, 05001724107L,
458 462 02614772546L, 04120731531L, 04665262210L, 07347467531L,
459 463 06735253126L, 06042345173L, 03072226605L, 01464164730L,
460 464 03247435524L, 07652510057L, 01546775256L, 05714532133L,
461 465 06173260402L, 07517101630L, 02431460343L, 01743245566L,
462 466 00261675137L, 02433103631L, 03421772437L, 04447707466L,
463 467 04435620103L, 03757017115L, 03641531772L, 06767633246L,
464 468 02673230344L, 00260612216L, 04133454451L, 00615531516L,
465 469 06137717526L, 02574116560L, 02304023373L, 07061702261L,
466 470 05153031405L, 05322056705L, 07401116734L, 06552375715L,
467 471 06165233473L, 05311063631L, 01212221723L, 01052267235L,
468 472 06000615237L, 01075222665L, 06330216006L, 04402355630L,
469 473 01451177262L, 02000133436L, 06025467062L, 07121076461L,
470 474 03123433522L, 01010635225L, 01716177066L, 05161746527L,
471 475 01736635071L, 06243505026L, 03637211610L, 01756474365L,
472 476 04723077174L, 03642763134L, 05750130273L, 03655541561L,
473 477 };
474 478
475 479 long
476 480 hashinc(long hash)
477 481 {
478 482 long bit;
479 483
480 484 hash &= hmask;
481 485 bit = hmask+1;
482 486 for (;;) {
483 487 bit >>= 1;
484 488 if (bit == 0)
485 489 return (0L);
486 490 if ((hash&bit) == 0)
487 491 return (hash|bit);
488 492 hash &= ~bit;
489 493 }
490 494 }
491 495
492 496 long
493 497 calchash(datum item)
494 498 {
495 499 int i, j, f;
496 500 long hashl;
497 501 int hashi;
498 502
499 503 hashl = 0;
500 504 hashi = 0;
501 505 for (i = 0; i < item.dsize; i++) {
502 506 f = item.dptr[i];
503 507 for (j = 0; j < BYTESIZ; j += 4) {
504 508 hashi += hitab[f&017];
505 509 hashl += hltab[hashi&63];
506 510 f >>= 4;
507 511 }
508 512 }
509 513 return (hashl);
510 514 }
511 515
512 516 void
513 517 delitem(char buf[PBLKSIZ], int n)
514 518 {
515 519 short *sp;
516 520 int i1, i2, i3;
↓ open down ↓ |
473 lines elided |
↑ open up ↑ |
517 521
518 522 sp = (short *)buf;
519 523 if (n < 0 || n >= sp[0])
520 524 goto bad;
521 525 i1 = sp[n+1];
522 526 i2 = PBLKSIZ;
523 527 if (n > 0)
524 528 i2 = sp[n+1-1];
525 529 i3 = sp[sp[0]+1-1];
526 530 if (i2 > i1)
527 - while (i1 > i3) {
528 - i1--;
529 - i2--;
530 - buf[i2] = buf[i1];
531 - buf[i1] = 0;
532 - }
531 + while (i1 > i3) {
532 + i1--;
533 + i2--;
534 + buf[i2] = buf[i1];
535 + buf[i1] = 0;
536 + }
533 537 i2 -= i1;
534 538 for (i1 = n+1; i1 < sp[0]; i1++)
535 539 sp[i1+1-1] = sp[i1+1] + i2;
536 540 sp[0]--;
537 541 sp[sp[0]+1] = 0;
538 542 return;
539 543
540 544 bad:
541 545 (void) printf("bad delitem\n");
542 546 abort();
543 547 }
544 548
545 549 int
546 550 additem(char buf[PBLKSIZ], datum item)
547 551 {
548 552 short *sp;
549 553 int i1, i2;
550 554
551 555 sp = (short *)buf;
552 556 i1 = PBLKSIZ;
553 557 if (sp[0] > 0)
554 558 i1 = sp[sp[0]+1-1];
555 559 i1 -= item.dsize;
556 560 i2 = (int)((sp[0]+2) * sizeof (short));
557 561 if (i1 <= i2)
558 562 return (-1);
559 563 sp[sp[0]+1] = (short)i1;
560 564 for (i2 = 0; i2 < item.dsize; i2++) {
561 565 buf[i1] = item.dptr[i2];
562 566 i1++;
563 567 }
564 568 sp[0]++;
565 569 return (sp[0]-1);
566 570 }
567 571
568 572 void
569 573 chkblk(char buf[PBLKSIZ])
570 574 {
571 575 short *sp;
572 576 int t, i;
573 577
574 578 sp = (short *)buf;
575 579 t = PBLKSIZ;
576 580 for (i = 0; i < sp[0]; i++) {
577 581 if (sp[i+1] > t)
578 582 goto bad;
579 583 t = sp[i+1];
580 584 }
581 585 if (t < (sp[0]+1)*sizeof (short))
582 586 goto bad;
583 587 return;
584 588
585 589 bad:
586 590 (void) printf("bad block\n");
587 591 abort();
588 592 bzero(buf, PBLKSIZ);
589 593 }
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX