Commit 6e230f01 authored by Julien Muchembled's avatar Julien Muchembled

Make userhosts an executable library which can be used as a wrapper

parent 74b2ee92
/libuserhosts.so
/userhosts
CFLAGS ?= -O2 -s
CFLAGS += -Wall -fPIC
CFLAGS += -Wall -fPIE -pie
LDLIBS = -ldl
PREFIX = /usr/local
.PHONY: all install uninstall clean
all: userhosts.so
all: userhosts
userhosts.so: userhosts.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -Wl,-soname,$@ $(LDLIBS) -o $@ $<
userhosts: userhosts.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $<
install: all
install -Dpm 0644 userhosts.so $(DESTDIR)$(PREFIX)/lib/userhosts/userhosts.so
install -Dp userhosts $(DESTDIR)$(PREFIX)/bin/userhosts
uninstall:
-cd $(DESTDIR)$(PREFIX) && rm -f lib/userhosts/userhosts.so
-cd $(DESTDIR)$(PREFIX) && rm -f bin/userhosts
clean:
-rm -f libuserhosts.so
-rm -f userhosts
check: userhosts
@export HOSTS=`mktemp` && trap "rm $$HOSTS" 0 && \
echo 2001:db8::1 $<.example.com >$$HOSTS && \
set getent hosts $<.example.com && \
a=`./$< $$@` && b=`LD_PRELOAD=./$< $$@` && [ "$$a" = "$$b" ] && \
echo "$$a" |grep -q ^2001:db8::1 && ! $$@
......@@ -31,4 +31,8 @@ Just run "make".
Usage
-----
$ env HOSTS=/path/to/custom/hosts LD_PRELOAD=/path/to/libuserhosts.so <command>
$ HOSTS=/path/to/custom/hosts LD_PRELOAD=/path/to/userhosts <command>
`userhosts` is also an executable wrapper that appends itself to LD_PRELOAD:
$ HOSTS=/path/to/custom/hosts userhosts <command>
......@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#define ORIGINAL_HOSTS_PATH "/etc/hosts"
......@@ -85,3 +86,36 @@ FILE *fopen(const char *path, const char *mode) {
path = replacement_hosts;
return (*original_fopen)(path, mode);
}
int main(int argc, char *argv[]) {
char *ld_preload, *p;
int ret = -1;
if (argc <= 1)
fprintf(stderr, "usage: userhosts <command> [<args>]\n");
else {
/* In order not to depend on /proc, getauxval(AT_EXECFN) from <sys/auxv.h>
* should be used. However, this requires glibc >= 2.16. */
ld_preload = realpath("/proc/self/exe", NULL);
if (!ld_preload)
p = "realpath";
else {
if ((p = getenv("LD_PRELOAD"))) {
size_t n = strlen(ld_preload);
ld_preload = realloc(ld_preload, n + strlen(p) + 2);
ld_preload[n++] = ':';
strcpy(ld_preload + n, p);
}
ret = setenv("LD_PRELOAD", ld_preload, 1);
free(ld_preload);
if (ret)
p = "setenv";
else {
ret = execvp(argv[1], &argv[1]);
p = "execvp";
}
}
perror(p);
}
return ret;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment