* [gentoo-commits] proj/elfix:master commit in: misc/mangle-paxflags/, misc/install.wrapper.c/, misc/change-interp/, ...
@ 2014-01-18 13:18 Anthony G. Basile
0 siblings, 0 replies; only message in thread
From: Anthony G. Basile @ 2014-01-18 13:18 UTC (permalink / raw
To: gentoo-commits
commit: 84846a047baade3488d1538f16d54e4b8a80682b
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 11 15:01:40 2014 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Jan 11 15:03:13 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=84846a04
misc/install.wrapper.c: address comments #47 and #48, Bug #465000
---
misc/change-interp/.gitignore | 1 +
misc/elf-manipulate/.gitignore | 1 +
misc/install.wrapper.c/Makefile.am | 16 +++
misc/install.wrapper.c/autogen.sh | 6 +
misc/install.wrapper.c/checkcopyattrs.sh | 32 +++++
misc/install.wrapper.c/configure.ac | 30 +++++
misc/install.wrapper.c/getfatter.sh | 5 -
misc/install.wrapper.c/install.wrapper.c | 196 ++++++++++++++++++++-----------
misc/install.wrapper.c/setfatter.sh | 6 -
misc/mangle-paxflags/.gitignore | 1 +
10 files changed, 214 insertions(+), 80 deletions(-)
diff --git a/misc/change-interp/.gitignore b/misc/change-interp/.gitignore
new file mode 100644
index 0000000..2460008
--- /dev/null
+++ b/misc/change-interp/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/misc/elf-manipulate/.gitignore b/misc/elf-manipulate/.gitignore
new file mode 100644
index 0000000..2460008
--- /dev/null
+++ b/misc/elf-manipulate/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/misc/install.wrapper.c/Makefile.am b/misc/install.wrapper.c/Makefile.am
new file mode 100644
index 0000000..b047805
--- /dev/null
+++ b/misc/install.wrapper.c/Makefile.am
@@ -0,0 +1,16 @@
+CFLAGS=
+noinst_PROGRAMS = install-xattr
+install_xattr_SOURCES = install.wrapper.c
+install_xattr_CFLAGS = -ggdb -Wall -O3
+
+check_SCRIPTS = checkcopyattrs
+TEST = $(check_SCRIPTS)
+
+checkcopyattrs:
+ $(srcdir)/checkcopyattrs.sh
+
+EXTRA_DIST = checkcopyattrs.sh
+CLEANFILES = a b c x y z d/* e/*
+
+clean-local:
+ -rm -rf d e
diff --git a/misc/install.wrapper.c/autogen.sh b/misc/install.wrapper.c/autogen.sh
new file mode 100755
index 0000000..3888ff3
--- /dev/null
+++ b/misc/install.wrapper.c/autogen.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+aclocal && \
+autoheader && \
+autoconf && \
+automake --add-missing --copy
diff --git a/misc/install.wrapper.c/checkcopyattrs.sh b/misc/install.wrapper.c/checkcopyattrs.sh
new file mode 100755
index 0000000..4b3e7f3
--- /dev/null
+++ b/misc/install.wrapper.c/checkcopyattrs.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+set -e
+
+touch a b c
+mkdir -p d e
+setfattr -n user.foo -v "bar" a
+setfattr -n user.pax.flags -v "mr" a
+setfattr -n user.pax.flags -v "p" b
+setfattr -n user.pax.flags -v "r" c
+
+./install-xattr a x
+./install-xattr b y
+./install-xattr c z
+
+[ "$(getfattr --only-values -n user.foo x)" == "bar" ]
+[ "$(getfattr --only-values -n user.pax.flags x)" == "mr" ]
+[ "$(getfattr --only-values -n user.pax.flags y)" == "p" ]
+[ "$(getfattr --only-values -n user.pax.flags z)" == "r" ]
+
+./install-xattr a b c d
+
+[ "$(getfattr --only-values -n user.foo d/a)" == "bar" ]
+[ "$(getfattr --only-values -n user.pax.flags d/a)" == "mr" ]
+[ "$(getfattr --only-values -n user.pax.flags d/b)" == "p" ]
+[ "$(getfattr --only-values -n user.pax.flags d/c)" == "r" ]
+
+./install-xattr -t e a b c
+
+[ "$(getfattr --only-values -n user.foo e/a)" == "bar" ]
+[ "$(getfattr --only-values -n user.pax.flags e/a)" == "mr" ]
+[ "$(getfattr --only-values -n user.pax.flags e/b)" == "p" ]
+[ "$(getfattr --only-values -n user.pax.flags e/c)" == "r" ]
diff --git a/misc/install.wrapper.c/configure.ac b/misc/install.wrapper.c/configure.ac
new file mode 100644
index 0000000..08cc0ca
--- /dev/null
+++ b/misc/install.wrapper.c/configure.ac
@@ -0,0 +1,30 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([install-wrapper],[1])
+AC_CONFIG_SRCDIR([install.wrapper.c])
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([1.13 foreign])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([memset realpath strdup])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/misc/install.wrapper.c/getfatter.sh b/misc/install.wrapper.c/getfatter.sh
deleted file mode 100755
index c0eda95..0000000
--- a/misc/install.wrapper.c/getfatter.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-getfattr -d a b c 2>/dev/null
-getfattr -d d/* 2>/dev/null
-getfattr -d x y z 2>/dev/null
diff --git a/misc/install.wrapper.c/install.wrapper.c b/misc/install.wrapper.c/install.wrapper.c
index 2728381..441b7b8 100644
--- a/misc/install.wrapper.c/install.wrapper.c
+++ b/misc/install.wrapper.c/install.wrapper.c
@@ -7,33 +7,83 @@
* Wrapper for coreutil's install to preserve extended attributes.
*/
-#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <err.h>
#include <fnmatch.h>
#include <ctype.h>
-#include <libgen.h>
#include <getopt.h>
-
+#include <libgen.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/xattr.h>
+static void *
+xmalloc(size_t size)
+{
+ char *ret = malloc(size);
+ if (ret < 0)
+ err(1, "malloc() failed");
+ return ret;
+}
+
+static char *
+path_join(const char *path, const char *file)
+{
+ size_t len_path = strlen(path);
+ size_t len_file = strlen(file);
+ char *ret = xmalloc(len_path + len_file + 2);
+
+ memcpy(ret, path, len_path);
+ ret[len_path] = '/';
+ memcpy(ret + len_path + 1, file, len_file);
+ ret[len_path + len_file + 1] = '\0';
+
+ return ret;
+}
+
+static ssize_t
+xlistxattr(const char *path, char *list, size_t size)
+{
+ ssize_t ret = listxattr(path, list, size);
+ if (ret < 0)
+ err(1, "listxattr() failed");
+ return ret;
+}
+
+static ssize_t
+xgetxattr(const char *path, char *list, char *value, size_t size)
+{
+ ssize_t ret = getxattr(path, list, value, size);
+ if (ret < 0)
+ err(1, "getxattr() failed");
+ return ret;
+}
+
+static ssize_t
+xsetxattr(const char *path, char *list, char *value , size_t size)
+{
+ ssize_t ret = setxattr(path, list, value, size, 0);
+ if (ret < 0)
+ err(1, "setxattr() failed");
+ return ret;
+}
+
static void
copyxattr(const char *source, const char *target)
{
- int i, j;
char *exclude, *portage_xattr_exclude; /* strings of excluded xattr names */
- int len; /* length of the string of excluded xattr names */
+ size_t i, j; /* counters to walk through strings */
+ size_t len; /* length of the string of excluded xattr names */
ssize_t lsize, xsize; /* size in bytes of the list of xattrs and the values */
char *lxattr, *value; /* string of xattr names and the values */
- lsize = listxattr(source, 0, 0);
- lxattr = (char *)malloc(lsize);
- listxattr(source, lxattr, lsize);
+ lsize = xlistxattr(source, 0, 0);
+ lxattr = xmalloc(lsize);
+ xlistxattr(source, lxattr, lsize);
portage_xattr_exclude = getenv("PORTAGE_XATTR_EXCLUDE");
if (portage_xattr_exclude == NULL)
@@ -43,40 +93,44 @@ copyxattr(const char *source, const char *target)
len = strlen(exclude);
- /* We convert exclude[] to an array of concatenated null */
- /* terminated strings. lxattr[] is already such an array. */
+ /* We convert exclude[] to an array of concatenated null
+ * terminated strings. lxattr[] is already such an array.
+ */
for (i = 0; i < len; i++)
if (isspace(exclude[i]))
exclude[i] = 0;
- i = 0 ;
- while(1) {
- while (lxattr[i++] == 0);
+ i = 0;
+ while (1) {
+ while (lxattr[i++] == 0)
+ continue;
if (i >= lsize)
break;
- j = 0 ;
- while(1) {
- while (exclude[j++] == 0);
+ j = 0;
+ while (1) {
+ while (exclude[j++] == 0)
+ continue;
if (j >= len)
break;
if (!fnmatch(&exclude[j-1], &lxattr[i-1], 0))
goto skip;
- while (exclude[j++] != 0);
+ while (exclude[j++] != 0)
+ continue;
if (j >= len)
break;
}
- xsize = getxattr(source, &lxattr[i-1], 0, 0);
- if (xsize != -1) {
- value = (char *)malloc(xsize);
+ xsize = xgetxattr(source, &lxattr[i-1], 0, 0);
+ if (xsize > 0) {
+ value = xmalloc(xsize);
memset(value, 0, xsize);
- getxattr(source, &lxattr[i-1], value, xsize);
- setxattr(target, &lxattr[i-1], value, xsize, 0);
+ xgetxattr(source, &lxattr[i-1], value, xsize);
+ xsetxattr(target, &lxattr[i-1], value, xsize);
free(value);
}
- skip:
+ skip:
while (lxattr[i++] != 0);
if (i >= lsize)
break;
@@ -84,25 +138,26 @@ copyxattr(const char *source, const char *target)
free(lxattr);
free(exclude);
-
- return;
}
static char *
-which(char *mydir)
+which(const char *mydir)
{
char *mycandir = realpath(mydir, NULL); /* canonical value of argv[0]'s dirname */
char *path, *env_path = getenv("PATH"); /* full $PATH string */
/* If we don't have $PATH in our environment, then pick a sane path. */
- if (env_path == NULL)
- path = strdup("/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin");
+ if (env_path == NULL) {
+ size_t len = confstr(_CS_PATH, 0, 0);
+ path = xmalloc(len);
+ confstr(_CS_PATH, path, len);
+ }
else
path = strdup(env_path);
char *dir; /* one directory in the $PATH string */
- char *candir ; /* canonical value of that directory */
+ char *candir; /* canonical value of that directory */
char *file; /* file name = path + "/install" */
char *savedptr; /* reentrant context for strtok_r() */
@@ -113,20 +168,21 @@ which(char *mydir)
while (dir) {
candir = realpath(dir, NULL);
- /* You don't get a canonical path for ~/bin etc., so skip. */
+ /* ignore invalid paths that cannot be cannoicalized */
if (!candir)
goto skip;
- /* If argv[0]'s canonical dirname == the path's canonical dirname, then we */
- /* skip this path otheriwise we get into an infinite self-invocation. */
- if ( !fnmatch(mycandir, candir, 0) )
+ /* If argv[0]'s canonical dirname == the path's canonical dirname, then we
+ * skip this path otheriwise we get into an infinite self-invocation.
+ */
+ if (!fnmatch(mycandir, candir, 0))
goto skip;
- if (asprintf(&file,"%s/%s", candir, "install") == -1)
- abort();
+ file = path_join(candir, "install");
- /* If the file exists and is either a regular file or sym link, */
- /* assume we found the system's install. */
+ /* If the file exists and is either a regular file or sym link,
+ * assume we found the system's install.
+ */
if (stat(file, &s) == 0)
if (S_ISREG(s.st_mode) || S_ISLNK(s.st_mode)) {
free(candir);
@@ -137,13 +193,12 @@ which(char *mydir)
free(file);
- skip:
+ skip:
free(candir);
dir = strtok_r(NULL, ":", &savedptr);
}
- /* If we got here, then we didn't find install in the path */
- abort();
+ err(1, "failed to find system 'install'");
}
@@ -151,8 +206,8 @@ which(char *mydir)
int
main(int argc, char* argv[], char* envp[])
{
- int i ;
- int status ; /* exit status of child "install" process */
+ int i;
+ int status; /* exit status of child "install" process */
int opts_directory = 0; /* if -d was given, then all arguments are directories */
int opts_target_directory = 0; /* if -t was given, then we're installing to a target directory */
@@ -166,7 +221,7 @@ main(int argc, char* argv[], char* envp[])
struct stat s; /* test if a file is a regular file or a directory */
- opterr = 0; /* we skip many legitimate arguments, so silence any warning */
+ opterr = 0; /* we skip many legitimate flags, so silence any warning */
while (1) {
static struct option long_options[] = {
@@ -175,88 +230,91 @@ main(int argc, char* argv[], char* envp[])
{ 0, 0, 0, 0 }
};
- int option_index = 0;
-
+ int option_index;
int c = getopt_long(argc, argv, "dt:", long_options, &option_index);
if (c == -1)
break;
switch (c) {
- case 0 :
+ case 0:
case '?':
+ /* We skip the flags we don't care about */
break;
case 'd':
- opts_directory = 1 ;
+ opts_directory = 1;
break;
case 't':
- opts_target_directory = 1 ;
- if (asprintf(&target, "%s", optarg) == -1)
- abort();
+ opts_target_directory = 1;
+ target = optarg;
break;
default:
- abort();
+ err(1, "getopt_long() failed");
}
}
first = optind;
- last = argc-1;
+ last = argc - 1;
switch (fork()) {
case -1:
- abort();
+ err(1, "fork() failed");
case 0:
install = which(dirname(argv[0]));
execve(install, argv, envp);
- free(install);
- break;
+ /* When the child exists, the kernel will free(install) for us.
+ * Also, no break since we never return from execve.
+ */
default:
wait(&status);
/* If all the targets are directories, do nothing. */
if (opts_directory)
- return EXIT_SUCCESS;
+ return status;
if (!opts_target_directory) {
- target = strdup(argv[last]);
+ target = argv[last];
if (stat(target, &s) != 0)
return EXIT_FAILURE;
- target_is_directory = s.st_mode & S_IFDIR;
+ target_is_directory = S_ISDIR(s.st_mode);
} else {
/* target was set above with the -t option */
target_is_directory = 1;
}
if (target_is_directory) {
- /* If -t was passed, then the last argv *is* */
- /* a file, so we include it for copyxattr(). */
+ /* If -t was passed, then the last argv *is*
+ * a file, so we include it for copyxattr().
+ */
if (opts_target_directory)
last++;
for (i = first; i < last; i++) {
- /* We reproduce install's behavior and skip */
- /* all extra directories on the command line */
- /* that are not the final target directory. */
- stat(argv[i], &s);
+ if (stat(argv[i], &s) != 0)
+ return EXIT_FAILURE;
+ /* We reproduce install's behavior and skip
+ * all extra directories on the command line
+ * that are not the final target directory.
+ */
if (S_ISDIR(s.st_mode))
continue;
- if (asprintf(&path, "%s/%s", target, argv[i]) == -1)
- abort();
+ path = path_join(target, argv[i]);
copyxattr(argv[i], path);
-
free(path);
}
} else
copyxattr(argv[first], target);
- free(target);
+ return status;
}
- return EXIT_SUCCESS;
+
+ /* We should never get here */
+ return EXIT_FAILURE;
}
diff --git a/misc/install.wrapper.c/setfatter.sh b/misc/install.wrapper.c/setfatter.sh
deleted file mode 100755
index 2e9747e..0000000
--- a/misc/install.wrapper.c/setfatter.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-touch a b c
-setfattr -n user.pax.flags -v "mr" a
-setfattr -n user.blah -v "hithere" a
-setfattr -n user.pax.flags -v p b
-setfattr -n user.pax.flags -v r c
diff --git a/misc/mangle-paxflags/.gitignore b/misc/mangle-paxflags/.gitignore
new file mode 100644
index 0000000..2460008
--- /dev/null
+++ b/misc/mangle-paxflags/.gitignore
@@ -0,0 +1 @@
+!Makefile
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-01-18 13:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-18 13:18 [gentoo-commits] proj/elfix:master commit in: misc/mangle-paxflags/, misc/install.wrapper.c/, misc/change-interp/, Anthony G. Basile
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox