Gentoo Archives: gentoo-commits

From: Mike Frysinger <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/sandbox:master commit in: libsbutil/, libsbutil/gnulib/, /
Date: Sun, 20 Sep 2015 08:15:39
Message-Id: 1442732610.105b7e047e98e8f9211a30133d0cc1cb97aef9b0.vapier@gentoo
1 commit: 105b7e047e98e8f9211a30133d0cc1cb97aef9b0
2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
3 AuthorDate: Sun Sep 20 07:03:30 2015 +0000
4 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
5 CommitDate: Sun Sep 20 07:03:30 2015 +0000
6 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=105b7e04
7
8 libsbutil: gnulib: import modules for canonicalize_filename_mode
9
10 This lays the groundwork for fixing handling of broken symlinks. The
11 gnulib code is hand imported because using the gnulib tool imports a
12 ton of code we do not want. Only the bare minimum is imported so we
13 can use the canonicalize_filename_mode function.
14
15 This function is needed to canonicalize symlinks that are ultimately
16 broken. The current sandbox/C library code only supports two modes:
17 (1) dereference a single symlink
18 (2) dereference *all* symlinks, but only if all links are valid
19
20 For sandbox, we need to know the final path a symlink points to even
21 if that path doesn't (yet) exist.
22
23 Note: This commit doesn't actually fix the bug, just brings in the
24 functions we need to do so.
25
26 URL: https://bugs.gentoo.org/540828
27 Reported-by: Rick Farina <zerochaos <AT> gentoo.org>
28 Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>
29
30 configure.ac | 5 +-
31 headers.h | 2 +
32 libsbutil/Makefile.am | 24 +
33 libsbutil/gnulib/areadlink-with-size.c | 104 +++
34 libsbutil/gnulib/areadlink.h | 33 +
35 libsbutil/gnulib/bitrotate.c | 3 +
36 libsbutil/gnulib/bitrotate.h | 136 ++++
37 libsbutil/gnulib/canonicalize.c | 354 +++++++++
38 libsbutil/gnulib/canonicalize.h | 48 ++
39 libsbutil/gnulib/careadlinkat.h | 67 ++
40 libsbutil/gnulib/dosname.h | 53 ++
41 libsbutil/gnulib/file-set.c | 74 ++
42 libsbutil/gnulib/file-set.h | 15 +
43 libsbutil/gnulib/gl-inline.h | 92 +++
44 libsbutil/gnulib/glue.h | 10 +
45 libsbutil/gnulib/hash-pjw.c | 40 ++
46 libsbutil/gnulib/hash-pjw.h | 23 +
47 libsbutil/gnulib/hash-triple.c | 77 ++
48 libsbutil/gnulib/hash-triple.h | 24 +
49 libsbutil/gnulib/hash.c | 1225 ++++++++++++++++++++++++++++++++
50 libsbutil/gnulib/hash.h | 103 +++
51 libsbutil/gnulib/pathmax.h | 83 +++
52 libsbutil/gnulib/same-inode.h | 33 +
53 libsbutil/gnulib/same.h | 25 +
54 libsbutil/gnulib/xalloc-oversized.h | 38 +
55 libsbutil/gnulib/xalloc.h | 1 +
56 libsbutil/gnulib/xgetcwd.h | 21 +
57 libsbutil/sbutil.h | 3 +
58 28 files changed, 2715 insertions(+), 1 deletion(-)
59
60 diff --git a/configure.ac b/configure.ac
61 index 73227db..e705d41 100644
62 --- a/configure.ac
63 +++ b/configure.ac
64 @@ -1,6 +1,6 @@
65 AC_PREREQ([2.61])
66 AC_INIT([sandbox], [2.8], [sandbox@g.o])
67 -AM_INIT_AUTOMAKE([1.12 dist-xz no-dist-gzip silent-rules -Wall])
68 +AM_INIT_AUTOMAKE([1.12 dist-xz no-dist-gzip silent-rules subdir-objects -Wall])
69 AM_SILENT_RULES([yes]) # AM_INIT_AUTOMAKE([silent-rules]) is broken atm
70 AC_CONFIG_HEADER([config.h])
71 AC_CONFIG_MACRO_DIR([m4])
72 @@ -417,6 +417,9 @@ if test "x${LDFLAG_VER}" = "x" ; then
73 fi
74 AC_SUBST([LDFLAG_VER])
75
76 +dnl Add some glue for gnulib modules that include config.h directly.
77 +AH_BOTTOM([#include "headers.h"])
78 +
79 AC_CONFIG_TESTDIR([tests])
80
81 AC_CONFIG_FILES([src/sandbox.sh], [chmod +x src/sandbox.sh])
82
83 diff --git a/headers.h b/headers.h
84 index 42b7c25..1dc140e 100644
85 --- a/headers.h
86 +++ b/headers.h
87 @@ -146,4 +146,6 @@
88 # include "localdecls.h"
89 #endif
90
91 +#include "libsbutil/gnulib/glue.h"
92 +
93 #endif
94
95 diff --git a/libsbutil/Makefile.am b/libsbutil/Makefile.am
96 index 39a5ab6..0c41500 100644
97 --- a/libsbutil/Makefile.am
98 +++ b/libsbutil/Makefile.am
99 @@ -42,6 +42,30 @@ libsbutil_la_SOURCES = \
100 src/config.c \
101 include/rcscripts/util/dynbuf.h \
102 src/dynbuf.c \
103 + gnulib/areadlink.h \
104 + gnulib/areadlink-with-size.c \
105 + gnulib/bitrotate.c \
106 + gnulib/bitrotate.h \
107 + gnulib/canonicalize.c \
108 + gnulib/canonicalize.h \
109 + gnulib/careadlinkat.h \
110 + gnulib/dosname.h \
111 + gnulib/file-set.c \
112 + gnulib/file-set.h \
113 + gnulib/gl-inline.h \
114 + gnulib/glue.h \
115 + gnulib/hash.c \
116 + gnulib/hash.h \
117 + gnulib/hash-pjw.c \
118 + gnulib/hash-pjw.h \
119 + gnulib/hash-triple.c \
120 + gnulib/hash-triple.h \
121 + gnulib/pathmax.h \
122 + gnulib/same.h \
123 + gnulib/same-inode.h \
124 + gnulib/xalloc.h \
125 + gnulib/xalloc-oversized.h \
126 + gnulib/xgetcwd.h \
127 $(LOCAL_INCLUDES)
128
129 EXTRA_DIST = headers.h
130
131 diff --git a/libsbutil/gnulib/areadlink-with-size.c b/libsbutil/gnulib/areadlink-with-size.c
132 new file mode 100644
133 index 0000000..e3a8c50
134 --- /dev/null
135 +++ b/libsbutil/gnulib/areadlink-with-size.c
136 @@ -0,0 +1,104 @@
137 +/* readlink wrapper to return the link name in malloc'd storage.
138 + Unlike xreadlink and xreadlink_with_size, don't ever call exit.
139 +
140 + Copyright (C) 2001, 2003-2007, 2009-2015 Free Software Foundation, Inc.
141 +
142 + This program is free software: you can redistribute it and/or modify
143 + it under the terms of the GNU General Public License as published by
144 + the Free Software Foundation; either version 3 of the License, or
145 + (at your option) any later version.
146 +
147 + This program is distributed in the hope that it will be useful,
148 + but WITHOUT ANY WARRANTY; without even the implied warranty of
149 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
150 + GNU General Public License for more details.
151 +
152 + You should have received a copy of the GNU General Public License
153 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
154 +
155 +/* Written by Jim Meyering <jim@××××××××.net> */
156 +
157 +#include <config.h>
158 +
159 +#include "areadlink.h"
160 +
161 +#include <errno.h>
162 +#include <limits.h>
163 +#include <stdint.h>
164 +#include <stdlib.h>
165 +#include <unistd.h>
166 +
167 +#ifndef SSIZE_MAX
168 +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
169 +#endif
170 +
171 +/* SYMLINK_MAX is used only for an initial memory-allocation sanity
172 + check, so it's OK to guess too small on hosts where there is no
173 + arbitrary limit to symbolic link length. */
174 +#ifndef SYMLINK_MAX
175 +# define SYMLINK_MAX 1024
176 +#endif
177 +
178 +#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
179 +
180 +/* Call readlink to get the symbolic link value of FILE.
181 + SIZE is a hint as to how long the link is expected to be;
182 + typically it is taken from st_size. It need not be correct.
183 + Return a pointer to that NUL-terminated string in malloc'd storage.
184 + If readlink fails, malloc fails, or if the link value is longer
185 + than SSIZE_MAX, return NULL (caller may use errno to diagnose). */
186 +
187 +char *
188 +areadlink_with_size (char const *file, size_t size)
189 +{
190 + /* Some buggy file systems report garbage in st_size. Defend
191 + against them by ignoring outlandish st_size values in the initial
192 + memory allocation. */
193 + size_t symlink_max = SYMLINK_MAX;
194 + size_t INITIAL_LIMIT_BOUND = 8 * 1024;
195 + size_t initial_limit = (symlink_max < INITIAL_LIMIT_BOUND
196 + ? symlink_max + 1
197 + : INITIAL_LIMIT_BOUND);
198 +
199 + /* The initial buffer size for the link value. */
200 + size_t buf_size = size < initial_limit ? size + 1 : initial_limit;
201 +
202 + while (1)
203 + {
204 + ssize_t r;
205 + size_t link_length;
206 + char *buffer = malloc (buf_size);
207 +
208 + if (buffer == NULL)
209 + return NULL;
210 + r = readlink (file, buffer, buf_size);
211 + link_length = r;
212 +
213 + /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
214 + with errno == ERANGE if the buffer is too small. */
215 + if (r < 0 && errno != ERANGE)
216 + {
217 + int saved_errno = errno;
218 + free (buffer);
219 + errno = saved_errno;
220 + return NULL;
221 + }
222 +
223 + if (link_length < buf_size)
224 + {
225 + buffer[link_length] = 0;
226 + return buffer;
227 + }
228 +
229 + free (buffer);
230 + if (buf_size <= MAXSIZE / 2)
231 + buf_size *= 2;
232 + else if (buf_size < MAXSIZE)
233 + buf_size = MAXSIZE;
234 + else
235 + {
236 + errno = ENOMEM;
237 + return NULL;
238 + }
239 + }
240 +}
241
242 diff --git a/libsbutil/gnulib/areadlink.h b/libsbutil/gnulib/areadlink.h
243 new file mode 100644
244 index 0000000..d9e0fa1
245 --- /dev/null
246 +++ b/libsbutil/gnulib/areadlink.h
247 @@ -0,0 +1,33 @@
248 +/* Read symbolic links without size limitation.
249 +
250 + Copyright (C) 2001, 2003-2004, 2007, 2009-2015 Free Software Foundation,
251 + Inc.
252 +
253 + This program is free software: you can redistribute it and/or modify
254 + it under the terms of the GNU General Public License as published by
255 + the Free Software Foundation; either version 3 of the License, or
256 + (at your option) any later version.
257 +
258 + This program is distributed in the hope that it will be useful,
259 + but WITHOUT ANY WARRANTY; without even the implied warranty of
260 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
261 + GNU General Public License for more details.
262 +
263 + You should have received a copy of the GNU General Public License
264 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
265 +
266 +/* Written by Jim Meyering <jim@××××××××.net> */
267 +
268 +#include <stddef.h>
269 +
270 +extern char *areadlink (char const *filename);
271 +extern char *areadlink_with_size (char const *filename, size_t size_hint);
272 +
273 +#if GNULIB_AREADLINKAT
274 +extern char *areadlinkat (int fd, char const *filename);
275 +#endif
276 +
277 +#if GNULIB_AREADLINKAT_WITH_SIZE
278 +extern char *areadlinkat_with_size (int fd, char const *filename,
279 + size_t size_hint);
280 +#endif
281
282 diff --git a/libsbutil/gnulib/bitrotate.c b/libsbutil/gnulib/bitrotate.c
283 new file mode 100644
284 index 0000000..a8f6028
285 --- /dev/null
286 +++ b/libsbutil/gnulib/bitrotate.c
287 @@ -0,0 +1,3 @@
288 +#include <config.h>
289 +#define BITROTATE_INLINE _GL_EXTERN_INLINE
290 +#include "bitrotate.h"
291
292 diff --git a/libsbutil/gnulib/bitrotate.h b/libsbutil/gnulib/bitrotate.h
293 new file mode 100644
294 index 0000000..1665e99
295 --- /dev/null
296 +++ b/libsbutil/gnulib/bitrotate.h
297 @@ -0,0 +1,136 @@
298 +/* bitrotate.h - Rotate bits in integers
299 + Copyright (C) 2008-2015 Free Software Foundation, Inc.
300 +
301 + This program is free software: you can redistribute it and/or modify
302 + it under the terms of the GNU General Public License as published by
303 + the Free Software Foundation; either version 3 of the License, or
304 + (at your option) any later version.
305 +
306 + This program is distributed in the hope that it will be useful,
307 + but WITHOUT ANY WARRANTY; without even the implied warranty of
308 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
309 + GNU General Public License for more details.
310 +
311 + You should have received a copy of the GNU General Public License
312 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
313 +
314 +/* Written by Simon Josefsson <simon@×××××××××.org>, 2008. */
315 +
316 +#ifndef _GL_BITROTATE_H
317 +#define _GL_BITROTATE_H
318 +
319 +#include <limits.h>
320 +#include <stdint.h>
321 +#include <sys/types.h>
322 +
323 +#ifndef _GL_INLINE_HEADER_BEGIN
324 + #error "Please include config.h first."
325 +#endif
326 +_GL_INLINE_HEADER_BEGIN
327 +#ifndef BITROTATE_INLINE
328 +# define BITROTATE_INLINE _GL_INLINE
329 +#endif
330 +
331 +#ifdef UINT64_MAX
332 +/* Given an unsigned 64-bit argument X, return the value corresponding
333 + to rotating the bits N steps to the left. N must be between 1 and
334 + 63 inclusive. */
335 +BITROTATE_INLINE uint64_t
336 +rotl64 (uint64_t x, int n)
337 +{
338 + return ((x << n) | (x >> (64 - n))) & UINT64_MAX;
339 +}
340 +
341 +/* Given an unsigned 64-bit argument X, return the value corresponding
342 + to rotating the bits N steps to the right. N must be between 1 to
343 + 63 inclusive.*/
344 +BITROTATE_INLINE uint64_t
345 +rotr64 (uint64_t x, int n)
346 +{
347 + return ((x >> n) | (x << (64 - n))) & UINT64_MAX;
348 +}
349 +#endif
350 +
351 +/* Given an unsigned 32-bit argument X, return the value corresponding
352 + to rotating the bits N steps to the left. N must be between 1 and
353 + 31 inclusive. */
354 +BITROTATE_INLINE uint32_t
355 +rotl32 (uint32_t x, int n)
356 +{
357 + return ((x << n) | (x >> (32 - n))) & UINT32_MAX;
358 +}
359 +
360 +/* Given an unsigned 32-bit argument X, return the value corresponding
361 + to rotating the bits N steps to the right. N must be between 1 to
362 + 31 inclusive.*/
363 +BITROTATE_INLINE uint32_t
364 +rotr32 (uint32_t x, int n)
365 +{
366 + return ((x >> n) | (x << (32 - n))) & UINT32_MAX;
367 +}
368 +
369 +/* Given a size_t argument X, return the value corresponding
370 + to rotating the bits N steps to the left. N must be between 1 and
371 + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */
372 +BITROTATE_INLINE size_t
373 +rotl_sz (size_t x, int n)
374 +{
375 + return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX;
376 +}
377 +
378 +/* Given a size_t argument X, return the value corresponding
379 + to rotating the bits N steps to the right. N must be between 1 to
380 + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */
381 +BITROTATE_INLINE size_t
382 +rotr_sz (size_t x, int n)
383 +{
384 + return ((x >> n) | (x << ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX;
385 +}
386 +
387 +/* Given an unsigned 16-bit argument X, return the value corresponding
388 + to rotating the bits N steps to the left. N must be between 1 to
389 + 15 inclusive, but on most relevant targets N can also be 0 and 16
390 + because 'int' is at least 32 bits and the arguments must widen
391 + before shifting. */
392 +BITROTATE_INLINE uint16_t
393 +rotl16 (uint16_t x, int n)
394 +{
395 + return ((x << n) | (x >> (16 - n))) & UINT16_MAX;
396 +}
397 +
398 +/* Given an unsigned 16-bit argument X, return the value corresponding
399 + to rotating the bits N steps to the right. N must be in 1 to 15
400 + inclusive, but on most relevant targets N can also be 0 and 16
401 + because 'int' is at least 32 bits and the arguments must widen
402 + before shifting. */
403 +BITROTATE_INLINE uint16_t
404 +rotr16 (uint16_t x, int n)
405 +{
406 + return ((x >> n) | (x << (16 - n))) & UINT16_MAX;
407 +}
408 +
409 +/* Given an unsigned 8-bit argument X, return the value corresponding
410 + to rotating the bits N steps to the left. N must be between 1 to 7
411 + inclusive, but on most relevant targets N can also be 0 and 8
412 + because 'int' is at least 32 bits and the arguments must widen
413 + before shifting. */
414 +BITROTATE_INLINE uint8_t
415 +rotl8 (uint8_t x, int n)
416 +{
417 + return ((x << n) | (x >> (8 - n))) & UINT8_MAX;
418 +}
419 +
420 +/* Given an unsigned 8-bit argument X, return the value corresponding
421 + to rotating the bits N steps to the right. N must be in 1 to 7
422 + inclusive, but on most relevant targets N can also be 0 and 8
423 + because 'int' is at least 32 bits and the arguments must widen
424 + before shifting. */
425 +BITROTATE_INLINE uint8_t
426 +rotr8 (uint8_t x, int n)
427 +{
428 + return ((x >> n) | (x << (8 - n))) & UINT8_MAX;
429 +}
430 +
431 +_GL_INLINE_HEADER_END
432 +
433 +#endif /* _GL_BITROTATE_H */
434
435 diff --git a/libsbutil/gnulib/canonicalize.c b/libsbutil/gnulib/canonicalize.c
436 new file mode 100644
437 index 0000000..397ac76
438 --- /dev/null
439 +++ b/libsbutil/gnulib/canonicalize.c
440 @@ -0,0 +1,354 @@
441 +/* Return the canonical absolute name of a given file.
442 + Copyright (C) 1996-2015 Free Software Foundation, Inc.
443 +
444 + This program is free software: you can redistribute it and/or modify
445 + it under the terms of the GNU General Public License as published by
446 + the Free Software Foundation; either version 3 of the License, or
447 + (at your option) any later version.
448 +
449 + This program is distributed in the hope that it will be useful,
450 + but WITHOUT ANY WARRANTY; without even the implied warranty of
451 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
452 + GNU General Public License for more details.
453 +
454 + You should have received a copy of the GNU General Public License
455 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
456 +
457 +#include <config.h>
458 +
459 +#include "canonicalize.h"
460 +
461 +#include <errno.h>
462 +#include <stdlib.h>
463 +#include <string.h>
464 +#include <sys/stat.h>
465 +#include <unistd.h>
466 +
467 +#include "areadlink.h"
468 +#include "file-set.h"
469 +#include "hash-triple.h"
470 +#include "pathmax.h"
471 +#include "xalloc.h"
472 +#include "xgetcwd.h"
473 +#include "dosname.h"
474 +
475 +#define MULTIPLE_BITS_SET(i) (((i) & ((i) - 1)) != 0)
476 +
477 +/* In this file, we cannot handle file names longer than PATH_MAX.
478 + On systems with no file name length limit, use a fallback. */
479 +#ifndef PATH_MAX
480 +# define PATH_MAX 8192
481 +#endif
482 +
483 +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
484 +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
485 +#endif
486 +
487 +#if ISSLASH ('\\')
488 +# define SLASHES "/\\"
489 +#else
490 +# define SLASHES "/"
491 +#endif
492 +
493 +#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \
494 + || GNULIB_CANONICALIZE_LGPL)
495 +/* Return the canonical absolute name of file NAME. A canonical name
496 + does not contain any ".", ".." components nor any repeated file name
497 + separators ('/') or symlinks. All components must exist.
498 + The result is malloc'd. */
499 +
500 +char *
501 +canonicalize_file_name (const char *name)
502 +{
503 + return canonicalize_filename_mode (name, CAN_EXISTING);
504 +}
505 +#endif /* !HAVE_CANONICALIZE_FILE_NAME */
506 +
507 +/* Return true if we've already seen the triple, <FILENAME, dev, ino>.
508 + If *HT is not initialized, initialize it. */
509 +static bool
510 +seen_triple (Hash_table **ht, char const *filename, struct stat const *st)
511 +{
512 + if (*ht == NULL)
513 + {
514 + size_t initial_capacity = 7;
515 + *ht = hash_initialize (initial_capacity,
516 + NULL,
517 + triple_hash,
518 + triple_compare_ino_str,
519 + triple_free);
520 + if (*ht == NULL)
521 + xalloc_die ();
522 + }
523 +
524 + if (seen_file (*ht, filename, st))
525 + return true;
526 +
527 + record_file (*ht, filename, st);
528 + return false;
529 +}
530 +
531 +/* Return the canonical absolute name of file NAME, while treating
532 + missing elements according to CAN_MODE. A canonical name
533 + does not contain any ".", ".." components nor any repeated file name
534 + separators ('/') or, depending on other CAN_MODE flags, symlinks.
535 + Whether components must exist or not depends on canonicalize mode.
536 + The result is malloc'd. */
537 +
538 +char *
539 +canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode)
540 +{
541 + char *rname, *dest, *extra_buf = NULL;
542 + char const *start;
543 + char const *end;
544 + char const *rname_limit;
545 + size_t extra_len = 0;
546 + Hash_table *ht = NULL;
547 + int saved_errno;
548 + int can_flags = can_mode & ~CAN_MODE_MASK;
549 + bool logical = can_flags & CAN_NOLINKS;
550 + size_t prefix_len;
551 +
552 + can_mode &= CAN_MODE_MASK;
553 +
554 + if (MULTIPLE_BITS_SET (can_mode))
555 + {
556 + errno = EINVAL;
557 + return NULL;
558 + }
559 +
560 + if (name == NULL)
561 + {
562 + errno = EINVAL;
563 + return NULL;
564 + }
565 +
566 + if (name[0] == '\0')
567 + {
568 + errno = ENOENT;
569 + return NULL;
570 + }
571 +
572 + /* This is always zero for Posix hosts, but can be 2 for MS-Windows
573 + and MS-DOS X:/foo/bar file names. */
574 + prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
575 +
576 + if (!IS_ABSOLUTE_FILE_NAME (name))
577 + {
578 + rname = xgetcwd ();
579 + if (!rname)
580 + return NULL;
581 + dest = strchr (rname, '\0');
582 + if (dest - rname < PATH_MAX)
583 + {
584 + char *p = xrealloc (rname, PATH_MAX);
585 + dest = p + (dest - rname);
586 + rname = p;
587 + rname_limit = rname + PATH_MAX;
588 + }
589 + else
590 + {
591 + rname_limit = dest;
592 + }
593 + start = name;
594 + prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
595 + }
596 + else
597 + {
598 + rname = xmalloc (PATH_MAX);
599 + rname_limit = rname + PATH_MAX;
600 + dest = rname;
601 + if (prefix_len)
602 + {
603 + memcpy (rname, name, prefix_len);
604 + dest += prefix_len;
605 + }
606 + *dest++ = '/';
607 + if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
608 + {
609 + if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
610 + *dest++ = '/';
611 + *dest = '\0';
612 + }
613 + start = name + prefix_len;
614 + }
615 +
616 + for ( ; *start; start = end)
617 + {
618 + /* Skip sequence of multiple file name separators. */
619 + while (ISSLASH (*start))
620 + ++start;
621 +
622 + /* Find end of component. */
623 + for (end = start; *end && !ISSLASH (*end); ++end)
624 + /* Nothing. */;
625 +
626 + if (end - start == 0)
627 + break;
628 + else if (end - start == 1 && start[0] == '.')
629 + /* nothing */;
630 + else if (end - start == 2 && start[0] == '.' && start[1] == '.')
631 + {
632 + /* Back up to previous component, ignore if at root already. */
633 + if (dest > rname + prefix_len + 1)
634 + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
635 + continue;
636 + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
637 + && !prefix_len && ISSLASH (*dest) && !ISSLASH (dest[1]))
638 + dest++;
639 + }
640 + else
641 + {
642 + struct stat st;
643 +
644 + if (!ISSLASH (dest[-1]))
645 + *dest++ = '/';
646 +
647 + if (dest + (end - start) >= rname_limit)
648 + {
649 + ptrdiff_t dest_offset = dest - rname;
650 + size_t new_size = rname_limit - rname;
651 +
652 + if (end - start + 1 > PATH_MAX)
653 + new_size += end - start + 1;
654 + else
655 + new_size += PATH_MAX;
656 + rname = xrealloc (rname, new_size);
657 + rname_limit = rname + new_size;
658 +
659 + dest = rname + dest_offset;
660 + }
661 +
662 + dest = memcpy (dest, start, end - start);
663 + dest += end - start;
664 + *dest = '\0';
665 +
666 + if (logical && (can_mode == CAN_MISSING))
667 + {
668 + /* Avoid the stat in this case as it's inconsequential.
669 + i.e. we're neither resolving symlinks or testing
670 + component existence. */
671 + st.st_mode = 0;
672 + }
673 + else if ((logical ? stat (rname, &st) : lstat (rname, &st)) != 0)
674 + {
675 + saved_errno = errno;
676 + if (can_mode == CAN_EXISTING)
677 + goto error;
678 + if (can_mode == CAN_ALL_BUT_LAST)
679 + {
680 + if (end[strspn (end, SLASHES)] || saved_errno != ENOENT)
681 + goto error;
682 + continue;
683 + }
684 + st.st_mode = 0;
685 + }
686 +
687 + if (S_ISLNK (st.st_mode))
688 + {
689 + char *buf;
690 + size_t n, len;
691 +
692 + /* Detect loops. We cannot use the cycle-check module here,
693 + since it's actually possible to encounter the same symlink
694 + more than once in a given traversal. However, encountering
695 + the same symlink,NAME pair twice does indicate a loop. */
696 + if (seen_triple (&ht, name, &st))
697 + {
698 + if (can_mode == CAN_MISSING)
699 + continue;
700 + saved_errno = ELOOP;
701 + goto error;
702 + }
703 +
704 + buf = areadlink_with_size (rname, st.st_size);
705 + if (!buf)
706 + {
707 + if (can_mode == CAN_MISSING && errno != ENOMEM)
708 + continue;
709 + saved_errno = errno;
710 + goto error;
711 + }
712 +
713 + n = strlen (buf);
714 + len = strlen (end);
715 +
716 + if (!extra_len)
717 + {
718 + extra_len =
719 + ((n + len + 1) > PATH_MAX) ? (n + len + 1) : PATH_MAX;
720 + extra_buf = xmalloc (extra_len);
721 + }
722 + else if ((n + len + 1) > extra_len)
723 + {
724 + extra_len = n + len + 1;
725 + extra_buf = xrealloc (extra_buf, extra_len);
726 + }
727 +
728 + /* Careful here, end may be a pointer into extra_buf... */
729 + memmove (&extra_buf[n], end, len + 1);
730 + name = end = memcpy (extra_buf, buf, n);
731 +
732 + if (IS_ABSOLUTE_FILE_NAME (buf))
733 + {
734 + size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
735 +
736 + if (pfxlen)
737 + memcpy (rname, buf, pfxlen);
738 + dest = rname + pfxlen;
739 + *dest++ = '/'; /* It's an absolute symlink */
740 + if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
741 + {
742 + if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
743 + *dest++ = '/';
744 + *dest = '\0';
745 + }
746 + /* Install the new prefix to be in effect hereafter. */
747 + prefix_len = pfxlen;
748 + }
749 + else
750 + {
751 + /* Back up to previous component, ignore if at root
752 + already: */
753 + if (dest > rname + prefix_len + 1)
754 + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
755 + continue;
756 + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
757 + && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
758 + dest++;
759 + }
760 +
761 + free (buf);
762 + }
763 + else
764 + {
765 + if (!S_ISDIR (st.st_mode) && *end && (can_mode != CAN_MISSING))
766 + {
767 + saved_errno = ENOTDIR;
768 + goto error;
769 + }
770 + }
771 + }
772 + }
773 + if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
774 + --dest;
775 + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
776 + && ISSLASH (*dest) && !ISSLASH (dest[1]))
777 + dest++;
778 + *dest = '\0';
779 + if (rname_limit != dest + 1)
780 + rname = xrealloc (rname, dest - rname + 1);
781 +
782 + free (extra_buf);
783 + if (ht)
784 + hash_free (ht);
785 + return rname;
786 +
787 +error:
788 + free (extra_buf);
789 + free (rname);
790 + if (ht)
791 + hash_free (ht);
792 + errno = saved_errno;
793 + return NULL;
794 +}
795
796 diff --git a/libsbutil/gnulib/canonicalize.h b/libsbutil/gnulib/canonicalize.h
797 new file mode 100644
798 index 0000000..236cba5
799 --- /dev/null
800 +++ b/libsbutil/gnulib/canonicalize.h
801 @@ -0,0 +1,48 @@
802 +/* Return the canonical absolute name of a given file.
803 + Copyright (C) 1996-2007, 2009-2015 Free Software Foundation, Inc.
804 +
805 + This program is free software: you can redistribute it and/or modify
806 + it under the terms of the GNU General Public License as published by
807 + the Free Software Foundation; either version 3 of the License, or
808 + (at your option) any later version.
809 +
810 + This program is distributed in the hope that it will be useful,
811 + but WITHOUT ANY WARRANTY; without even the implied warranty of
812 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
813 + GNU General Public License for more details.
814 +
815 + You should have received a copy of the GNU General Public License
816 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
817 +
818 +#ifndef CANONICALIZE_H_
819 +# define CANONICALIZE_H_
820 +
821 +#include <stdlib.h> /* for canonicalize_file_name */
822 +
823 +#define CAN_MODE_MASK (CAN_EXISTING | CAN_ALL_BUT_LAST | CAN_MISSING)
824 +
825 +enum canonicalize_mode_t
826 + {
827 + /* All components must exist. */
828 + CAN_EXISTING = 0,
829 +
830 + /* All components excluding last one must exist. */
831 + CAN_ALL_BUT_LAST = 1,
832 +
833 + /* No requirements on components existence. */
834 + CAN_MISSING = 2,
835 +
836 + /* Don't expand symlinks. */
837 + CAN_NOLINKS = 4
838 + };
839 +typedef enum canonicalize_mode_t canonicalize_mode_t;
840 +
841 +/* Return the canonical absolute name of file NAME, while treating
842 + missing elements according to CAN_MODE. A canonical name
843 + does not contain any `.', `..' components nor any repeated file name
844 + separators ('/') or, depending on other CAN_MODE flags, symlinks.
845 + Whether components must exist or not depends on canonicalize mode.
846 + The result is malloc'd. */
847 +char *canonicalize_filename_mode (const char *, canonicalize_mode_t);
848 +
849 +#endif /* !CANONICALIZE_H_ */
850
851 diff --git a/libsbutil/gnulib/careadlinkat.h b/libsbutil/gnulib/careadlinkat.h
852 new file mode 100644
853 index 0000000..4eb9fcc
854 --- /dev/null
855 +++ b/libsbutil/gnulib/careadlinkat.h
856 @@ -0,0 +1,67 @@
857 +/* Read symbolic links into a buffer without size limitation, relative to fd.
858 +
859 + Copyright (C) 2011-2015 Free Software Foundation, Inc.
860 +
861 + This program is free software: you can redistribute it and/or modify
862 + it under the terms of the GNU General Public License as published by
863 + the Free Software Foundation; either version 3 of the License, or
864 + (at your option) any later version.
865 +
866 + This program is distributed in the hope that it will be useful,
867 + but WITHOUT ANY WARRANTY; without even the implied warranty of
868 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
869 + GNU General Public License for more details.
870 +
871 + You should have received a copy of the GNU General Public License
872 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
873 +
874 +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
875 +
876 +#ifndef _GL_CAREADLINKAT_H
877 +#define _GL_CAREADLINKAT_H
878 +
879 +#include <fcntl.h>
880 +#include <unistd.h>
881 +
882 +struct allocator;
883 +
884 +/* Assuming the current directory is FD, get the symbolic link value
885 + of FILENAME as a null-terminated string and put it into a buffer.
886 + If FD is AT_FDCWD, FILENAME is interpreted relative to the current
887 + working directory, as in openat.
888 +
889 + If the link is small enough to fit into BUFFER put it there.
890 + BUFFER's size is BUFFER_SIZE, and BUFFER can be null
891 + if BUFFER_SIZE is zero.
892 +
893 + If the link is not small, put it into a dynamically allocated
894 + buffer managed by ALLOC. It is the caller's responsibility to free
895 + the returned value if it is nonnull and is not BUFFER.
896 +
897 + The PREADLINKAT function specifies how to read links. It operates
898 + like POSIX readlinkat()
899 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
900 + but can assume that its first argument is the same as FD.
901 +
902 + If successful, return the buffer address; otherwise return NULL and
903 + set errno. */
904 +
905 +char *careadlinkat (int fd, char const *filename,
906 + char *buffer, size_t buffer_size,
907 + struct allocator const *alloc,
908 + ssize_t (*preadlinkat) (int, char const *,
909 + char *, size_t));
910 +
911 +/* Suitable value for careadlinkat's FD argument. */
912 +#if HAVE_READLINKAT
913 +/* AT_FDCWD is declared in <fcntl.h>. */
914 +#else
915 +/* Define AT_FDCWD independently, so that the careadlinkat module does
916 + not depend on the fcntl-h module. We might as well use the same value
917 + as fcntl-h. */
918 +# ifndef AT_FDCWD
919 +# define AT_FDCWD (-3041965)
920 +# endif
921 +#endif
922 +
923 +#endif /* _GL_CAREADLINKAT_H */
924
925 diff --git a/libsbutil/gnulib/dosname.h b/libsbutil/gnulib/dosname.h
926 new file mode 100644
927 index 0000000..893baf6
928 --- /dev/null
929 +++ b/libsbutil/gnulib/dosname.h
930 @@ -0,0 +1,53 @@
931 +/* File names on MS-DOS/Windows systems.
932 +
933 + Copyright (C) 2000-2001, 2004-2006, 2009-2015 Free Software Foundation, Inc.
934 +
935 + This program is free software: you can redistribute it and/or modify
936 + it under the terms of the GNU General Public License as published by
937 + the Free Software Foundation; either version 3 of the License, or
938 + (at your option) any later version.
939 +
940 + This program is distributed in the hope that it will be useful,
941 + but WITHOUT ANY WARRANTY; without even the implied warranty of
942 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
943 + GNU General Public License for more details.
944 +
945 + You should have received a copy of the GNU General Public License
946 + along with this program. If not, see <http://www.gnu.org/licenses/>.
947 +
948 + From Paul Eggert and Jim Meyering. */
949 +
950 +#ifndef _DOSNAME_H
951 +#define _DOSNAME_H
952 +
953 +#if (defined _WIN32 || defined __WIN32__ || \
954 + defined __MSDOS__ || defined __CYGWIN__ || \
955 + defined __EMX__ || defined __DJGPP__)
956 + /* This internal macro assumes ASCII, but all hosts that support drive
957 + letters use ASCII. */
958 +# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \
959 + <= 'z' - 'a')
960 +# define FILE_SYSTEM_PREFIX_LEN(Filename) \
961 + (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
962 +# ifndef __CYGWIN__
963 +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1
964 +# endif
965 +# define ISSLASH(C) ((C) == '/' || (C) == '\\')
966 +#else
967 +# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
968 +# define ISSLASH(C) ((C) == '/')
969 +#endif
970 +
971 +#ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
972 +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
973 +#endif
974 +
975 +#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
976 +# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
977 +# else
978 +# define IS_ABSOLUTE_FILE_NAME(F) \
979 + (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0)
980 +#endif
981 +#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
982 +
983 +#endif /* DOSNAME_H_ */
984
985 diff --git a/libsbutil/gnulib/file-set.c b/libsbutil/gnulib/file-set.c
986 new file mode 100644
987 index 0000000..1cf2f0c
988 --- /dev/null
989 +++ b/libsbutil/gnulib/file-set.c
990 @@ -0,0 +1,74 @@
991 +/* Specialized functions to manipulate a set of files.
992 + Copyright (C) 2007, 2009-2015 Free Software Foundation, Inc.
993 +
994 + This program is free software: you can redistribute it and/or modify
995 + it under the terms of the GNU General Public License as published by
996 + the Free Software Foundation; either version 3 of the License, or
997 + (at your option) any later version.
998 +
999 + This program is distributed in the hope that it will be useful,
1000 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1001 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1002 + GNU General Public License for more details.
1003 +
1004 + You should have received a copy of the GNU General Public License
1005 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
1006 +
1007 +/* written by Jim Meyering */
1008 +
1009 +#include <config.h>
1010 +#include "file-set.h"
1011 +
1012 +#include "hash-triple.h"
1013 +#include "xalloc.h"
1014 +
1015 +/* Record file, FILE, and dev/ino from *STATS, in the hash table, HT.
1016 + If HT is NULL, return immediately.
1017 + If memory allocation fails, exit immediately. */
1018 +void
1019 +record_file (Hash_table *ht, char const *file, struct stat const *stats)
1020 +{
1021 + struct F_triple *ent;
1022 +
1023 + if (ht == NULL)
1024 + return;
1025 +
1026 + ent = xmalloc (sizeof *ent);
1027 + ent->name = xstrdup (file);
1028 + ent->st_ino = stats->st_ino;
1029 + ent->st_dev = stats->st_dev;
1030 +
1031 + {
1032 + struct F_triple *ent_from_table = hash_insert (ht, ent);
1033 + if (ent_from_table == NULL)
1034 + {
1035 + /* Insertion failed due to lack of memory. */
1036 + xalloc_die ();
1037 + }
1038 +
1039 + if (ent_from_table != ent)
1040 + {
1041 + /* There was alread a matching entry in the table, so ENT was
1042 + not inserted. Free it. */
1043 + triple_free (ent);
1044 + }
1045 + }
1046 +}
1047 +
1048 +/* Return true if there is an entry in hash table, HT,
1049 + for the file described by FILE and STATS. */
1050 +bool
1051 +seen_file (Hash_table const *ht, char const *file,
1052 + struct stat const *stats)
1053 +{
1054 + struct F_triple new_ent;
1055 +
1056 + if (ht == NULL)
1057 + return false;
1058 +
1059 + new_ent.name = (char *) file;
1060 + new_ent.st_ino = stats->st_ino;
1061 + new_ent.st_dev = stats->st_dev;
1062 +
1063 + return !!hash_lookup (ht, &new_ent);
1064 +}
1065
1066 diff --git a/libsbutil/gnulib/file-set.h b/libsbutil/gnulib/file-set.h
1067 new file mode 100644
1068 index 0000000..4e47d95
1069 --- /dev/null
1070 +++ b/libsbutil/gnulib/file-set.h
1071 @@ -0,0 +1,15 @@
1072 +#include <sys/types.h>
1073 +#include <sys/stat.h>
1074 +#include <stdbool.h>
1075 +
1076 +#include "hash.h"
1077 +
1078 +extern void record_file (Hash_table *ht, char const *file,
1079 + struct stat const *stats)
1080 +#if defined __GNUC__ && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3)
1081 + __attribute__ ((nonnull (2, 3)))
1082 +#endif
1083 +;
1084 +
1085 +extern bool seen_file (Hash_table const *ht, char const *file,
1086 + struct stat const *stats);
1087
1088 diff --git a/libsbutil/gnulib/gl-inline.h b/libsbutil/gnulib/gl-inline.h
1089 new file mode 100644
1090 index 0000000..bb8598e
1091 --- /dev/null
1092 +++ b/libsbutil/gnulib/gl-inline.h
1093 @@ -0,0 +1,92 @@
1094 +/* Expansion of gl_EXTERN_INLINE */
1095 +
1096 +/* Please see the Gnulib manual for how to use these macros.
1097 +
1098 + Suppress extern inline with HP-UX cc, as it appears to be broken; see
1099 + <http://lists.gnu.org/archive/html/bug-texinfo/2013-02/msg00030.html>.
1100 +
1101 + Suppress extern inline with Sun C in standards-conformance mode, as it
1102 + mishandles inline functions that call each other. E.g., for 'inline void f
1103 + (void) { } inline void g (void) { f (); }', c99 incorrectly complains
1104 + 'reference to static identifier "f" in extern inline function'.
1105 + This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
1106 +
1107 + Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
1108 + on configurations that mistakenly use 'static inline' to implement
1109 + functions or macros in standard C headers like <ctype.h>. For example,
1110 + if isdigit is mistakenly implemented via a static inline function,
1111 + a program containing an extern inline function that calls isdigit
1112 + may not work since the C standard prohibits extern inline functions
1113 + from calling static functions. This bug is known to occur on:
1114 +
1115 + OS X 10.8 and earlier; see:
1116 + http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html
1117 +
1118 + DragonFly; see
1119 + http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log
1120 +
1121 + FreeBSD; see:
1122 + http://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00104.html
1123 +
1124 + OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
1125 + for clang but remains for g++; see <http://trac.macports.org/ticket/41033>.
1126 + Assume DragonFly and FreeBSD will be similar. */
1127 +#if (((defined __APPLE__ && defined __MACH__) \
1128 + || defined __DragonFly__ || defined __FreeBSD__) \
1129 + && (defined __header_inline \
1130 + ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
1131 + && ! defined __clang__) \
1132 + : ((! defined _DONT_USE_CTYPE_INLINE_ \
1133 + && (defined __GNUC__ || defined __cplusplus)) \
1134 + || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
1135 + && defined __GNUC__ && ! defined __cplusplus))))
1136 +# define _GL_EXTERN_INLINE_STDHEADER_BUG
1137 +#endif
1138 +#if ((__GNUC__ \
1139 + ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
1140 + : (199901L <= __STDC_VERSION__ \
1141 + && !defined __HP_cc \
1142 + && !(defined __SUNPRO_C && __STDC__))) \
1143 + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
1144 +# define _GL_INLINE inline
1145 +# define _GL_EXTERN_INLINE extern inline
1146 +# define _GL_EXTERN_INLINE_IN_USE
1147 +#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
1148 + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
1149 +# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
1150 + /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */
1151 +# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
1152 +# else
1153 +# define _GL_INLINE extern inline
1154 +# endif
1155 +# define _GL_EXTERN_INLINE extern
1156 +# define _GL_EXTERN_INLINE_IN_USE
1157 +#else
1158 +# define _GL_INLINE static _GL_UNUSED
1159 +# define _GL_EXTERN_INLINE static _GL_UNUSED
1160 +#endif
1161 +
1162 +/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
1163 + suppress bogus "no previous prototype for 'FOO'"
1164 + and "no previous declaration for 'FOO'" diagnostics,
1165 + when FOO is an inline function in the header; see
1166 + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
1167 + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */
1168 +#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
1169 +# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
1170 +# define _GL_INLINE_HEADER_CONST_PRAGMA
1171 +# else
1172 +# define _GL_INLINE_HEADER_CONST_PRAGMA \
1173 + _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
1174 +# endif
1175 +# define _GL_INLINE_HEADER_BEGIN \
1176 + _Pragma ("GCC diagnostic push") \
1177 + _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
1178 + _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
1179 + _GL_INLINE_HEADER_CONST_PRAGMA
1180 +# define _GL_INLINE_HEADER_END \
1181 + _Pragma ("GCC diagnostic pop")
1182 +#else
1183 +# define _GL_INLINE_HEADER_BEGIN
1184 +# define _GL_INLINE_HEADER_END
1185 +#endif
1186
1187 diff --git a/libsbutil/gnulib/glue.h b/libsbutil/gnulib/glue.h
1188 new file mode 100644
1189 index 0000000..083ab73
1190 --- /dev/null
1191 +++ b/libsbutil/gnulib/glue.h
1192 @@ -0,0 +1,10 @@
1193 +/* gnulib-specific glue logic that normally gnulib macros would set up.
1194 + *
1195 + * Copyright 1999-2015 Gentoo Foundation
1196 + * Licensed under the GPL-2
1197 + */
1198 +
1199 +#define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
1200 +#define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
1201 +
1202 +#include "gl-inline.h"
1203
1204 diff --git a/libsbutil/gnulib/hash-pjw.c b/libsbutil/gnulib/hash-pjw.c
1205 new file mode 100644
1206 index 0000000..b2e0251
1207 --- /dev/null
1208 +++ b/libsbutil/gnulib/hash-pjw.c
1209 @@ -0,0 +1,40 @@
1210 +/* hash-pjw.c -- compute a hash value from a NUL-terminated string.
1211 +
1212 + Copyright (C) 2001, 2003, 2006, 2009-2015 Free Software Foundation, Inc.
1213 +
1214 + This program is free software: you can redistribute it and/or modify
1215 + it under the terms of the GNU General Public License as published by
1216 + the Free Software Foundation; either version 3 of the License, or
1217 + (at your option) any later version.
1218 +
1219 + This program is distributed in the hope that it will be useful,
1220 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1221 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1222 + GNU General Public License for more details.
1223 +
1224 + You should have received a copy of the GNU General Public License
1225 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
1226 +
1227 +#include <config.h>
1228 +
1229 +#include "hash-pjw.h"
1230 +
1231 +#include <limits.h>
1232 +
1233 +#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
1234 +
1235 +/* A hash function for NUL-terminated char* strings using
1236 + the method described by Bruno Haible.
1237 + See http://www.haible.de/bruno/hashfunc.html. */
1238 +
1239 +size_t
1240 +hash_pjw (const void *x, size_t tablesize)
1241 +{
1242 + const char *s;
1243 + size_t h = 0;
1244 +
1245 + for (s = x; *s; s++)
1246 + h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
1247 +
1248 + return h % tablesize;
1249 +}
1250
1251 diff --git a/libsbutil/gnulib/hash-pjw.h b/libsbutil/gnulib/hash-pjw.h
1252 new file mode 100644
1253 index 0000000..f4b005c
1254 --- /dev/null
1255 +++ b/libsbutil/gnulib/hash-pjw.h
1256 @@ -0,0 +1,23 @@
1257 +/* hash-pjw.h -- declaration for a simple hash function
1258 + Copyright (C) 2001, 2003, 2009-2015 Free Software Foundation, Inc.
1259 +
1260 + This program is free software: you can redistribute it and/or modify
1261 + it under the terms of the GNU General Public License as published by
1262 + the Free Software Foundation; either version 3 of the License, or
1263 + (at your option) any later version.
1264 +
1265 + This program is distributed in the hope that it will be useful,
1266 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1267 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1268 + GNU General Public License for more details.
1269 +
1270 + You should have received a copy of the GNU General Public License
1271 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
1272 +
1273 +#include <stddef.h>
1274 +
1275 +/* Compute a hash code for a NUL-terminated string starting at X,
1276 + and return the hash code modulo TABLESIZE.
1277 + The result is platform dependent: it depends on the size of the 'size_t'
1278 + type and on the signedness of the 'char' type. */
1279 +extern size_t hash_pjw (void const *x, size_t tablesize) _GL_ATTRIBUTE_PURE;
1280
1281 diff --git a/libsbutil/gnulib/hash-triple.c b/libsbutil/gnulib/hash-triple.c
1282 new file mode 100644
1283 index 0000000..c3b6d9f
1284 --- /dev/null
1285 +++ b/libsbutil/gnulib/hash-triple.c
1286 @@ -0,0 +1,77 @@
1287 +/* Hash functions for file-related triples: name, device, inode.
1288 + Copyright (C) 2007, 2009-2015 Free Software Foundation, Inc.
1289 +
1290 + This program is free software: you can redistribute it and/or modify
1291 + it under the terms of the GNU General Public License as published by
1292 + the Free Software Foundation; either version 3 of the License, or
1293 + (at your option) any later version.
1294 +
1295 + This program is distributed in the hope that it will be useful,
1296 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1297 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1298 + GNU General Public License for more details.
1299 +
1300 + You should have received a copy of the GNU General Public License
1301 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
1302 +
1303 +/* written by Jim Meyering */
1304 +
1305 +#include <config.h>
1306 +
1307 +#include "hash-triple.h"
1308 +
1309 +#include <stdlib.h>
1310 +#include <string.h>
1311 +
1312 +#include "hash-pjw.h"
1313 +#include "same.h"
1314 +#include "same-inode.h"
1315 +
1316 +#define STREQ(a, b) (strcmp (a, b) == 0)
1317 +
1318 +/* Hash an F_triple, and *do* consider the file name. */
1319 +size_t
1320 +triple_hash (void const *x, size_t table_size)
1321 +{
1322 + struct F_triple const *p = x;
1323 + size_t tmp = hash_pjw (p->name, table_size);
1324 +
1325 + /* Ignoring the device number here should be fine. */
1326 + return (tmp ^ p->st_ino) % table_size;
1327 +}
1328 +
1329 +/* Hash an F_triple, without considering the file name. */
1330 +size_t
1331 +triple_hash_no_name (void const *x, size_t table_size)
1332 +{
1333 + struct F_triple const *p = x;
1334 +
1335 + /* Ignoring the device number here should be fine. */
1336 + return p->st_ino % table_size;
1337 +}
1338 +
1339 +/* Compare two F_triple structs. */
1340 +bool
1341 +triple_compare (void const *x, void const *y)
1342 +{
1343 + struct F_triple const *a = x;
1344 + struct F_triple const *b = y;
1345 + return (SAME_INODE (*a, *b) && same_name (a->name, b->name)) ? true : false;
1346 +}
1347 +
1348 +bool
1349 +triple_compare_ino_str (void const *x, void const *y)
1350 +{
1351 + struct F_triple const *a = x;
1352 + struct F_triple const *b = y;
1353 + return (SAME_INODE (*a, *b) && STREQ (a->name, b->name)) ? true : false;
1354 +}
1355 +
1356 +/* Free an F_triple. */
1357 +void
1358 +triple_free (void *x)
1359 +{
1360 + struct F_triple *a = x;
1361 + free (a->name);
1362 + free (a);
1363 +}
1364
1365 diff --git a/libsbutil/gnulib/hash-triple.h b/libsbutil/gnulib/hash-triple.h
1366 new file mode 100644
1367 index 0000000..0658d81
1368 --- /dev/null
1369 +++ b/libsbutil/gnulib/hash-triple.h
1370 @@ -0,0 +1,24 @@
1371 +#ifndef HASH_TRIPLE_H
1372 +#define HASH_TRIPLE_H
1373 +
1374 +#include <sys/types.h>
1375 +#include <sys/stat.h>
1376 +#include <stdbool.h>
1377 +
1378 +/* Describe a just-created or just-renamed destination file. */
1379 +struct F_triple
1380 +{
1381 + char *name;
1382 + ino_t st_ino;
1383 + dev_t st_dev;
1384 +};
1385 +
1386 +extern size_t triple_hash (void const *x, size_t table_size) _GL_ATTRIBUTE_PURE;
1387 +extern size_t triple_hash_no_name (void const *x, size_t table_size)
1388 + _GL_ATTRIBUTE_PURE;
1389 +extern bool triple_compare (void const *x, void const *y);
1390 +extern bool triple_compare_ino_str (void const *x, void const *y)
1391 + _GL_ATTRIBUTE_PURE;
1392 +extern void triple_free (void *x);
1393 +
1394 +#endif
1395
1396 diff --git a/libsbutil/gnulib/hash.c b/libsbutil/gnulib/hash.c
1397 new file mode 100644
1398 index 0000000..4f27d5c
1399 --- /dev/null
1400 +++ b/libsbutil/gnulib/hash.c
1401 @@ -0,0 +1,1225 @@
1402 +/* hash - hashing table processing.
1403 +
1404 + Copyright (C) 1998-2004, 2006-2007, 2009-2015 Free Software Foundation, Inc.
1405 +
1406 + Written by Jim Meyering, 1992.
1407 +
1408 + This program is free software: you can redistribute it and/or modify
1409 + it under the terms of the GNU General Public License as published by
1410 + the Free Software Foundation; either version 3 of the License, or
1411 + (at your option) any later version.
1412 +
1413 + This program is distributed in the hope that it will be useful,
1414 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1415 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416 + GNU General Public License for more details.
1417 +
1418 + You should have received a copy of the GNU General Public License
1419 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
1420 +
1421 +/* A generic hash table package. */
1422 +
1423 +/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead
1424 + of malloc. If you change USE_OBSTACK, you have to recompile! */
1425 +
1426 +#include <config.h>
1427 +
1428 +#include "hash.h"
1429 +
1430 +#include "bitrotate.h"
1431 +#include "xalloc-oversized.h"
1432 +
1433 +#include <stdint.h>
1434 +#include <stdio.h>
1435 +#include <stdlib.h>
1436 +
1437 +#if USE_OBSTACK
1438 +# include "obstack.h"
1439 +# ifndef obstack_chunk_alloc
1440 +# define obstack_chunk_alloc malloc
1441 +# endif
1442 +# ifndef obstack_chunk_free
1443 +# define obstack_chunk_free free
1444 +# endif
1445 +#endif
1446 +
1447 +struct hash_entry
1448 + {
1449 + void *data;
1450 + struct hash_entry *next;
1451 + };
1452 +
1453 +struct hash_table
1454 + {
1455 + /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
1456 + for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
1457 + are not empty, there are N_ENTRIES active entries in the table. */
1458 + struct hash_entry *bucket;
1459 + struct hash_entry const *bucket_limit;
1460 + size_t n_buckets;
1461 + size_t n_buckets_used;
1462 + size_t n_entries;
1463 +
1464 + /* Tuning arguments, kept in a physically separate structure. */
1465 + const Hash_tuning *tuning;
1466 +
1467 + /* Three functions are given to 'hash_initialize', see the documentation
1468 + block for this function. In a word, HASHER randomizes a user entry
1469 + into a number up from 0 up to some maximum minus 1; COMPARATOR returns
1470 + true if two user entries compare equally; and DATA_FREER is the cleanup
1471 + function for a user entry. */
1472 + Hash_hasher hasher;
1473 + Hash_comparator comparator;
1474 + Hash_data_freer data_freer;
1475 +
1476 + /* A linked list of freed struct hash_entry structs. */
1477 + struct hash_entry *free_entry_list;
1478 +
1479 +#if USE_OBSTACK
1480 + /* Whenever obstacks are used, it is possible to allocate all overflowed
1481 + entries into a single stack, so they all can be freed in a single
1482 + operation. It is not clear if the speedup is worth the trouble. */
1483 + struct obstack entry_stack;
1484 +#endif
1485 + };
1486 +
1487 +/* A hash table contains many internal entries, each holding a pointer to
1488 + some user-provided data (also called a user entry). An entry indistinctly
1489 + refers to both the internal entry and its associated user entry. A user
1490 + entry contents may be hashed by a randomization function (the hashing
1491 + function, or just "hasher" for short) into a number (or "slot") between 0
1492 + and the current table size. At each slot position in the hash table,
1493 + starts a linked chain of entries for which the user data all hash to this
1494 + slot. A bucket is the collection of all entries hashing to the same slot.
1495 +
1496 + A good "hasher" function will distribute entries rather evenly in buckets.
1497 + In the ideal case, the length of each bucket is roughly the number of
1498 + entries divided by the table size. Finding the slot for a data is usually
1499 + done in constant time by the "hasher", and the later finding of a precise
1500 + entry is linear in time with the size of the bucket. Consequently, a
1501 + larger hash table size (that is, a larger number of buckets) is prone to
1502 + yielding shorter chains, *given* the "hasher" function behaves properly.
1503 +
1504 + Long buckets slow down the lookup algorithm. One might use big hash table
1505 + sizes in hope to reduce the average length of buckets, but this might
1506 + become inordinate, as unused slots in the hash table take some space. The
1507 + best bet is to make sure you are using a good "hasher" function (beware
1508 + that those are not that easy to write! :-), and to use a table size
1509 + larger than the actual number of entries. */
1510 +
1511 +/* If an insertion makes the ratio of nonempty buckets to table size larger
1512 + than the growth threshold (a number between 0.0 and 1.0), then increase
1513 + the table size by multiplying by the growth factor (a number greater than
1514 + 1.0). The growth threshold defaults to 0.8, and the growth factor
1515 + defaults to 1.414, meaning that the table will have doubled its size
1516 + every second time 80% of the buckets get used. */
1517 +#define DEFAULT_GROWTH_THRESHOLD 0.8f
1518 +#define DEFAULT_GROWTH_FACTOR 1.414f
1519 +
1520 +/* If a deletion empties a bucket and causes the ratio of used buckets to
1521 + table size to become smaller than the shrink threshold (a number between
1522 + 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a
1523 + number greater than the shrink threshold but smaller than 1.0). The shrink
1524 + threshold and factor default to 0.0 and 1.0, meaning that the table never
1525 + shrinks. */
1526 +#define DEFAULT_SHRINK_THRESHOLD 0.0f
1527 +#define DEFAULT_SHRINK_FACTOR 1.0f
1528 +
1529 +/* Use this to initialize or reset a TUNING structure to
1530 + some sensible values. */
1531 +static const Hash_tuning default_tuning =
1532 + {
1533 + DEFAULT_SHRINK_THRESHOLD,
1534 + DEFAULT_SHRINK_FACTOR,
1535 + DEFAULT_GROWTH_THRESHOLD,
1536 + DEFAULT_GROWTH_FACTOR,
1537 + false
1538 + };
1539 +
1540 +/* Information and lookup. */
1541 +
1542 +/* The following few functions provide information about the overall hash
1543 + table organization: the number of entries, number of buckets and maximum
1544 + length of buckets. */
1545 +
1546 +/* Return the number of buckets in the hash table. The table size, the total
1547 + number of buckets (used plus unused), or the maximum number of slots, are
1548 + the same quantity. */
1549 +
1550 +size_t
1551 +hash_get_n_buckets (const Hash_table *table)
1552 +{
1553 + return table->n_buckets;
1554 +}
1555 +
1556 +/* Return the number of slots in use (non-empty buckets). */
1557 +
1558 +size_t
1559 +hash_get_n_buckets_used (const Hash_table *table)
1560 +{
1561 + return table->n_buckets_used;
1562 +}
1563 +
1564 +/* Return the number of active entries. */
1565 +
1566 +size_t
1567 +hash_get_n_entries (const Hash_table *table)
1568 +{
1569 + return table->n_entries;
1570 +}
1571 +
1572 +/* Return the length of the longest chain (bucket). */
1573 +
1574 +size_t
1575 +hash_get_max_bucket_length (const Hash_table *table)
1576 +{
1577 + struct hash_entry const *bucket;
1578 + size_t max_bucket_length = 0;
1579 +
1580 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
1581 + {
1582 + if (bucket->data)
1583 + {
1584 + struct hash_entry const *cursor = bucket;
1585 + size_t bucket_length = 1;
1586 +
1587 + while (cursor = cursor->next, cursor)
1588 + bucket_length++;
1589 +
1590 + if (bucket_length > max_bucket_length)
1591 + max_bucket_length = bucket_length;
1592 + }
1593 + }
1594 +
1595 + return max_bucket_length;
1596 +}
1597 +
1598 +/* Do a mild validation of a hash table, by traversing it and checking two
1599 + statistics. */
1600 +
1601 +bool
1602 +hash_table_ok (const Hash_table *table)
1603 +{
1604 + struct hash_entry const *bucket;
1605 + size_t n_buckets_used = 0;
1606 + size_t n_entries = 0;
1607 +
1608 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
1609 + {
1610 + if (bucket->data)
1611 + {
1612 + struct hash_entry const *cursor = bucket;
1613 +
1614 + /* Count bucket head. */
1615 + n_buckets_used++;
1616 + n_entries++;
1617 +
1618 + /* Count bucket overflow. */
1619 + while (cursor = cursor->next, cursor)
1620 + n_entries++;
1621 + }
1622 + }
1623 +
1624 + if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries)
1625 + return true;
1626 +
1627 + return false;
1628 +}
1629 +
1630 +void
1631 +hash_print_statistics (const Hash_table *table, FILE *stream)
1632 +{
1633 + size_t n_entries = hash_get_n_entries (table);
1634 + size_t n_buckets = hash_get_n_buckets (table);
1635 + size_t n_buckets_used = hash_get_n_buckets_used (table);
1636 + size_t max_bucket_length = hash_get_max_bucket_length (table);
1637 +
1638 + fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries);
1639 + fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets);
1640 + fprintf (stream, "# buckets used: %lu (%.2f%%)\n",
1641 + (unsigned long int) n_buckets_used,
1642 + (100.0 * n_buckets_used) / n_buckets);
1643 + fprintf (stream, "max bucket length: %lu\n",
1644 + (unsigned long int) max_bucket_length);
1645 +}
1646 +
1647 +/* Hash KEY and return a pointer to the selected bucket.
1648 + If TABLE->hasher misbehaves, abort. */
1649 +static struct hash_entry *
1650 +safe_hasher (const Hash_table *table, const void *key)
1651 +{
1652 + size_t n = table->hasher (key, table->n_buckets);
1653 + if (! (n < table->n_buckets))
1654 + abort ();
1655 + return table->bucket + n;
1656 +}
1657 +
1658 +/* If ENTRY matches an entry already in the hash table, return the
1659 + entry from the table. Otherwise, return NULL. */
1660 +
1661 +void *
1662 +hash_lookup (const Hash_table *table, const void *entry)
1663 +{
1664 + struct hash_entry const *bucket = safe_hasher (table, entry);
1665 + struct hash_entry const *cursor;
1666 +
1667 + if (bucket->data == NULL)
1668 + return NULL;
1669 +
1670 + for (cursor = bucket; cursor; cursor = cursor->next)
1671 + if (entry == cursor->data || table->comparator (entry, cursor->data))
1672 + return cursor->data;
1673 +
1674 + return NULL;
1675 +}
1676 +
1677 +/* Walking. */
1678 +
1679 +/* The functions in this page traverse the hash table and process the
1680 + contained entries. For the traversal to work properly, the hash table
1681 + should not be resized nor modified while any particular entry is being
1682 + processed. In particular, entries should not be added, and an entry
1683 + may be removed only if there is no shrink threshold and the entry being
1684 + removed has already been passed to hash_get_next. */
1685 +
1686 +/* Return the first data in the table, or NULL if the table is empty. */
1687 +
1688 +void *
1689 +hash_get_first (const Hash_table *table)
1690 +{
1691 + struct hash_entry const *bucket;
1692 +
1693 + if (table->n_entries == 0)
1694 + return NULL;
1695 +
1696 + for (bucket = table->bucket; ; bucket++)
1697 + if (! (bucket < table->bucket_limit))
1698 + abort ();
1699 + else if (bucket->data)
1700 + return bucket->data;
1701 +}
1702 +
1703 +/* Return the user data for the entry following ENTRY, where ENTRY has been
1704 + returned by a previous call to either 'hash_get_first' or 'hash_get_next'.
1705 + Return NULL if there are no more entries. */
1706 +
1707 +void *
1708 +hash_get_next (const Hash_table *table, const void *entry)
1709 +{
1710 + struct hash_entry const *bucket = safe_hasher (table, entry);
1711 + struct hash_entry const *cursor;
1712 +
1713 + /* Find next entry in the same bucket. */
1714 + cursor = bucket;
1715 + do
1716 + {
1717 + if (cursor->data == entry && cursor->next)
1718 + return cursor->next->data;
1719 + cursor = cursor->next;
1720 + }
1721 + while (cursor != NULL);
1722 +
1723 + /* Find first entry in any subsequent bucket. */
1724 + while (++bucket < table->bucket_limit)
1725 + if (bucket->data)
1726 + return bucket->data;
1727 +
1728 + /* None found. */
1729 + return NULL;
1730 +}
1731 +
1732 +/* Fill BUFFER with pointers to active user entries in the hash table, then
1733 + return the number of pointers copied. Do not copy more than BUFFER_SIZE
1734 + pointers. */
1735 +
1736 +size_t
1737 +hash_get_entries (const Hash_table *table, void **buffer,
1738 + size_t buffer_size)
1739 +{
1740 + size_t counter = 0;
1741 + struct hash_entry const *bucket;
1742 + struct hash_entry const *cursor;
1743 +
1744 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
1745 + {
1746 + if (bucket->data)
1747 + {
1748 + for (cursor = bucket; cursor; cursor = cursor->next)
1749 + {
1750 + if (counter >= buffer_size)
1751 + return counter;
1752 + buffer[counter++] = cursor->data;
1753 + }
1754 + }
1755 + }
1756 +
1757 + return counter;
1758 +}
1759 +
1760 +/* Call a PROCESSOR function for each entry of a hash table, and return the
1761 + number of entries for which the processor function returned success. A
1762 + pointer to some PROCESSOR_DATA which will be made available to each call to
1763 + the processor function. The PROCESSOR accepts two arguments: the first is
1764 + the user entry being walked into, the second is the value of PROCESSOR_DATA
1765 + as received. The walking continue for as long as the PROCESSOR function
1766 + returns nonzero. When it returns zero, the walking is interrupted. */
1767 +
1768 +size_t
1769 +hash_do_for_each (const Hash_table *table, Hash_processor processor,
1770 + void *processor_data)
1771 +{
1772 + size_t counter = 0;
1773 + struct hash_entry const *bucket;
1774 + struct hash_entry const *cursor;
1775 +
1776 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
1777 + {
1778 + if (bucket->data)
1779 + {
1780 + for (cursor = bucket; cursor; cursor = cursor->next)
1781 + {
1782 + if (! processor (cursor->data, processor_data))
1783 + return counter;
1784 + counter++;
1785 + }
1786 + }
1787 + }
1788 +
1789 + return counter;
1790 +}
1791 +
1792 +/* Allocation and clean-up. */
1793 +
1794 +/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
1795 + This is a convenience routine for constructing other hashing functions. */
1796 +
1797 +#if USE_DIFF_HASH
1798 +
1799 +/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
1800 + B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
1801 + Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
1802 + algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
1803 + may not be good for your application." */
1804 +
1805 +size_t
1806 +hash_string (const char *string, size_t n_buckets)
1807 +{
1808 +# define HASH_ONE_CHAR(Value, Byte) \
1809 + ((Byte) + rotl_sz (Value, 7))
1810 +
1811 + size_t value = 0;
1812 + unsigned char ch;
1813 +
1814 + for (; (ch = *string); string++)
1815 + value = HASH_ONE_CHAR (value, ch);
1816 + return value % n_buckets;
1817 +
1818 +# undef HASH_ONE_CHAR
1819 +}
1820 +
1821 +#else /* not USE_DIFF_HASH */
1822 +
1823 +/* This one comes from 'recode', and performs a bit better than the above as
1824 + per a few experiments. It is inspired from a hashing routine found in the
1825 + very old Cyber 'snoop', itself written in typical Greg Mansfield style.
1826 + (By the way, what happened to this excellent man? Is he still alive?) */
1827 +
1828 +size_t
1829 +hash_string (const char *string, size_t n_buckets)
1830 +{
1831 + size_t value = 0;
1832 + unsigned char ch;
1833 +
1834 + for (; (ch = *string); string++)
1835 + value = (value * 31 + ch) % n_buckets;
1836 + return value;
1837 +}
1838 +
1839 +#endif /* not USE_DIFF_HASH */
1840 +
1841 +/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
1842 + number at least equal to 11. */
1843 +
1844 +static bool _GL_ATTRIBUTE_CONST
1845 +is_prime (size_t candidate)
1846 +{
1847 + size_t divisor = 3;
1848 + size_t square = divisor * divisor;
1849 +
1850 + while (square < candidate && (candidate % divisor))
1851 + {
1852 + divisor++;
1853 + square += 4 * divisor;
1854 + divisor++;
1855 + }
1856 +
1857 + return (candidate % divisor ? true : false);
1858 +}
1859 +
1860 +/* Round a given CANDIDATE number up to the nearest prime, and return that
1861 + prime. Primes lower than 10 are merely skipped. */
1862 +
1863 +static size_t _GL_ATTRIBUTE_CONST
1864 +next_prime (size_t candidate)
1865 +{
1866 + /* Skip small primes. */
1867 + if (candidate < 10)
1868 + candidate = 10;
1869 +
1870 + /* Make it definitely odd. */
1871 + candidate |= 1;
1872 +
1873 + while (SIZE_MAX != candidate && !is_prime (candidate))
1874 + candidate += 2;
1875 +
1876 + return candidate;
1877 +}
1878 +
1879 +void
1880 +hash_reset_tuning (Hash_tuning *tuning)
1881 +{
1882 + *tuning = default_tuning;
1883 +}
1884 +
1885 +/* If the user passes a NULL hasher, we hash the raw pointer. */
1886 +static size_t
1887 +raw_hasher (const void *data, size_t n)
1888 +{
1889 + /* When hashing unique pointers, it is often the case that they were
1890 + generated by malloc and thus have the property that the low-order
1891 + bits are 0. As this tends to give poorer performance with small
1892 + tables, we rotate the pointer value before performing division,
1893 + in an attempt to improve hash quality. */
1894 + size_t val = rotr_sz ((size_t) data, 3);
1895 + return val % n;
1896 +}
1897 +
1898 +/* If the user passes a NULL comparator, we use pointer comparison. */
1899 +static bool
1900 +raw_comparator (const void *a, const void *b)
1901 +{
1902 + return a == b;
1903 +}
1904 +
1905 +
1906 +/* For the given hash TABLE, check the user supplied tuning structure for
1907 + reasonable values, and return true if there is no gross error with it.
1908 + Otherwise, definitively reset the TUNING field to some acceptable default
1909 + in the hash table (that is, the user loses the right of further modifying
1910 + tuning arguments), and return false. */
1911 +
1912 +static bool
1913 +check_tuning (Hash_table *table)
1914 +{
1915 + const Hash_tuning *tuning = table->tuning;
1916 + float epsilon;
1917 + if (tuning == &default_tuning)
1918 + return true;
1919 +
1920 + /* Be a bit stricter than mathematics would require, so that
1921 + rounding errors in size calculations do not cause allocations to
1922 + fail to grow or shrink as they should. The smallest allocation
1923 + is 11 (due to next_prime's algorithm), so an epsilon of 0.1
1924 + should be good enough. */
1925 + epsilon = 0.1f;
1926 +
1927 + if (epsilon < tuning->growth_threshold
1928 + && tuning->growth_threshold < 1 - epsilon
1929 + && 1 + epsilon < tuning->growth_factor
1930 + && 0 <= tuning->shrink_threshold
1931 + && tuning->shrink_threshold + epsilon < tuning->shrink_factor
1932 + && tuning->shrink_factor <= 1
1933 + && tuning->shrink_threshold + epsilon < tuning->growth_threshold)
1934 + return true;
1935 +
1936 + table->tuning = &default_tuning;
1937 + return false;
1938 +}
1939 +
1940 +/* Compute the size of the bucket array for the given CANDIDATE and
1941 + TUNING, or return 0 if there is no possible way to allocate that
1942 + many entries. */
1943 +
1944 +static size_t _GL_ATTRIBUTE_PURE
1945 +compute_bucket_size (size_t candidate, const Hash_tuning *tuning)
1946 +{
1947 + if (!tuning->is_n_buckets)
1948 + {
1949 + float new_candidate = candidate / tuning->growth_threshold;
1950 + if (SIZE_MAX <= new_candidate)
1951 + return 0;
1952 + candidate = new_candidate;
1953 + }
1954 + candidate = next_prime (candidate);
1955 + if (xalloc_oversized (candidate, sizeof (struct hash_entry *)))
1956 + return 0;
1957 + return candidate;
1958 +}
1959 +
1960 +/* Allocate and return a new hash table, or NULL upon failure. The initial
1961 + number of buckets is automatically selected so as to _guarantee_ that you
1962 + may insert at least CANDIDATE different user entries before any growth of
1963 + the hash table size occurs. So, if have a reasonably tight a-priori upper
1964 + bound on the number of entries you intend to insert in the hash table, you
1965 + may save some table memory and insertion time, by specifying it here. If
1966 + the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE
1967 + argument has its meaning changed to the wanted number of buckets.
1968 +
1969 + TUNING points to a structure of user-supplied values, in case some fine
1970 + tuning is wanted over the default behavior of the hasher. If TUNING is
1971 + NULL, the default tuning parameters are used instead. If TUNING is
1972 + provided but the values requested are out of bounds or might cause
1973 + rounding errors, return NULL.
1974 +
1975 + The user-supplied HASHER function, when not NULL, accepts two
1976 + arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a
1977 + slot number for that entry which should be in the range 0..TABLE_SIZE-1.
1978 + This slot number is then returned.
1979 +
1980 + The user-supplied COMPARATOR function, when not NULL, accepts two
1981 + arguments pointing to user data, it then returns true for a pair of entries
1982 + that compare equal, or false otherwise. This function is internally called
1983 + on entries which are already known to hash to the same bucket index,
1984 + but which are distinct pointers.
1985 +
1986 + The user-supplied DATA_FREER function, when not NULL, may be later called
1987 + with the user data as an argument, just before the entry containing the
1988 + data gets freed. This happens from within 'hash_free' or 'hash_clear'.
1989 + You should specify this function only if you want these functions to free
1990 + all of your 'data' data. This is typically the case when your data is
1991 + simply an auxiliary struct that you have malloc'd to aggregate several
1992 + values. */
1993 +
1994 +Hash_table *
1995 +hash_initialize (size_t candidate, const Hash_tuning *tuning,
1996 + Hash_hasher hasher, Hash_comparator comparator,
1997 + Hash_data_freer data_freer)
1998 +{
1999 + Hash_table *table;
2000 +
2001 + if (hasher == NULL)
2002 + hasher = raw_hasher;
2003 + if (comparator == NULL)
2004 + comparator = raw_comparator;
2005 +
2006 + table = malloc (sizeof *table);
2007 + if (table == NULL)
2008 + return NULL;
2009 +
2010 + if (!tuning)
2011 + tuning = &default_tuning;
2012 + table->tuning = tuning;
2013 + if (!check_tuning (table))
2014 + {
2015 + /* Fail if the tuning options are invalid. This is the only occasion
2016 + when the user gets some feedback about it. Once the table is created,
2017 + if the user provides invalid tuning options, we silently revert to
2018 + using the defaults, and ignore further request to change the tuning
2019 + options. */
2020 + goto fail;
2021 + }
2022 +
2023 + table->n_buckets = compute_bucket_size (candidate, tuning);
2024 + if (!table->n_buckets)
2025 + goto fail;
2026 +
2027 + table->bucket = calloc (table->n_buckets, sizeof *table->bucket);
2028 + if (table->bucket == NULL)
2029 + goto fail;
2030 + table->bucket_limit = table->bucket + table->n_buckets;
2031 + table->n_buckets_used = 0;
2032 + table->n_entries = 0;
2033 +
2034 + table->hasher = hasher;
2035 + table->comparator = comparator;
2036 + table->data_freer = data_freer;
2037 +
2038 + table->free_entry_list = NULL;
2039 +#if USE_OBSTACK
2040 + obstack_init (&table->entry_stack);
2041 +#endif
2042 + return table;
2043 +
2044 + fail:
2045 + free (table);
2046 + return NULL;
2047 +}
2048 +
2049 +/* Make all buckets empty, placing any chained entries on the free list.
2050 + Apply the user-specified function data_freer (if any) to the datas of any
2051 + affected entries. */
2052 +
2053 +void
2054 +hash_clear (Hash_table *table)
2055 +{
2056 + struct hash_entry *bucket;
2057 +
2058 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
2059 + {
2060 + if (bucket->data)
2061 + {
2062 + struct hash_entry *cursor;
2063 + struct hash_entry *next;
2064 +
2065 + /* Free the bucket overflow. */
2066 + for (cursor = bucket->next; cursor; cursor = next)
2067 + {
2068 + if (table->data_freer)
2069 + table->data_freer (cursor->data);
2070 + cursor->data = NULL;
2071 +
2072 + next = cursor->next;
2073 + /* Relinking is done one entry at a time, as it is to be expected
2074 + that overflows are either rare or short. */
2075 + cursor->next = table->free_entry_list;
2076 + table->free_entry_list = cursor;
2077 + }
2078 +
2079 + /* Free the bucket head. */
2080 + if (table->data_freer)
2081 + table->data_freer (bucket->data);
2082 + bucket->data = NULL;
2083 + bucket->next = NULL;
2084 + }
2085 + }
2086 +
2087 + table->n_buckets_used = 0;
2088 + table->n_entries = 0;
2089 +}
2090 +
2091 +/* Reclaim all storage associated with a hash table. If a data_freer
2092 + function has been supplied by the user when the hash table was created,
2093 + this function applies it to the data of each entry before freeing that
2094 + entry. */
2095 +
2096 +void
2097 +hash_free (Hash_table *table)
2098 +{
2099 + struct hash_entry *bucket;
2100 + struct hash_entry *cursor;
2101 + struct hash_entry *next;
2102 +
2103 + /* Call the user data_freer function. */
2104 + if (table->data_freer && table->n_entries)
2105 + {
2106 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
2107 + {
2108 + if (bucket->data)
2109 + {
2110 + for (cursor = bucket; cursor; cursor = cursor->next)
2111 + table->data_freer (cursor->data);
2112 + }
2113 + }
2114 + }
2115 +
2116 +#if USE_OBSTACK
2117 +
2118 + obstack_free (&table->entry_stack, NULL);
2119 +
2120 +#else
2121 +
2122 + /* Free all bucket overflowed entries. */
2123 + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++)
2124 + {
2125 + for (cursor = bucket->next; cursor; cursor = next)
2126 + {
2127 + next = cursor->next;
2128 + free (cursor);
2129 + }
2130 + }
2131 +
2132 + /* Also reclaim the internal list of previously freed entries. */
2133 + for (cursor = table->free_entry_list; cursor; cursor = next)
2134 + {
2135 + next = cursor->next;
2136 + free (cursor);
2137 + }
2138 +
2139 +#endif
2140 +
2141 + /* Free the remainder of the hash table structure. */
2142 + free (table->bucket);
2143 + free (table);
2144 +}
2145 +
2146 +/* Insertion and deletion. */
2147 +
2148 +/* Get a new hash entry for a bucket overflow, possibly by recycling a
2149 + previously freed one. If this is not possible, allocate a new one. */
2150 +
2151 +static struct hash_entry *
2152 +allocate_entry (Hash_table *table)
2153 +{
2154 + struct hash_entry *new;
2155 +
2156 + if (table->free_entry_list)
2157 + {
2158 + new = table->free_entry_list;
2159 + table->free_entry_list = new->next;
2160 + }
2161 + else
2162 + {
2163 +#if USE_OBSTACK
2164 + new = obstack_alloc (&table->entry_stack, sizeof *new);
2165 +#else
2166 + new = malloc (sizeof *new);
2167 +#endif
2168 + }
2169 +
2170 + return new;
2171 +}
2172 +
2173 +/* Free a hash entry which was part of some bucket overflow,
2174 + saving it for later recycling. */
2175 +
2176 +static void
2177 +free_entry (Hash_table *table, struct hash_entry *entry)
2178 +{
2179 + entry->data = NULL;
2180 + entry->next = table->free_entry_list;
2181 + table->free_entry_list = entry;
2182 +}
2183 +
2184 +/* This private function is used to help with insertion and deletion. When
2185 + ENTRY matches an entry in the table, return a pointer to the corresponding
2186 + user data and set *BUCKET_HEAD to the head of the selected bucket.
2187 + Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in
2188 + the table, unlink the matching entry. */
2189 +
2190 +static void *
2191 +hash_find_entry (Hash_table *table, const void *entry,
2192 + struct hash_entry **bucket_head, bool delete)
2193 +{
2194 + struct hash_entry *bucket = safe_hasher (table, entry);
2195 + struct hash_entry *cursor;
2196 +
2197 + *bucket_head = bucket;
2198 +
2199 + /* Test for empty bucket. */
2200 + if (bucket->data == NULL)
2201 + return NULL;
2202 +
2203 + /* See if the entry is the first in the bucket. */
2204 + if (entry == bucket->data || table->comparator (entry, bucket->data))
2205 + {
2206 + void *data = bucket->data;
2207 +
2208 + if (delete)
2209 + {
2210 + if (bucket->next)
2211 + {
2212 + struct hash_entry *next = bucket->next;
2213 +
2214 + /* Bump the first overflow entry into the bucket head, then save
2215 + the previous first overflow entry for later recycling. */
2216 + *bucket = *next;
2217 + free_entry (table, next);
2218 + }
2219 + else
2220 + {
2221 + bucket->data = NULL;
2222 + }
2223 + }
2224 +
2225 + return data;
2226 + }
2227 +
2228 + /* Scan the bucket overflow. */
2229 + for (cursor = bucket; cursor->next; cursor = cursor->next)
2230 + {
2231 + if (entry == cursor->next->data
2232 + || table->comparator (entry, cursor->next->data))
2233 + {
2234 + void *data = cursor->next->data;
2235 +
2236 + if (delete)
2237 + {
2238 + struct hash_entry *next = cursor->next;
2239 +
2240 + /* Unlink the entry to delete, then save the freed entry for later
2241 + recycling. */
2242 + cursor->next = next->next;
2243 + free_entry (table, next);
2244 + }
2245 +
2246 + return data;
2247 + }
2248 + }
2249 +
2250 + /* No entry found. */
2251 + return NULL;
2252 +}
2253 +
2254 +/* Internal helper, to move entries from SRC to DST. Both tables must
2255 + share the same free entry list. If SAFE, only move overflow
2256 + entries, saving bucket heads for later, so that no allocations will
2257 + occur. Return false if the free entry list is exhausted and an
2258 + allocation fails. */
2259 +
2260 +static bool
2261 +transfer_entries (Hash_table *dst, Hash_table *src, bool safe)
2262 +{
2263 + struct hash_entry *bucket;
2264 + struct hash_entry *cursor;
2265 + struct hash_entry *next;
2266 + for (bucket = src->bucket; bucket < src->bucket_limit; bucket++)
2267 + if (bucket->data)
2268 + {
2269 + void *data;
2270 + struct hash_entry *new_bucket;
2271 +
2272 + /* Within each bucket, transfer overflow entries first and
2273 + then the bucket head, to minimize memory pressure. After
2274 + all, the only time we might allocate is when moving the
2275 + bucket head, but moving overflow entries first may create
2276 + free entries that can be recycled by the time we finally
2277 + get to the bucket head. */
2278 + for (cursor = bucket->next; cursor; cursor = next)
2279 + {
2280 + data = cursor->data;
2281 + new_bucket = safe_hasher (dst, data);
2282 +
2283 + next = cursor->next;
2284 +
2285 + if (new_bucket->data)
2286 + {
2287 + /* Merely relink an existing entry, when moving from a
2288 + bucket overflow into a bucket overflow. */
2289 + cursor->next = new_bucket->next;
2290 + new_bucket->next = cursor;
2291 + }
2292 + else
2293 + {
2294 + /* Free an existing entry, when moving from a bucket
2295 + overflow into a bucket header. */
2296 + new_bucket->data = data;
2297 + dst->n_buckets_used++;
2298 + free_entry (dst, cursor);
2299 + }
2300 + }
2301 + /* Now move the bucket head. Be sure that if we fail due to
2302 + allocation failure that the src table is in a consistent
2303 + state. */
2304 + data = bucket->data;
2305 + bucket->next = NULL;
2306 + if (safe)
2307 + continue;
2308 + new_bucket = safe_hasher (dst, data);
2309 +
2310 + if (new_bucket->data)
2311 + {
2312 + /* Allocate or recycle an entry, when moving from a bucket
2313 + header into a bucket overflow. */
2314 + struct hash_entry *new_entry = allocate_entry (dst);
2315 +
2316 + if (new_entry == NULL)
2317 + return false;
2318 +
2319 + new_entry->data = data;
2320 + new_entry->next = new_bucket->next;
2321 + new_bucket->next = new_entry;
2322 + }
2323 + else
2324 + {
2325 + /* Move from one bucket header to another. */
2326 + new_bucket->data = data;
2327 + dst->n_buckets_used++;
2328 + }
2329 + bucket->data = NULL;
2330 + src->n_buckets_used--;
2331 + }
2332 + return true;
2333 +}
2334 +
2335 +/* For an already existing hash table, change the number of buckets through
2336 + specifying CANDIDATE. The contents of the hash table are preserved. The
2337 + new number of buckets is automatically selected so as to _guarantee_ that
2338 + the table may receive at least CANDIDATE different user entries, including
2339 + those already in the table, before any other growth of the hash table size
2340 + occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the
2341 + exact number of buckets desired. Return true iff the rehash succeeded. */
2342 +
2343 +bool
2344 +hash_rehash (Hash_table *table, size_t candidate)
2345 +{
2346 + Hash_table storage;
2347 + Hash_table *new_table;
2348 + size_t new_size = compute_bucket_size (candidate, table->tuning);
2349 +
2350 + if (!new_size)
2351 + return false;
2352 + if (new_size == table->n_buckets)
2353 + return true;
2354 + new_table = &storage;
2355 + new_table->bucket = calloc (new_size, sizeof *new_table->bucket);
2356 + if (new_table->bucket == NULL)
2357 + return false;
2358 + new_table->n_buckets = new_size;
2359 + new_table->bucket_limit = new_table->bucket + new_size;
2360 + new_table->n_buckets_used = 0;
2361 + new_table->n_entries = 0;
2362 + new_table->tuning = table->tuning;
2363 + new_table->hasher = table->hasher;
2364 + new_table->comparator = table->comparator;
2365 + new_table->data_freer = table->data_freer;
2366 +
2367 + /* In order for the transfer to successfully complete, we need
2368 + additional overflow entries when distinct buckets in the old
2369 + table collide into a common bucket in the new table. The worst
2370 + case possible is a hasher that gives a good spread with the old
2371 + size, but returns a constant with the new size; if we were to
2372 + guarantee table->n_buckets_used-1 free entries in advance, then
2373 + the transfer would be guaranteed to not allocate memory.
2374 + However, for large tables, a guarantee of no further allocation
2375 + introduces a lot of extra memory pressure, all for an unlikely
2376 + corner case (most rehashes reduce, rather than increase, the
2377 + number of overflow entries needed). So, we instead ensure that
2378 + the transfer process can be reversed if we hit a memory
2379 + allocation failure mid-transfer. */
2380 +
2381 + /* Merely reuse the extra old space into the new table. */
2382 +#if USE_OBSTACK
2383 + new_table->entry_stack = table->entry_stack;
2384 +#endif
2385 + new_table->free_entry_list = table->free_entry_list;
2386 +
2387 + if (transfer_entries (new_table, table, false))
2388 + {
2389 + /* Entries transferred successfully; tie up the loose ends. */
2390 + free (table->bucket);
2391 + table->bucket = new_table->bucket;
2392 + table->bucket_limit = new_table->bucket_limit;
2393 + table->n_buckets = new_table->n_buckets;
2394 + table->n_buckets_used = new_table->n_buckets_used;
2395 + table->free_entry_list = new_table->free_entry_list;
2396 + /* table->n_entries and table->entry_stack already hold their value. */
2397 + return true;
2398 + }
2399 +
2400 + /* We've allocated new_table->bucket (and possibly some entries),
2401 + exhausted the free list, and moved some but not all entries into
2402 + new_table. We must undo the partial move before returning
2403 + failure. The only way to get into this situation is if new_table
2404 + uses fewer buckets than the old table, so we will reclaim some
2405 + free entries as overflows in the new table are put back into
2406 + distinct buckets in the old table.
2407 +
2408 + There are some pathological cases where a single pass through the
2409 + table requires more intermediate overflow entries than using two
2410 + passes. Two passes give worse cache performance and takes
2411 + longer, but at this point, we're already out of memory, so slow
2412 + and safe is better than failure. */
2413 + table->free_entry_list = new_table->free_entry_list;
2414 + if (! (transfer_entries (table, new_table, true)
2415 + && transfer_entries (table, new_table, false)))
2416 + abort ();
2417 + /* table->n_entries already holds its value. */
2418 + free (new_table->bucket);
2419 + return false;
2420 +}
2421 +
2422 +/* Insert ENTRY into hash TABLE if there is not already a matching entry.
2423 +
2424 + Return -1 upon memory allocation failure.
2425 + Return 1 if insertion succeeded.
2426 + Return 0 if there is already a matching entry in the table,
2427 + and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT
2428 + to that entry.
2429 +
2430 + This interface is easier to use than hash_insert when you must
2431 + distinguish between the latter two cases. More importantly,
2432 + hash_insert is unusable for some types of ENTRY values. When using
2433 + hash_insert, the only way to distinguish those cases is to compare
2434 + the return value and ENTRY. That works only when you can have two
2435 + different ENTRY values that point to data that compares "equal". Thus,
2436 + when the ENTRY value is a simple scalar, you must use
2437 + hash_insert_if_absent. ENTRY must not be NULL. */
2438 +int
2439 +hash_insert_if_absent (Hash_table *table, void const *entry,
2440 + void const **matched_ent)
2441 +{
2442 + void *data;
2443 + struct hash_entry *bucket;
2444 +
2445 + /* The caller cannot insert a NULL entry, since hash_lookup returns NULL
2446 + to indicate "not found", and hash_find_entry uses "bucket->data == NULL"
2447 + to indicate an empty bucket. */
2448 + if (! entry)
2449 + abort ();
2450 +
2451 + /* If there's a matching entry already in the table, return that. */
2452 + if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL)
2453 + {
2454 + if (matched_ent)
2455 + *matched_ent = data;
2456 + return 0;
2457 + }
2458 +
2459 + /* If the growth threshold of the buckets in use has been reached, increase
2460 + the table size and rehash. There's no point in checking the number of
2461 + entries: if the hashing function is ill-conditioned, rehashing is not
2462 + likely to improve it. */
2463 +
2464 + if (table->n_buckets_used
2465 + > table->tuning->growth_threshold * table->n_buckets)
2466 + {
2467 + /* Check more fully, before starting real work. If tuning arguments
2468 + became invalid, the second check will rely on proper defaults. */
2469 + check_tuning (table);
2470 + if (table->n_buckets_used
2471 + > table->tuning->growth_threshold * table->n_buckets)
2472 + {
2473 + const Hash_tuning *tuning = table->tuning;
2474 + float candidate =
2475 + (tuning->is_n_buckets
2476 + ? (table->n_buckets * tuning->growth_factor)
2477 + : (table->n_buckets * tuning->growth_factor
2478 + * tuning->growth_threshold));
2479 +
2480 + if (SIZE_MAX <= candidate)
2481 + return -1;
2482 +
2483 + /* If the rehash fails, arrange to return NULL. */
2484 + if (!hash_rehash (table, candidate))
2485 + return -1;
2486 +
2487 + /* Update the bucket we are interested in. */
2488 + if (hash_find_entry (table, entry, &bucket, false) != NULL)
2489 + abort ();
2490 + }
2491 + }
2492 +
2493 + /* ENTRY is not matched, it should be inserted. */
2494 +
2495 + if (bucket->data)
2496 + {
2497 + struct hash_entry *new_entry = allocate_entry (table);
2498 +
2499 + if (new_entry == NULL)
2500 + return -1;
2501 +
2502 + /* Add ENTRY in the overflow of the bucket. */
2503 +
2504 + new_entry->data = (void *) entry;
2505 + new_entry->next = bucket->next;
2506 + bucket->next = new_entry;
2507 + table->n_entries++;
2508 + return 1;
2509 + }
2510 +
2511 + /* Add ENTRY right in the bucket head. */
2512 +
2513 + bucket->data = (void *) entry;
2514 + table->n_entries++;
2515 + table->n_buckets_used++;
2516 +
2517 + return 1;
2518 +}
2519 +
2520 +/* If ENTRY matches an entry already in the hash table, return the pointer
2521 + to the entry from the table. Otherwise, insert ENTRY and return ENTRY.
2522 + Return NULL if the storage required for insertion cannot be allocated.
2523 + This implementation does not support duplicate entries or insertion of
2524 + NULL. */
2525 +
2526 +void *
2527 +hash_insert (Hash_table *table, void const *entry)
2528 +{
2529 + void const *matched_ent;
2530 + int err = hash_insert_if_absent (table, entry, &matched_ent);
2531 + return (err == -1
2532 + ? NULL
2533 + : (void *) (err == 0 ? matched_ent : entry));
2534 +}
2535 +
2536 +/* If ENTRY is already in the table, remove it and return the just-deleted
2537 + data (the user may want to deallocate its storage). If ENTRY is not in the
2538 + table, don't modify the table and return NULL. */
2539 +
2540 +void *
2541 +hash_delete (Hash_table *table, const void *entry)
2542 +{
2543 + void *data;
2544 + struct hash_entry *bucket;
2545 +
2546 + data = hash_find_entry (table, entry, &bucket, true);
2547 + if (!data)
2548 + return NULL;
2549 +
2550 + table->n_entries--;
2551 + if (!bucket->data)
2552 + {
2553 + table->n_buckets_used--;
2554 +
2555 + /* If the shrink threshold of the buckets in use has been reached,
2556 + rehash into a smaller table. */
2557 +
2558 + if (table->n_buckets_used
2559 + < table->tuning->shrink_threshold * table->n_buckets)
2560 + {
2561 + /* Check more fully, before starting real work. If tuning arguments
2562 + became invalid, the second check will rely on proper defaults. */
2563 + check_tuning (table);
2564 + if (table->n_buckets_used
2565 + < table->tuning->shrink_threshold * table->n_buckets)
2566 + {
2567 + const Hash_tuning *tuning = table->tuning;
2568 + size_t candidate =
2569 + (tuning->is_n_buckets
2570 + ? table->n_buckets * tuning->shrink_factor
2571 + : (table->n_buckets * tuning->shrink_factor
2572 + * tuning->growth_threshold));
2573 +
2574 + if (!hash_rehash (table, candidate))
2575 + {
2576 + /* Failure to allocate memory in an attempt to
2577 + shrink the table is not fatal. But since memory
2578 + is low, we can at least be kind and free any
2579 + spare entries, rather than keeping them tied up
2580 + in the free entry list. */
2581 +#if ! USE_OBSTACK
2582 + struct hash_entry *cursor = table->free_entry_list;
2583 + struct hash_entry *next;
2584 + while (cursor)
2585 + {
2586 + next = cursor->next;
2587 + free (cursor);
2588 + cursor = next;
2589 + }
2590 + table->free_entry_list = NULL;
2591 +#endif
2592 + }
2593 + }
2594 + }
2595 + }
2596 +
2597 + return data;
2598 +}
2599 +
2600 +/* Testing. */
2601 +
2602 +#if TESTING
2603 +
2604 +void
2605 +hash_print (const Hash_table *table)
2606 +{
2607 + struct hash_entry *bucket = (struct hash_entry *) table->bucket;
2608 +
2609 + for ( ; bucket < table->bucket_limit; bucket++)
2610 + {
2611 + struct hash_entry *cursor;
2612 +
2613 + if (bucket)
2614 + printf ("%lu:\n", (unsigned long int) (bucket - table->bucket));
2615 +
2616 + for (cursor = bucket; cursor; cursor = cursor->next)
2617 + {
2618 + char const *s = cursor->data;
2619 + /* FIXME */
2620 + if (s)
2621 + printf (" %s\n", s);
2622 + }
2623 + }
2624 +}
2625 +
2626 +#endif /* TESTING */
2627
2628 diff --git a/libsbutil/gnulib/hash.h b/libsbutil/gnulib/hash.h
2629 new file mode 100644
2630 index 0000000..1e90c31
2631 --- /dev/null
2632 +++ b/libsbutil/gnulib/hash.h
2633 @@ -0,0 +1,103 @@
2634 +/* hash - hashing table processing.
2635 + Copyright (C) 1998-1999, 2001, 2003, 2009-2015 Free Software Foundation,
2636 + Inc.
2637 + Written by Jim Meyering <meyering@××××××.com>, 1998.
2638 +
2639 + This program is free software: you can redistribute it and/or modify
2640 + it under the terms of the GNU General Public License as published by
2641 + the Free Software Foundation; either version 3 of the License, or
2642 + (at your option) any later version.
2643 +
2644 + This program is distributed in the hope that it will be useful,
2645 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2646 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2647 + GNU General Public License for more details.
2648 +
2649 + You should have received a copy of the GNU General Public License
2650 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
2651 +
2652 +/* A generic hash table package. */
2653 +
2654 +/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
2655 + obstacks instead of malloc, and recompile 'hash.c' with same setting. */
2656 +
2657 +#ifndef HASH_H_
2658 +# define HASH_H_
2659 +
2660 +# include <stdio.h>
2661 +# include <stdbool.h>
2662 +
2663 +/* The __attribute__ feature is available in gcc versions 2.5 and later.
2664 + The warn_unused_result attribute appeared first in gcc-3.4.0. */
2665 +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
2666 +# define _GL_ATTRIBUTE_WUR __attribute__ ((__warn_unused_result__))
2667 +# else
2668 +# define _GL_ATTRIBUTE_WUR /* empty */
2669 +# endif
2670 +
2671 +# ifndef _GL_ATTRIBUTE_DEPRECATED
2672 +/* The __attribute__((__deprecated__)) feature
2673 + is available in gcc versions 3.1 and newer. */
2674 +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 1)
2675 +# define _GL_ATTRIBUTE_DEPRECATED /* empty */
2676 +# else
2677 +# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))
2678 +# endif
2679 +# endif
2680 +
2681 +typedef size_t (*Hash_hasher) (const void *, size_t);
2682 +typedef bool (*Hash_comparator) (const void *, const void *);
2683 +typedef void (*Hash_data_freer) (void *);
2684 +typedef bool (*Hash_processor) (void *, void *);
2685 +
2686 +struct hash_tuning
2687 + {
2688 + /* This structure is mainly used for 'hash_initialize', see the block
2689 + documentation of 'hash_reset_tuning' for more complete comments. */
2690 +
2691 + float shrink_threshold; /* ratio of used buckets to trigger a shrink */
2692 + float shrink_factor; /* ratio of new smaller size to original size */
2693 + float growth_threshold; /* ratio of used buckets to trigger a growth */
2694 + float growth_factor; /* ratio of new bigger size to original size */
2695 + bool is_n_buckets; /* if CANDIDATE really means table size */
2696 + };
2697 +
2698 +typedef struct hash_tuning Hash_tuning;
2699 +
2700 +struct hash_table;
2701 +
2702 +typedef struct hash_table Hash_table;
2703 +
2704 +/* Information and lookup. */
2705 +size_t hash_get_n_buckets (const Hash_table *) _GL_ATTRIBUTE_PURE;
2706 +size_t hash_get_n_buckets_used (const Hash_table *) _GL_ATTRIBUTE_PURE;
2707 +size_t hash_get_n_entries (const Hash_table *) _GL_ATTRIBUTE_PURE;
2708 +size_t hash_get_max_bucket_length (const Hash_table *) _GL_ATTRIBUTE_PURE;
2709 +bool hash_table_ok (const Hash_table *) _GL_ATTRIBUTE_PURE;
2710 +void hash_print_statistics (const Hash_table *, FILE *);
2711 +void *hash_lookup (const Hash_table *, const void *);
2712 +
2713 +/* Walking. */
2714 +void *hash_get_first (const Hash_table *) _GL_ATTRIBUTE_PURE;
2715 +void *hash_get_next (const Hash_table *, const void *);
2716 +size_t hash_get_entries (const Hash_table *, void **, size_t);
2717 +size_t hash_do_for_each (const Hash_table *, Hash_processor, void *);
2718 +
2719 +/* Allocation and clean-up. */
2720 +size_t hash_string (const char *, size_t) _GL_ATTRIBUTE_PURE;
2721 +void hash_reset_tuning (Hash_tuning *);
2722 +Hash_table *hash_initialize (size_t, const Hash_tuning *,
2723 + Hash_hasher, Hash_comparator,
2724 + Hash_data_freer) _GL_ATTRIBUTE_WUR;
2725 +void hash_clear (Hash_table *);
2726 +void hash_free (Hash_table *);
2727 +
2728 +/* Insertion and deletion. */
2729 +bool hash_rehash (Hash_table *, size_t) _GL_ATTRIBUTE_WUR;
2730 +void *hash_insert (Hash_table *, const void *) _GL_ATTRIBUTE_WUR;
2731 +
2732 +int hash_insert_if_absent (Hash_table *table, const void *entry,
2733 + const void **matched_ent);
2734 +void *hash_delete (Hash_table *, const void *);
2735 +
2736 +#endif
2737
2738 diff --git a/libsbutil/gnulib/pathmax.h b/libsbutil/gnulib/pathmax.h
2739 new file mode 100644
2740 index 0000000..2a5af08
2741 --- /dev/null
2742 +++ b/libsbutil/gnulib/pathmax.h
2743 @@ -0,0 +1,83 @@
2744 +/* Define PATH_MAX somehow. Requires sys/types.h.
2745 + Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2015 Free Software
2746 + Foundation, Inc.
2747 +
2748 + This program is free software; you can redistribute it and/or modify
2749 + it under the terms of the GNU General Public License as published by
2750 + the Free Software Foundation; either version 2, or (at your option)
2751 + any later version.
2752 +
2753 + This program is distributed in the hope that it will be useful,
2754 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2755 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2756 + GNU General Public License for more details.
2757 +
2758 + You should have received a copy of the GNU General Public License
2759 + along with this program; if not, see <http://www.gnu.org/licenses/>. */
2760 +
2761 +#ifndef _PATHMAX_H
2762 +# define _PATHMAX_H
2763 +
2764 +/* POSIX:2008 defines PATH_MAX to be the maximum number of bytes in a filename,
2765 + including the terminating NUL byte.
2766 + <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html>
2767 + PATH_MAX is not defined on systems which have no limit on filename length,
2768 + such as GNU/Hurd.
2769 +
2770 + This file does *not* define PATH_MAX always. Programs that use this file
2771 + can handle the GNU/Hurd case in several ways:
2772 + - Either with a package-wide handling, or with a per-file handling,
2773 + - Either through a
2774 + #ifdef PATH_MAX
2775 + or through a fallback like
2776 + #ifndef PATH_MAX
2777 + # define PATH_MAX 8192
2778 + #endif
2779 + or through a fallback like
2780 + #ifndef PATH_MAX
2781 + # define PATH_MAX pathconf ("/", _PC_PATH_MAX)
2782 + #endif
2783 + */
2784 +
2785 +# include <unistd.h>
2786 +
2787 +# include <limits.h>
2788 +
2789 +# ifndef _POSIX_PATH_MAX
2790 +# define _POSIX_PATH_MAX 256
2791 +# endif
2792 +
2793 +/* Don't include sys/param.h if it already has been. */
2794 +# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
2795 +# include <sys/param.h>
2796 +# endif
2797 +
2798 +# if !defined PATH_MAX && defined MAXPATHLEN
2799 +# define PATH_MAX MAXPATHLEN
2800 +# endif
2801 +
2802 +# ifdef __hpux
2803 +/* On HP-UX, PATH_MAX designates the maximum number of bytes in a filename,
2804 + *not* including the terminating NUL byte, and is set to 1023.
2805 + Additionally, when _XOPEN_SOURCE is defined to 500 or more, PATH_MAX is
2806 + not defined at all any more. */
2807 +# undef PATH_MAX
2808 +# define PATH_MAX 1024
2809 +# endif
2810 +
2811 +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
2812 +/* The page "Naming Files, Paths, and Namespaces" on msdn.microsoft.com,
2813 + section "Maximum Path Length Limitation",
2814 + <http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx#maxpath>
2815 + explains that the maximum size of a filename, including the terminating
2816 + NUL byte, is 260 = 3 + 256 + 1.
2817 + This is the same value as
2818 + - FILENAME_MAX in <stdio.h>,
2819 + - _MAX_PATH in <stdlib.h>,
2820 + - MAX_PATH in <windef.h>.
2821 + Undefine the original value, because mingw's <limits.h> gets it wrong. */
2822 +# undef PATH_MAX
2823 +# define PATH_MAX 260
2824 +# endif
2825 +
2826 +#endif /* _PATHMAX_H */
2827
2828 diff --git a/libsbutil/gnulib/same-inode.h b/libsbutil/gnulib/same-inode.h
2829 new file mode 100644
2830 index 0000000..ecc3049
2831 --- /dev/null
2832 +++ b/libsbutil/gnulib/same-inode.h
2833 @@ -0,0 +1,33 @@
2834 +/* Determine whether two stat buffers refer to the same file.
2835 +
2836 + Copyright (C) 2006, 2009-2015 Free Software Foundation, Inc.
2837 +
2838 + This program is free software: you can redistribute it and/or modify
2839 + it under the terms of the GNU General Public License as published by
2840 + the Free Software Foundation; either version 3 of the License, or
2841 + (at your option) any later version.
2842 +
2843 + This program is distributed in the hope that it will be useful,
2844 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2845 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2846 + GNU General Public License for more details.
2847 +
2848 + You should have received a copy of the GNU General Public License
2849 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
2850 +
2851 +#ifndef SAME_INODE_H
2852 +# define SAME_INODE_H 1
2853 +
2854 +# ifdef __VMS
2855 +# define SAME_INODE(a, b) \
2856 + ((a).st_ino[0] == (b).st_ino[0] \
2857 + && (a).st_ino[1] == (b).st_ino[1] \
2858 + && (a).st_ino[2] == (b).st_ino[2] \
2859 + && (a).st_dev == (b).st_dev)
2860 +# else
2861 +# define SAME_INODE(a, b) \
2862 + ((a).st_ino == (b).st_ino \
2863 + && (a).st_dev == (b).st_dev)
2864 +# endif
2865 +
2866 +#endif
2867
2868 diff --git a/libsbutil/gnulib/same.h b/libsbutil/gnulib/same.h
2869 new file mode 100644
2870 index 0000000..ee313c5
2871 --- /dev/null
2872 +++ b/libsbutil/gnulib/same.h
2873 @@ -0,0 +1,25 @@
2874 +/* Determine whether two file names refer to the same file.
2875 +
2876 + Copyright (C) 1997-2000, 2003-2004, 2009-2015 Free Software Foundation, Inc.
2877 +
2878 + This program is free software: you can redistribute it and/or modify
2879 + it under the terms of the GNU General Public License as published by
2880 + the Free Software Foundation; either version 3 of the License, or
2881 + (at your option) any later version.
2882 +
2883 + This program is distributed in the hope that it will be useful,
2884 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2885 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2886 + GNU General Public License for more details.
2887 +
2888 + You should have received a copy of the GNU General Public License
2889 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
2890 +
2891 +#ifndef SAME_H_
2892 +# define SAME_H_ 1
2893 +
2894 +# include <stdbool.h>
2895 +
2896 +bool same_name (const char *source, const char *dest);
2897 +
2898 +#endif /* SAME_H_ */
2899
2900 diff --git a/libsbutil/gnulib/xalloc-oversized.h b/libsbutil/gnulib/xalloc-oversized.h
2901 new file mode 100644
2902 index 0000000..f0e9778
2903 --- /dev/null
2904 +++ b/libsbutil/gnulib/xalloc-oversized.h
2905 @@ -0,0 +1,38 @@
2906 +/* xalloc-oversized.h -- memory allocation size checking
2907 +
2908 + Copyright (C) 1990-2000, 2003-2004, 2006-2015 Free Software Foundation, Inc.
2909 +
2910 + This program is free software: you can redistribute it and/or modify
2911 + it under the terms of the GNU General Public License as published by
2912 + the Free Software Foundation; either version 3 of the License, or
2913 + (at your option) any later version.
2914 +
2915 + This program is distributed in the hope that it will be useful,
2916 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2917 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2918 + GNU General Public License for more details.
2919 +
2920 + You should have received a copy of the GNU General Public License
2921 + along with this program. If not, see <http://www.gnu.org/licenses/>. */
2922 +
2923 +#ifndef XALLOC_OVERSIZED_H_
2924 +# define XALLOC_OVERSIZED_H_
2925 +
2926 +# include <stddef.h>
2927 +
2928 +/* Return 1 if an array of N objects, each of size S, cannot exist due
2929 + to size arithmetic overflow. S must be positive and N must be
2930 + nonnegative. This is a macro, not a function, so that it
2931 + works correctly even when SIZE_MAX < N.
2932 +
2933 + By gnulib convention, SIZE_MAX represents overflow in size
2934 + calculations, so the conservative dividend to use here is
2935 + SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
2936 + However, malloc (SIZE_MAX) fails on all known hosts where
2937 + sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
2938 + exactly-SIZE_MAX allocations on such hosts; this avoids a test and
2939 + branch when S is known to be 1. */
2940 +# define xalloc_oversized(n, s) \
2941 + ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
2942 +
2943 +#endif /* !XALLOC_OVERSIZED_H_ */
2944
2945 diff --git a/libsbutil/gnulib/xalloc.h b/libsbutil/gnulib/xalloc.h
2946 new file mode 100644
2947 index 0000000..3077f27
2948 --- /dev/null
2949 +++ b/libsbutil/gnulib/xalloc.h
2950 @@ -0,0 +1 @@
2951 +#include "sbutil.h"
2952
2953 diff --git a/libsbutil/gnulib/xgetcwd.h b/libsbutil/gnulib/xgetcwd.h
2954 new file mode 100644
2955 index 0000000..765fab4
2956 --- /dev/null
2957 +++ b/libsbutil/gnulib/xgetcwd.h
2958 @@ -0,0 +1,21 @@
2959 +/* This is slightly wrong as libsbutil code is supposed to work both in
2960 + * libsandbox and in sandbox, but egetcwd is only available in the former.
2961 + * We'll worry about that if/when it becomes an issue for other programs.
2962 + *
2963 + * Copyright 1999-2015 Gentoo Foundation
2964 + * Licensed under the GPL-2
2965 + */
2966 +
2967 +_GL_INLINE_HEADER_BEGIN
2968 +
2969 +extern char *egetcwd(char *buf, size_t size);
2970 +
2971 +_GL_INLINE char *xgetcwd(void)
2972 +{
2973 + char *ret = egetcwd(NULL, 0);
2974 + if (ret == NULL && errno == ENOMEM)
2975 + xalloc_die();
2976 + return ret;
2977 +}
2978 +
2979 +_GL_INLINE_HEADER_END
2980
2981 diff --git a/libsbutil/sbutil.h b/libsbutil/sbutil.h
2982 index c76465f..56fe6d3 100644
2983 --- a/libsbutil/sbutil.h
2984 +++ b/libsbutil/sbutil.h
2985 @@ -140,10 +140,13 @@ char *__xstrndup(const char *str, size_t size, const char *file, const char *fun
2986 #define xrealloc(_ptr, _size) __xrealloc(_ptr, _size, __FILE__, __func__, __LINE__)
2987 #define xstrdup(_str) __xstrdup(_str, __FILE__, __func__, __LINE__)
2988 #define xstrndup(_str, _size) __xstrndup(_str, _size, __FILE__, __func__, __LINE__)
2989 +#define xalloc_die() __sb_ebort(__FILE__, __func__, __LINE__, "out of memory")
2990
2991 /* errno helpers */
2992 #define save_errno() int old_errno = errno;
2993 #define restore_errno() errno = old_errno;
2994 #define saved_errno old_errno
2995
2996 +#include "gnulib/canonicalize.h"
2997 +
2998 #endif /* __SBUTIL_H__ */