nspluginwrapper-1.3.0

Taken from Debian orig.tar.gz file.
This commit is contained in:
David Benjamin 2011-03-05 22:20:16 -05:00
parent 910986a89b
commit b15fb20458
17 changed files with 1888 additions and 608 deletions

297
ChangeLog
View File

@ -1,8 +1,58 @@
2009-01-01 07:36 Gwenole Beauchesne <gb.public@free.fr>
2009-01-02 08:50 Gwenole Beauchesne <gb.public@free.fr>
* NEWS, nspluginwrapper.spec: Updates for 1.2.2.
* NEWS, nspluginwrapper.spec: Fix spelling.
2009-01-01 07:34 Gwenole Beauchesne <gb.public@free.fr>
2009-01-01 20:51 Gwenole Beauchesne <gb.public@free.fr>
* src/rpc.c: Factor our socket creation.
2009-01-01 20:26 Gwenole Beauchesne <gb.public@free.fr>
* src/npruntime-impl.h, src/npruntime.c, src/npw-viewer.c: Make it
possible to disable NPIdentifier cache with
NPW_NPRUNTIME_CACHE=no too.
2009-01-01 17:58 Gwenole Beauchesne <gb.public@free.fr>
* NEWS, nspluginwrapper.spec: Updates for 1.3.0.
2009-01-01 17:56 Gwenole Beauchesne <gb.public@free.fr>
* configure, lsb-build/headers/glib-2.0/glib.h,
lsb-build/stub_libs/libglib-2.0.c: Add g_hash_table_find() and
g_hash_table_remove_all() thunks. Besides, for bi-arch builds,
it's assumed that 32-/64-bit glib versions are the same and
exports the same functions.
2009-01-01 17:46 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Add NPIdentifier cache.
2009-01-01 15:13 Gwenole Beauchesne <gb.public@free.fr>
* src/npruntime-impl.h, src/npruntime.c: Add NPClass::HasMethod
cache so that to lower RPC round-trip.
2009-01-01 13:54 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Forcibly destroy the Xt source on exit.
2009-01-01 11:02 Gwenole Beauchesne <gb.public@free.fr>
* NEWS: Updates.
2009-01-01 10:58 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Don't create Xt polling sources if we know the
plug-in uses Gtk (XEMBED).
2009-01-01 10:33 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Get rid of the extra 25ms timer. The Xt timers
& input sources are now
checked in the X events source ::prepare() function.
2009-01-01 07:31 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, NEWS, README, configure, src/cxxabi-compat.cpp,
src/debug.c, src/debug.h, src/libxpcom.c, src/npruntime-impl.h,
@ -17,85 +67,186 @@
utils/getdeps.sh, utils/mkruntime.sh, utils/repackage.sh: Update
copyright notices.
2008-12-28 11:36 Gwenole Beauchesne <gb.public@free.fr>
2008-12-29 15:14 Gwenole Beauchesne <gb.public@free.fr>
* NEWS, src/npw-malloc.c, src/npw-malloc.h, src/npw-viewer.c:
Backport from trunk:
* src/npw-config.c: Fix upgrades from previous versions.
2008-12-29 14:53 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, nspluginwrapper.spec: Rename loader script to
npviewer.sh.
2008-12-29 14:52 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, configure, src/npw-config.c, src/npw-wrapper.c,
src/sysdeps.h: Make it possible to use alternate viewer paths
with --viewer-paths configure option. By default,
pkglibdir/%ARCH%/%OS% is used. If no viewer path includes an
ARCH/OS expansion, then nspluginwrapper files are installed in a
"flat" hierarchy. NPW_PluginInfo format is now extended to
include the viewer_path[] too.
2008-12-29 10:48 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.sh: Move down NPW_VIEWER_DIR, after
TARGET_ARCH/TARGET_OS were normalised. Also fix uses of
normalized ARCH/OS variables.
2008-12-29 09:47 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.sh: Normalize ARCH/OS variables here too.
2008-12-28 18:16 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, src/npw-viewer.sh: Factor out install paths.
2008-12-28 17:18 Gwenole Beauchesne <gb.public@free.fr>
* configure: Improve biarch-build check.
2008-12-28 17:03 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, configure, src/rpc.c: Normalize CPU and OS values for
both hosts and targets. Cleanup a few internal configure option
names. Rephrase --enable-generic.
2008-12-28 11:25 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Make sure NPWindow::ws_info points to a unique
location for the lifetime of the window. This fixes support for
the VLC plugin that makes a local copy of NPWindow but doesn't
bother about making an NPWindow::ws_info copy.
2008-12-28 11:21 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-malloc.c, src/npw-malloc.h: Add NPW_MemAllocCopy() and
NPW_MemClone() functions.
2008-12-27 15:19 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Minor clean-ups.
2008-12-27 14:56 Gwenole Beauchesne <gb.public@free.fr>
* configure: Enable main-thread checks by default for all builds
from snapshots.
2008-12-27 14:54 Gwenole Beauchesne <gb.public@free.fr>
* configure, src/npruntime.c, src/npw-viewer.c: Rework configure
option. Use NPW_THREAD_CHECK=yes (or "1") at run-time.
2008-12-27 14:45 Gwenole Beauchesne <gb.public@free.fr>
* configure, src/npruntime.c, src/npw-viewer.c: Convert the PID
check to a main-thread check.
2008-12-27 12:19 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-malloc.c: Simplify memory allocation code further.
2008-12-27 12:07 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-malloc.c: Allow malloc-checks for the libc memory
allocation hooks too. This also simplifies/clarifies the
different memory allocation backends.
2008-12-27 11:45 Gwenole Beauchesne <gb.public@free.fr>
* Makefile, configure, src/npw-malloc.c: Enable malloc-checks by
default for all builds from snapshots.
2008-12-27 11:16 Gwenole Beauchesne <gb.public@free.fr>
* configure, src/npw-malloc.c, src/npw-malloc.h: Add basic malloc
check routines to detect possible buffer overflows or
underflows. This is enabled at run-time with
NPW_MALLOC_CHECK=yes (or "1").
2008-12-26 23:31 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-wrapper.c: Fix NPN_GetStringIdentifiers() to free
identifiers with NPW_MemFree().
2008-12-26 23:24 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-player.c: Fix stream_new() to return NULL if an error
occurred.
2008-12-26 21:34 Gwenole Beauchesne <gb.public@free.fr>
* NEWS, nspluginwrapper.spec: Merge documentation updates from
1.2-branch.
2008-12-26 21:26 Gwenole Beauchesne <gb.public@free.fr>
* src/npruntime.c: Use NPW_MemAlloc() instead of NPW_MemAlloc0()
since all struct members are initialized manually.
2008-12-26 21:24 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-malloc.c: Report an error instead of a debug-warning for
NPW_MemFree()'ing a pointer that was not allocated with
NPW_MemAlloc().
2008-12-25 21:23 Gwenole Beauchesne <gb.public@free.fr>
* src/debug.h: Merge from 1.2-branch:
Make sure NPWindow::ws_info points to a unique location for the
lifetime of the window. This fixes support for the VLC plugin
that makes a local copy of NPWindow but doesn't bother about
making an NPWindow::ws_info copy.
Fix npw_return_if_fail() definition in !DEBUG mode.
2008-12-26 23:37 Gwenole Beauchesne <gb.public@free.fr>
2008-12-25 21:22 Gwenole Beauchesne <gb.public@free.fr>
* NEWS: Updates with "hot" fixes.
2008-12-26 23:33 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-wrapper.c: Backport from trunk:
* src/npw-viewer.c: Merge from 1.2-branch:
Fix NPN_GetStringIdentifiers() to free identifiers with
NPW_MemFree().
* src/npw-player.c: Backport from trunk:
Destroy the plugin window in NPP_Destroy(). NPAPI docs mention
plugin shall not use graphics operations beyond that call. So,
don't bother with broken plugins, we already have our own bugs
to bother with...
2008-12-25 21:21 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-rpc.h, src/npw-viewer.c, src/npw-wrapper.c: Revert RPC
sync and silent X errors commits. They didn't fix anything in a
useful way. IOW, don't bother fixing bugs that are not
nspluginwrapper related and that could actually degrade its
stability.
2008-12-21 12:19 Gwenole Beauchesne <gb.public@free.fr>
* nspluginwrapper.spec, src/npw-wrapper.c: Bump release for
development.
2008-12-21 09:32 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-rpc.h, src/npw-viewer.c, src/npw-wrapper.c: Try to
improve the RPC flush mechanism. Flash doesn't like "cancelled"
NPN_GetURLNotify() with an NPERR_INVALID_INSTANCE_ERROR return.
So, we try our best to honour that call prior to sending
NPP_Destroy().
2008-12-21 08:19 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-wrapper.c: Purge all incoming RPC prior to calling
NPP_Destroy().
2008-12-21 08:16 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Don't kill the application on X errors. That
is, we ignore all X errors that could arise between the
completion of NPP_Destroy() and plugin_instance_finalize(). This
is not fully correct as other plugins can be created and then
destroyed in the while.
Fix stream_new() to return NULL if an error occurred.
2008-12-26 13:42 Gwenole Beauchesne <gb.public@free.fr>
* nspluginwrapper.spec: Bump release for development.
2008-12-25 21:43 Gwenole Beauchesne <gb.public@free.fr>
* nspluginwrapper.spec: Fix day-of-week.
2008-12-25 21:40 Gwenole Beauchesne <gb.public@free.fr>
* NEWS, nspluginwrapper.spec: Updates for real 1.2.0 release.
2008-12-25 21:37 Gwenole Beauchesne <gb.public@free.fr>
* ChangeLog, Makefile: Fix ChangeLog generation for the branch.
2008-12-25 21:29 Gwenole Beauchesne <gb.public@free.fr>
* ChangeLog: Generated by svn2cl.
2008-12-25 21:29 Gwenole Beauchesne <gb.public@free.fr>
* ChangeLog: Generated by svn2cl.
2008-12-21 21:43 Gwenole Beauchesne <gb.public@free.fr>
* src/debug.h: Fix npw_return_if_fail() definition in !DEBUG mode.
2008-12-21 14:02 Gwenole Beauchesne <gb.public@free.fr>
* src/npw-viewer.c: Destroy the plugin window in NPP_Destroy().
NPAPI docs mention plugin shall not use graphics operations
beyond that call. So, don't bother with broken plugins, we
already have our own bugs to bother with...
2008-12-21 12:14 Gwenole Beauchesne <gb.public@free.fr>
* .: Create nspluginwrapper-1.2-branch from rev 837.
XXX: this is a hack to debug later because in the presence of
Firefox 3.0 (i.e. neither 3.1b2 nor 2.x are affected, it seems),
the toplevel window receives an "unexpected GDK_DESTROY from the
outside". Native plugins often get that without nspluginwrapper
too but the application is not killed either.
2008-12-20 22:24 Gwenole Beauchesne <gb.public@free.fr>
* gwenole/projects/nspluginwrapper/trunk/ChangeLog: Generated by
svn2cl.
2008-12-20 22:22 Gwenole Beauchesne <gb.public@free.fr>
* gwenole/projects/nspluginwrapper/trunk/NEWS,
gwenole/projects/nspluginwrapper/trunk/nspluginwrapper.spec:
1.2.0.
2008-12-20 21:32 Gwenole Beauchesne <gb.public@free.fr>
* gwenole/projects/nspluginwrapper/trunk/src/npw-config.c:
Suppress error messages in non-verbose mode when exec()'ing
npviewer.bin (Stanislav Brabec).
* ChangeLog: Generated by svn2cl.
2008-12-20 22:22 Gwenole Beauchesne <gb.public@free.fr>

View File

@ -23,10 +23,10 @@ endif
ifeq ($(SNAPSHOT),)
SNAPSHOT := $(shell echo "$(RELEASE)" | grep "^0")
ifeq ($(SNAPSHOT),$(RELEASE))
SNAPSHOT := 1
SNAPSHOT := 2
endif
endif
ifeq ($(SNAPSHOT),1)
ifeq ($(SNAPSHOT),2)
VERSION_SUFFIX = -$(SVNDATE)
endif
@ -77,7 +77,7 @@ X_LDFLAGS += -Wl,--rpath,$(x11prefix)/$(lib64)
endif
ARCH_32 = $(ARCH)
ifeq ($(biarch), yes)
ifeq ($(build_biarch), yes)
ARCH_32 = $(TARGET_ARCH)
LSB_LIBS = $(LSB_OBJ_DIR)/libc.so $(LSB_OBJ_DIR)/libgcc_s_32.so
LSB_LIBS += $(LSB_CORE_STUBS:%=$(LSB_OBJ_DIR)/%.so)
@ -114,7 +114,7 @@ npviewer_PROGRAM = npviewer.bin
npviewer_RAWSRCS = npw-viewer.c npw-common.c npw-malloc.c npw-rpc.c rpc.c debug.c utils.c npruntime.c
npviewer_SOURCES = $(npviewer_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
npviewer_OBJECTS = $(npviewer_RAWSRCS:%.c=npviewer-%.o)
ifeq ($(biarch),yes)
ifeq ($(build_biarch),yes)
npviewer_CFLAGS = $(CFLAGS_32)
npviewer_CFLAGS += -I$(LSB_INC_DIR)
npviewer_CFLAGS += -I$(LSB_INC_DIR)/glib-2.0
@ -155,7 +155,7 @@ libxpcom_RAWSRCS = libxpcom.c debug.c
libxpcom_SOURCES = $(libxpcom_RAWSRCS:%.c=$(SRC_PATH)/src/%.c)
libxpcom_OBJECTS = $(libxpcom_RAWSRCS:%.c=libxpcom-%.o)
libxpcom_CFLAGS = $(PIC_CFLAGS)
ifeq ($(biarch),yes)
ifeq ($(build_biarch),yes)
libxpcom_CFLAGS += -I$(LSB_INC_DIR)
libxpcom_LDFLAGS = $(LDFLAGS_32) -L$(LSB_OBJ_DIR)
endif
@ -182,7 +182,7 @@ ifneq (,$(findstring $(OS),netbsd dragonfly))
npconfig_LDFLAGS += $(libpthread_LDFLAGS)
endif
nploader_PROGRAM = npviewer
nploader_PROGRAM = npviewer.sh
nploader_RAWSRCS = npw-viewer.sh
nploader_SOURCES = $(nploader_RAWSRCS:%.sh=$(SRC_PATH)/src/%.sh)
@ -255,51 +255,43 @@ distclean: clean
uninstall: uninstall.player uninstall.wrapper uninstall.viewer uninstall.libxpcom uninstall.libnoxshm uninstall.loader uninstall.config uninstall.dirs
uninstall.dirs:
rmdir $(DESTDIR)$(pkglibdir)/noarch
rmdir $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)
rmdir $(DESTDIR)$(pkglibdir)/$(ARCH)
ifneq ($(ARCH),$(ARCH_32))
rmdir $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)
rmdir $(DESTDIR)$(pkglibdir)/$(ARCH_32)
endif
rmdir -p $(DESTDIR)$(nptargetdir) || :
rmdir -p $(DESTDIR)$(nphostdir) || :
rmdir -p $(DESTDIR)$(npcommondir) || :
uninstall.player:
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM)
rm -f $(DESTDIR)$(nphostdir)/$(npplayer_PROGRAM)
uninstall.wrapper:
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npwrapper_LIBRARY)
rm -f $(DESTDIR)$(nphostdir)/$(npwrapper_LIBRARY)
uninstall.viewer:
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM)
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM:%.bin=%)
rm -f $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM)
rm -f $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM:%.bin=%)
uninstall.libxpcom:
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libxpcom_LIBRARY)
rm -f $(DESTDIR)$(nptargetdir)/$(libxpcom_LIBRARY)
uninstall.libnoxshm:
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libnoxshm_LIBRARY)
rm -f $(DESTDIR)$(nptargetdir)/$(libnoxshm_LIBRARY)
uninstall.loader:
rm -f $(DESTDIR)$(pkglibdir)/noarch/$(nploader_PROGRAM)
rm -f $(DESTDIR)$(npcommondir)/$(nploader_PROGRAM)
uninstall.config:
rm -f $(DESTDIR)$(bindir)/nspluginwrapper
rm -f $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM)
rm -f $(DESTDIR)$(nphostdir)/$(npconfig_PROGRAM)
uninstall.mkruntime:
rm -f $(DESTDIR)$(pkglibdir)/noarch/mkruntime
rm -f $(DESTDIR)$(npcommondir)/mkruntime
install: install.dirs install.player install.wrapper install.viewer install.libxpcom install.libnoxshm install.loader install.config
install.dirs:
mkdir -p $(DESTDIR)$(pkglibdir)/noarch
mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH)
mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)
ifneq ($(ARCH),$(ARCH_32))
mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH_32)
mkdir -p $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)
endif
mkdir -p $(DESTDIR)$(npcommondir) || :
mkdir -p $(DESTDIR)$(nphostdir) || :
mkdir -p $(DESTDIR)$(nptargetdir) || :
ifeq ($(build_player),yes)
install.player: $(npplayer_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npplayer_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npplayer_PROGRAM) $(DESTDIR)$(nphostdir)/$(npplayer_PROGRAM)
mkdir -p $(DESTDIR)$(bindir)
$(LN_S) $(pkglibdir)/$(ARCH)/$(OS)/$(npplayer_PROGRAM) $(DESTDIR)$(bindir)/nspluginplayer
$(LN_S) $(nphostdir)/$(npplayer_PROGRAM) $(DESTDIR)$(bindir)/nspluginplayer
else
install.player:
endif
install.wrapper: $(npwrapper_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(npwrapper_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npwrapper_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(npwrapper_LIBRARY) $(DESTDIR)$(nphostdir)/$(npwrapper_LIBRARY)
ifeq ($(build_viewer),yes)
install.viewer: install.viewer.bin install.viewer.glue
install.libxpcom: do.install.libxpcom
@ -310,26 +302,26 @@ install.libxpcom:
install.libnoxshm:
endif
install.viewer.bin: $(npviewer_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npviewer_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npviewer_PROGRAM) $(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM)
install.viewer.glue::
p=$(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(npviewer_PROGRAM:%.bin=%); \
p=$(DESTDIR)$(nptargetdir)/$(npviewer_PROGRAM:%.bin=%); \
echo "#!/bin/sh" > $$p; \
echo "TARGET_OS=$(TARGET_OS)" >> $$p; \
echo "TARGET_ARCH=$(TARGET_ARCH)" >> $$p; \
echo ". $(pkglibdir)/noarch/$(nploader_PROGRAM)" >> $$p; \
echo ". $(npcommondir)/$(nploader_PROGRAM)" >> $$p; \
chmod 755 $$p
do.install.libxpcom: $(libxpcom_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(libxpcom_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libxpcom_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(libxpcom_LIBRARY) $(DESTDIR)$(nptargetdir)/$(libxpcom_LIBRARY)
do.install.libnoxshm: $(libnoxshm_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(libnoxshm_LIBRARY) $(DESTDIR)$(pkglibdir)/$(ARCH_32)/$(TARGET_OS)/$(libnoxshm_LIBRARY)
$(INSTALL) -m 755 $(STRIP_OPT) $(libnoxshm_LIBRARY) $(DESTDIR)$(nptargetdir)/$(libnoxshm_LIBRARY)
install.config: $(npconfig_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npconfig_PROGRAM) $(DESTDIR)$(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM)
$(INSTALL) -m 755 $(STRIP_OPT) $(npconfig_PROGRAM) $(DESTDIR)$(nphostdir)/$(npconfig_PROGRAM)
mkdir -p $(DESTDIR)$(bindir)
$(LN_S) $(pkglibdir)/$(ARCH)/$(OS)/$(npconfig_PROGRAM) $(DESTDIR)$(bindir)/nspluginwrapper
$(LN_S) $(nphostdir)/$(npconfig_PROGRAM) $(DESTDIR)$(bindir)/nspluginwrapper
install.loader: $(nploader_PROGRAM)
$(INSTALL) -m 755 $(nploader_PROGRAM) $(DESTDIR)$(pkglibdir)/noarch/$(nploader_PROGRAM)
$(INSTALL) -m 755 $(nploader_PROGRAM) $(DESTDIR)$(npcommondir)/$(nploader_PROGRAM)
install.mkruntime: $(SRC_PATH)/utils/mkruntime.sh
$(INSTALL) -m 755 $< $(DESTDIR)$(pkglibdir)/noarch/mkruntime
$(INSTALL) -m 755 $< $(DESTDIR)$(npcommondir)/mkruntime
$(archivedir)::
[ -d $(archivedir) ] || mkdir $(archivedir) > /dev/null 2>&1
@ -342,7 +334,7 @@ $(archivedir)$(SRCARCHIVE): $(archivedir) $(FILES)
BUILDDIR=`mktemp -d /tmp/buildXXXXXXXX` ; \
mkdir -p $$BUILDDIR/$(PACKAGE)-$(VERSION) ; \
(cd $(SRC_PATH) && tar c $(FILES)) | tar x -C $$BUILDDIR/$(PACKAGE)-$(VERSION) ; \
[ "$(SNAPSHOT)" = "1" ] && svndate_def="%" || svndate_def="#" ; \
[ "$(SNAPSHOT)" = "2" ] && svndate_def="%" || svndate_def="#" ; \
sed -e "s/^[%#]define svndate.*/$${svndate_def}define svndate $(SVNDATE)/" \
< $(SRC_PATH)/nspluginwrapper.spec \
> $$BUILDDIR/$(PACKAGE)-$(VERSION)/nspluginwrapper.spec ; \
@ -367,7 +359,7 @@ localrpm: $(archivedir)$(SRCARCHIVE).bz2
changelog: ../common/authors.xml
svn_prefix=`svn info .|sed -n '/^URL *: .*\/svn\/\(.*\)$$/s//\1\//p'`; \
LC_ALL=C TZ=GMT svn2cl --strip-prefix=$$svn_prefix --authors=../common/authors.xml --accum || :
LC_ALL=C TZ=GMT svn2cl --strip-prefix=$$svn_prefix --authors=../common/authors.xml || :
changelog.commit: changelog
svn commit -m "Generated by svn2cl." ChangeLog
@ -413,7 +405,7 @@ npconfig-%.o: $(SRC_PATH)/src/%.c
$(CC) -o $@ -c $< $(CPPFLAGS) $(CFLAGS)
$(nploader_PROGRAM): $(nploader_SOURCES)
sed -e "s|%NPW_LIBDIR%|$(pkglibdir)|" $< > $@
sed -e 's|%NPW_VIEWER_DIR%|$(nptargetdir_var)|' $< > $@
chmod 755 $@
$(LSB_OBJ_DIR)::

11
NEWS
View File

@ -1,6 +1,14 @@
nspluginwrapper NEWS -- history of user-visible changes. 2009-01-02
Copyright (C) 2005-2009 Gwenole Beauchesne
Version 1.3.0 (BETA) - 02.Jan.2009
* Don't poll for Xt events in Gtk (XEMBED) plug-ins
* Use 40 Hz timer for Xt events only when necessary (Xt input sources)
* Add NPIdentifier and NPClass::HasMethod caches, i.e. lower RPC traffic
* Add support for multiple viewer paths, see --viewer-paths=PATH-EXPR
* Add basic checks for malloc()'ed buffer underflow/overflow
* Add checks for single-threaded calls into the browser (NPN_*() functions)
Version 1.2.2 - 02.Jan.2009
* Fix support for the VLC plug-in
* Fix memory deallocation in NPN_GetStringIdentifiers()
@ -12,7 +20,8 @@ Version 1.2.0 - 26.Dec.2008
* Add support for SunStudio compilers
* Add support for Flash Player 10 on OpenSolaris 2008.11
* Fix build on non-Linux platforms
* Fix NPP_Destroy() to keep NPP instances longer, but destroy window immediately
* Fix NPP_Destroy() to keep NPP instances longer
* Fix NPP_Destroy() to destroy the plugin window immediately
Version 1.1.10 (BETA) - 08.Dec.2008
* Fix NPPVpluginScriptableNPObject::Invalidate()

310
configure vendored
View File

@ -19,60 +19,6 @@ TMPO="${TMPDIR1}/npw-conf-${RANDOM}-$$-${RANDOM}.o"
TMPE="${TMPDIR1}/npw-conf-${RANDOM}-$$-${RANDOM}"
TMPS="${TMPDIR1}/npw-conf-${RANDOM}-$$-${RANDOM}.S"
# default parameters
prefix="/usr"
lib32=""
lib64=""
x_base_dirs=""
biarch="guess"
build_viewer="guess"
build_player="yes"
linux_only="guess"
strip="no"
cc="gcc"
cxx="g++"
host_os=`uname -s | tr '[A-Z]' '[a-z]'`
host_cpu=`uname -m`
target_os="linux"
target_cpu="i386"
rpc_init_timeout=5
malloc_hooks="glib,libc"
use_pid_check="no"
case "$host_cpu" in
arm*)
host_cpu="arm"
;;
i386|i486|i586|i686|i86pc|BePC)
host_cpu="i386"
;;
ia64)
host_cpu="ia64"
;;
"Power Macintosh"|ppc)
host_cpu="ppc"
;;
ppc64)
host_cpu="ppc64"
;;
sparc)
host_cpu="sparc"
;;
sparc64)
host_cpu="sparc64"
;;
x86_64|amd64)
host_cpu="x86_64"
;;
*)
host_cpu="unknown"
;;
esac
case "$host_os" in
sunos*)
host_os="solaris"
;;
esac
# find source path
# XXX: we assume an absolute path is given when launching configure,
# except in './configure' case.
@ -84,6 +30,105 @@ if test -z "$source_path" -o "$source_path" = "." ; then
source_path_used="no"
fi
# determine versions
VERSION=`sed < $source_path/$PACKAGE.spec -n '/^\%define version[ ]*/s///p'`
RELEASE=`sed < $source_path/$PACKAGE.spec -n '/^\%define release[ ]*/s///p'`
SVNDATE=`sed < $source_path/$PACKAGE.spec -n '/^\%define svndate[ ]*/s///p'`
if test -z "$SVNDATE"; then
SVNDATE=`date '+%Y%m%d'`
fi
MAJOR_VERSION=`echo "$VERSION"|cut -d'.' -f1`
MINOR_VERSION=`echo "$VERSION"|cut -d'.' -f2`
MICRO_VERSION=`echo "$VERSION"|cut -d'.' -f3`
# development snapshots are officially generated tarballs for testing
# ("odd" minor and micro versions)
is_odd() {
local rem=`expr "$1" % 2`
test $rem -eq 1 && return 0 || return 1
}
if is_odd $MINOR_VERSION || is_odd $MICRO_VERSION; then
SNAPSHOT=1
else
SNAPSHOT=0
fi
# snapshots can also be unofficially generated tarballs
# (Release: 0.1 in specfile)
if echo "$RELEASE" | grep -q ^0; then
SNAPSHOT=2
fi
if test $SNAPSHOT -ge 1; then
yes_for_snapshots="yes"
else
yes_for_snapshots="no"
fi
# default parameters
prefix="/usr"
lib32=""
lib64=""
x_base_dirs=""
build_viewer="guess"
build_player="yes"
build_generic="guess"
build_biarch="guess"
strip="no"
cc="gcc"
cxx="g++"
host_os=`uname -s | tr '[A-Z]' '[a-z]'`
host_cpu=`uname -m`
target_os="linux"
target_cpu="i386"
rpc_init_timeout=5
malloc_hooks="glib,libc"
enable_malloc_check="$yes_for_snapshots"
enable_thread_check="$yes_for_snapshots"
normalize_cpu() {
local cpu="$1"
case "$cpu" in
arm*)
cpu="arm"
;;
i[3456]86|k[678]|i86pc|BePC)
cpu="i386"
;;
ia64)
cpu="ia64"
;;
"Power Macintosh"|ppc)
cpu="ppc"
;;
ppc64)
cpu="ppc64"
;;
sparc)
cpu="sparc"
;;
sparc64)
cpu="sparc64"
;;
x86_64|amd64)
cpu="x86_64"
;;
esac
echo "$cpu"
}
normalize_os() {
local os="$1"
case "$os" in
sunos*)
os="solaris"
;;
esac
echo "$os"
}
for opt do
case "$opt" in
--prefix=*)
@ -92,14 +137,20 @@ case "$opt" in
--pkglibdir=*)
pkglibdir=`echo "$opt" | cut -d '=' -f 2`
;;
--viewer-paths=*)
viewer_paths=`echo "$opt" | cut -d '=' -f 2`
;;
--target-os=*)
target_os=`echo "$opt" | cut -d '=' -f 2 | tr '[A-Z]' '[a-z]'`
;;
--target-cpu=*)
target_cpu=`echo "$opt" | cut -d '=' -f 2 | sed -e 's/^i.86$/i386/'`
target_cpu=`echo "$opt" | cut -d '=' -f 2`
;;
--enable-generic)
linux_only="no"
build_generic="yes"
;;
--disable-generic)
build_generic="no"
;;
--enable-strip)
strip="yes"
@ -108,10 +159,10 @@ case "$opt" in
strip="no"
;;
--enable-biarch)
biarch="yes"
build_biarch="yes"
;;
--disable-biarch)
biarch="no"
build_biarch="no"
;;
--enable-viewer)
build_viewer="yes"
@ -125,11 +176,17 @@ case "$opt" in
--disable-player)
build_player="no"
;;
--enable-pid-check)
use_pid_check="yes"
--enable-thread-check)
enable_thread_check="yes"
;;
--disable-pid-check)
use_pid_check="no"
--disable-thread-check)
enable_thread_check="no"
;;
--enable-malloc-check)
enable_malloc_check="yes"
;;
--disable-malloc-check)
enable_malloc_check="no"
;;
--with-lib32=*)
lib32=`echo "$opt" | cut -d '=' -f 2`
@ -155,34 +212,45 @@ case "$opt" in
esac
done
host_cpu=`normalize_cpu "$host_cpu"`
host_os=`normalize_os "$host_os"`
target_cpu=`normalize_cpu "$target_cpu"`
target_os=`normalize_os "$target_os"`
# check for linux only build
if test "$linux_only" = "guess"; then
if test "$build_generic" = "guess"; then
if test "$host_os" = "linux" -a "$target_os" = "linux"; then
linux_only="yes"
build_generic="no"
else
linux_only="no"
build_generic="yes"
fi
fi
# check for biarch build (Linux only)
if test "$biarch" = "guess"; then
# XXX: biarch builds require LSB headers for now
biarch="no"
# XXX: biarch builds require LSB headers for now
build_biarch_possible="no"
if test "$host_os" = "linux" -a "$target_os" = "linux"; then
case $host_cpu:$target_cpu in
x86_64:i386 | ppc64:ppc)
if test "$host_os" = "linux"; then
biarch="yes"
fi
build_biarch_possible="yes"
;;
esac
fi
if test "$build_biarch" = "guess"; then
build_biarch="$build_biarch_possible"
elif test "$build_biarch" = "yes"; then
if test "$build_biarch_possible" = "no"; then
echo "WARNING: bi-arch build is not possible, disabling"
build_biarch="no"
fi
fi
# check for viewer build
if test "$build_viewer" = "guess"; then
build_viewer="no"
case $host_os in
linux)
if test "$host_cpu" = "$target_cpu" -o "$biarch" = "yes"; then
if test "$host_cpu" = "$target_cpu" -o "$build_biarch" = "yes"; then
build_viewer="yes"
fi
;;
@ -224,6 +292,12 @@ if test -z "$pkglibdir"; then
pkglibdir="$prefix/lib/$PACKAGE"
fi
# check for viewer paths
default_viewer_paths="$pkglibdir/%ARCH%/%OS%"
if test -z "$viewer_paths"; then
viewer_paths="$default_viewer_paths"
fi
# check for __attribute__((visibility())) support
cat > $TMPC << EOF
int foo __attribute__((visibility("hidden"))) = 1;
@ -280,7 +354,7 @@ else
fi
# check for __stack_chk_fail() in target GNU C library
if test "$biarch" = "yes"; then
if test "$build_biarch" = "yes"; then
glibc_header_dir="/usr/include"
libc_provides_ssp=no
if test -f $glibc_header_dir/features.h \
@ -370,7 +444,7 @@ if test "$compiler" = "gcc"; then
CFLAGS="$CFLAGS -mtune=generic"
fi
fi
if test "$biarch" = "yes" -a -z "$CFLAGS_32"; then
if test "$build_biarch" = "yes" -a -z "$CFLAGS_32"; then
CFLAGS_32="-m32 -O2 -g"
if check_cc_option -mtune=generic $CFLAGS_32; then
CFLAGS_32="$CFLAGS_32 -mtune=generic"
@ -596,7 +670,7 @@ for mh in $malloc_hooks_list; do
is_ok="yes"
;;
glib)
if test "x$linux_only" = "xno"; then
if test "x$build_generic" = "xyes"; then
echo "WARNING: disabling glib memory hooks with --enable-generic"
elif ! $pkgconfig --atleast-version=2.10 glib-2.0; then
echo "WARNING: disabling glib memory hooks that require glib >= 2.10 (system is $GLIB_VERSION)"
@ -631,6 +705,7 @@ echo "Standard options:"
echo " --help print this message"
echo " --prefix=PREFIX install in PREFIX [$prefix]"
echo " --pkglibdir=ROOT install private files in ROOT [$pkglibdir]"
echo " --viewer-paths=PATH allowed viewer lookup PATH [$viewer_paths]"
echo " --target-os=OS build plugin support for target OS [$target_os]"
echo " --target-cpu=CPU build plugin support for target CPU [$target_cpu]"
echo " --enable-viewer build viewer [$build_viewer]"
@ -639,9 +714,10 @@ echo ""
echo "Advanced options (experts only):"
echo " --source-path=PATH path of source code [$source_path]"
echo " --enable-strip strip resulting binaries and libraries [$strip]"
echo " --enable-generic don't use system-specific additions"
echo " --enable-biarch build both 32-bit and 64-bit components at once"
echo " --enable-pid-check enable PID check (DEBUG) [$use_pid_check]"
echo " --enable-generic build with generic APIs [$build_generic]"
echo " --enable-biarch build both 32-bit and 64-bit components at once [$build_biarch]"
echo " --enable-thread-check enable main thread checks (DEBUG) [$enable_thread_check]"
echo " --enable-malloc-check enable memory allocation checks (DEBUG) [$enable_malloc_check]"
echo " --with-lib32=NAME use NAME as the 32-bit library dir name [$lib32]"
echo " --with-lib64=NAME use NAME as the 64-bit library dir name [$lib64]"
echo " --with-x11-prefix=PREFIX use PREFIX as the X11 base dir [autodetect]"
@ -654,18 +730,19 @@ echo "NOTE: The object files are built at the place where configure is launched"
exit 1
fi
echo "Source path $source_path"
echo "Install prefix $prefix"
echo "nspluginwrapper root dir $pkglibdir"
echo "Strip binaries $strip"
echo "Bi-arch build $biarch"
echo "Viewer paths $viewer_paths"
echo "Build viewer $build_viewer"
echo "Build for Linux only $linux_only"
echo "Build standalone player $build_player"
echo "Build 32-/64-bit at once $build_biarch"
echo "Build with generic APIs $build_generic"
echo "32-bit library dir name $lib32"
echo "64-bit library dir name $lib64"
echo "Source path $source_path"
echo "C compiler $cc"
echo "C++ compiler $cxx"
echo "Strip binaries $strip"
echo "Host OS $host_os"
echo "Host CPU $host_cpu"
echo "Host big endian $bigendian"
@ -673,7 +750,8 @@ echo "Target OS $target_os"
echo "Target CPU $target_cpu"
echo "RPC init timeout $rpc_init_timeout secs"
echo "Memory allocation hooks $malloc_hooks"
echo "Use PID check (DEBUG) $use_pid_check"
echo "Use thread checks (DEBUG) $enable_thread_check"
echo "Use malloc checks (DEBUG) $enable_malloc_check"
config_mak="config-host.mak"
echo "# Automatically generated by configure - do not modify" > $config_mak
@ -691,7 +769,7 @@ echo "GTK_CFLAGS=$GTK_CFLAGS" >> $config_mak
echo "GTK_LDFLAGS=$GTK_LDFLAGS" >> $config_mak
echo "CURL_CFLAGS=$CURL_CFLAGS" >> $config_mak
echo "CURL_LDFLAGS=$CURL_LDFLAGS" >> $config_mak
if test "$biarch" = "yes"; then
if test "$build_biarch" = "yes"; then
echo "LDFLAGS_32=-m32" >> $config_mak
echo "CFLAGS_32=$CFLAGS_32" >> $config_mak
else
@ -768,7 +846,7 @@ fi
echo "SRC_PATH=$source_path" >> $config_mak
echo "build_viewer=$build_viewer" >> $config_mak
echo "build_player=$build_player" >> $config_mak
echo "biarch=$biarch" >> $config_mak
echo "build_biarch=$build_biarch" >> $config_mak
echo "lib32=$lib32" >> $config_mak
echo "lib64=$lib64" >> $config_mak
echo "prefix=$prefix" >> $config_mak
@ -780,21 +858,11 @@ echo "#define LIBDIR \"$libdir\"" >> $config_h
echo "x11prefix=$x_base_dir" >> $config_mak
echo "ALLOW_STRIP=$strip" >> $config_mak
VERSION=`sed < $source_path/$PACKAGE.spec -n '/^\%define version[ ]*/s///p'`
RELEASE=`sed < $source_path/$PACKAGE.spec -n '/^\%define release[ ]*/s///p'`
SVNDATE=`sed < $source_path/$PACKAGE.spec -n '/^\%define svndate[ ]*/s///p'`
if test -z "$SVNDATE"; then
SVNDATE=`date '+%Y%m%d'`
fi
SNAPSHOT=0
if echo "$RELEASE" | grep -q ^0; then
SNAPSHOT=1
fi
echo "VERSION=$VERSION" >> $config_mak
echo "SVNDATE=$SVNDATE" >> $config_mak
echo "SNAPSHOT=$SNAPSHOT" >> $config_mak
echo "#define NPW_SNAPSHOT $SNAPSHOT" >> $config_h
if test "$SNAPSHOT" = "1"; then
if test $SNAPSHOT -ge 2; then
echo "#define NPW_VERSION \"$VERSION-Pre ($SVNDATE)\"" >> $config_h
else
echo "#define NPW_VERSION \"$VERSION\"" >> $config_h
@ -803,6 +871,26 @@ fi
echo "pkglibdir=$pkglibdir" >> $config_mak
echo "#define NPW_LIBDIR \"$pkglibdir\"" >> $config_h
# check if we want to install files in ARCH/OS specific locations
if echo ":$viewer_paths" | $EGREP -q ":$pkglibdir/%(ARCH|OS)%"; then
npw_common_libdir="$pkglibdir/noarch"
npw_host_libdir="$pkglibdir/$host_cpu/$host_os"
npw_target_libdir="$pkglibdir/$target_cpu/$target_os"
npw_target_libdir_var="$pkglibdir/\\\$\$TARGET_ARCH/\\\$\$TARGET_OS"
else
npw_common_libdir="$pkglibdir"
npw_host_libdir="$npw_common_libdir"
npw_target_libdir="$npw_common_libdir"
npw_target_libdir_var="$npw_common_libdir"
fi
echo "npcommondir=$npw_common_libdir" >> $config_mak
echo "nphostdir=$npw_host_libdir" >> $config_mak
echo "nptargetdir=$npw_target_libdir" >> $config_mak
echo "nptargetdir_var=$npw_target_libdir_var" >> $config_mak
echo "#define NPW_HOST_LIBDIR \"$npw_host_libdir\"" >> $config_h
echo "#define NPW_TARGET_LIBDIR \"$npw_target_libdir\"" >> $config_h
echo "#define NPW_VIEWER_PATHS \"$viewer_paths\"" >> $config_h
echo "#define RPC_INIT_TIMEOUT $rpc_init_timeout" >> $config_h
for mh in $malloc_hooks; do
@ -832,11 +920,29 @@ if test "$libc_provides_ssp" = "yes"; then
else
echo "#undef TARGET_LIBC_PROVIDES_SSP" >> $config_h
fi
if test "$use_pid_check" = "yes"; then
echo "#define USE_PID_CHECK 1" >> $config_h
if test "$enable_thread_check" = "yes"; then
echo "#define ENABLE_THREAD_CHECK 1" >> $config_h
else
echo "#define USE_PID_CHECK 0" >> $config_h
echo "#undef ENABLE_THREAD_CHECK" >> $config_h
fi
if test "$enable_malloc_check" = "yes"; then
echo "#define ENABLE_MALLOC_CHECK 1" >> $config_h
else
echo "#undef ENABLE_MALLOC_CHECK" >> $config_h
fi
# check for functions in <glib.h>
for func in g_hash_table_remove_all g_hash_table_find; do
cat > $TMPC << EOF
extern void $func(void);
int main(void) { $func(); return 0; }
EOF
if $cc $TMPC -o $TMPE $GLIB_CFLAGS $GLIB_LDFLAGS > /dev/null 2>&1; then
func_def=`echo "$func" | tr '[:lower:]./-' '[:upper:]___'`
echo "#define HAVE_$func_def 1" >> $config_h
fi
rm -f $TMPC $TMPE
done
config_mak="config.mak"
echo "# Automatically generated by configure - do not modify" > $config_mak
@ -846,8 +952,10 @@ config_h="config.h"
echo "/* Automatically generated by configure - do not modify */" > $config_h
echo "#include \"config-host.h\"" >> $config_h
if test "$linux_only" = "yes"; then
echo "#define BUILD_LINUX_ONLY 1" >> $config_h
if test "$build_generic" = "yes"; then
echo "#define BUILD_GENERIC 1" >> $config_h
else
echo "#undef BUILD_GENERIC" >> $config_h
fi
if test "$target_os" = "linux"; then

View File

@ -2642,6 +2642,7 @@ extern "C" {
extern GHashTable *g_hash_table_new(GHashFunc, GEqualFunc);
extern const gchar *g_dir_read_name(GDir *);
extern gboolean g_hash_table_remove(GHashTable *, gconstpointer);
extern void g_hash_table_remove_all(GHashTable *);
extern gchar *g_utf8_strdown(const gchar *, gssize);
extern GIOCondition g_io_channel_get_buffer_condition(GIOChannel *);
extern GSource *g_child_watch_source_new(GPid);

View File

@ -195,6 +195,7 @@ void g_hash_table_lookup_extended() {} ;
void g_hash_table_new() {} ;
void g_hash_table_new_full() {} ;
void g_hash_table_remove() {} ;
void g_hash_table_remove_all() {} ;
void g_hash_table_replace() {} ;
void g_hash_table_size() {} ;
void g_hash_table_steal() {} ;

View File

@ -1,7 +1,7 @@
%define name nspluginwrapper
%define version 1.2.2
%define version 1.3.0
%define release 1
#define svndate DATE
#define svndate 20090102
# define 32-bit arch of multiarch platforms
%define arch_32 %{nil}
@ -159,7 +159,7 @@ fi
%{plugindir}/npwrapper.so
%dir %{pkglibdir}
%dir %{pkglibdir}/noarch
%{pkglibdir}/noarch/npviewer
%{pkglibdir}/noarch/npviewer.sh
%dir %{pkglibdir}/%{_arch}
%dir %{pkglibdir}/%{_arch}/%{_os}
%{pkglibdir}/%{_arch}/%{_os}/npconfig
@ -191,6 +191,14 @@ fi
%endif
%changelog
* Fri Jan 02 2009 Gwenole Beauchesne <gb.public@free.fr> 1.3.0-1
- don't poll for Xt events in Gtk (XEMBED) plug-ins
- use 40 Hz timer for Xt events only when necessary (Xt input sources)
- add NPIdentifier and NPClass::HasMethod caches, i.e. lower RPC traffic
- add support for multiple viewer paths, see --viewer-paths=PATH-EXPR
- add basic checks for malloc()'ed buffer underflow/overflow
- add checks for single-threaded calls into the browser (NPN_*() functions)
* Fri Jan 02 2009 Gwenole Beauchesne <gb.public@free.fr> 1.2.2-1
- fix support for the VLC plug-in
- fix memory deallocation in NPN_GetStringIdentifiers()

View File

@ -27,6 +27,7 @@ typedef struct {
uint32_t npobj_id;
bool is_valid;
void *plugin;
void *hasMethod_cache;
} NPObjectInfo;
extern NPObjectInfo *npobject_info_new(NPObject *npobj) attribute_hidden;
@ -59,6 +60,10 @@ extern char *string_of_NPVariant(const struct _NPVariant *arg) attribute_hidden;
extern void print_npvariant_args(const struct _NPVariant *args, uint32_t nargs) attribute_hidden;
// Deactivate all NPObject instances
extern void npruntime_deactivate(void);
extern void npruntime_deactivate(void) attribute_hidden;
// Check whether to use NPRuntime data caching
// (on by default, disabled with NPW_NPRUNTIME_CACHE=0|no)
extern bool npruntime_use_cache(void) attribute_hidden;
#endif /* NPRUNTIME_IMPL_H */

View File

@ -30,17 +30,57 @@
#include "debug.h"
// Define to enable NPClass::HasMethod cache
#define USE_NPCLASS_HAS_METHOD_CACHE 1
// Define to enable NPClass::HasProperty cache (derived from ::HasMethod cache)
#define USE_NPCLASS_HAS_PROPERTY_CACHE 1
// Defined in npw-{wrapper,viewer}.c
extern rpc_connection_t *g_rpc_connection attribute_hidden;
// Defined in npw-viewer.c
#if USE_PID_CHECK && NPW_IS_PLUGIN
extern bool pid_check(void);
#if defined(ENABLE_THREAD_CHECK) && NPW_IS_PLUGIN
extern bool thread_check(void);
#else
#define pid_check() true
#define thread_check() true
#endif
/* ====================================================================== */
/* === Helpers === */
/* ====================================================================== */
static inline bool get_use_npruntime_cache_env(void)
{
const gchar *env = getenv("NPW_NPRUNTIME_CACHE");
return env == NULL || (strcmp(env, "no") != 0 && strcmp(env, "0") != 0);
}
bool npruntime_use_cache(void)
{
static int use_cache = -1;
if (G_UNLIKELY(use_cache < 0))
use_cache = get_use_npruntime_cache_env();
return use_cache;
}
static inline bool use_npclass_has_method_cache(void)
{
#if USE_NPCLASS_HAS_METHOD_CACHE
return npruntime_use_cache();
#else
return false;
#endif
}
static inline bool use_npclass_has_property_cache(void)
{
/* this depends on the NPClass::HasMethod cache */
return use_npclass_has_method_cache();
}
/* ====================================================================== */
/* === NPClass Bridge === */
/* ====================================================================== */
@ -131,8 +171,8 @@ void g_NPClass_Invalidate(NPObject *npobj)
if (!is_valid_npobject_class(npobj))
return;
if (!pid_check()) {
npw_printf("WARNING: NPClass::Invalidate called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::Invalidate not called from the main thread\n");
return;
}
@ -196,18 +236,34 @@ static bool npclass_invoke_HasMethod(NPObject *npobj, NPIdentifier name)
return ret;
}
static bool npclass_cached_HasMethod(NPObject *npobj, NPIdentifier name)
{
NPObjectInfo *npobj_info = npobject_info_lookup(npobj);
if (use_npclass_has_method_cache() && npobj_info) {
if (G_UNLIKELY(npobj_info->hasMethod_cache == NULL))
npobj_info->hasMethod_cache = g_hash_table_new(NULL, NULL);
gpointer hasMethod = NULL;
if (g_hash_table_lookup_extended(npobj_info->hasMethod_cache, name, NULL, &hasMethod))
return GPOINTER_TO_UINT(hasMethod);
}
bool hasMethod = npclass_invoke_HasMethod(npobj, name);
if (use_npclass_has_method_cache() && npobj_info)
g_hash_table_insert(npobj_info->hasMethod_cache, name, GUINT_TO_POINTER(hasMethod));
return hasMethod;
}
bool g_NPClass_HasMethod(NPObject *npobj, NPIdentifier name)
{
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::HasMethod called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::HasMethod not called from the main thread\n");
return false;
}
D(bugiI("NPClass::HasMethod(npobj %p, name id %p)\n", npobj, name));
bool ret = npclass_invoke_HasMethod(npobj, name);
bool ret = npclass_cached_HasMethod(npobj, name);
D(bugiD("NPClass::HasMethod return: %d\n", ret));
return ret;
}
@ -300,8 +356,8 @@ bool g_NPClass_Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args,
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::Invoke called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::Invoke not called from the main thread\n");
return false;
}
@ -399,8 +455,8 @@ bool g_NPClass_InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t ar
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::InvokeDefault called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::InvokeDefault not called from the main thread\n");
return false;
}
@ -468,18 +524,29 @@ static bool npclass_invoke_HasProperty(NPObject *npobj, NPIdentifier name)
return ret;
}
static bool npclass_cached_HasProperty(NPObject *npobj, NPIdentifier name)
{
NPObjectInfo *npobj_info = npobject_info_lookup(npobj);
if (use_npclass_has_property_cache() && npobj_info && npobj_info->hasMethod_cache) {
/* If the NPIdentifier references a method, it can't be a property */
if (g_hash_table_lookup_extended(npobj_info->hasMethod_cache, name, NULL, NULL))
return false;
}
return npclass_invoke_HasProperty(npobj, name);
}
bool g_NPClass_HasProperty(NPObject *npobj, NPIdentifier name)
{
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::HasProperty called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::HasProperty not called from the main thread\n");
return false;
}
D(bugiI("NPClass::HasProperty(npobj %p, name id %p)\n", npobj, name));
bool ret = npclass_invoke_HasProperty(npobj, name);
bool ret = npclass_cached_HasProperty(npobj, name);
D(bugiD("NPClass::HasProperty return: %d\n", ret));
return ret;
}
@ -559,8 +626,8 @@ bool g_NPClass_GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::GetProperty called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::GetProperty not called from the main thread\n");
return false;
}
@ -645,8 +712,8 @@ bool g_NPClass_SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::SetProperty called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::SetProperty not called from the main thread\n");
return false;
}
@ -716,8 +783,8 @@ bool g_NPClass_RemoveProperty(NPObject *npobj, NPIdentifier name)
if (!is_valid_npobject_class(npobj))
return false;
if (!pid_check()) {
npw_printf("WARNING: NPClass::RemoveProperty called from the wrong process\n");
if (!thread_check()) {
npw_printf("WARNING: NPClass::RemoveProperty not called from the main thread\n");
return false;
}
@ -734,22 +801,31 @@ bool g_NPClass_RemoveProperty(NPObject *npobj, NPIdentifier name)
NPObjectInfo *npobject_info_new(NPObject *npobj)
{
NPObjectInfo *npobj_info = NPW_MemNew0(NPObjectInfo, 1);
NPObjectInfo *npobj_info = NPW_MemNew(NPObjectInfo, 1);
if (npobj_info) {
static uint32_t id;
npobj_info->npobj = npobj;
npobj_info->npobj_id = ++id;
npobj_info->is_valid = true;
npobj_info->plugin = NULL;
npobj_info->hasMethod_cache = NULL;
}
return npobj_info;
}
void npobject_info_destroy(NPObjectInfo *npobj_info)
{
if (npobj_info) {
npw_plugin_instance_unref(npobj_info->plugin);
NPW_MemFree(npobj_info);
if (npobj_info == NULL)
return;
npw_plugin_instance_unref(npobj_info->plugin);
if (npobj_info->hasMethod_cache) {
g_hash_table_destroy(npobj_info->hasMethod_cache);
npobj_info->hasMethod_cache = NULL;
}
NPW_MemFree(npobj_info);
}

View File

@ -71,6 +71,71 @@ static int strstart(const char *str, const char *val, const char **ptr)
return 1;
}
static const char *strnstr(const char *str, int len, const char *substr)
{
const char *match = strstr(str, substr);
if (len > 0 && (match + strlen(substr) > str + len))
match = NULL;
return match;
}
typedef struct {
const char *name;
const char *value;
} Var;
static int strexpand(char *dst, int dstlen, const char *src, int srclen, const Var *vars)
{
if (dst == NULL || dstlen < 1 || src == NULL)
return -1;
if (srclen <= 0)
srclen = strlen(src);
int n = 0;
for (int i = 0; i < srclen; i++) {
char ch = src[i];
if (ch != '%') {
dst[n++] = ch;
if (n >= dstlen - 1)
return -1;
}
else {
char var[16];
const char *str = &src[i + 1];
const char *end = strchr(str, '%');
if (end == NULL)
error("unterminated var '%s'", str);
int len = end - str;
if (len >= sizeof(var) - 1) {
len = sizeof(var) - 1;
memcpy(var, str, len);
var[len] = '\0';
error("unsupported var '%s...'", var);
}
memcpy(var, str, len);
var[len] = '\0';
str = NULL;
for (int j = 0; vars[j].name != NULL; j++) {
if (strcmp(vars[j].name, var) == 0) {
str = vars[j].value;
break;
}
}
if (str == NULL)
error("could not expand var '%s'", var);
i += len + 1;
len = strlen(str);
memcpy(&dst[n], str, len);
n += len;
}
}
dst[n] = '\0';
return 0;
}
/* Implement mkdir -p with default permissions (derived from busybox code) */
static int mkdir_p(const char *path)
{
@ -489,6 +554,30 @@ enum {
EXIT_VIEWER_NATIVE = 20
};
static bool is_plugin_viewer_ok(const char *viewer_path, const char *filename)
{
int pid = fork();
if (pid < 0)
return false;
if (pid == 0) {
if (!g_verbose) {
// don't spit out errors in non-verbose mode, we only need
// to know whether there is a valid viewer or not
freopen("/dev/null", "w", stderr);
}
execl(viewer_path, NPW_VIEWER, "--test", "--plugin", filename, NULL);
exit(1);
}
else {
int status;
while (waitpid(pid, &status, 0) != pid)
;
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
return true;
}
return false;
}
static int detect_plugin_viewer(const char *filename, NPW_PluginInfo *out_plugin_info)
{
static const char *target_arch_table[] = {
@ -522,52 +611,60 @@ static int detect_plugin_viewer(const char *filename, NPW_PluginInfo *out_plugin
&& out_plugin_info->target_os && strcmp(out_plugin_info->target_os, HOST_OS) == 0)
return EXIT_VIEWER_NATIVE;
for (int i = 0; i < target_arch_table_size; i++) {
const char *target_arch = target_arch_table[i];
if (target_arch == NULL)
continue;
char viewer_arch_path[PATH_MAX];
sprintf(viewer_arch_path, "%s/%s", NPW_LIBDIR, target_arch);
if (access(viewer_arch_path, F_OK) != 0) {
target_arch_table[i] = NULL; // this target ARCH is not available, skip it for good
continue;
}
for (int j = 0; j < target_os_table_size; j++) {
const char *target_os = target_os_table[j];
if (target_os == NULL)
enum { VAR_ARCH, VAR_OS, VAR_COUNT };
Var vars[VAR_COUNT+1];
vars[VAR_ARCH].name = "ARCH";
vars[VAR_OS].name = "OS";
vars[VAR_COUNT].name = NULL;
vars[VAR_COUNT].value = NULL;
char viewer_path[sizeof(out_plugin_info->viewer_path)];
const int viewer_path_len = sizeof(viewer_path) - strlen(NPW_VIEWER) - 1;
const char viewer_paths[] = NPW_VIEWER_PATHS;
const char *viewer_path_spec_end, *viewer_path_spec = viewer_paths;
do {
int len;
if ((viewer_path_spec_end = strchr(viewer_path_spec, ':')) != NULL)
len = viewer_path_spec_end - viewer_path_spec;
else
len = strchr(viewer_path_spec, '\0') - viewer_path_spec;
for (int i = 0; i < target_arch_table_size; i++) {
const char *target_arch = target_arch_table[i];
if (target_arch == NULL)
continue;
char viewer_path[PATH_MAX];
sprintf(viewer_path, "%s/%s/%s", viewer_arch_path, target_os, NPW_VIEWER);
if (access(viewer_path, F_OK) != 0)
continue;
int pid = fork();
if (pid < 0)
continue;
else if (pid == 0) {
if (!g_verbose) {
// don't spit out errors in non-verbose mode, we only need
// to know whether there is a valid viewer or not
freopen("/dev/null", "w", stderr);
vars[VAR_ARCH].value = target_arch;
for (int j = 0; j < target_os_table_size; j++) {
const char *target_os = target_os_table[j];
if (target_os == NULL)
continue;
vars[VAR_OS].value = target_os;
if (strexpand(viewer_path, viewer_path_len, viewer_path_spec, len, vars) < 0)
continue;
strcat(viewer_path, "/" NPW_VIEWER);
if (access(viewer_path, F_OK) != 0)
continue;
if (is_plugin_viewer_ok(viewer_path, filename)) {
strcpy(out_plugin_info->target_arch, target_arch);
strcpy(out_plugin_info->target_os, target_os);
strcpy(out_plugin_info->viewer_path, viewer_path);
return EXIT_VIEWER_OK;
}
execl(viewer_path, NPW_VIEWER, "--test", "--plugin", filename, NULL);
exit(1);
}
else {
int status;
while (waitpid(pid, &status, 0) != pid)
;
if (WIFEXITED(status)) {
status = WEXITSTATUS(status);
if (status == EXIT_VIEWER_OK && out_plugin_info) {
strcpy(out_plugin_info->target_arch, target_arch);
strcpy(out_plugin_info->target_os, target_os);
}
return status;
}
return EXIT_VIEWER_ERROR;
if (strnstr(viewer_path_spec, len, "%OS%") == NULL)
break; // don't iterate over OS table if there is no "%OS%" pattern
}
if (strnstr(viewer_path_spec, len, "%ARCH%") == NULL)
break; // don't iterate over ARCH table if there is no "%ARCH%" pattern
}
}
viewer_path_spec += len + 1;
} while (viewer_path_spec_end != NULL);
return EXIT_VIEWER_NOT_FOUND;
}
@ -604,15 +701,27 @@ static bool is_wrapper_plugin_handle(void *handle, NPW_PluginInfo *out_plugin_in
if ((pi = (NPW_PluginInfo *)dlsym(handle, "NPW_Plugin")) == NULL)
return false;
if (out_plugin_info) {
int plugin_info_version = 0;
if (strncmp(pi->ident, "NPW:0.9.90", 10) != 0)
plugin_info_version = 1;
if (strncmp(pi->ident, "NPW:X:", 6) == 0)
plugin_info_version = pi->struct_version;
out_plugin_info->struct_version = plugin_info_version;
strcpy(out_plugin_info->ident, pi->ident);
strcpy(out_plugin_info->path, pi->path);
out_plugin_info->mtime = pi->mtime;
out_plugin_info->target_arch[0] = '\0';
out_plugin_info->target_os[0] = '\0';
if (strncmp(pi->ident, "NPW:0.9.90", 10) != 0) { // additional members in 0.9.91+
if (plugin_info_version >= 1) { // additional members in 0.9.91+
strcpy(out_plugin_info->target_arch, pi->target_arch);
strcpy(out_plugin_info->target_os, pi->target_os);
}
else {
out_plugin_info->target_arch[0] = '\0';
out_plugin_info->target_os[0] = '\0';
}
if (plugin_info_version >= 2) // additional members in 1.3.0+
strcpy(out_plugin_info->viewer_path, pi->viewer_path);
else
out_plugin_info->viewer_path[0] = '\0';
}
return true;
}
@ -628,12 +737,26 @@ static bool is_wrapper_plugin(const char *plugin_path, NPW_PluginInfo *out_plugi
return ret;
}
static bool is_master_wrapper_plugin(const char *plugin_path)
{
static const char *master_plugin_paths[] = {
NPW_LIBDIR "/" HOST_ARCH "/" NPW_WRAPPER,
NPW_LIBDIR "/" HOST_ARCH "/" HOST_OS "/" NPW_WRAPPER,
NPW_DEFAULT_PLUGIN_PATH,
NULL
};
for (int i = 0; master_plugin_paths[i] != NULL; i++) {
if (strcmp(master_plugin_paths[i], plugin_path) == 0)
return true;
}
return false;
}
static bool is_wrapper_plugin_0(const char *plugin_path)
{
NPW_PluginInfo plugin_info;
return is_wrapper_plugin(plugin_path, &plugin_info)
&& strcmp(plugin_info.path, NPW_DEFAULT_PLUGIN_PATH) != 0 // exclude OS/ARCH npwrapper.so
&& strcmp(plugin_info.path, NPW_OLD_DEFAULT_PLUGIN_PATH) != 0; // exclude ARCH npwrapper.so
&& !is_master_wrapper_plugin(plugin_path);
}
static bool has_system_wide_wrapper_plugin(const char *plugin_path, bool check_ident)
@ -789,11 +912,17 @@ static int do_install_plugin(const char *plugin_path, const char *plugin_dir, NP
if (!is_plugin_viewer_available(plugin_path, plugin_info))
return 15;
}
if (plugin_info->viewer_path[0] == '\0') {
if (!is_plugin_viewer_available(plugin_path, plugin_info))
return 16;
}
NPW_PluginInfo *pi = (NPW_PluginInfo *)(plugin_data + ofs - NPW_PLUGIN_IDENT_SIZE);
pi->mtime = st.st_mtime;
strcpy(pi->target_arch, plugin_info->target_arch);
strcpy(pi->target_os, plugin_info->target_os);
pi->struct_version = w_plugin_info.struct_version;
strcpy(pi->viewer_path, plugin_info->viewer_path);
int mode = 0700;
if (!is_user_home_path(d_plugin_path) &&
@ -902,6 +1031,7 @@ static int update_plugin(const char *plugin_path)
int ret = 0;
NPW_PluginInfo plugin_info;
memset(&plugin_info, 0, sizeof(plugin_info));
is_wrapper_plugin(plugin_path, &plugin_info);
struct stat st;
@ -968,13 +1098,21 @@ static int auto_update_plugins(void)
static int list_plugin(const char *plugin_path)
{
NPW_PluginInfo plugin_info;
memset(&plugin_info, 0, sizeof(plugin_info));
is_wrapper_plugin(plugin_path, &plugin_info);
printf("%s\n", plugin_path);
printf(" Original plugin: %s\n", plugin_info.path);
if (plugin_info.struct_version >= 2 && plugin_info.viewer_path[0] != '\0')
printf(" Plugin viewer: %s\n", plugin_info.viewer_path);
char *str = strtok(plugin_info.ident, ":");
if (str && strcmp(str, "NPW") == 0) {
str = strtok(NULL, ":");
if (plugin_info.struct_version >= 2) { /* skip 'X' */
if (str[0] != 'X')
error("invalid NPW_PluginInfo format");
str = strtok(NULL, ":");
}
if (str) {
printf(" Wrapper version string: %s", str);
str = strtok(NULL, ":");
@ -1083,15 +1221,19 @@ static int process_install(int argc, char *argv[])
for (i = 0; i < argc; i++) {
NPW_PluginInfo plugin_info;
memset(&plugin_info, 0, sizeof(plugin_info));
const char *plugin_path = argv[i];
if (!is_plugin(plugin_path, &plugin_info))
error("%s is not a valid NPAPI plugin", plugin_path);
ret = detect_plugin_viewer(plugin_path, &plugin_info);
if (ret != EXIT_VIEWER_OK) {
if (ret == EXIT_VIEWER_NATIVE)
return 0; /* silently ignore exit status */
error("no appropriate viewer found for %s", plugin_path);
}
ret = install_plugin(plugin_path, &plugin_info);
if (ret != 0)
return ret;

View File

@ -23,18 +23,34 @@
#define DEBUG 1
#include "debug.h"
typedef void *(*NPW_MemAllocProcPtr) (uint32_t);
typedef void *(*NPW_MemAlloc0ProcPtr) (uint32_t);
typedef void (*NPW_MemFreeProcPtr) (void *);
typedef void *(*NPW_MemAllocProcPtr) (uint32_t);
typedef void (*NPW_MemFreeProcPtr) (void *, uint32_t);
typedef struct _NPW_MallocHooks NPW_MallocHooks;
struct _NPW_MallocHooks
{
NPW_MemAllocProcPtr memalloc;
NPW_MemAlloc0ProcPtr memalloc0;
NPW_MemFreeProcPtr memfree;
NPW_MemAllocProcPtr memalloc;
NPW_MemAllocProcPtr memalloc0;
NPW_MemFreeProcPtr memfree;
};
#define NPW_MALLOC_MAGIC 0x4e50574d /* 'NPWM' */
typedef struct _NPW_MemBlock NPW_MemBlock;
struct _NPW_MemBlock
{
uint32_t magic;
uint32_t real_size;
uint32_t alloc_size;
uint32_t alloc_lineno;
const char *alloc_file;
};
static void *npw_mem_alloc (uint32_t size, const char *file, int lineno);
static void *npw_mem_alloc0 (uint32_t size, const char *file, int lineno);
static void *npw_mem_alloc_copy (uint32_t size, const void *ptr, const char *file, int lineno);
static void npw_mem_free (void *ptr, const char *file, int lineno);
/* ====================================================================== */
/* === Standard C library === */
/* ====================================================================== */
@ -59,7 +75,7 @@ NPW_Libc_MemAlloc0 (uint32_t size)
}
static void
NPW_Libc_MemFree (void *ptr)
NPW_Libc_MemFree (void *ptr, uint32_t size)
{
free (ptr);
}
@ -82,57 +98,22 @@ static const NPW_MallocHooks g_libc_hooks = {
#if USE_MALLOC_GLIB
#include <glib.h>
#define NPW_GLIB_MALLOC_MAGIC 0x476c6962 /* 'Glib' */
typedef struct _NPW_Glib_MemBlock NPW_Glib_MemBlock;
struct _NPW_Glib_MemBlock
{
uint32_t magic;
uint32_t real_size;
char data[];
};
static void *
NPW_Glib_MemAlloc (uint32_t size)
{
uint32_t real_size;
NPW_Glib_MemBlock *mem;
real_size = sizeof (*mem) + size;
if ((mem = g_slice_alloc (real_size)) == NULL)
return NULL;
mem->magic = NPW_GLIB_MALLOC_MAGIC;
mem->real_size = real_size;
return &mem->data[0];
return g_slice_alloc (size);
}
static void *
NPW_Glib_MemAlloc0 (uint32_t size)
{
uint32_t real_size;
NPW_Glib_MemBlock *mem;
real_size = sizeof (*mem) + size;
if ((mem = g_slice_alloc0 (real_size)) == NULL)
return NULL;
mem->magic = NPW_GLIB_MALLOC_MAGIC;
mem->real_size = real_size;
return &mem->data[0];
return g_slice_alloc0 (size);
}
static void
NPW_Glib_MemFree (void *ptr)
NPW_Glib_MemFree (void *ptr, uint32_t size)
{
if (ptr == NULL)
return;
NPW_Glib_MemBlock *mem = (NPW_Glib_MemBlock *)((char *)ptr - sizeof (*mem));
if (mem->magic == NPW_GLIB_MALLOC_MAGIC)
g_slice_free1 (mem->real_size, mem);
else
{
D(bug("WARNING: block %p was not allocated with NPN_MemAlloc(), reverting to libc free()\n", ptr));
free (ptr);
}
g_slice_free1 (size, ptr);
}
static const NPW_MallocHooks g_glib_hooks = {
@ -190,26 +171,200 @@ get_malloc_hooks (void)
void *
NPW_MemAlloc (uint32_t size)
{
return get_malloc_hooks ()->memalloc (size);
return npw_mem_alloc (size, NULL, 0);
}
void *
NPW_MemAlloc0 (uint32_t size)
{
return get_malloc_hooks ()->memalloc0 (size);
return npw_mem_alloc0 (size, NULL, 0);
}
void *
NPW_MemAllocCopy (uint32_t size, const void *src)
NPW_MemAllocCopy (uint32_t size, const void *ptr)
{
void *ptr = NPW_MemAlloc (size);
if (ptr)
memcpy (ptr, src, size);
return ptr;
return npw_mem_alloc_copy (size, ptr, NULL, 0);
}
void
NPW_MemFree (void *ptr)
{
get_malloc_hooks ()->memfree (ptr);
npw_mem_free (ptr, NULL, 0);
}
void *
NPW_Debug_MemAlloc (uint32_t size, const char *file, int lineno)
{
return npw_mem_alloc (size, file, lineno);
}
void *
NPW_Debug_MemAlloc0 (uint32_t size, const char *file, int lineno)
{
return npw_mem_alloc0 (size, file, lineno);
}
void *
NPW_Debug_MemAllocCopy (uint32_t size, const void *ptr, const char *file, int lineno)
{
return npw_mem_alloc_copy (size, ptr, file, lineno);
}
void
NPW_Debug_MemFree (void *ptr, const char *file, int lineno)
{
npw_mem_free (ptr, file, lineno);
}
/* ====================================================================== */
/* === Implementation allowing basic underflow/overflow checks === */
/* ====================================================================== */
#ifdef ENABLE_MALLOC_CHECK
static bool
is_malloc_check_enabled_1 (void)
{
const char *malloc_check_str;
if ((malloc_check_str = getenv ("NPW_MALLOC_CHECK")) != NULL)
return ((strcmp (malloc_check_str, "yes") == 0) ||
(strcmp (malloc_check_str, "1") == 0));
/* enable malloc-checks by default for all builds from snapshots */
return NPW_SNAPSHOT > 0;
}
#endif
#define MALLOC_CHECK_GUARD_MARK 'E'
#define MALLOC_CHECK_GUARD_SIZE malloc_check_guards_size ()
static inline bool
is_malloc_check_enabled (void)
{
#ifdef ENABLE_MALLOC_CHECK
static int malloc_check = -1;
if (malloc_check < 0)
malloc_check = is_malloc_check_enabled_1 ();
return malloc_check;
#else
return false;
#endif
}
static inline uint32_t
malloc_check_guards_size (void)
{
return is_malloc_check_enabled () ? 16 : 0;
}
static void
malloc_check_guards_init (uint8_t *ptr, uint32_t size)
{
if (!is_malloc_check_enabled ())
return;
memset (ptr - MALLOC_CHECK_GUARD_SIZE,
MALLOC_CHECK_GUARD_MARK,
MALLOC_CHECK_GUARD_SIZE);
memset (ptr + size,
MALLOC_CHECK_GUARD_MARK,
MALLOC_CHECK_GUARD_SIZE);
}
static bool
malloc_check_guards_ok (uint8_t *ptr, uint32_t size, int *punderflow, int *poverflow)
{
if (!is_malloc_check_enabled ())
return true;
int i, underflow = 0, overflow = 0;
for (i = 0; i < MALLOC_CHECK_GUARD_SIZE; i++)
{
if (ptr[-(1 + i)] != MALLOC_CHECK_GUARD_MARK)
++underflow;
if (ptr[size + i] != MALLOC_CHECK_GUARD_MARK)
++overflow;
}
if (punderflow)
*punderflow = underflow;
if (poverflow)
*poverflow = overflow;
return !underflow && !overflow;
}
static inline void *
npw_do_mem_alloc (NPW_MemAllocProcPtr mem_alloc_func, uint32_t size, const char *file, int lineno)
{
uint32_t real_size;
NPW_MemBlock *mem;
real_size = sizeof (*mem) + size + 2 * MALLOC_CHECK_GUARD_SIZE;
if ((mem = mem_alloc_func (real_size)) == NULL)
return NULL;
mem->magic = NPW_MALLOC_MAGIC;
mem->real_size = real_size;
mem->alloc_size = size;
mem->alloc_file = file;
mem->alloc_lineno = lineno;
uint8_t *ptr = (uint8_t *)mem + sizeof (*mem) + MALLOC_CHECK_GUARD_SIZE;
malloc_check_guards_init (ptr, size);
return ptr;
}
static void *
npw_mem_alloc (uint32_t size, const char *file, int lineno)
{
return npw_do_mem_alloc (get_malloc_hooks ()->memalloc, size, file, lineno);
}
static void *
npw_mem_alloc0 (uint32_t size, const char *file, int lineno)
{
return npw_do_mem_alloc (get_malloc_hooks ()->memalloc0, size, file, lineno);
}
static void *
npw_mem_alloc_copy (uint32_t size, const void *src, const char *file, int lineno)
{
void *ptr = npw_mem_alloc (size, file, lineno);
if (ptr)
memcpy (ptr, src, size);
return ptr;
}
static void
npw_mem_free (void *ptr, const char *file, int lineno)
{
if (ptr == NULL)
return;
NPW_MemBlock *mem = (NPW_MemBlock *)((char *)ptr - (sizeof (*mem) + MALLOC_CHECK_GUARD_SIZE));
if (mem->magic == NPW_MALLOC_MAGIC)
{
int underflow, overflow;
if (!malloc_check_guards_ok (ptr, mem->alloc_size, &underflow, &overflow))
{
if (underflow)
npw_printf ("ERROR: detected underflow of %d bytes\n"
" for block allocated at %s:%d\n"
" and released at %s:%d\n",
underflow,
mem->alloc_file, mem->alloc_lineno,
file, lineno);
if (overflow)
npw_printf ("ERROR: detected overflow of %d bytes\n"
" for block allocated at %s:%d\n"
" and released at %s:%d\n",
overflow,
mem->alloc_file, mem->alloc_lineno,
file, lineno);
}
get_malloc_hooks ()->memfree (mem, mem->real_size);
}
else
{
npw_printf("ERROR: block %p was not allocated with NPW_MemAlloc(), reverting to libc free()\n", ptr);
free (ptr);
}
}

View File

@ -33,6 +33,18 @@ NPW_MemAllocCopy (uint32_t size, const void *ptr);
void
NPW_MemFree (void *ptr);
void *
NPW_Debug_MemAlloc (uint32_t size, const char *file, int lineno);
void *
NPW_Debug_MemAlloc0 (uint32_t size, const char *file, int lineno);
void *
NPW_Debug_MemAllocCopy (uint32_t size, const void *ptr, const char *file, int lineno);
void
NPW_Debug_MemFree (void *ptr, const char *file, int lineno);
#define NPW_MemNew(type, n) \
((type *) NPW_MemAlloc ((n) * sizeof (type)))
@ -42,4 +54,11 @@ NPW_MemFree (void *ptr);
#define NPW_MemClone(type, ptr) \
((type *) NPW_MemAllocCopy (sizeof (type), ptr))
#ifdef ENABLE_MALLOC_CHECK
# define NPW_MemAlloc(SIZE) NPW_Debug_MemAlloc(SIZE, __FILE__, __LINE__)
# define NPW_MemAlloc0(SIZE) NPW_Debug_MemAlloc0(SIZE, __FILE__, __LINE__)
# define NPW_MemAllocCopy(SIZE, PTR) NPW_Debug_MemAllocCopy(SIZE, PTR, __FILE__, __LINE__)
# define NPW_MemFree(PTR) NPW_Debug_MemFree(PTR, __FILE__, __LINE__)
#endif
#endif /* NPW_MALLOC_H */

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,8 @@
#
# nsplugin viewer wrapper script (C) 2005-2006 Gwenole Beauchesne
#
OS="`uname -s`"
OS="`uname -s | tr '[A-Z]' '[a-z]'`"
ARCH="`uname -m`"
NPW_LIBDIR="%NPW_LIBDIR%"
if test -z "$TARGET_OS"; then
echo "*** NSPlugin Viewer *** error, TARGET_OS not initialized"
@ -16,7 +15,54 @@ if test -z "$TARGET_ARCH"; then
exit 1
fi
NPW_VIEWER_DIR=$NPW_LIBDIR/$TARGET_ARCH/$TARGET_OS
normalize_cpu() {
local cpu="$1"
case "$cpu" in
arm*)
cpu="arm"
;;
i[3456]86|k[678]|i86pc|BePC)
cpu="i386"
;;
ia64)
cpu="ia64"
;;
"Power Macintosh"|ppc)
cpu="ppc"
;;
ppc64)
cpu="ppc64"
;;
sparc)
cpu="sparc"
;;
sparc64)
cpu="sparc64"
;;
x86_64|amd64)
cpu="x86_64"
;;
esac
echo "$cpu"
}
normalize_os() {
local os="$1"
case "$os" in
sunos*)
os="solaris"
;;
esac
echo "$os"
}
ARCH=`normalize_cpu "$ARCH"`
OS=`normalize_os "$OS"`
TARGET_ARCH=`normalize_cpu "$TARGET_ARCH"`
TARGET_OS=`normalize_os "$TARGET_OS"`
# Define where npviewer.bin is located
NPW_VIEWER_DIR="%NPW_VIEWER_DIR%"
# Set a new LD_LIBRARY_PATH that is TARGET specific
export LD_LIBRARY_PATH=$NPW_VIEWER_DIR
@ -31,24 +77,15 @@ NPW_USE_XSHM=${NPW_USE_XSHM:-yes}
NPW_USE_VALGRIND=${NPW_USE_VALGRIND:-no}
can_use_valgrind="no"
case $ARCH in
i?86|i86pc)
ARCH=i386
;;
amd64)
ARCH=x86_64
;;
esac
if test "$ARCH" != "$TARGET_ARCH"; then
case $TARGET_ARCH in
i386)
if test "$ARCH" = "x86_64"; then
case "$OS" in
Linux)
linux)
LOADER=`which linux32`
;;
FreeBSD | NetBSD)
freebsd | netbsd)
# XXX check that COMPAT_LINUX is enabled or fail otherwise
LOADER="none"
;;
@ -66,7 +103,7 @@ if test "$ARCH" != "$TARGET_ARCH"; then
ppc)
if test "$ARCH" = "ppc64"; then
case "$OS" in
Linux)
linux)
LOADER=`which linux32`
;;
esac
@ -98,7 +135,7 @@ if test "$NPW_USE_XSHM" != "yes"; then
fi
# Expand PATH for RealPlayer package on NetBSD (realplay)
if test "$OS" = "NetBSD"; then
if test "$OS" = "netbsd"; then
REALPLAYER_HOME="/usr/pkg/lib/RealPlayer"
if test -x "$REALPLAYER_HOME/realplay"; then
export PATH=$PATH:$REALPLAYER_HOME
@ -114,7 +151,7 @@ case " $@ " in
# XXX: detect QEMU target soundwrapper differently
case "$LOADER" in
*linux32)
if test "$OS" = "Linux"; then
if test "$OS" = "linux"; then
soundwrapper=`which soundwrapper 2>/dev/null`
if test -x "$soundwrapper"; then
LOADER="$LOADER $soundwrapper"

View File

@ -21,7 +21,6 @@
#define _GNU_SOURCE 1 /* RTLD_DEFAULT */
#include "sysdeps.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -61,12 +60,17 @@ const NPW_PluginInfo NPW_Plugin = {
NPW_DEFAULT_PLUGIN_PATH,
0,
HOST_OS,
HOST_ARCH
HOST_ARCH,
NPW_PLUGIN_INFO_VERSION,
""
};
// Path to plugin to use
static const char *plugin_path = NPW_Plugin.path;
// Path to associated plugin viewer
static const char *plugin_viewer_path = NPW_Plugin.viewer_path;
// Netscape exported functions
static NPNetscapeFuncs mozilla_funcs;
@ -2607,7 +2611,7 @@ g_NP_GetValue(void *future, NPPVariable variable, void *value)
str =
"<a href=\"http://gwenole.beauchesne.info/projects/nspluginwrapper/\">nspluginwrapper</a> "
" is a cross-platform NPAPI plugin viewer, in particular for linux/i386 plugins.<br>"
"This software is available under the terms of the GNU General Public License.<br>"
"This <b>beta</b> software is available under the terms of the GNU General Public License.<br>"
;
ret = NPERR_NO_ERROR;
}
@ -3348,15 +3352,13 @@ static void plugin_init(int is_NP_Initialize)
static int init_count = 0;
++init_count;
char viewer_path[PATH_MAX];
sprintf(viewer_path, "%s/%s/%s/%s", NPW_LIBDIR, NPW_Plugin.target_arch, NPW_Plugin.target_os, NPW_VIEWER);
char connection_path[128];
sprintf(connection_path, "%s/%s/%d-%d", NPW_CONNECTION_PATH, plugin_file_name, getpid(), init_count);
// Cache MIME info and plugin name/description
if (g_plugin.name == NULL && g_plugin.description == NULL && g_plugin.formats == NULL) {
char command[1024];
if (snprintf(command, sizeof(command), "%s --info --plugin %s", viewer_path, plugin_path) >= sizeof(command))
if (snprintf(command, sizeof(command), "%s --info --plugin %s", plugin_viewer_path, plugin_path) >= sizeof(command))
return;
FILE *viewer_fp = popen(command, "r");
if (viewer_fp == NULL)
@ -3416,7 +3418,7 @@ static void plugin_init(int is_NP_Initialize)
npw_close_all_open_files();
execv(viewer_path, argv);
execv(plugin_viewer_path, argv);
npw_printf("ERROR: failed to execute NSPlugin viewer\n");
_Exit(255);
}

223
src/rpc.c
View File

@ -60,9 +60,11 @@
// build of the viewer can interoperate with non-Linux wrappers. Linux
// distributions can use this code though.
// XXX better clean-up dead sockets properly on failure...
#ifdef BUILD_LINUX_ONLY
#ifndef BUILD_GENERIC
#if defined(__linux__)
#define USE_ANONYMOUS_SOCKETS 1
#endif
#endif
// Define the maximum amount of time (in seconds) to wait for a message
#ifndef RPC_MESSAGE_TIMEOUT
@ -459,6 +461,8 @@ struct rpc_connection {
int status;
int socket;
char *socket_path;
struct sockaddr_un socket_addr;
socklen_t socket_addr_len;
int server_socket;
int server_thread_active;
pthread_t server_thread;
@ -663,25 +667,22 @@ static int _rpc_socket_path(char **pathp, const char *ident)
return n;
}
// Initialize server-side RPC system
rpc_connection_t *rpc_init_server(const char *ident)
// Create a new RPC connection (initialize common structure members)
static rpc_connection_t *rpc_connection_new(int type, const char *ident)
{
D(bug("rpc_init_server ident='%s'\n", ident));
rpc_connection_t *connection;
struct sockaddr_un addr;
socklen_t addr_len;
if (ident == NULL)
return NULL;
connection = (rpc_connection_t *)calloc(1, sizeof(*connection));
if (connection == NULL)
if ((connection = (rpc_connection_t *)calloc(1, sizeof(*connection))) == NULL)
return NULL;
connection->type = RPC_CONNECTION_SERVER;
connection->type = type;
connection->refcnt = 1;
connection->status = RPC_STATUS_CLOSED;
connection->socket = -1;
connection->server_socket = -1;
connection->server_thread_active = 0;
connection->error_callback = NULL;
connection->error_callback_data = NULL;
@ -690,136 +691,54 @@ rpc_connection_t *rpc_init_server(const char *ident)
connection->handle_depth = 0;
connection->sync_depth = 0;
connection->pending_sync_depth = 0;
if ((connection->types = rpc_map_new_full((free))) == NULL) {
rpc_exit(connection);
return NULL;
}
if ((connection->methods = rpc_map_new()) == NULL) {
rpc_exit(connection);
return NULL;
}
if ((connection->server_socket = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0)) < 0) {
perror("server socket");
int fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
if (fd < 0) {
perror("socket");
rpc_exit(connection);
return NULL;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
connection->socket_path = NULL;
addr_len = _rpc_socket_path(&connection->socket_path, ident);
memcpy(&addr.sun_path[0], connection->socket_path, addr_len);
addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
addr.sun_len = addr_len;
#endif
if (type == RPC_CONNECTION_SERVER)
connection->server_socket = fd;
else {
connection->socket = fd;
if (bind(connection->server_socket, (struct sockaddr *)&addr, addr_len) < 0) {
perror("server bind");
rpc_exit(connection);
return NULL;
}
if (listen(connection->server_socket, 1) < 0) {
perror("server listen");
rpc_exit(connection);
return NULL;
}
connection->status = RPC_STATUS_ACTIVE;
return connection;
}
// Initialize client-side RPC system
rpc_connection_t *rpc_init_client(const char *ident)
{
D(bug("rpc_init_client ident='%s'\n", ident));
rpc_connection_t *connection;
struct sockaddr_un addr;
socklen_t addr_len;
if (ident == NULL)
return NULL;
connection = (rpc_connection_t *)calloc(1, sizeof(*connection));
if (connection == NULL)
return NULL;
connection->type = RPC_CONNECTION_CLIENT;
connection->refcnt = 1;
connection->status = RPC_STATUS_CLOSED;
connection->server_socket = -1;
connection->error_callback = NULL;
connection->error_callback_data = NULL;
connection->dispatch_depth = 0;
connection->invoke_depth = 0;
connection->handle_depth = 0;
connection->sync_depth = 0;
connection->pending_sync_depth = 0;
if ((connection->types = rpc_map_new_full((free))) == NULL) {
rpc_exit(connection);
return NULL;
}
if ((connection->methods = rpc_map_new()) == NULL) {
rpc_exit(connection);
return NULL;
}
if ((connection->socket = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0)) < 0) {
perror("client socket");
rpc_exit(connection);
return NULL;
}
if (rpc_set_non_blocking_io(connection->socket) < 0) {
perror("client socket set non-blocking");
rpc_exit(connection);
return NULL;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
connection->socket_path = NULL;
addr_len = _rpc_socket_path(&connection->socket_path, ident);
memcpy(&addr.sun_path[0], connection->socket_path, addr_len);
addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
addr.sun_len = addr_len;
#endif
// Wait at most RPC_INIT_TIMEOUT seconds for server to initialize
const int N_CONNECT_WAIT_DELAY = 10;
int n_connect_attempts = (rpc_init_timeout() * 1000) / N_CONNECT_WAIT_DELAY;
if (n_connect_attempts == 0)
n_connect_attempts = 1;
while (n_connect_attempts > 0) {
if (connect(connection->socket, (struct sockaddr *)&addr, addr_len) == 0)
break;
if (n_connect_attempts > 1 && errno != ECONNREFUSED && errno != ENOENT) {
perror("client_connect");
if (rpc_set_non_blocking_io(fd) < 0) {
perror("socket set non-blocking");
rpc_exit(connection);
return NULL;
}
n_connect_attempts--;
rpc_delay(N_CONNECT_WAIT_DELAY * 1000);
}
if (n_connect_attempts == 0) {
rpc_exit(connection);
return NULL;
}
connection->status = RPC_STATUS_ACTIVE;
memset(&connection->socket_addr, 0, sizeof(connection->socket_addr));
connection->socket_addr.sun_family = AF_UNIX;
connection->socket_path = NULL;
connection->socket_addr_len = _rpc_socket_path(&connection->socket_path, ident);
memcpy(&connection->socket_addr.sun_path[0], connection->socket_path, connection->socket_addr_len);
connection->socket_addr_len += offsetof(struct sockaddr_un, sun_path); /* though POSIX says size of the actual sockaddr structure */
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
connection->socket_addr.sun_len = connection->socket_addr_len;
#endif
return connection;
}
// Close RPC connection
int rpc_exit(rpc_connection_t *connection)
// Destroy an RPC connection
static void rpc_connection_destroy(rpc_connection_t *connection)
{
D(bug("rpc_exit\n"));
if (connection == NULL)
return RPC_ERROR_CONNECTION_NULL;
return;
if (connection->socket_path) {
if (connection->socket_path[0])
@ -860,6 +779,78 @@ int rpc_exit(rpc_connection_t *connection)
}
free(connection);
}
// Initialize server-side RPC system
rpc_connection_t *rpc_init_server(const char *ident)
{
D(bug("rpc_init_server ident='%s'\n", ident));
rpc_connection_t *connection;
if ((connection = rpc_connection_new(RPC_CONNECTION_SERVER, ident)) == NULL)
return NULL;
if (bind(connection->server_socket, (struct sockaddr *)&connection->socket_addr, connection->socket_addr_len) < 0) {
perror("server bind");
rpc_exit(connection);
return NULL;
}
if (listen(connection->server_socket, 1) < 0) {
perror("server listen");
rpc_exit(connection);
return NULL;
}
connection->status = RPC_STATUS_ACTIVE;
return connection;
}
// Initialize client-side RPC system
rpc_connection_t *rpc_init_client(const char *ident)
{
D(bug("rpc_init_client ident='%s'\n", ident));
rpc_connection_t *connection;
if ((connection = rpc_connection_new(RPC_CONNECTION_CLIENT, ident)) == NULL)
return NULL;
// Wait at most RPC_INIT_TIMEOUT seconds for server to initialize
const int N_CONNECT_WAIT_DELAY = 10;
int n_connect_attempts = (rpc_init_timeout() * 1000) / N_CONNECT_WAIT_DELAY;
if (n_connect_attempts == 0)
n_connect_attempts = 1;
while (n_connect_attempts > 0) {
if (connect(connection->socket, (struct sockaddr *)&connection->socket_addr, connection->socket_addr_len) == 0)
break;
if (n_connect_attempts > 1 && errno != ECONNREFUSED && errno != ENOENT) {
perror("client_connect");
rpc_exit(connection);
return NULL;
}
n_connect_attempts--;
rpc_delay(N_CONNECT_WAIT_DELAY * 1000);
}
if (n_connect_attempts == 0) {
rpc_exit(connection);
return NULL;
}
connection->status = RPC_STATUS_ACTIVE;
return connection;
}
// Close RPC connection
int rpc_exit(rpc_connection_t *connection)
{
D(bug("rpc_exit\n"));
if (connection == NULL)
return RPC_ERROR_CONNECTION_NULL;
rpc_connection_destroy(connection);
return RPC_ERROR_NO_ERROR;
}

View File

@ -45,9 +45,9 @@
#define NPW_VIEWER NPW_VIEWER_BASE
#define NPW_WRAPPER_BASE "npwrapper"
#define NPW_WRAPPER NPW_WRAPPER_BASE ".so"
#define NPW_OLD_DEFAULT_PLUGIN_PATH NPW_LIBDIR "/" HOST_ARCH "/" NPW_WRAPPER
#define NPW_DEFAULT_PLUGIN_PATH NPW_LIBDIR "/" HOST_ARCH "/" HOST_OS "/" NPW_WRAPPER
#define NPW_PLUGIN_IDENT "NPW:" NPW_VERSION
#define NPW_DEFAULT_PLUGIN_PATH NPW_HOST_LIBDIR "/" NPW_WRAPPER
#define NPW_PLUGIN_INFO_VERSION 2
#define NPW_PLUGIN_IDENT "NPW:X:" NPW_VERSION
#define NPW_PLUGIN_IDENT_SIZE 32
typedef struct __attribute__((packed)) {
char ident[NPW_PLUGIN_IDENT_SIZE];
@ -55,6 +55,8 @@ typedef struct __attribute__((packed)) {
time_t mtime;
char target_arch[65];
char target_os[65];
char struct_version; /* extended format "NPW:X:VERSION" */
char viewer_path[PATH_MAX];
} NPW_PluginInfo;
#if defined(BUILD_XPCOM)