* With a nice bit of hackery, get the Google Talk plugin to work. Yay

for proprietary software.  Tested with Firefox and Chrome.

svn path=/nixpkgs/trunk/; revision=33519
This commit is contained in:
Eelco Dolstra 2012-04-01 15:21:30 +00:00
parent cd83eb3173
commit 1405f49820
3 changed files with 76 additions and 33 deletions

View File

@ -1,18 +1,18 @@
{ stdenv, fetchurl, rpm, cpio, pkgsi686Linux, mesa, xorg, cairo { stdenv, fetchurl, rpm, cpio, mesa, xorg, cairo
, libpng, gtk, glib, fontconfig, freetype, curl , libpng12, gtk, glib, gdk_pixbuf, fontconfig, freetype, curl
, dbus_glib, alsaLib, pulseaudio, udev
}: }:
with stdenv.lib; with stdenv.lib;
let let
rpathNative = makeLibraryPath rpathPlugin = makeLibraryPath
[ stdenv.gcc.gcc [ mesa
mesa
xorg.libXt xorg.libXt
xorg.libX11 xorg.libX11
cairo cairo
libpng libpng12
gtk gtk
glib glib
fontconfig fontconfig
@ -20,32 +20,33 @@ let
curl curl
]; ];
rpath32 = makeLibraryPath rpathProgram = makeLibraryPath
[ pkgsi686Linux.gdk_pixbuf [ gdk_pixbuf
pkgsi686Linux.glib glib
pkgsi686Linux.gtk gtk
pkgsi686Linux.xorg.libX11 xorg.libX11
pkgsi686Linux.xorg.libXcomposite xorg.libXcomposite
pkgsi686Linux.xorg.libXfixes xorg.libXfixes
pkgsi686Linux.xorg.libXrender xorg.libXrender
pkgsi686Linux.xorg.libXrandr xorg.libXrandr
pkgsi686Linux.gcc.gcc stdenv.gcc.gcc
pkgsi686Linux.alsaLib alsaLib
pkgsi686Linux.pulseaudio pulseaudio
pkgsi686Linux.dbus_glib dbus_glib
pkgsi686Linux.udev udev
curl
]; ];
in in
stdenv.mkDerivation { stdenv.mkDerivation {
name = "google-talk-plugin-2.107.0"; name = "google-talk-plugin-2.8.5.0";
src = src =
if stdenv.system == "x86_64-linux" then if stdenv.system == "x86_64-linux" then
fetchurl { fetchurl {
url = "http://dl.google.com/linux/direct/google-talkplugin_current_x86_64.rpm"; url = "http://dl.google.com/linux/direct/google-talkplugin_current_x86_64.rpm";
sha256 = "1jdcnz4iwnjmrr5xyqgam1yd0dc2vyd9iij5imnir4r88l5fc9wh"; sha256 = "15909wnhspjci0fspvh5j87v1xl7dfix36zrpvk6fpc3m0vys0nh";
} }
else else
throw "Google Talk does not support your platform."; throw "Google Talk does not support your platform.";
@ -59,14 +60,15 @@ stdenv.mkDerivation {
installPhase = installPhase =
'' ''
mkdir -p $out/lib/mozilla/plugins plugins=$out/lib/mozilla/plugins
cp opt/google/talkplugin/libnp*.so $out/lib/mozilla/plugins/ mkdir -p $plugins
cp opt/google/talkplugin/libnp*.so $plugins
patchelf --set-rpath "${makeLibraryPath [ stdenv.gcc.gcc ]}:${stdenv.gcc.gcc}/lib64" \ patchelf --set-rpath "${makeLibraryPath [ stdenv.gcc.gcc xorg.libX11 ]}:${stdenv.gcc.gcc}/lib64" \
$out/lib/mozilla/plugins/libnpgoogletalk64.so $plugins/libnpgoogletalk.so
patchelf --set-rpath "$out/libexec/google/talkplugin/lib:${rpathNative}:${stdenv.gcc.gcc}/lib64" \ patchelf --set-rpath "$out/libexec/google/talkplugin/lib:${rpathPlugin}:${stdenv.gcc.gcc}/lib64" \
$out/lib/mozilla/plugins/libnpgtpo3dautoplugin.so $plugins/libnpgtpo3dautoplugin.so
mkdir -p $out/libexec/google/talkplugin mkdir -p $out/libexec/google/talkplugin
cp opt/google/talkplugin/GoogleTalkPlugin $out/libexec/google/talkplugin/ cp opt/google/talkplugin/GoogleTalkPlugin $out/libexec/google/talkplugin/
@ -74,10 +76,20 @@ stdenv.mkDerivation {
mkdir -p $out/libexec/google/talkplugin/lib mkdir -p $out/libexec/google/talkplugin/lib
cp opt/google/talkplugin/lib/libCg* $out/libexec/google/talkplugin/lib/ cp opt/google/talkplugin/lib/libCg* $out/libexec/google/talkplugin/lib/
patchelf --set-rpath "$out/libexec/google/talkplugin/lib" \
$out/libexec/google/talkplugin/lib/libCgGL.so
patchelf \ patchelf \
--set-interpreter ${pkgsi686Linux.glibc}/lib/ld-linux*.so.2 \ --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
--set-rpath ${rpath32} \ --set-rpath "${rpathProgram}:${stdenv.gcc.gcc}/lib64" \
$out/libexec/google/talkplugin/GoogleTalkPlugin $out/libexec/google/talkplugin/GoogleTalkPlugin
# Generate an LD_PRELOAD wrapper to redirect execvp() calls to
# /opt/../GoogleTalkPlugin.
preload=$out/libexec/google/talkplugin/libpreload.so
mkdir -p $(dirname $preload)
gcc -shared ${./preload.c} -o $preload -ldl -DOUT=\"$out\" -fPIC
echo $preload > $plugins/extra-ld-preload
''; '';
dontStrip = true; dontStrip = true;
@ -88,5 +100,6 @@ stdenv.mkDerivation {
meta = { meta = {
homepage = http://www.google.com/chat/video/; homepage = http://www.google.com/chat/video/;
license = "unfree"; license = "unfree";
maintainers = [ stdenv.lib.maintainers.eelco ];
}; };
} }

View File

@ -0,0 +1,32 @@
/* Google Talk Plugin executes a helper program in /opt. This
LD_PRELOAD library intercepts execvp() calls to redirect them to
the corresponding location in $out. */
#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>
char origDir [] = "/opt/google/talkplugin/GoogleTalkPlugin";
char realDir [] = OUT "/libexec/google/talkplugin/GoogleTalkPlugin";
const char * rewrite(const char * path, char * buf)
{
if (strncmp(path, origDir, sizeof(origDir) - 1) != 0) return path;
if (snprintf(buf, PATH_MAX, "%s%s", realDir, path + sizeof(origDir) - 1) >= PATH_MAX)
abort();
return buf;
}
int execvp(const char * path, char * const argv[])
{
fprintf(stderr, "foo %s\n", path);
int (*_execvp) (const char *, char * const argv[]) = dlsym(RTLD_NEXT, "execvp");
char buf[PATH_MAX];
return _execvp(rewrite(path, buf), argv);
}

View File

@ -6854,9 +6854,7 @@ let
googleearth = callPackage_i686 ../applications/misc/googleearth { }; googleearth = callPackage_i686 ../applications/misc/googleearth { };
google_talk_plugin = callPackage ../applications/networking/browsers/mozilla-plugins/google-talk-plugin { google_talk_plugin = callPackage ../applications/networking/browsers/mozilla-plugins/google-talk-plugin { };
inherit pkgsi686Linux;
};
gosmore = builderDefsPackage ../applications/misc/gosmore { gosmore = builderDefsPackage ../applications/misc/gosmore {
inherit fetchsvn curl pkgconfig libxml2 gtk; inherit fetchsvn curl pkgconfig libxml2 gtk;