Tue Apr 23 22:18:56 2024 UTC (16d)
pass lint, simplify


(christos)
diff -r1.35 -r1.36 src/usr.sbin/makefs/walk.c

cvs diff -r1.35 -r1.36 src/usr.sbin/makefs/walk.c (expand / switch to unified diff)

--- src/usr.sbin/makefs/walk.c 2024/04/23 22:12:48 1.35
+++ src/usr.sbin/makefs/walk.c 2024/04/23 22:18:56 1.36
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: walk.c,v 1.35 2024/04/23 22:12:48 christos Exp $ */ 1/* $NetBSD: walk.c,v 1.36 2024/04/23 22:18:56 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Wasabi Systems, Inc. 4 * Copyright (c) 2001 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Luke Mewburn for Wasabi Systems, Inc. 7 * Written by Luke Mewburn for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38#if HAVE_NBTOOL_CONFIG_H 38#if HAVE_NBTOOL_CONFIG_H
39#include "nbtool_config.h" 39#include "nbtool_config.h"
40#endif 40#endif
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43#if defined(__RCSID) && !defined(__lint) 43#if defined(__RCSID) && !defined(__lint)
44__RCSID("$NetBSD: walk.c,v 1.35 2024/04/23 22:12:48 christos Exp $"); 44__RCSID("$NetBSD: walk.c,v 1.36 2024/04/23 22:18:56 christos Exp $");
45#endif /* !__lint */ 45#endif /* !__lint */
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/stat.h> 48#include <sys/stat.h>
49 49
50#include <assert.h> 50#include <assert.h>
51#include <errno.h> 51#include <errno.h>
52#include <fcntl.h> 52#include <fcntl.h>
53#include <stdio.h> 53#include <stdio.h>
54#include <dirent.h> 54#include <dirent.h>
55#include <stdlib.h> 55#include <stdlib.h>
56#include <string.h> 56#include <string.h>
57#include <unistd.h> 57#include <unistd.h>
@@ -63,36 +63,37 @@ __RCSID("$NetBSD: walk.c,v 1.35 2024/04/ @@ -63,36 +63,37 @@ __RCSID("$NetBSD: walk.c,v 1.35 2024/04/
63static void apply_specdir(const char *, NODE *, fsnode *, int); 63static void apply_specdir(const char *, NODE *, fsnode *, int);
64static void apply_specentry(const char *, NODE *, fsnode *); 64static void apply_specentry(const char *, NODE *, fsnode *);
65static fsnode *create_fsnode(const char *, const char *, const char *, 65static fsnode *create_fsnode(const char *, const char *, const char *,
66 struct stat *); 66 struct stat *);
67static fsinode *link_check(fsinode *); 67static fsinode *link_check(fsinode *);
68 68
69/* 69/*
70 * fsnode_cmp -- 70 * fsnode_cmp --
71 * This function is used by `qsort` so sort one directory's 71 * This function is used by `qsort` so sort one directory's
72 * entries. `.` is always first, sollowed by anything else 72 * entries. `.` is always first, sollowed by anything else
73 * as compared by `strcmp()`. 73 * as compared by `strcmp()`.
74 */ 74 */
75static int 75static int
76fsnode_cmp (const void *_left, const void *_right) 76fsnode_cmp(const void *vleft, const void *vright)
77{ 77{
78 const fsnode * const left = *(const fsnode * const *)_left; 78 const fsnode * const *left = vleft;
79 const fsnode * const right = *(const fsnode * const *)_right; 79 const fsnode * const *right = vright;
 80 const char *lname = (*left)->name, *rname = (*right)->name;
80 81
81 if (strcmp (left->name, ".") == 0) 82 if (strcmp(lname, ".") == 0)
82 return -1; 83 return -1;
83 if (strcmp (right->name, ".") == 0) 84 if (strcmp(rname, ".") == 0)
84 return 1; 85 return 1;
85 return strcmp (left->name, right->name); 86 return strcmp(lname, rname);
86} 87}
87 88
88/* 89/*
89 * walk_dir -- 90 * walk_dir --
90 * build a tree of fsnodes from `root' and `dir', with a parent 91 * build a tree of fsnodes from `root' and `dir', with a parent
91 * fsnode of `parent' (which may be NULL for the root of the tree). 92 * fsnode of `parent' (which may be NULL for the root of the tree).
92 * append the tree to a fsnode of `join' if it is not NULL. 93 * append the tree to a fsnode of `join' if it is not NULL.
93 * each "level" is a directory, with the "." entry guaranteed to be 94 * each "level" is a directory, with the "." entry guaranteed to be
94 * at the start of the list, and without ".." entries. 95 * at the start of the list, and without ".." entries.
95 */ 96 */
96fsnode * 97fsnode *
97walk_dir(const char *root, const char *dir, fsnode *parent, fsnode *join, 98walk_dir(const char *root, const char *dir, fsnode *parent, fsnode *join,
98 int replace, int follow) 99 int replace, int follow)
@@ -239,34 +240,34 @@ walk_dir(const char *root, const char *d @@ -239,34 +240,34 @@ walk_dir(const char *root, const char *d
239 replace, follow); 240 replace, follow);
240 continue; 241 continue;
241 } 242 }
242 } 243 }
243 if (stbuf.st_nlink > 1) { 244 if (stbuf.st_nlink > 1) {
244 fsinode *curino; 245 fsinode *curino;
245 246
246 curino = link_check(cur->inode); 247 curino = link_check(cur->inode);
247 if (curino != NULL) { 248 if (curino != NULL) {
248 free(cur->inode); 249 free(cur->inode);
249 cur->inode = curino; 250 cur->inode = curino;
250 cur->inode->nlink++; 251 cur->inode->nlink++;
251 if (debug & DEBUG_WALK_DIR_LINKCHECK) 252 if (debug & DEBUG_WALK_DIR_LINKCHECK)
252 printf("link_check: found [%llu, %llu]\n", 253 printf("link_check: found [%ju, %ju]\n",
253 (unsigned long long)curino->st.st_dev, 254 (uintmax_t)curino->st.st_dev,
254 (unsigned long long)curino->st.st_ino); 255 (uintmax_t)curino->st.st_ino);
255 } 256 }
256 } 257 }
257 if (S_ISLNK(cur->type)) { 258 if (S_ISLNK(cur->type)) {
258 char slink[PATH_MAX+1]; 259 char slink[PATH_MAX+1];
259 int llen; 260 ssize_t llen;
260 261
261 llen = readlink(path, slink, sizeof(slink) - 1); 262 llen = readlink(path, slink, sizeof(slink) - 1);
262 if (llen == -1) 263 if (llen == -1)
263 err(EXIT_FAILURE, "Readlink `%s'", path); 264 err(EXIT_FAILURE, "Readlink `%s'", path);
264 slink[llen] = '\0'; 265 slink[llen] = '\0';
265 cur->symlink = estrdup(slink); 266 cur->symlink = estrdup(slink);
266 } 267 }
267 } 268 }
268 assert(first != NULL); 269 assert(first != NULL);
269 if (join == NULL) 270 if (join == NULL)
270 for (cur = first->next; cur != NULL; cur = cur->next) 271 for (cur = first->next; cur != NULL; cur = cur->next)
271 cur->first = first; 272 cur->first = first;
272 if (closedir(dirp) == -1) 273 if (closedir(dirp) == -1)
@@ -584,29 +585,29 @@ apply_specentry(const char *dir, NODE *s @@ -584,29 +585,29 @@ apply_specentry(const char *dir, NODE *s
584 if (specnode->flags & (F_GID | F_GNAME)) { 585 if (specnode->flags & (F_GID | F_GNAME)) {
585 ASEPRINT("gid", "%d", 586 ASEPRINT("gid", "%d",
586 dirnode->inode->st.st_gid, specnode->st_gid); 587 dirnode->inode->st.st_gid, specnode->st_gid);
587 dirnode->inode->st.st_gid = specnode->st_gid; 588 dirnode->inode->st.st_gid = specnode->st_gid;
588 } 589 }
589 if (specnode->flags & F_MODE) { 590 if (specnode->flags & F_MODE) {
590 ASEPRINT("mode", "%#o", 591 ASEPRINT("mode", "%#o",
591 dirnode->inode->st.st_mode & ALLPERMS, specnode->st_mode); 592 dirnode->inode->st.st_mode & ALLPERMS, specnode->st_mode);
592 dirnode->inode->st.st_mode &= ~ALLPERMS; 593 dirnode->inode->st.st_mode &= ~ALLPERMS;
593 dirnode->inode->st.st_mode |= (specnode->st_mode & ALLPERMS); 594 dirnode->inode->st.st_mode |= (specnode->st_mode & ALLPERMS);
594 } 595 }
595 /* XXX: ignoring F_NLINK for now */ 596 /* XXX: ignoring F_NLINK for now */
596 if (specnode->flags & F_SIZE) { 597 if (specnode->flags & F_SIZE) {
597 ASEPRINT("size", "%lld", 598 ASEPRINT("size", "%jd",
598 (long long)dirnode->inode->st.st_size, 599 (intmax_t)dirnode->inode->st.st_size,
599 (long long)specnode->st_size); 600 (intmax_t)specnode->st_size);
600 dirnode->inode->st.st_size = specnode->st_size; 601 dirnode->inode->st.st_size = specnode->st_size;
601 } 602 }
602 if (specnode->flags & F_SLINK) { 603 if (specnode->flags & F_SLINK) {
603 assert(dirnode->symlink != NULL); 604 assert(dirnode->symlink != NULL);
604 assert(specnode->slink != NULL); 605 assert(specnode->slink != NULL);
605 ASEPRINT("symlink", "%s", dirnode->symlink, specnode->slink); 606 ASEPRINT("symlink", "%s", dirnode->symlink, specnode->slink);
606 free(dirnode->symlink); 607 free(dirnode->symlink);
607 dirnode->symlink = estrdup(specnode->slink); 608 dirnode->symlink = estrdup(specnode->slink);
608 } 609 }
609 if (specnode->flags & F_TIME) { 610 if (specnode->flags & F_TIME) {
610 ASEPRINT("time", "%ld", 611 ASEPRINT("time", "%ld",
611 (long)dirnode->inode->st.st_mtime, 612 (long)dirnode->inode->st.st_mtime,
612 (long)specnode->st_mtimespec.tv_sec); 613 (long)specnode->st_mtimespec.tv_sec);
@@ -619,33 +620,33 @@ apply_specentry(const char *dir, NODE *s @@ -619,33 +620,33 @@ apply_specentry(const char *dir, NODE *s
619 dirnode->inode->st.st_ctimensec = start_time.tv_nsec; 620 dirnode->inode->st.st_ctimensec = start_time.tv_nsec;
620#endif 621#endif
621 } 622 }
622 if (specnode->flags & (F_UID | F_UNAME)) { 623 if (specnode->flags & (F_UID | F_UNAME)) {
623 ASEPRINT("uid", "%d", 624 ASEPRINT("uid", "%d",
624 dirnode->inode->st.st_uid, specnode->st_uid); 625 dirnode->inode->st.st_uid, specnode->st_uid);
625 dirnode->inode->st.st_uid = specnode->st_uid; 626 dirnode->inode->st.st_uid = specnode->st_uid;
626 } 627 }
627#if HAVE_STRUCT_STAT_ST_FLAGS 628#if HAVE_STRUCT_STAT_ST_FLAGS
628 if (specnode->flags & F_FLAGS) { 629 if (specnode->flags & F_FLAGS) {
629 ASEPRINT("flags", "%#lX", 630 ASEPRINT("flags", "%#lX",
630 (unsigned long)dirnode->inode->st.st_flags, 631 (unsigned long)dirnode->inode->st.st_flags,
631 (unsigned long)specnode->st_flags); 632 (unsigned long)specnode->st_flags);
632 dirnode->inode->st.st_flags = specnode->st_flags; 633 dirnode->inode->st.st_flags = (unsigned int)specnode->st_flags;
633 } 634 }
634#endif 635#endif
635 if (specnode->flags & F_DEV) { 636 if (specnode->flags & F_DEV) {
636 ASEPRINT("rdev", "%#llx", 637 ASEPRINT("rdev", "%#jx",
637 (unsigned long long)dirnode->inode->st.st_rdev, 638 (uintmax_t)dirnode->inode->st.st_rdev,
638 (unsigned long long)specnode->st_rdev); 639 (uintmax_t)specnode->st_rdev);
639 dirnode->inode->st.st_rdev = specnode->st_rdev; 640 dirnode->inode->st.st_rdev = specnode->st_rdev;
640 } 641 }
641#undef ASEPRINT 642#undef ASEPRINT
642 643
643 dirnode->flags |= FSNODE_F_HASSPEC; 644 dirnode->flags |= FSNODE_F_HASSPEC;
644} 645}
645 646
646 647
647/* 648/*
648 * dump_fsnodes -- 649 * dump_fsnodes --
649 * dump the fsnodes from `cur' 650 * dump the fsnodes from `cur'
650 */ 651 */
651void 652void
@@ -702,58 +703,57 @@ inode_type(mode_t mode) @@ -702,58 +703,57 @@ inode_type(mode_t mode)
702 * link_check -- 703 * link_check --
703 * return pointer to fsinode matching `entry's st_ino & st_dev if it exists, 704 * return pointer to fsinode matching `entry's st_ino & st_dev if it exists,
704 * otherwise add `entry' to table and return NULL 705 * otherwise add `entry' to table and return NULL
705 */ 706 */
706/* This was borrowed from du.c and tweaked to keep an fsnode 707/* This was borrowed from du.c and tweaked to keep an fsnode
707 * pointer instead. -- dbj@netbsd.org 708 * pointer instead. -- dbj@netbsd.org
708 */ 709 */
709static fsinode * 710static fsinode *
710link_check(fsinode *entry) 711link_check(fsinode *entry)
711{ 712{
712 static struct entry { 713 static struct entry {
713 fsinode *data; 714 fsinode *data;
714 } *htable; 715 } *htable;
715 static int htshift; /* log(allocated size) */ 716 static size_t htshift; /* log(allocated size) */
716 static int htmask; /* allocated size - 1 */ 717 static size_t htmask; /* allocated size - 1 */
717 static int htused; /* 2*number of insertions */ 718 static size_t htused; /* 2*number of insertions */
718 int h, h2; 719 size_t h, h2;
719 uint64_t tmp; 720 uint64_t tmp;
720 /* this constant is (1<<64)/((1+sqrt(5))/2) 721 /* this constant is (1<<64)/((1+sqrt(5))/2)
721 * aka (word size)/(golden ratio) 722 * aka (word size)/(golden ratio)
722 */ 723 */
723 const uint64_t HTCONST = 11400714819323198485ULL; 724 const uint64_t HTCONST = 11400714819323198485ULL;
724 const int HTBITS = 64; 725 const size_t HTBITS = 64;
725 726
726 /* Never store zero in hashtable */ 727 /* Never store zero in hashtable */
727 assert(entry); 728 assert(entry);
728 729
729 /* Extend hash table if necessary, keep load under 0.5 */ 730 /* Extend hash table if necessary, keep load under 0.5 */
730 if (htused<<1 >= htmask) { 731 if (htused<<1 >= htmask) {
731 struct entry *ohtable; 732 struct entry *ohtable;
732 733
733 if (!htable) 734 if (!htable)
734 htshift = 10; /* starting hashtable size */ 735 htshift = 10; /* starting hashtable size */
735 else 736 else
736 htshift++; /* exponential hashtable growth */ 737 htshift++; /* exponential hashtable growth */
737 738
738 htmask = (1 << htshift) - 1; 739 htmask = (1 << htshift) - 1;
739 htused = 0; 740 htused = 0;
740 741
741 ohtable = htable; 742 ohtable = htable;
742 htable = ecalloc(htmask+1, sizeof(*htable)); 743 htable = ecalloc(htmask+1, sizeof(*htable));
743 /* populate newly allocated hashtable */ 744 /* populate newly allocated hashtable */
744 if (ohtable) { 745 if (ohtable) {
745 int i; 746 for (size_t i = 0; i <= htmask>>1; i++)
746 for (i = 0; i <= htmask>>1; i++) 
747 if (ohtable[i].data) 747 if (ohtable[i].data)
748 link_check(ohtable[i].data); 748 link_check(ohtable[i].data);
749 free(ohtable); 749 free(ohtable);
750 } 750 }
751 } 751 }
752 752
753 /* multiplicative hashing */ 753 /* multiplicative hashing */
754 tmp = entry->st.st_dev; 754 tmp = entry->st.st_dev;
755 tmp <<= HTBITS>>1; 755 tmp <<= HTBITS>>1;
756 tmp |= entry->st.st_ino; 756 tmp |= entry->st.st_ino;
757 tmp *= HTCONST; 757 tmp *= HTCONST;
758 h = tmp >> (HTBITS - htshift); 758 h = tmp >> (HTBITS - htshift);
759 h2 = 1 | ( tmp >> (HTBITS - (htshift<<1) - 1)); /* must be odd */ 759 h2 = 1 | ( tmp >> (HTBITS - (htshift<<1) - 1)); /* must be odd */