[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Sat, 5 Oct 2024 03:22:55 -0400 (EDT) |
branch: master
commit 9f4aae1e97fa75b373318d518ef73a9a7a5d797e
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Mon Aug 19 19:26:15 2024 +0200
* tp/Texinfo/XS: run
gnulib-tool --add-import euidaccess
* tp/Texinfo/XS/convert/html_prepare_converter.c
(load_htmlxref_files): start of load_htmlxref_files implementation.
* tp/Texinfo/Convert/HTML.pm: add a comment.
---
ChangeLog | 10 ++
tp/Texinfo/Convert/HTML.pm | 3 +-
tp/Texinfo/XS/Makefile.am | 4 +-
tp/Texinfo/XS/convert/html_prepare_converter.c | 45 +++++
tp/Texinfo/XS/gnulib/lib/Makefile.am | 1 +
tp/Texinfo/XS/gnulib/lib/access.c | 71 ++++++++
tp/Texinfo/XS/gnulib/lib/euidaccess.c | 224 +++++++++++++++++++++++++
tp/Texinfo/XS/gnulib/lib/getgroups.c | 125 ++++++++++++++
tp/Texinfo/XS/gnulib/lib/group-member.c | 114 +++++++++++++
tp/Texinfo/XS/gnulib/lib/root-uid.h | 30 ++++
tp/Texinfo/XS/gnulib/m4/access.m4 | 66 ++++++++
tp/Texinfo/XS/gnulib/m4/euidaccess.m4 | 56 +++++++
tp/Texinfo/XS/gnulib/m4/getgroups.m4 | 109 ++++++++++++
tp/Texinfo/XS/gnulib/m4/gnulib-cache.m4 | 2 +
tp/Texinfo/XS/gnulib/m4/gnulib-comp.m4 | 9 +
tp/Texinfo/XS/gnulib/m4/group-member.m4 | 28 ++++
tp/Texinfo/XS/gnulib/po/POTFILES.in | 5 +
17 files changed, 899 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d388d7a4e7..18c71c35f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2024-08-18 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS: run
+ gnulib-tool --add-import euidaccess
+
+ * tp/Texinfo/XS/convert/html_prepare_converter.c
+ (load_htmlxref_files): start of load_htmlxref_files implementation.
+
+ * tp/Texinfo/Convert/HTML.pm: add a comment.
+
2024-08-18 Patrice Dumas <pertusus@free.fr>
Comments on potential overflows, change in associated comments
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index efe8d6eabb..a70cd89c02 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -6145,6 +6145,7 @@ sub _convert_printindex_command($$$$)
}
+ # FIXME not part of the API
$self->_new_document_context($cmdname);
my $rule = $self->get_conf('DEFAULT_RULE');
@@ -13248,7 +13249,7 @@ sub _open_command_update_context($$)
if (exists($brace_commands{$command_name})
and $brace_commands{$command_name} eq 'context') {
$self->_new_document_context($command_name);
- }
+ }
if (exists($format_context_commands{$command_name})) {
push @{$self->{'document_context'}->[-1]->{'formatting_context'}},
{'context_name' => '@'.$command_name};
diff --git a/tp/Texinfo/XS/Makefile.am b/tp/Texinfo/XS/Makefile.am
index f8df8c74e6..fa39738a4f 100644
--- a/tp/Texinfo/XS/Makefile.am
+++ b/tp/Texinfo/XS/Makefile.am
@@ -430,9 +430,9 @@ libtexinfo_convert_la_SOURCES = \
libtexinfo_convert_la_CPPFLAGS = -I$(srcdir)/main -I$(srcdir)/convert
-I$(srcdir)/structuring_transfo -I$(srcdir)/parsetexi $(AM_CPPFLAGS)
$(GNULIB_CPPFLAGS) $(XSLIBS_CPPFLAGS)
libtexinfo_convert_la_CFLAGS = $(XSLIBS_CFLAGS)
libtexinfo_convert_la_LIBADD = libtexinfo.la libtexinfoxs.la
$(top_builddir)/gnulib/lib/libgnu.la
-libtexinfo_convert_la_LDFLAGS = -version-info 0:0:0 $(perl_conf_LDFLAGS)
$(LTLIBINTL) $(LTLIBICONV) $(LTLIBUNISTRING)
+libtexinfo_convert_la_LDFLAGS = -version-info 0:0:0 $(perl_conf_LDFLAGS)
$(EUIDACCESS_LIBGEN) $(LTLIBINTL) $(LTLIBICONV) $(LTLIBUNISTRING)
# example to trigger errors associated with no undefined
-#libtexinfo_convert_la_LDFLAGS = -version-info 0:0:0 -Wl,--no-undefined
$(perl_conf_LDFLAGS) $(perl_conf_PERL_LINK) $(LTLIBINTL) $(LTLIBICONV)
$(LTLIBUNISTRING)
+#libtexinfo_convert_la_LDFLAGS = -version-info 0:0:0 -Wl,--no-undefined
$(perl_conf_LDFLAGS) $(perl_conf_PERL_LINK) $(EUIDACCESS_LIBGEN) $(LTLIBINTL)
$(LTLIBICONV) $(LTLIBUNISTRING)
########################## Parsetexi XS parser
diff --git a/tp/Texinfo/XS/convert/html_prepare_converter.c
b/tp/Texinfo/XS/convert/html_prepare_converter.c
index 130e843127..4c4c053b71 100644
--- a/tp/Texinfo/XS/convert/html_prepare_converter.c
+++ b/tp/Texinfo/XS/convert/html_prepare_converter.c
@@ -20,6 +20,8 @@
#include <stddef.h>
#include <string.h>
#include <errno.h>
+/* for euidaccess. Not portable, use gnulib */
+#include <unistd.h>
#include "text.h"
#include "command_ids.h"
@@ -46,6 +48,8 @@
#include "convert_to_text.h"
#include "output_unit.h"
#include "html_conversion_state.h"
+/* encoded_output_file_name */
+#include "convert_utils.h"
/* no_brace_command_accent_upper_case
xml_text_entity_no_arg_commands_formatting */
#include "converter.h"
@@ -614,6 +618,45 @@ html_format_setup (void)
defaults based on customization variables.
Apply specific customizations (from Perl) */
+
+
+void
+load_htmlxref_files (CONVERTER *self)
+{
+ const char *htmlxref_mode = self->conf->HTMLXREF_MODE.o.string;
+ const char *htmlxref_file_name = "htmlxref.cnf";
+ STRING_LIST htmlxref_files;
+
+ if (htmlxref_mode && !strcmp (htmlxref_mode, "none"))
+ return;
+
+ memset (&htmlxref_files, 0, sizeof (STRING_LIST));
+ if (htmlxref_mode && !strcmp (htmlxref_mode, "file"))
+ {
+ char *encoded_htmlxref_file_name;
+ char *path_encoding;
+ const char *htmlxref_file = self->conf->HTMLXREF_FILE.o.string;
+
+ if (htmlxref_file)
+ htmlxref_file_name = htmlxref_file;
+
+ /* cast to remove const */
+ encoded_htmlxref_file_name
+ = encoded_output_file_name (self->conf, &self->document->global_info,
+ (char *)htmlxref_file_name,
+ &path_encoding, 0);
+ free (path_encoding);
+
+ if (euidaccess (encoded_htmlxref_file_name, R_OK) == 0)
+ add_string (encoded_htmlxref_file_name, &htmlxref_files);
+ else
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0, "could not find html refs config file %s",
+ htmlxref_file_name);
+ free (encoded_htmlxref_file_name);
+ }
+}
+
/* this code corresponds to the Perl converter_initialize code, only for
code to be called before Perl customization setup information is passed */
void
@@ -652,6 +695,8 @@ html_converter_initialize_beginning (CONVERTER *self)
option_force_conf (&self->conf->INDEX_ENTRY_COLON, 0, "");
if (!self->conf->MENU_ENTRY_COLON.o.string)
option_force_conf (&self->conf->MENU_ENTRY_COLON, 0, "");
+
+ load_htmlxref_files (self);
}
/* for customized special_unit_info (coming from Perl) */
diff --git a/tp/Texinfo/XS/gnulib/lib/Makefile.am
b/tp/Texinfo/XS/gnulib/lib/Makefile.am
index a0a88be5a8..189003af53 100644
--- a/tp/Texinfo/XS/gnulib/lib/Makefile.am
+++ b/tp/Texinfo/XS/gnulib/lib/Makefile.am
@@ -35,6 +35,7 @@
# --macro-prefix=gl \
# --po-domain=texinfo_tp \
# copy-file \
+# euidaccess \
# getline \
# iconv \
# libunistring \
diff --git a/tp/Texinfo/XS/gnulib/lib/access.c
b/tp/Texinfo/XS/gnulib/lib/access.c
new file mode 100644
index 0000000000..c3bdbff41d
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/lib/access.c
@@ -0,0 +1,71 @@
+/* Test the access rights of a file.
+ Copyright (C) 2019-2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined _WIN32 && !defined __CYGWIN__
+# include <io.h>
+#endif
+
+int
+access (const char *file, int mode)
+#undef access
+{
+ int ret;
+
+#if defined _WIN32 && !defined __CYGWIN__
+ if ((mode & X_OK) != 0)
+ mode = (mode & ~X_OK) | R_OK;
+ ret = _access (file, mode);
+#else
+ ret = access (file, mode);
+#endif
+
+#if (defined _WIN32 && !defined __CYGWIN__) || ACCESS_TRAILING_SLASH_BUG
+# if defined _WIN32 && !defined __CYGWIN__
+ if (ret == 0 || errno == EINVAL)
+# else
+ if (ret == 0)
+# endif
+ {
+ size_t file_len = strlen (file);
+ if (file_len > 0 && file[file_len - 1] == '/')
+ {
+ struct stat st;
+ if (stat (file, &st) == 0)
+ {
+ if (! S_ISDIR (st.st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+ else
+ return (mode == F_OK && errno == EOVERFLOW ? 0 : -1);
+ }
+ }
+#endif
+ return ret;
+}
diff --git a/tp/Texinfo/XS/gnulib/lib/euidaccess.c
b/tp/Texinfo/XS/gnulib/lib/euidaccess.c
new file mode 100644
index 0000000000..6229f2c0d0
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/lib/euidaccess.c
@@ -0,0 +1,224 @@
+/* euidaccess -- check if effective user id can access file
+
+ Copyright (C) 1990-1991, 1995, 1998, 2000, 2003-2006, 2008-2024 Free
+ Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by David MacKenzie and Torbjorn Granlund.
+ Adapted for GNU C library by Roland McGrath. */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#if !(defined _WIN32 && ! defined __CYGWIN__)
+# include "root-uid.h"
+#endif
+
+#if HAVE_LIBGEN_H
+# include <libgen.h>
+#endif
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#if defined EACCES && !defined EACCESS
+# define EACCESS EACCES
+#endif
+
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+
+#ifdef _LIBC
+
+# define access __access
+# define getuid __getuid
+# define getgid __getgid
+# define geteuid __geteuid
+# define getegid __getegid
+# define group_member __group_member
+# define euidaccess __euidaccess
+# undef stat
+# define stat stat64
+
+#endif
+
+/* Return 0 if the user has permission of type MODE on FILE;
+ otherwise, return -1 and set 'errno'.
+ Like access, except that it uses the effective user and group
+ id's instead of the real ones, and it does not always check for read-only
+ file system, text busy, etc. */
+
+int
+euidaccess (const char *file, int mode)
+{
+#if HAVE_FACCESSAT /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */
+ return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
+#elif defined EFF_ONLY_OK /* IRIX, OSF/1, Interix */
+ return access (file, mode | EFF_ONLY_OK);
+#elif defined ACC_SELF /* AIX */
+ return accessx (file, mode, ACC_SELF);
+#elif HAVE_EACCESS /* FreeBSD */
+ return eaccess (file, mode);
+#elif defined _WIN32 && ! defined __CYGWIN__ /* mingw */
+ return access (file, mode);
+#else /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, BeOS
*/
+
+ uid_t uid = getuid ();
+ gid_t gid = getgid ();
+ uid_t euid = geteuid ();
+ gid_t egid = getegid ();
+ struct stat stats;
+
+# if HAVE_DECL_SETREGID && PREFER_NONREENTRANT_EUIDACCESS
+
+ /* Define PREFER_NONREENTRANT_EUIDACCESS if you prefer euidaccess to
+ return the correct result even if this would make it
+ nonreentrant. Define this only if your entire application is
+ safe even if the uid or gid might temporarily change. If your
+ application uses signal handlers or threads it is probably not
+ safe. */
+
+ if (mode == F_OK)
+ {
+ int result = stat (file, &stats);
+ return result != 0 && errno == EOVERFLOW ? 0 : result;
+ }
+ else
+ {
+ int result;
+ int saved_errno;
+
+ if (uid != euid)
+ setreuid (euid, uid);
+ if (gid != egid)
+ setregid (egid, gid);
+
+ result = access (file, mode);
+ saved_errno = errno;
+
+ /* Restore them. */
+ if (uid != euid)
+ setreuid (uid, euid);
+ if (gid != egid)
+ setregid (gid, egid);
+
+ errno = saved_errno;
+ return result;
+ }
+
+# else
+
+ /* The following code assumes the traditional Unix model, and is not
+ correct on systems that have ACLs or the like. However, it's
+ better than nothing, and it is reentrant. */
+
+ unsigned int granted;
+ if (uid == euid && gid == egid)
+ /* If we are not set-uid or set-gid, access does the same. */
+ return access (file, mode);
+
+ if (stat (file, &stats) == -1)
+ return mode == F_OK && errno == EOVERFLOW ? 0 : -1;
+
+ /* The super-user can read and write any file, and execute any file
+ that anyone can execute. */
+ if (euid == ROOT_UID
+ && ((mode & X_OK) == 0
+ || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
+ return 0;
+
+ /* Convert the mode to traditional form, clearing any bogus bits. */
+ if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
+ mode &= 7;
+ else
+ mode = ((mode & R_OK ? 4 : 0)
+ + (mode & W_OK ? 2 : 0)
+ + (mode & X_OK ? 1 : 0));
+
+ if (mode == 0)
+ return 0; /* The file exists. */
+
+ /* Convert the file's permission bits to traditional form. */
+ if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
+ && S_IRGRP == (4 << 3) && S_IWGRP == (2 << 3) && S_IXGRP == (1 << 3)
+ && S_IROTH == (4 << 0) && S_IWOTH == (2 << 0) && S_IXOTH == (1 << 0))
+ granted = stats.st_mode;
+ else
+ granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
+ + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
+ + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
+ + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
+ + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
+ + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
+ + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
+ + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
+ + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
+
+ if (euid == stats.st_uid)
+ granted >>= 6;
+ else if (egid == stats.st_gid || group_member (stats.st_gid))
+ granted >>= 3;
+
+ if ((mode & ~granted) == 0)
+ return 0;
+ __set_errno (EACCESS);
+ return -1;
+
+# endif
+#endif
+}
+#undef euidaccess
+#ifdef weak_alias
+weak_alias (__euidaccess, euidaccess)
+#endif
+
+#ifdef TEST
+# include <error.h>
+# include <stdio.h>
+# include <stdlib.h>
+
+int
+main (int argc, char **argv)
+{
+ char *file;
+ int mode;
+ int err;
+
+ if (argc < 3)
+ abort ();
+ file = argv[1];
+ mode = atoi (argv[2]);
+
+ err = euidaccess (file, mode);
+ printf ("%d\n", err);
+ if (err != 0)
+ error (0, errno, "%s", file);
+ exit (0);
+}
+#endif
diff --git a/tp/Texinfo/XS/gnulib/lib/getgroups.c
b/tp/Texinfo/XS/gnulib/lib/getgroups.c
new file mode 100644
index 0000000000..9f4908e997
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/lib/getgroups.c
@@ -0,0 +1,125 @@
+/* provide consistent interface to getgroups for systems that don't allow N==0
+
+ Copyright (C) 1996, 1999, 2003, 2006-2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#if !HAVE_GETGROUPS
+
+/* Provide a stub that fails with ENOSYS, since there is no group
+ information available on mingw. */
+int
+getgroups (_GL_UNUSED int n, _GL_UNUSED GETGROUPS_T *groups)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+#else /* HAVE_GETGROUPS */
+
+# undef getgroups
+# ifndef GETGROUPS_ZERO_BUG
+# define GETGROUPS_ZERO_BUG 0
+# endif
+
+/* On OS X 10.6 and later, use the usual getgroups, not the one
+ supplied when _DARWIN_C_SOURCE is defined. _DARWIN_C_SOURCE is
+ normally defined, since it means "conform to POSIX, but add
+ non-POSIX extensions even if that violates the POSIX namespace
+ rules", which is what we normally want. But with getgroups there
+ is an inconsistency, and _DARWIN_C_SOURCE means "change getgroups()
+ so that it no longer works right". The BUGS section of compat(5)
+ says that the behavior is dubious if you compile different sections
+ of a program with different _DARWIN_C_SOURCE settings, so fix only
+ the offending symbol. */
+# ifdef __APPLE__
+int posix_getgroups (int, gid_t []) __asm ("_getgroups");
+# define getgroups posix_getgroups
+# endif
+
+/* On at least NeXTstep 3.2, getgroups (0, NULL) always fails.
+ On other systems, it returns the number of supplemental
+ groups for the process. This function handles that special case
+ and lets the system-provided function handle all others. However,
+ it can fail with ENOMEM if memory is tight. It is unspecified
+ whether the effective group id is included in the list. */
+
+int
+rpl_getgroups (int n, gid_t *group)
+{
+ int n_groups;
+ GETGROUPS_T *gbuf;
+
+ if (n < 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (n != 0 || !GETGROUPS_ZERO_BUG)
+ {
+ int result;
+ if (sizeof *group == sizeof *gbuf)
+ return getgroups (n, (GETGROUPS_T *) group);
+
+ if (SIZE_MAX / sizeof *gbuf <= n)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ gbuf = malloc (n * sizeof *gbuf);
+ if (!gbuf)
+ return -1;
+ result = getgroups (n, gbuf);
+ if (0 <= result)
+ {
+ n = result;
+ while (n--)
+ group[n] = gbuf[n];
+ }
+ free (gbuf);
+ return result;
+ }
+
+ n = 20;
+ while (1)
+ {
+ /* No need to worry about address arithmetic overflow here,
+ since the ancient systems that we're running on have low
+ limits on the number of secondary groups. */
+ gbuf = malloc (n * sizeof *gbuf);
+ if (!gbuf)
+ return -1;
+ n_groups = getgroups (n, gbuf);
+ if (n_groups == -1 ? errno != EINVAL : n_groups < n)
+ break;
+ free (gbuf);
+ n *= 2;
+ }
+
+ free (gbuf);
+ return n_groups;
+}
+
+#endif /* HAVE_GETGROUPS */
diff --git a/tp/Texinfo/XS/gnulib/lib/group-member.c
b/tp/Texinfo/XS/gnulib/lib/group-member.c
new file mode 100644
index 0000000000..43b4983100
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/lib/group-member.c
@@ -0,0 +1,114 @@
+/* group-member.c -- determine whether group id is in calling user's group list
+
+ Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2024 Free Software
+ Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <stdckdint.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+/* Most processes have no more than this many groups, and for these
+ processes we can avoid using malloc. */
+enum { GROUPBUF_SIZE = 100 };
+
+struct group_info
+ {
+ gid_t *group;
+ gid_t groupbuf[GROUPBUF_SIZE];
+ };
+
+static void
+free_group_info (struct group_info const *g)
+{
+ if (g->group != g->groupbuf)
+ free (g->group);
+}
+
+static int
+get_group_info (struct group_info *gi)
+{
+ int n_groups = getgroups (GROUPBUF_SIZE, gi->groupbuf);
+ gi->group = gi->groupbuf;
+
+ if (n_groups < 0)
+ {
+ int n_group_slots = getgroups (0, NULL);
+ size_t nbytes;
+ if (! ckd_mul (&nbytes, n_group_slots, sizeof *gi->group))
+ {
+ gi->group = malloc (nbytes);
+ if (gi->group)
+ n_groups = getgroups (n_group_slots, gi->group);
+ }
+ }
+
+ /* In case of error, the user loses. */
+ return n_groups;
+}
+
+/* Return non-zero if GID is one that we have in our groups list.
+ Note that the groups list is not guaranteed to contain the current
+ or effective group ID, so they should generally be checked
+ separately. */
+
+int
+group_member (gid_t gid)
+{
+ int i;
+ int found;
+ struct group_info gi;
+ int n_groups = get_group_info (&gi);
+
+ /* Search through the list looking for GID. */
+ found = 0;
+ for (i = 0; i < n_groups; i++)
+ {
+ if (gid == gi.group[i])
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ free_group_info (&gi);
+
+ return found;
+}
+
+#ifdef TEST
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ gid_t gid;
+
+ gid = atoi (argv[i]);
+ printf ("%d: %s\n", gid, group_member (gid) ? "yes" : "no");
+ }
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/tp/Texinfo/XS/gnulib/lib/root-uid.h
b/tp/Texinfo/XS/gnulib/lib/root-uid.h
new file mode 100644
index 0000000000..ba50bfd4e6
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/lib/root-uid.h
@@ -0,0 +1,30 @@
+/* The user ID that always has appropriate privileges in the POSIX sense.
+
+ Copyright 2012-2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#ifndef ROOT_UID_H_
+#define ROOT_UID_H_
+
+/* The user ID that always has appropriate privileges in the POSIX sense. */
+#ifdef __TANDEM
+# define ROOT_UID 65535
+#else
+# define ROOT_UID 0
+#endif
+
+#endif
diff --git a/tp/Texinfo/XS/gnulib/m4/access.m4
b/tp/Texinfo/XS/gnulib/m4/access.m4
new file mode 100644
index 0000000000..93844ffbaf
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/m4/access.m4
@@ -0,0 +1,66 @@
+# access.m4
+# serial 3
+dnl Copyright (C) 2019-2024 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_ACCESS],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ dnl On native Windows, access (= _access) does not support the X_OK mode.
+ dnl It works by chance on some versions of mingw.
+ case "$host_os" in
+ mingw* | windows*)
+ REPLACE_ACCESS=1
+ ;;
+ *)
+ dnl Mac OS X 10.5 mistakenly allows access("link-to-file/",amode).
+ AC_CHECK_FUNCS_ONCE([lstat])
+ AC_CACHE_CHECK([whether access honors trailing slash],
+ [gl_cv_func_access_slash_works],
+ [# Assume that if we have lstat, we can also check symlinks.
+ if test $ac_cv_func_lstat = yes; then
+ rm -rf conftest.f conftest.lnk
+ touch conftest.f || AC_MSG_ERROR([cannot create temporary files])
+ ln -s conftest.f conftest.lnk
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <unistd.h>
+ ]],
+ [[int result = 0;
+ if (access ("conftest.lnk/", R_OK) == 0)
+ result |= 1;
+ return result;
+ ]])],
+ [gl_cv_func_access_slash_works=yes],
+ [gl_cv_func_access_slash_works=no],
+ dnl When crosscompiling, assume access is broken.
+ [case "$host_os" in
+ # Guess yes on Linux systems.
+ linux-* | linux) gl_cv_func_access_slash_works="guessing
yes" ;;
+ # Guess yes on systems that emulate the
Linux system calls.
+ midipix*) gl_cv_func_access_slash_works="guessing
yes" ;;
+ # Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_access_slash_works="guessing
yes" ;;
+ # If we don't know, obey
--enable-cross-guesses.
+ *)
gl_cv_func_access_slash_works="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ rm -rf conftest.f conftest.lnk
+ else
+ gl_cv_func_access_slash_works="guessing yes"
+ fi
+ ])
+ case "$gl_cv_func_access_slash_works" in
+ *yes) ;;
+ *)
+ REPLACE_ACCESS=1
+ AC_DEFINE([ACCESS_TRAILING_SLASH_BUG], [1],
+ [Define if access does not correctly handle trailing slashes.])
+ ;;
+ esac
+ ;;
+ esac
+])
diff --git a/tp/Texinfo/XS/gnulib/m4/euidaccess.m4
b/tp/Texinfo/XS/gnulib/m4/euidaccess.m4
new file mode 100644
index 0000000000..3ade282f4e
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/m4/euidaccess.m4
@@ -0,0 +1,56 @@
+# euidaccess.m4
+# serial 17
+dnl Copyright (C) 2002-2024 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_NONREENTRANT_EUIDACCESS],
+[
+ AC_REQUIRE([gl_FUNC_EUIDACCESS])
+ AC_CHECK_DECLS([setregid])
+ AC_DEFINE([PREFER_NONREENTRANT_EUIDACCESS], [1],
+ [Define this if you prefer euidaccess to return the correct result
+ even if this would make it nonreentrant. Define this only if your
+ entire application is safe even if the uid or gid might temporarily
+ change. If your application uses signal handlers or threads it
+ is probably not safe.])
+])
+
+AC_DEFUN([gl_FUNC_EUIDACCESS],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+ dnl Persuade glibc <unistd.h> to declare euidaccess().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_FUNCS([euidaccess])
+ if test $ac_cv_func_euidaccess = no; then
+ HAVE_EUIDACCESS=0
+ fi
+])
+
+# Prerequisites of lib/euidaccess.c.
+AC_DEFUN([gl_PREREQ_EUIDACCESS], [
+ dnl Prefer POSIX faccessat over non-standard euidaccess.
+ gl_CHECK_FUNCS_ANDROID([faccessat], [[#include <unistd.h>]])
+ dnl Try various other non-standard fallbacks.
+ AC_CHECK_HEADERS([libgen.h])
+ AC_FUNC_GETGROUPS
+
+ # Solaris 9 and 10 need -lgen to get the eaccess function.
+ # Save and restore LIBS so -lgen isn't added to it. Otherwise, *all*
+ # programs in the package would end up linked with that potentially-shared
+ # library, inducing unnecessary run-time overhead.
+ EUIDACCESS_LIBGEN=
+ AC_SUBST([EUIDACCESS_LIBGEN])
+ gl_saved_libs=$LIBS
+ AC_SEARCH_LIBS([eaccess], [gen],
+ [test "$ac_cv_search_eaccess" = "none required" ||
+ EUIDACCESS_LIBGEN=$ac_cv_search_eaccess])
+ AC_CHECK_FUNCS([eaccess])
+ LIBS=$gl_saved_libs
+ # For backward compatibility.
+ LIB_EACCESS="$EUIDACCESS_LIBGEN"
+ AC_SUBST([LIB_EACCESS])
+])
diff --git a/tp/Texinfo/XS/gnulib/m4/getgroups.m4
b/tp/Texinfo/XS/gnulib/m4/getgroups.m4
new file mode 100644
index 0000000000..5457275e9e
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/m4/getgroups.m4
@@ -0,0 +1,109 @@
+# getgroups.m4
+# serial 25
+dnl Copyright (C) 1996-1997, 1999-2004, 2008-2024 Free Software Foundation,
Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering.
+dnl A wrapper around AC_FUNC_GETGROUPS.
+
+# This is taken from the following Autoconf patch:
+#
https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9
+AC_DEFUN([AC_FUNC_GETGROUPS],
+[
+ AC_REQUIRE([AC_TYPE_GETGROUPS])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+ AC_CHECK_FUNC([getgroups])
+
+ # If we don't yet have getgroups, see if it's in -lbsd.
+ # This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
+ gl_saved_LIBS=$LIBS
+ if test $ac_cv_func_getgroups = no; then
+ AC_CHECK_LIB(bsd, getgroups, [GETGROUPS_LIB=-lbsd])
+ fi
+
+ # Run the program to test the functionality of the system-supplied
+ # getgroups function only if there is such a function.
+ if test $ac_cv_func_getgroups = yes; then
+ AC_CACHE_CHECK([for working getgroups], [ac_cv_func_getgroups_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [AC_INCLUDES_DEFAULT],
+ [[/* On NeXTstep 3.2, getgroups (0, 0) always fails. */
+ return getgroups (0, 0) == -1;]])
+ ],
+ [ac_cv_func_getgroups_works=yes],
+ [ac_cv_func_getgroups_works=no],
+ [case "$host_os" in # ((
+ # Guess yes on glibc systems.
+ *-gnu* | gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
+ # Guess yes on musl systems.
+ *-musl*) ac_cv_func_getgroups_works="guessing yes" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *) ac_cv_func_getgroups_works="$gl_cross_guess_normal"
;;
+ esac
+ ])
+ ])
+ else
+ ac_cv_func_getgroups_works=no
+ fi
+ case "$ac_cv_func_getgroups_works" in
+ *yes)
+ AC_DEFINE([HAVE_GETGROUPS], [1],
+ [Define to 1 if your system has a working `getgroups' function.])
+ ;;
+ esac
+ LIBS=$gl_saved_LIBS
+])# AC_FUNC_GETGROUPS
+
+AC_DEFUN([gl_FUNC_GETGROUPS],
+[
+ AC_REQUIRE([AC_TYPE_GETGROUPS])
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ AC_FUNC_GETGROUPS
+ if test $ac_cv_func_getgroups != yes; then
+ HAVE_GETGROUPS=0
+ else
+ if test "$ac_cv_type_getgroups" != gid_t \
+ || { case "$ac_cv_func_getgroups_works" in
+ *yes) false;;
+ *) true;;
+ esac
+ }; then
+ REPLACE_GETGROUPS=1
+ AC_DEFINE([GETGROUPS_ZERO_BUG], [1], [Define this to 1 if
+ getgroups(0,NULL) does not return the number of groups.])
+ else
+ dnl Detect Mac OS X and FreeBSD bug; POSIX requires getgroups(-1,ptr)
+ dnl to fail.
+ AC_CACHE_CHECK([whether getgroups handles negative values],
+ [gl_cv_func_getgroups_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+ [[int size = getgroups (0, 0);
+ gid_t *list = malloc (size * sizeof *list);
+ int result = getgroups (-1, list) != -1;
+ free (list);
+ return result;]])],
+ [gl_cv_func_getgroups_works=yes],
+ [gl_cv_func_getgroups_works=no],
+ [case "$host_os" in
+ # Guess yes on glibc systems.
+ *-gnu* | gnu*) gl_cv_func_getgroups_works="guessing yes" ;;
+ # Guess yes on musl systems.
+ *-musl*) gl_cv_func_getgroups_works="guessing yes" ;;
+ # If we don't know, obey --enable-cross-guesses.
+ *)
gl_cv_func_getgroups_works="$gl_cross_guess_normal" ;;
+ esac
+ ])])
+ case "$gl_cv_func_getgroups_works" in
+ *yes) ;;
+ *) REPLACE_GETGROUPS=1 ;;
+ esac
+ fi
+ fi
+ test -n "$GETGROUPS_LIB" && LIBS="$GETGROUPS_LIB $LIBS"
+])
diff --git a/tp/Texinfo/XS/gnulib/m4/gnulib-cache.m4
b/tp/Texinfo/XS/gnulib/m4/gnulib-cache.m4
index 8ab12d7271..2f1f7e0b36 100644
--- a/tp/Texinfo/XS/gnulib/m4/gnulib-cache.m4
+++ b/tp/Texinfo/XS/gnulib/m4/gnulib-cache.m4
@@ -40,6 +40,7 @@
# --macro-prefix=gl \
# --po-domain=texinfo_tp \
# copy-file \
+# euidaccess \
# getline \
# iconv \
# libunistring \
@@ -79,6 +80,7 @@
gl_LOCAL_DIR([])
gl_MODULES([
copy-file
+ euidaccess
getline
iconv
libunistring
diff --git a/tp/Texinfo/XS/gnulib/m4/gnulib-comp.m4
b/tp/Texinfo/XS/gnulib/m4/gnulib-comp.m4
index 62832f7e1b..95c59a7cbd 100644
--- a/tp/Texinfo/XS/gnulib/m4/gnulib-comp.m4
+++ b/tp/Texinfo/XS/gnulib/m4/gnulib-comp.m4
@@ -318,6 +318,12 @@ AC_DEFUN([gl_INIT],
AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])])
gl_ERROR_H
AC_PROG_MKDIR_P
+ gl_FUNC_EUIDACCESS
+ gl_CONDITIONAL([GL_COND_OBJ_EUIDACCESS], [test $HAVE_EUIDACCESS = 0])
+ AM_COND_IF([GL_COND_OBJ_EUIDACCESS], [
+ gl_PREREQ_EUIDACCESS
+ ])
+ gl_UNISTD_MODULE_INDICATOR([euidaccess])
AC_REQUIRE([gl_EXTERN_INLINE])
gl_FUNC_FCNTL
gl_CONDITIONAL([GL_COND_OBJ_FCNTL],
@@ -1016,6 +1022,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/errno.in.h
lib/error.c
lib/error.in.h
+ lib/euidaccess.c
lib/exitfail.c
lib/exitfail.h
lib/fcntl.c
@@ -1266,6 +1273,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/errno_h.m4
m4/error.m4
m4/error_h.m4
+ m4/euidaccess.m4
m4/exponentd.m4
m4/extensions-aix.m4
m4/extensions.m4
@@ -1283,6 +1291,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/gettime.m4
m4/gettimeofday.m4
m4/gnulib-common.m4
+ m4/group-member.m4
m4/host-cpu-c-abi.m4
m4/iconv.m4
m4/include_next.m4
diff --git a/tp/Texinfo/XS/gnulib/m4/group-member.m4
b/tp/Texinfo/XS/gnulib/m4/group-member.m4
new file mode 100644
index 0000000000..f8ceb1d818
--- /dev/null
+++ b/tp/Texinfo/XS/gnulib/m4/group-member.m4
@@ -0,0 +1,28 @@
+# group-member.m4
+# serial 14
+dnl Copyright (C) 1999-2001, 2003-2007, 2009-2024 Free Software Foundation,
Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Jim Meyering
+
+AC_DEFUN([gl_FUNC_GROUP_MEMBER],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+ dnl Persuade glibc <unistd.h> to declare group_member().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ dnl Do this replacement check manually because I want the hyphen
+ dnl (not the underscore) in the filename.
+ AC_CHECK_FUNC([group_member], , [
+ HAVE_GROUP_MEMBER=0
+ ])
+])
+
+# Prerequisites of lib/group-member.c.
+AC_DEFUN([gl_PREREQ_GROUP_MEMBER],
+[
+ AC_REQUIRE([AC_FUNC_GETGROUPS])
+])
diff --git a/tp/Texinfo/XS/gnulib/po/POTFILES.in
b/tp/Texinfo/XS/gnulib/po/POTFILES.in
index 4838a0c320..cc19ebfbd8 100644
--- a/tp/Texinfo/XS/gnulib/po/POTFILES.in
+++ b/tp/Texinfo/XS/gnulib/po/POTFILES.in
@@ -23,6 +23,7 @@
# List of files which contain translatable strings.
gnulib/lib/_Noreturn.h
+gnulib/lib/access.c
gnulib/lib/acl-errno-valid.c
gnulib/lib/acl-internal.c
gnulib/lib/acl-internal.h
@@ -60,6 +61,7 @@ gnulib/lib/dup2.c
gnulib/lib/errno.in.h
gnulib/lib/error.c
gnulib/lib/error.in.h
+gnulib/lib/euidaccess.c
gnulib/lib/exitfail.c
gnulib/lib/exitfail.h
gnulib/lib/fcntl.c
@@ -77,12 +79,14 @@ gnulib/lib/full-write.h
gnulib/lib/get-permissions.c
gnulib/lib/getdelim.c
gnulib/lib/getdtablesize.c
+gnulib/lib/getgroups.c
gnulib/lib/getline.c
gnulib/lib/getprogname.c
gnulib/lib/getprogname.h
gnulib/lib/gettext.h
gnulib/lib/gettime.c
gnulib/lib/gettimeofday.c
+gnulib/lib/group-member.c
gnulib/lib/hard-locale.c
gnulib/lib/hard-locale.h
gnulib/lib/ialloc.c
@@ -137,6 +141,7 @@ gnulib/lib/rawmemchr.valgrind
gnulib/lib/read.c
gnulib/lib/realloc.c
gnulib/lib/reallocarray.c
+gnulib/lib/root-uid.h
gnulib/lib/safe-read.c
gnulib/lib/safe-read.h
gnulib/lib/safe-write.c