diff options
Diffstat (limited to 'pkgs')
-rw-r--r-- | pkgs/applications/networking/instant-messengers/hipchat/default.nix | 13 | ||||
-rw-r--r-- | pkgs/build-support/libredirect/default.nix | 14 | ||||
-rw-r--r-- | pkgs/build-support/libredirect/libredirect.c | 104 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 2 |
4 files changed, 128 insertions, 5 deletions
diff --git a/pkgs/applications/networking/instant-messengers/hipchat/default.nix b/pkgs/applications/networking/instant-messengers/hipchat/default.nix index 857f162d7e47..6da12905f560 100644 --- a/pkgs/applications/networking/instant-messengers/hipchat/default.nix +++ b/pkgs/applications/networking/instant-messengers/hipchat/default.nix @@ -1,6 +1,7 @@ { stdenv, fetchurl, libtool, xlibs, freetype, fontconfig, openssl, glib , mesa, gstreamer, gst_plugins_base, dbus, alsaLib, zlib, libuuid -, libxml2, libxslt, sqlite, libogg, libvorbis, xz, libcanberra, makeWrapper }: +, libxml2, libxslt, sqlite, libogg, libvorbis, xz, libcanberra +, makeWrapper, libredirect, xkeyboard_config }: let @@ -67,8 +68,8 @@ stdenv.mkDerivation { buildCommand = '' tar xf ${src} - d=$out/libexec/hipchat - mkdir -p $out/libexec + mkdir -p $out/libexec/hipchat/bin + d=$out/libexec/hipchat/lib rm -rfv opt/HipChat/lib/{libstdc++*,libz*,libuuid*,libxml2*,libxslt*,libsqlite*,libogg*,libvorbis*,liblzma*,libcanberra.*,libcanberra-*} mv opt/HipChat/lib/ $d mv usr/share $out @@ -85,9 +86,11 @@ stdenv.mkDerivation { makeWrapper $d/hipchat.bin $out/bin/hipchat \ --set HIPCHAT_LD_LIBRARY_PATH '"$LD_LIBRARY_PATH"' \ - --set HIPCHAT_QT_PLUGIN_PATH '"$QT_PLUGIN_PATH"' + --set HIPCHAT_QT_PLUGIN_PATH '"$QT_PLUGIN_PATH"' \ + --set LD_PRELOAD "${libredirect}/lib/libredirect.so" \ + --set NIX_REDIRECTS /usr/share/X11/xkb=${xkeyboard_config}/share/X11/xkb - mv opt/HipChat/bin/linuxbrowserlaunch $out/bin + mv opt/HipChat/bin/linuxbrowserlaunch $out/libexec/hipchat/bin/ ''; meta = { diff --git a/pkgs/build-support/libredirect/default.nix b/pkgs/build-support/libredirect/default.nix new file mode 100644 index 000000000000..a8a497d46d73 --- /dev/null +++ b/pkgs/build-support/libredirect/default.nix @@ -0,0 +1,14 @@ +{ stdenv }: + +stdenv.mkDerivation { + name = "libredirect-0"; + + unpackPhase = "cp ${./libredirect.c} libredirect.c"; + + buildPhase = + '' + gcc -Wall -std=c99 -O3 -shared libredirect.c -o libredirect.so -fPIC -ldl + ''; + + installPhase = "mkdir -p $out/lib; cp libredirect.so $out/lib"; +} diff --git a/pkgs/build-support/libredirect/libredirect.c b/pkgs/build-support/libredirect/libredirect.c new file mode 100644 index 000000000000..4afed3add75b --- /dev/null +++ b/pkgs/build-support/libredirect/libredirect.c @@ -0,0 +1,104 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <limits.h> +#include <string.h> + +#define MAX_REDIRECTS 128 + +static int nrRedirects = 0; +static char * from[MAX_REDIRECTS]; +static char * to[MAX_REDIRECTS]; + +// FIXME: might run too late. +static void init() __attribute__((constructor)); + +static void init() +{ + char * spec = getenv("NIX_REDIRECTS"); + if (!spec) return; + + unsetenv("NIX_REDIRECTS"); + + char * spec2 = malloc(strlen(spec) + 1); + strcpy(spec2, spec); + + char * pos = spec2, * eq; + while ((eq = strchr(pos, '='))) { + *eq = 0; + from[nrRedirects] = pos; + pos = eq + 1; + to[nrRedirects] = pos; + nrRedirects++; + if (nrRedirects == MAX_REDIRECTS) break; + char * end = strchr(pos, ':'); + if (!end) break; + *end = 0; + pos = end + 1; + } + +} + +static const char * rewrite(const char * path, char * buf) +{ + for (int n = 0; n < nrRedirects; ++n) { + int len = strlen(from[n]); + if (strncmp(path, from[n], len) != 0) continue; + if (snprintf(buf, PATH_MAX, "%s%s", to[n], path + len) >= PATH_MAX) + abort(); + return buf; + } + + return path; +} + +/* The following set of Glibc library functions is very incomplete - + it contains only what we needed for programs in Nixpkgs. Just add + more functions as needed. */ + +int open(const char * path, int flags, ...) +{ + int (*open_real) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open"); + mode_t mode = 0; + if (flags & O_CREAT) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } + char buf[PATH_MAX]; + return open_real(rewrite(path, buf), flags, mode); +} + +int open64(const char * path, int flags, ...) +{ + int (*open64_real) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open64"); + mode_t mode = 0; + if (flags & O_CREAT) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } + char buf[PATH_MAX]; + return open64_real(rewrite(path, buf), flags, mode); +} + +FILE * fopen(const char * path, const char * mode) +{ + FILE * (*fopen_real) (const char *, const char *) = dlsym(RTLD_NEXT, "fopen"); + char buf[PATH_MAX]; + return fopen_real(rewrite(path, buf), mode); +} + +int __xstat(int ver, const char * path, struct stat * st) +{ + int (*__xstat_real) (int ver, const char *, struct stat *) = dlsym(RTLD_NEXT, "__xstat"); + char buf[PATH_MAX]; + return __xstat_real(ver, rewrite(path, buf), st); +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index fd4161190b65..f27efd104df1 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -373,6 +373,8 @@ let inherit url; }; + libredirect = callPackage ../build-support/libredirect { }; + makeDesktopItem = import ../build-support/make-desktopitem { inherit stdenv; }; |