FAQ Search Today's Posts Mark Forums Read

» Linux Archive
Home
New Posts
Search
FAQ


Go Back   Linux Archive > Redhat > Fedora/Linux Management Tools

 
 
LinkBack Thread Tools
 
Old 08-08-2008, 02:43 PM
"Richard W.M. Jones"
 
Default "Launch virt-viewer" (new) browser plugin.

"Launch virt-viewer" (new) browser plugin.
- Based on npshell from xulrunner 1.9.0.
- Includes test page.


The file 'npunix.c' is pretty much identical to what is in xulrunner
1.9.0, except that I made a few const-correctness fixes.

The file 'npshell.c' is only minimally modified from what is in
xulrunner, just changed so that it calls the new plugin entry points.

The interesting stuff happens in 'launcher_plugin.c' and 'test.html'.

The easiest way to test this is:

./autogen.sh --enable-plugin
make
cp plugin/virt-viewer-plugin.so ~/.mozilla/plugins/
firefox `pwd`/plugin/test.html

Rich.

--
Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine. Supports Linux and Windows.
http://et.redhat.com/~rjones/virt-df/
# HG changeset patch
# User "Richard W.M. Jones <rjones@redhat.com>"
# Date 1218201453 -3600
# Node ID a378a0a13abae0ea86d07d2dacc1384f0ac712a8
# Parent dc12fc3a78696ea36adb442ed0aa3304cbf06596
"Launch virt-viewer" (new) browser plugin.
- Based on npshell from xulrunner 1.9.0.
- Includes test page.

diff -r dc12fc3a7869 -r a378a0a13aba plugin/Makefile.am
--- a/plugin/Makefile.am Fri Aug 08 11:29:51 2008 +0100
+++ b/plugin/Makefile.am Fri Aug 08 14:17:33 2008 +0100
@@ -1,4 +1,29 @@
if ENABLE_PLUGIN

+plugindir = $(libdir)/mozilla/plugins
+plugin_LTLIBRARIES = virt-viewer-plugin.la
+
+virt_viewer_plugin_la_SOURCES =
+ npshell.c npunix.c launcher_plugin.c launcher_plugin.h
+virt_viewer_plugin_la_LIBADD = @FIREFOX_PLUGIN_LIBS@
+virt_viewer_plugin_la_LDFLAGS = -module -avoid-version
+virt_viewer_plugin_la_CFLAGS =
+ -DENABLE_DEBUG=1 -DDEBUG=1
+ @FIREFOX_PLUGIN_CFLAGS@
+ @WARN_CFLAGS@
+
+all-local: virt-viewer-plugin.so
+
+virt-viewer-plugin.so: virt-viewer-plugin.la
+ cp .libs/virt-viewer-plugin.so $@
+
+# Only leave the .so file in the plugins directory.
+install-data-hook:
+ rm -f $(plugindir)/virt-viewer-plugin.a
+ $(plugindir)/virt-viewer-plugin.la
+
+CLEANFILES = virt-viewer-plugin.so
+
+EXTRA_DIST = test.html

endif
diff -r dc12fc3a7869 -r a378a0a13aba plugin/launcher_plugin.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/launcher_plugin.c Fri Aug 08 14:17:33 2008 +0100
@@ -0,0 +1,160 @@
+/*
+ * Virt Viewer New Browser Plugin
+ *
+ * Copyright (C) 2008 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Richard W.M. Jones <rjones@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include <npapi.h>
+#include <plstr.h>
+
+#include "launcher_plugin.h"
+
+static void startVirtViewerAndExit (PluginInstance *, const char *uri, const char *name, int direct, int waitvnc);
+
+NPError
+launcherRun (PluginInstance *self,
+ int16 argc, char* argn[], char* argv[])
+{
+ int i;
+ const char *uri = NULL;
+ const char *name = NULL;
+ int direct = 0;
+ int waitvnc = 0;
+ int pid;
+
+ /* Protect against being called multiple times. */
+ if (!self->launched) {
+ self->launched = TRUE;
+
+ /* Parse the parameters given in <embed ...>. */
+ i = argc;
+ while (i > 0) {
+ i --;
+ if (argv[i] != NULL) {
+ if (!PL_strcasecmp (argn[i], "URI"))
+ uri = argv[i];
+ else if (!PL_strcasecmp (argn[i], "NAME"))
+ name = argv[i];
+ else if (!PL_strcasecmp (argn[i], "DIRECT"))
+ direct = strcmp (argv[i], "1") == 0;
+ else if (!PL_strcasecmp (argn[i], "WAITVNC"))
+ waitvnc = strcmp (argv[i], "1") == 0;
+ }
+ }
+
+ /* Create child process. */
+ pid = fork ();
+ if (pid < 0) {
+ perror ("fork");
+ return NPERR_GENERIC_ERROR;
+ }
+ if (pid == 0) /* Child. */
+ startVirtViewerAndExit (self, uri, name, direct, waitvnc);
+ else /* Parent. */
+ waitpid (pid, NULL, 0);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+static void
+startVirtViewerAndExit (PluginInstance *self ATTRIBUTE_UNUSED,
+ const char *uri, const char *name,
+ int direct, int waitvnc)
+{
+ int pid;
+ int i, maxfd, len;
+ const char **argv;
+
+ /* Fork again to detach ourselves completely from the browser
+ * process (probably not necessary on Windoze).
+ */
+ pid = fork ();
+ if (pid < 0) {
+ perror ("fork");
+ return;
+ }
+ if (pid > 0) /* Parent. */
+ _exit (0);
+
+ /* Child ... Close any open file descriptors, leaving 0, 1 & 2
+ * connected so that we'll still see any error messages.
+ */
+ maxfd = sysconf (_SC_OPEN_MAX) - 1;
+ for (i = 3; i <= maxfd; ++i)
+ close (i);
+
+ /* Build the argument array. */
+ len = 1 + /* "virt-viewer" (argv 0) */
+ (uri ? 2 : 0) + /* "-c" uri */
+ (direct ? 1 : 0) + /* "-d" */
+ (waitvnc ? 1 : 0) + /* "-w" */
+ 1 + /* name */
+ 1; /* NULL */
+ argv = NPN_MemAlloc (sizeof (char *) * len);
+ if (!argv) {
+ perror ("malloc");
+ goto cleanup;
+ }
+
+ i = 0;
+ argv[i++] = "virt-viewer";
+ if (uri) {
+ argv[i++] = "-c";
+ argv[i++] = uri;
+ }
+ if (direct)
+ argv[i++] = "-d";
+ if (waitvnc)
+ argv[i++] = "-w";
+ argv[i++] = name;
+
+ argv[i++] = NULL;
+
+ if (i != len) {
+ fprintf (stderr,
+ "virt-viewer launcher_plugin: internal error: i=%d != len=%d
",
+ i, len);
+ goto cleanup;
+ }
+
+ execvp ("virt-viewer", argv);
+ perror ("execvp");
+
+ cleanup:
+ _exit (1);
+}
+
+void
+launcherDestroy (PluginInstance *self)
+{
+ /* Nothing to free. Just stop launcherRun from doing anything if
+ * the browser tries to (incorrectly) call it a second time. Not
+ * that well-written browsers would do anything like that. Oh no.
+ */
+ self->launched = TRUE;
+}
diff -r dc12fc3a7869 -r a378a0a13aba plugin/launcher_plugin.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/launcher_plugin.h Fri Aug 08 14:17:33 2008 +0100
@@ -0,0 +1,88 @@
+/*
+ * Virt Viewer New Browser Plugin
+ *
+ * Copyright (C) 2008 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Richard W.M. Jones <rjones@redhat.com>
+ */
+
+#include <config.h>
+
+#ifndef LAUNCHER_PLUGIN_H
+#define LAUNCHER_PLUGIN_H
+
+#include <stdarg.h>
+#include <npapi.h>
+
+#define PLUGIN_NAME "Virt-viewer new browser plugin"
+#define MIME_TYPES_HANDLED "application/x-virt-viewer:virt-viewer:Virt viewer"
+#define PLUGIN_DESCRIPTION "Browser plugin which launches 'virt-viewer' program to display virtual machine consoles."
+
+struct _PluginInstance {
+ /* These standard fields are filled in by npshell, based on
+ * standard parameters given to the plugin (eg. in <embed ...>).
+ */
+ uint16 mode;
+#ifdef MOZ_X11
+ NPWindow *window;
+ int32 x, y;
+ uint32 width, height;
+#endif
+
+ NPMIMEType type;
+ NPP instance;
+ char *pluginsPageUrl;
+ char *pluginsFileUrl;
+ NPBool pluginsHidden;
+
+ /* Custom fields for this plugin. */
+ NPBool launched; /* Did we launch the external program yet? */
+};
+
+typedef struct _PluginInstance PluginInstance;
+
+/* These functions in launcher_plugin.c are called from npshell
+ * when significant events happen in the lifecycle of the plugin
+ * instance.
+ */
+extern NPError launcherRun (PluginInstance *,
+ int16 argc, char* argn[], char* argv[]);
+extern void launcherDestroy (PluginInstance *);
+
+#ifdef __GNUC__
+#define ATTRIBUTE_UNUSED __attribute__((__unused__))
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+#ifdef ENABLE_DEBUG
+static void
+debug (const char *msg, ...)
+{
+ va_list args;
+
+ va_start (args, msg);
+ vfprintf (stderr, msg, args);
+ va_end (args);
+ fprintf (stderr, "
");
+ fflush (stderr);
+}
+#else
+static void debug (const char *msg ATTRIBUTE_UNUSED, ...) { }
+#endif
+
+#endif /* LAUNCHER_PLUGIN_H */
diff -r dc12fc3a7869 -r a378a0a13aba plugin/npshell.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/npshell.c Fri Aug 08 14:17:33 2008 +0100
@@ -0,0 +1,424 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Mak <smak@sun.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * npshell.c
+ *
+ * Netscape Client Plugin API
+ * - Function that need to be implemented by plugin developers
+ *
+ * This file defines a "shell" plugin that plugin developers can use
+ * as the basis for a real plugin. This shell just provides empty
+ * implementations of all functions that the plugin can implement
+ * that will be called by Netscape (the NPP_xxx methods defined in
+ * npapi.h).
+ *
+ * dp Suresh <dp@netscape.com>
+ * updated 5/1998 <pollmann@netscape.com>
+ * updated 9/2000 <smak@sun.com>
+ *
+ */
+
+#define _BSD_SOURCE 1 /* for strdup */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <npapi.h>
+#include <plstr.h>
+
+#include "launcher_plugin.h"
+
+/************************************************** *********************
+ *
+ * Implementations of plugin API functions
+ *
+ ************************************************** *********************/
+
+char *
+NPP_GetMIMEDescription(void)
+{
+ return((char *) MIME_TYPES_HANDLED);
+}
+
+NPError
+NPP_GetValue(NPP instance ATTRIBUTE_UNUSED, NPPVariable variable, void *value)
+{
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginNameString:
+ *((char **)value) = (char *) PLUGIN_NAME;
+ break;
+ case NPPVpluginDescriptionString:
+ *((char **)value) = (char *) PLUGIN_DESCRIPTION;
+ break;
+ default:
+ err = NPERR_GENERIC_ERROR;
+ }
+ return err;
+}
+
+NPError
+NPP_Initialize(void)
+{
+ return NPERR_NO_ERROR;
+}
+
+#ifdef OJI
+jref
+NPP_GetJavaClass()
+{
+ return NULL;
+}
+#endif
+
+void
+NPP_Shutdown(void)
+{
+}
+
+static NPMIMEType
+dupMimeType(NPMIMEType type)
+{
+ NPMIMEType mimetype = NPN_MemAlloc(strlen(type)+1);
+ if (mimetype)
+ strcpy(mimetype, type);
+ return(mimetype);
+}
+
+NPError
+NPP_New(NPMIMEType pluginType,
+ NPP instance,
+ uint16 mode,
+ int16 argc,
+ char* argn[],
+ char* argv[],
+ NPSavedData* saved ATTRIBUTE_UNUSED)
+{
+ PluginInstance* This;
+ int i;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This == NULL)
+ {
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+
+ memset(This, 0, sizeof(PluginInstance));
+
+ /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
+ This->mode = mode;
+ This->type = dupMimeType(pluginType);
+ This->instance = instance;
+ This->pluginsPageUrl = NULL;
+
+ /* Parse argument list passed to plugin instance */
+ /* We are interested in these arguments
+ * PLUGINSPAGE = <url>
+ */
+ i = argc;
+ while (i > 0)
+ {
+ i --;
+ if (argv[i] != NULL)
+ {
+ if (!PL_strcasecmp(argn[i], "PLUGINSPAGE"))
+ This->pluginsPageUrl = strdup(argv[i]);
+ else if (!PL_strcasecmp(argn[i], "PLUGINURL"))
+ This->pluginsFileUrl = strdup(argv[i]);
+ else if (!PL_strcasecmp(argn[i], "CODEBASE"))
+ This->pluginsPageUrl = strdup(argv[i]);
+ else if (!PL_strcasecmp(argn[i], "CLASSID"))
+ This->pluginsFileUrl = strdup(argv[i]);
+ else if (!PL_strcasecmp(argn[i], "HIDDEN"))
+ This->pluginsHidden = (!PL_strcasecmp(argv[i],
+ "TRUE"));
+ }
+ }
+
+ return launcherRun (This, argc, argn, argv);
+}
+
+NPError
+NPP_Destroy(NPP instance, NPSavedData** save ATTRIBUTE_UNUSED)
+{
+
+ PluginInstance* This;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This != NULL) {
+ launcherDestroy (This);
+ if (This->type)
+ NPN_MemFree(This->type);
+ if (This->pluginsPageUrl)
+ NPN_MemFree(This->pluginsPageUrl);
+ if (This->pluginsFileUrl)
+ NPN_MemFree(This->pluginsFileUrl);
+ NPN_MemFree(instance->pdata);
+ instance->pdata = NULL;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+
+NPError
+NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ PluginInstance* This;
+ NPSetWindowCallbackStruct *ws_info;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ ws_info = (NPSetWindowCallbackStruct *)window->ws_info;
+
+#ifdef MOZ_X11
+ if (This->window == (Window) window->window) {
+ /* The page with the plugin is being resized.
+ Save any UI information because the next time
+ around expect a SetWindow with a new window
+ id.
+ */
+#ifdef DEBUG
+ fprintf(stderr, "Nullplugin: plugin received window resize.
");
+ fprintf(stderr, "Window=(%i)
", (int)window);
+ fprintf(stderr, "W=(%i) H=(%i)
",
+ (int)window->width, (int)window->height);
+#endif
+ return NPERR_NO_ERROR;
+ } else {
+
+ This->window = (Window) window->window;
+ This->x = window->x;
+ This->y = window->y;
+ This->width = window->width;
+ This->height = window->height;
+ This->display = ws_info->display;
+ This->visual = ws_info->visual;
+ This->depth = ws_info->depth;
+ This->colormap = ws_info->colormap;
+ makePixmap(This);
+ makeWidget(This);
+ }
+#endif /* #ifdef MOZ_X11 */
+
+ return NPERR_NO_ERROR;
+}
+
+
+NPError
+NPP_NewStream(NPP instance,
+ NPMIMEType type ATTRIBUTE_UNUSED,
+ NPStream *stream ATTRIBUTE_UNUSED,
+ NPBool seekable ATTRIBUTE_UNUSED,
+ uint16 *stype ATTRIBUTE_UNUSED)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ return NPERR_NO_ERROR;
+}
+
+
+int32
+NPP_WriteReady(NPP instance, NPStream *stream)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ /* We don't want any data, kill the stream */
+ NPN_DestroyStream(instance, stream, NPRES_DONE);
+
+ /* Number of bytes ready to accept in NPP_Write() */
+ return -1L; /* don't accept any bytes in NPP_Write() */
+}
+
+
+int32
+NPP_Write(NPP instance, NPStream *stream,
+ int32 offset ATTRIBUTE_UNUSED,
+ int32 len ATTRIBUTE_UNUSED,
+ void *buffer ATTRIBUTE_UNUSED)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ /* We don't want any data, kill the stream */
+ NPN_DestroyStream(instance, stream, NPRES_DONE);
+
+ return -1L; /* don't accept any bytes in NPP_Write() */
+}
+
+
+NPError
+NPP_DestroyStream(NPP instance,
+ NPStream *stream ATTRIBUTE_UNUSED,
+ NPError reason ATTRIBUTE_UNUSED)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ /***** Insert NPP_DestroyStream code here *****
+ PluginInstance* This;
+ This = (PluginInstance*) instance->pdata;
+ **********************************************/
+
+ return NPERR_NO_ERROR;
+}
+
+
+void
+NPP_StreamAsFile(NPP instance ATTRIBUTE_UNUSED,
+ NPStream *stream ATTRIBUTE_UNUSED,
+ const char* fname ATTRIBUTE_UNUSED)
+{
+ /***** Insert NPP_StreamAsFile code here *****
+ PluginInstance* This;
+ if (instance != NULL)
+ This = (PluginInstance*) instance->pdata;
+ *********************************************/
+}
+
+
+void
+NPP_URLNotify(NPP instance ATTRIBUTE_UNUSED,
+ const char* url ATTRIBUTE_UNUSED,
+ NPReason reason ATTRIBUTE_UNUSED,
+ void* notifyData ATTRIBUTE_UNUSED)
+{
+ /***** Insert NPP_URLNotify code here *****
+ PluginInstance* This;
+ if (instance != NULL)
+ This = (PluginInstance*) instance->pdata;
+ *********************************************/
+}
+
+
+void
+NPP_Print(NPP instance, NPPrint* printInfo)
+{
+ if(printInfo == NULL)
+ return;
+
+ if (instance != NULL) {
+ /***** Insert NPP_Print code here *****
+ PluginInstance* This = (PluginInstance*) instance->pdata;
+ **************************************/
+
+ if (printInfo->mode == NP_FULL) {
+ /*
+ * PLUGIN DEVELOPERS:
+ * If your plugin would like to take over
+ * printing completely when it is in full-screen mode,
+ * set printInfo->pluginPrinted to TRUE and print your
+ * plugin as you see fit. If your plugin wants Netscape
+ * to handle printing in this case, set
+ * printInfo->pluginPrinted to FALSE (the default) and
+ * do nothing. If you do want to handle printing
+ * yourself, printOne is true if the print button
+ * (as opposed to the print menu) was clicked.
+ * On the Macintosh, platformPrint is a THPrint; on
+ * Windows, platformPrint is a structure
+ * (defined in npapi.h) containing the printer name, port,
+ * etc.
+ */
+
+ /***** Insert NPP_Print code here *****
+ void* platformPrint =
+ printInfo->print.fullPrint.platformPrint;
+ NPBool printOne =
+ printInfo->print.fullPrint.printOne;
+ **************************************/
+
+ /* Do the default*/
+ printInfo->print.fullPrint.pluginPrinted = FALSE;
+ }
+ else { /* If not fullscreen, we must be embedded */
+ /*
+ * PLUGIN DEVELOPERS:
+ * If your plugin is embedded, or is full-screen
+ * but you returned false in pluginPrinted above, NPP_Print
+ * will be called with mode == NP_EMBED. The NPWindow
+ * in the printInfo gives the location and dimensions of
+ * the embedded plugin on the printed page. On the
+ * Macintosh, platformPrint is the printer port; on
+ * Windows, platformPrint is the handle to the printing
+ * device context.
+ */
+
+ /***** Insert NPP_Print code here *****
+ NPWindow* printWindow =
+ &(printInfo->print.embedPrint.window);
+ void* platformPrint =
+ printInfo->print.embedPrint.platformPrint;
+ **************************************/
+ }
+ }
+}
+
+/*
+ * vim: set tabstop=4:
+ * vim: set shiftwidth=4:
+ * vim: set expandtab:
+ */
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r dc12fc3a7869 -r a378a0a13aba plugin/npunix.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/npunix.c Fri Aug 08 14:17:33 2008 +0100
@@ -0,0 +1,696 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Mak <smak@sun.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * npunix.c
+ *
+ * Netscape Client Plugin API
+ * - Wrapper function to interface with the Netscape Navigator
+ *
+ * dp Suresh <dp@netscape.com>
+ *
+ *----------------------------------------------------------------------
+ * PLUGIN DEVELOPERS:
+ * YOU WILL NOT NEED TO EDIT THIS FILE.
+ *----------------------------------------------------------------------
+ */
+
+#define XP_UNIX 1
+
+#include <stdio.h>
+#include "npapi.h"
+#include "npupp.h"
+
+/*
+ * Define PLUGIN_TRACE to have the wrapper functions print
+ * messages to stderr whenever they are called.
+ */
+
+#ifdef PLUGIN_TRACE
+#include <stdio.h>
+#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s
", msg)
+#else
+#define PLUGINDEBUGSTR(msg)
+#endif
+
+
+/************************************************** *********************
+ *
+ * Globals
+ *
+ ************************************************** *********************/
+
+static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
+
+
+/************************************************** *********************
+ *
+ * Wrapper functions : plugin calling Netscape Navigator
+ *
+ * These functions let the plugin developer just call the APIs
+ * as documented and defined in npapi.h, without needing to know
+ * about the function table and call macros in npupp.h.
+ *
+ ************************************************** *********************/
+
+void
+NPN_Version(int* plugin_major, int* plugin_minor,
+ int* netscape_major, int* netscape_minor)
+{
+ *plugin_major = NP_VERSION_MAJOR;
+ *plugin_minor = NP_VERSION_MINOR;
+
+ /* Major version is in high byte */
+ *netscape_major = gNetscapeFuncs.version >> 8;
+ /* Minor version is in low byte */
+ *netscape_minor = gNetscapeFuncs.version & 0xFF;
+}
+
+NPError
+NPN_GetValue(NPP instance, NPNVariable variable, void *r_value)
+{
+ return CallNPN_GetValueProc(gNetscapeFuncs.getvalue,
+ instance, variable, r_value);
+}
+
+NPError
+NPN_SetValue(NPP instance, NPPVariable variable, void *value)
+{
+ return CallNPN_SetValueProc(gNetscapeFuncs.setvalue,
+ instance, variable, value);
+}
+
+NPError
+NPN_GetURL(NPP instance, const char* url, const char* window)
+{
+ return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
+}
+
+NPError
+NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData)
+{
+ return CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnoti fy, instance, url, window, notifyData);
+}
+
+NPError
+NPN_PostURL(NPP instance, const char* url, const char* window,
+ uint32 len, const char* buf, NPBool file)
+{
+ return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance,
+ url, window, len, buf, file);
+}
+
+NPError
+NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len,
+ const char* buf, NPBool file, void* notifyData)
+{
+ return CallNPN_PostURLNotifyProc(gNetscapeFuncs.posturlno tify,
+ instance, url, window, len, buf, file, notifyData);
+}
+
+NPError
+NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
+{
+ return CallNPN_RequestReadProc(gNetscapeFuncs.requestread ,
+ stream, rangeList);
+}
+
+NPError
+NPN_NewStream(NPP instance, NPMIMEType type, const char *window,
+ NPStream** stream_ptr)
+{
+ return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance,
+ type, window, stream_ptr);
+}
+
+int32
+NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
+{
+ return CallNPN_WriteProc(gNetscapeFuncs.write, instance,
+ stream, len, buffer);
+}
+
+NPError
+NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
+{
+ return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroyst ream,
+ instance, stream, reason);
+}
+
+void
+NPN_Status(NPP instance, const char* message)
+{
+ CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
+}
+
+const char*
+NPN_UserAgent(NPP instance)
+{
+ return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
+}
+
+void*
+NPN_MemAlloc(uint32 size)
+{
+ return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
+}
+
+void NPN_MemFree(void* ptr)
+{
+ CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
+}
+
+uint32 NPN_MemFlush(uint32 size)
+{
+ return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
+}
+
+void NPN_ReloadPlugins(NPBool reloadPages)
+{
+ CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplu gins, reloadPages);
+}
+
+#ifdef OJI
+JRIEnv* NPN_GetJavaEnv()
+{
+ return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv);
+}
+
+jref NPN_GetJavaPeer(NPP instance)
+{
+ return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer ,
+ instance);
+}
+#endif
+
+void
+NPN_InvalidateRect(NPP instance, NPRect *invalidRect)
+{
+ CallNPN_InvalidateRectProc(gNetscapeFuncs.invalida terect, instance,
+ invalidRect);
+}
+
+void
+NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion)
+{
+ CallNPN_InvalidateRegionProc(gNetscapeFuncs.invali dateregion, instance,
+ invalidRegion);
+}
+
+void
+NPN_ForceRedraw(NPP instance)
+{
+ CallNPN_ForceRedrawProc(gNetscapeFuncs.forceredraw , instance);
+}
+
+void NPN_PushPopupsEnabledState(NPP instance, NPBool enabled)
+{
+ CallNPN_PushPopupsEnabledStateProc(gNetscapeFuncs. pushpopupsenabledstate,
+ instance, enabled);
+}
+
+void NPN_PopPopupsEnabledState(NPP instance)
+{
+ CallNPN_PopPopupsEnabledStateProc(gNetscapeFuncs.p oppopupsenabledstate,
+ instance);
+}
+
+NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name)
+{
+ return CallNPN_GetStringIdentifierProc(gNetscapeFuncs.get stringidentifier,
+ name);
+}
+
+void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
+ NPIdentifier *identifiers)
+{
+ CallNPN_GetStringIdentifiersProc(gNetscapeFuncs.ge tstringidentifiers,
+ names, nameCount, identifiers);
+}
+
+NPIdentifier NPN_GetIntIdentifier(int32_t intid)
+{
+ return CallNPN_GetIntIdentifierProc(gNetscapeFuncs.getint identifier, intid);
+}
+
+bool NPN_IdentifierIsString(NPIdentifier identifier)
+{
+ return CallNPN_IdentifierIsStringProc(gNetscapeFuncs.iden tifierisstring,
+ identifier);
+}
+
+NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier)
+{
+ return CallNPN_UTF8FromIdentifierProc(gNetscapeFuncs.utf8 fromidentifier,
+ identifier);
+}
+
+int32_t NPN_IntFromIdentifier(NPIdentifier identifier)
+{
+ return CallNPN_IntFromIdentifierProc(gNetscapeFuncs.intfr omidentifier,
+ identifier);
+}
+
+NPObject *NPN_CreateObject(NPP npp, NPClass *aClass)
+{
+ return CallNPN_CreateObjectProc(gNetscapeFuncs.createobje ct, npp, aClass);
+}
+
+NPObject *NPN_RetainObject(NPObject *obj)
+{
+ return CallNPN_RetainObjectProc(gNetscapeFuncs.retainobje ct, obj);
+}
+
+void NPN_ReleaseObject(NPObject *obj)
+{
+ CallNPN_ReleaseObjectProc(gNetscapeFuncs.releaseob ject, obj);
+}
+
+bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName,
+ const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+ return CallNPN_InvokeProc(gNetscapeFuncs.invoke, npp, obj, methodName,
+ args, argCount, result);
+}
+
+bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args,
+ uint32_t argCount, NPVariant *result)
+{
+ return CallNPN_InvokeDefaultProc(gNetscapeFuncs.invokeDef ault, npp, obj,
+ args, argCount, result);
+}
+
+bool NPN_Evaluate(NPP npp, NPObject* obj, NPString *script,
+ NPVariant *result)
+{
+ return CallNPN_EvaluateProc(gNetscapeFuncs.evaluate, npp, obj, script, result);
+}
+
+bool NPN_GetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName,
+ NPVariant *result)
+{
+ return CallNPN_GetPropertyProc(gNetscapeFuncs.getproperty , npp, obj,
+ propertyName, result);
+}
+
+bool NPN_SetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName,
+ const NPVariant *value)
+{
+ return CallNPN_SetPropertyProc(gNetscapeFuncs.setproperty , npp, obj,
+ propertyName, value);
+}
+
+bool NPN_RemoveProperty(NPP npp, NPObject* obj, NPIdentifier propertyName)
+{
+ return CallNPN_RemovePropertyProc(gNetscapeFuncs.removepr operty, npp, obj,
+ propertyName);
+}
+
+bool NPN_HasProperty(NPP npp, NPObject* obj, NPIdentifier propertyName)
+{
+ return CallNPN_HasPropertyProc(gNetscapeFuncs.hasproperty , npp, obj,
+ propertyName);
+}
+
+bool NPN_HasMethod(NPP npp, NPObject* obj, NPIdentifier methodName)
+{
+ return CallNPN_HasMethodProc(gNetscapeFuncs.hasmethod, npp, obj, methodName);
+}
+
+void NPN_ReleaseVariantValue(NPVariant *variant)
+{
+ CallNPN_ReleaseVariantValueProc(gNetscapeFuncs.rel easevariantvalue, variant);
+}
+
+void NPN_SetException(NPObject* obj, const NPUTF8 *message)
+{
+ CallNPN_SetExceptionProc(gNetscapeFuncs.setexcepti on, obj, message);
+}
+
+
+/************************************************** *********************
+ *
+ * Wrapper functions : Netscape Navigator -> plugin
+ *
+ * These functions let the plugin developer just create the APIs
+ * as documented and defined in npapi.h, without needing to
+ * install those functions in the function table or worry about
+ * setting up globals for 68K plugins.
+ *
+ ************************************************** *********************/
+
+NPError
+Private_New(NPMIMEType pluginType, NPP instance, uint16 mode,
+ int16 argc, char* argn[], char* argv[], NPSavedData* saved)
+{
+ NPError ret;
+ PLUGINDEBUGSTR("New");
+ ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
+ return ret;
+}
+
+NPError
+Private_Destroy(NPP instance, NPSavedData** save)
+{
+ PLUGINDEBUGSTR("Destroy");
+ return NPP_Destroy(instance, save);
+}
+
+NPError
+Private_SetWindow(NPP instance, NPWindow* window)
+{
+ NPError err;
+ PLUGINDEBUGSTR("SetWindow");
+ err = NPP_SetWindow(instance, window);
+ return err;
+}
+
+NPError
+Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype)
+{
+ NPError err;
+ PLUGINDEBUGSTR("NewStream");
+ err = NPP_NewStream(instance, type, stream, seekable, stype);
+ return err;
+}
+
+int32
+Private_WriteReady(NPP instance, NPStream* stream)
+{
+ unsigned int result;
+ PLUGINDEBUGSTR("WriteReady");
+ result = NPP_WriteReady(instance, stream);
+ return result;
+}
+
+int32
+Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
+ void* buffer)
+{
+ unsigned int result;
+ PLUGINDEBUGSTR("Write");
+ result = NPP_Write(instance, stream, offset, len, buffer);
+ return result;
+}
+
+void
+Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
+{
+ PLUGINDEBUGSTR("StreamAsFile");
+ NPP_StreamAsFile(instance, stream, fname);
+}
+
+
+NPError
+Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
+{
+ NPError err;
+ PLUGINDEBUGSTR("DestroyStream");
+ err = NPP_DestroyStream(instance, stream, reason);
+ return err;
+}
+
+void
+Private_URLNotify(NPP instance, const char* url,
+ NPReason reason, void* notifyData)
+
+{
+ PLUGINDEBUGSTR("URLNotify");
+ NPP_URLNotify(instance, url, reason, notifyData);
+}
+
+
+
+void
+Private_Print(NPP instance, NPPrint* platformPrint)
+{
+ PLUGINDEBUGSTR("Print");
+ NPP_Print(instance, platformPrint);
+}
+
+#ifdef OJI
+JRIGlobalRef
+Private_GetJavaClass(void)
+{
+ jref clazz = NPP_GetJavaClass();
+ if (clazz) {
+ JRIEnv* env = NPN_GetJavaEnv();
+ return JRI_NewGlobalRef(env, clazz);
+ }
+ return NULL;
+}
+#endif
+
+/************************************************** *********************
+ *
+ * These functions are located automagically by netscape.
+ *
+ ************************************************** *********************/
+
+/*
+ * NP_GetMIMEDescription
+ * - Netscape needs to know about this symbol
+ * - Netscape uses the return value to identify when an object instance
+ * of this plugin should be created.
+ */
+char *
+NP_GetMIMEDescription(void)
+{
+ return NPP_GetMIMEDescription();
+}
+
+/*
+ * NP_GetValue [optional]
+ * - Netscape needs to know about this symbol.
+ * - Interfaces with plugin to get values for predefined variables
+ * that the navigator needs.
+ */
+NPError
+NP_GetValue(void* future, NPPVariable variable, void *value)
+{
+ return NPP_GetValue(future, variable, value);
+}
+
+/*
+ * NP_Initialize
+ * - Netscape needs to know about this symbol.
+ * - It calls this function after looking up its symbol before it
+ * is about to create the first ever object of this kind.
+ *
+ * PARAMETERS
+ * nsTable - The netscape function table. If developers just use these
+ * wrappers, they don't need to worry about all these function
+ * tables.
+ * RETURN
+ * pluginFuncs
+ * - This functions needs to fill the plugin function table
+ * pluginFuncs and return it. Netscape Navigator plugin
+ * library will use this function table to call the plugin.
+ *
+ */
+NPError
+NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs)
+{
+ NPError err = NPERR_NO_ERROR;
+
+ PLUGINDEBUGSTR("NP_Initialize");
+
+ /* validate input parameters */
+
+ if ((nsTable == NULL) || (pluginFuncs == NULL))
+ err = NPERR_INVALID_FUNCTABLE_ERROR;
+
+ /*
+ * Check the major version passed in Netscape's function table.
+ * We won't load if the major version is newer than what we expect.
+ * Also check that the function tables passed in are big enough for
+ * all the functions we need (they could be bigger, if Netscape added
+ * new APIs, but that's OK with us -- we'll just ignore them).
+ *
+ */
+
+ if (err == NPERR_NO_ERROR) {
+ if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
+ err = NPERR_INCOMPATIBLE_VERSION_ERROR;
+ if (nsTable->size < ((char *)&nsTable->posturlnotify - (char *)nsTable))
+ err = NPERR_INVALID_FUNCTABLE_ERROR;
+ if (pluginFuncs->size < sizeof(NPPluginFuncs))
+ err = NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+
+ if (err == NPERR_NO_ERROR) {
+ /*
+ * Copy all the fields of Netscape function table into our
+ * copy so we can call back into Netscape later. Note that
+ * we need to copy the fields one by one, rather than assigning
+ * the whole structure, because the Netscape function table
+ * could actually be bigger than what we expect.
+ */
+ gNetscapeFuncs.version = nsTable->version;
+ gNetscapeFuncs.size = nsTable->size;
+ gNetscapeFuncs.posturl = nsTable->posturl;
+ gNetscapeFuncs.geturl = nsTable->geturl;
+ gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
+ gNetscapeFuncs.requestread = nsTable->requestread;
+ gNetscapeFuncs.newstream = nsTable->newstream;
+ gNetscapeFuncs.write = nsTable->write;
+ gNetscapeFuncs.destroystream = nsTable->destroystream;
+ gNetscapeFuncs.status = nsTable->status;
+ gNetscapeFuncs.uagent = nsTable->uagent;
+ gNetscapeFuncs.memalloc = nsTable->memalloc;
+ gNetscapeFuncs.memfree = nsTable->memfree;
+ gNetscapeFuncs.memflush = nsTable->memflush;
+ gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
+#ifdef OJI
+ gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
+ gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
+#endif
+ gNetscapeFuncs.getvalue = nsTable->getvalue;
+ gNetscapeFuncs.setvalue = nsTable->setvalue;
+ gNetscapeFuncs.posturlnotify = nsTable->posturlnotify;
+
+ if (nsTable->size >= ((char *)&nsTable->setexception - (char *)nsTable))
+ {
+ gNetscapeFuncs.invalidaterect = nsTable->invalidaterect;
+ gNetscapeFuncs.invalidateregion = nsTable->invalidateregion;
+ gNetscapeFuncs.forceredraw = nsTable->forceredraw;
+ gNetscapeFuncs.getstringidentifier = nsTable->getstringidentifier;
+ gNetscapeFuncs.getstringidentifiers = nsTable->getstringidentifiers;
+ gNetscapeFuncs.getintidentifier = nsTable->getintidentifier;
+ gNetscapeFuncs.identifierisstring = nsTable->identifierisstring;
+ gNetscapeFuncs.utf8fromidentifier = nsTable->utf8fromidentifier;
+ gNetscapeFuncs.intfromidentifier = nsTable->intfromidentifier;
+ gNetscapeFuncs.createobject = nsTable->createobject;
+ gNetscapeFuncs.retainobject = nsTable->retainobject;
+ gNetscapeFuncs.releaseobject = nsTable->releaseobject;
+ gNetscapeFuncs.invoke = nsTable->invoke;
+ gNetscapeFuncs.invokeDefault = nsTable->invokeDefault;
+ gNetscapeFuncs.evaluate = nsTable->evaluate;
+ gNetscapeFuncs.getproperty = nsTable->getproperty;
+ gNetscapeFuncs.setproperty = nsTable->setproperty;
+ gNetscapeFuncs.removeproperty = nsTable->removeproperty;
+ gNetscapeFuncs.hasproperty = nsTable->hasproperty;
+ gNetscapeFuncs.hasmethod = nsTable->hasmethod;
+ gNetscapeFuncs.releasevariantvalue = nsTable->releasevariantvalue;
+ gNetscapeFuncs.setexception = nsTable->setexception;
+ }
+ else
+ {
+ gNetscapeFuncs.invalidaterect = NULL;
+ gNetscapeFuncs.invalidateregion = NULL;
+ gNetscapeFuncs.forceredraw = NULL;
+ gNetscapeFuncs.getstringidentifier = NULL;
+ gNetscapeFuncs.getstringidentifiers = NULL;
+ gNetscapeFuncs.getintidentifier = NULL;
+ gNetscapeFuncs.identifierisstring = NULL;
+ gNetscapeFuncs.utf8fromidentifier = NULL;
+ gNetscapeFuncs.intfromidentifier = NULL;
+ gNetscapeFuncs.createobject = NULL;
+ gNetscapeFuncs.retainobject = NULL;
+ gNetscapeFuncs.releaseobject = NULL;
+ gNetscapeFuncs.invoke = NULL;
+ gNetscapeFuncs.invokeDefault = NULL;
+ gNetscapeFuncs.evaluate = NULL;
+ gNetscapeFuncs.getproperty = NULL;
+ gNetscapeFuncs.setproperty = NULL;
+ gNetscapeFuncs.removeproperty = NULL;
+ gNetscapeFuncs.hasproperty = NULL;
+ gNetscapeFuncs.releasevariantvalue = NULL;
+ gNetscapeFuncs.setexception = NULL;
+ }
+ if (nsTable->size >=
+ ((char *)&nsTable->poppopupsenabledstate - (char *)nsTable))
+ {
+ gNetscapeFuncs.pushpopupsenabledstate = nsTable->pushpopupsenabledstate;
+ gNetscapeFuncs.poppopupsenabledstate = nsTable->poppopupsenabledstate;
+ }
+ else
+ {
+ gNetscapeFuncs.pushpopupsenabledstate = NULL;
+ gNetscapeFuncs.poppopupsenabledstate = NULL;
+ }
+
+ /*
+ * Set up the plugin function table that Netscape will use to
+ * call us. Netscape needs to know about our version and size
+ * and have a UniversalProcPointer for every function we
+ * implement.
+ */
+ pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
+ pluginFuncs->size = sizeof(NPPluginFuncs);
+ pluginFuncs->newp = NewNPP_NewProc(Private_New);
+ pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
+ pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
+ pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
+ pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
+ pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
+ pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
+ pluginFuncs->write = NewNPP_WriteProc(Private_Write);
+ pluginFuncs->print = NewNPP_PrintProc(Private_Print);
+ pluginFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify);
+ pluginFuncs->event = NULL;
+#ifdef OJI
+ pluginFuncs->javaClass = Private_GetJavaClass();
+#endif
+ // This function is supposedly loaded magically, but that doesn't
+ // seem to be true.
+ pluginFuncs->getvalue = NewNPP_GetValueProc(NP_GetValue);
+
+ err = NPP_Initialize();
+ }
+
+ return err;
+}
+
+/*
+ * NP_Shutdown [optional]
+ * - Netscape needs to know about this symbol.
+ * - It calls this function after looking up its symbol after
+ * the last object of this kind has been destroyed.
+ *
+ */
+NPError
+NP_Shutdown(void)
+{
+ PLUGINDEBUGSTR("NP_Shutdown");
+ NPP_Shutdown();
+ return NPERR_NO_ERROR;
+}
diff -r dc12fc3a7869 -r a378a0a13aba plugin/test.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/test.html Fri Aug 08 14:17:33 2008 +0100
@@ -0,0 +1,19 @@
+<html>
+<body>
+
+ <h1>Virt Viewer new plugin test</h1>
+
+ <p>You will need to edit the source to
+ set <code>uri</code>, <code>name</code> etc.</p>
+
+ <embed type="application/x-virt-viewer"
+ hidden="1"
+ uri="qemu:///system"
+ name="1">
+ </embed>
+ <!-- also supported: direct="0|1" waitvnc="0|1" -->
+
+ <p>End of page</p>
+
+</body>
+</html>
_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@redhat.com
https://www.redhat.com/mailman/listinfo/et-mgmt-tools
 
Old 08-14-2008, 03:15 PM
"Daniel P. Berrange"
 
Default "Launch virt-viewer" (new) browser plugin.

On Fri, Aug 08, 2008 at 02:43:14PM +0100, Richard W.M. Jones wrote:
> +NPError
> +launcherRun (PluginInstance *self,
> + int16 argc, char* argn[], char* argv[])
> +{
> + int i;
> + const char *uri = NULL;
> + const char *name = NULL;
> + int direct = 0;
> + int waitvnc = 0;
> + int pid;
> +
> + /* Protect against being called multiple times. */
> + if (!self->launched) {
> + self->launched = TRUE;
> +
> + /* Parse the parameters given in <embed ...>. */
> + i = argc;
> + while (i > 0) {
> + i --;
> + if (argv[i] != NULL) {
> + if (!PL_strcasecmp (argn[i], "URI"))
> + uri = argv[i];
> + else if (!PL_strcasecmp (argn[i], "NAME"))
> + name = argv[i];
> + else if (!PL_strcasecmp (argn[i], "DIRECT"))
> + direct = strcmp (argv[i], "1") == 0;
> + else if (!PL_strcasecmp (argn[i], "WAITVNC"))
> + waitvnc = strcmp (argv[i], "1") == 0;
> + }
> + }
> +
> + /* Create child process. */
> + pid = fork ();
> + if (pid < 0) {
> + perror ("fork");
> + return NPERR_GENERIC_ERROR;
> + }
> + if (pid == 0) /* Child. */
> + startVirtViewerAndExit (self, uri, name, direct, waitvnc);
> + else /* Parent. */
> + waitpid (pid, NULL, 0);
> + }
> +
> + return NPERR_NO_ERROR;
> +}

Am I understanding this correctly, that it'll launch the virt-viewer
program immediately upon loading the HTML page containing the plugin
<embed> snippet ? If so that's a huge security problem - you are
spawning a program which is allowed to connect to any host on the
internet. It is also a denial-of-service - malicous javascript
could write a page containing thousands of <embed> snippets which
would spawn thousands of processes.

I'd rather expect the plugin to have a small embedded area in the
HTML page showing the details of what host will be connected to,
what port, and then a button which has to be explicitly pressed
to launch the external viewer.

For safety I think you also need to block all signals before doing
the fork() and reset signal handlers before unblocking and exec'ing,
and unblocking the parent. You don't want signal handlers from the
browser running in the child between the fork/exec window.

> +
> +static void
> +startVirtViewerAndExit (PluginInstance *self ATTRIBUTE_UNUSED,
> + const char *uri, const char *name,
> + int direct, int waitvnc)
> +{
> + int pid;
> + int i, maxfd, len;
> + const char **argv;
> +
> + /* Fork again to detach ourselves completely from the browser
> + * process (probably not necessary on Windoze).
> + */
> + pid = fork ();

Well Windows doesn't have fork()/exec() at all does it ?

> + if (pid < 0) {
> + perror ("fork");
> + return;
> + }
> + if (pid > 0) /* Parent. */
> + _exit (0);
> +
> + /* Child ... Close any open file descriptors, leaving 0, 1 & 2
> + * connected so that we'll still see any error messages.
> + */
> + maxfd = sysconf (_SC_OPEN_MAX) - 1;
> + for (i = 3; i <= maxfd; ++i)
> + close (i);
> +
> + /* Build the argument array. */
> + len = 1 + /* "virt-viewer" (argv 0) */
> + (uri ? 2 : 0) + /* "-c" uri */
> + (direct ? 1 : 0) + /* "-d" */
> + (waitvnc ? 1 : 0) + /* "-w" */
> + 1 + /* name */
> + 1; /* NULL */
> + argv = NPN_MemAlloc (sizeof (char *) * len);
> + if (!argv) {
> + perror ("malloc");
> + goto cleanup;
> + }
> +
> + i = 0;
> + argv[i++] = "virt-viewer";
> + if (uri) {
> + argv[i++] = "-c";
> + argv[i++] = uri;
> + }
> + if (direct)
> + argv[i++] = "-d";
> + if (waitvnc)
> + argv[i++] = "-w";
> + argv[i++] = name;
> +
> + argv[i++] = NULL;
> +
> + if (i != len) {
> + fprintf (stderr,
> + "virt-viewer launcher_plugin: internal error: i=%d != len=%d
",
> + i, len);
> + goto cleanup;
> + }
> +
> + execvp ("virt-viewer", argv);
> + perror ("execvp");
> +
> + cleanup:
> + _exit (1);
> +}
> +
> +void
> +launcherDestroy (PluginInstance *self)
> +{
> + /* Nothing to free. Just stop launcherRun from doing anything if
> + * the browser tries to (incorrectly) call it a second time. Not
> + * that well-written browsers would do anything like that. Oh no.
> + */
> + self->launched = TRUE;
> +}


Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@redhat.com
https://www.redhat.com/mailman/listinfo/et-mgmt-tools

Thu Aug 14 17:30:02 2008
Return-path: <ubuntu-users-bounces@lists.ubuntu.com>
Envelope-to: tom@linux-archive.org
Delivery-date: Thu, 14 Aug 2008 17:17:02 +0300
Received: from chlorine.canonical.com ([91.189.94.204])
by s2.java-tips.org with esmtp (Exim 4.69)
(envelope-from <ubuntu-users-bounces@lists.ubuntu.com>)
id 1KTddO-0003zi-Ir
for tom@linux-archive.org; Thu, 14 Aug 2008 17:17:02 +0300
Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com)
by chlorine.canonical.com with esmtp (Exim 4.60)
(envelope-from <ubuntu-users-bounces@lists.ubuntu.com>)
id 1KTdbU-0001A3-Nf; Thu, 14 Aug 2008 15:15:04 +0100
Received: from wa-out-1112.google.com ([209.85.146.176])
by chlorine.canonical.com with esmtp (Exim 4.60)
(envelope-from <qrczakmk@gmail.com>) id 1KTdbR-00019r-6d
for ubuntu-users@lists.ubuntu.com; Thu, 14 Aug 2008 15:15:01 +0100
Received: by wa-out-1112.google.com with SMTP id k22so236882waf.20
for <ubuntu-users@lists.ubuntu.com>;
Thu, 14 Aug 2008 07:14:59 -0700 (PDT)
Received: by 10.115.33.1 with SMTP id l1mr1184237waj.228.1218723299490;
Thu, 14 Aug 2008 07:14:59 -0700 (PDT)
Received: by 10.115.94.9 with HTTP; Thu, 14 Aug 2008 07:14:59 -0700 (PDT)
Message-ID: <3f4107910808140714tac96fe7v204c0c9994612ab7@mail. gmail.com>
Date: Thu, 14 Aug 2008 16:14:59 +0200
From: "=?UTF-8?Q?Marcin_=E2=80=98Qrczak=E2=80=99_Kowalczyk?="
<qrczak@knm.org.pl>
To: "Ubuntu user technical support,
not for general discussions" <ubuntu-users@lists.ubuntu.com>
Subject: Re: UUIDs on drives
In-Reply-To: <cc77dabe0808140651g4f1c1ab0ke1d418f22aaa3a46@mail .gmail.com>
MIME-Version: 1.0
Content-Disposition: inline
References: <g7m81u$ao0$1@ger.gmane.org>
<200808141223.26310.bastill@adam.com.au>
<48A3B224.3090203@tigershaunt.com>
<200808141538.38360.bastill@adam.com.au>
<cc77dabe0808140631x7d90e2fq9764caf6bb8cb19f@mail. gmail.com>
<3f4107910808140644q12b1538fl9021893de0b18ab9@mail .gmail.com>
<cc77dabe0808140651g4f1c1ab0ke1d418f22aaa3a46@mail .gmail.com>
X-Google-Sender-Auth: 6c708c2c3ac9f4b4
X-BeenThere: ubuntu-users@lists.ubuntu.com
X-Mailman-Version: 2.1.8
Precedence: list
Reply-To: "Ubuntu user technical support,
not for general discussions" <ubuntu-users@lists.ubuntu.com>
List-Id: "Ubuntu user technical support,
not for general discussions" <ubuntu-users.lists.ubuntu.com>
List-Unsubscribe: <https://lists.ubuntu.com/mailman/listinfo/ubuntu-users>,
<mailto:ubuntu-users-request@lists.ubuntu.com?subject=unsubscribe>
List-Archive: <https://lists.ubuntu.com/archives/ubuntu-users>
List-Post: <mailto:ubuntu-users@lists.ubuntu.com>
List-Help: <mailto:ubuntu-users-request@lists.ubuntu.com?subject=help>
List-Subscribe: <https://lists.ubuntu.com/mailman/listinfo/ubuntu-users>,
<mailto:ubuntu-users-request@lists.ubuntu.com?subject=subscribe>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Sender: ubuntu-users-bounces@lists.ubuntu.com
Errors-To: ubuntu-users-bounces@lists.ubuntu.com

MjAwOC84LzE0IEJyaWFuIE1jS2VlIDxicmlhbi5tY2tlZUBnbW FpbC5jb20+OgoKPj4gRXhjZXB0
IHdoZW4gcmVzaXppbmcgdGhlIHN3YXAgd2l0aCBncGFydGVkLC B3aGVyZSAvZGV2L3NkYTUgZG9l
cyBub3QKPj4gY2hhbmdlIGJ1dCBVVUlEIGRvZXMuCj4KPiBJIG NhbiBjb21lIHVwIHdpdGggYSBo
YWxmIGRvemVuIG90aGVyIHdheXMgd2hlcmUgVVVJRCBkb2Vzbi d0IGNoYW5nZQo+IGJ1dCBkcml2
ZSBsZXR0ZXIgZG9lcy4gIFdoYXQncyB5b3VyIHBvaW50PwoKVG hhdCBpdCB3b3VsZCBiZSBuaWNl
IHRvIGZpbmQgYSB3YXkgdG8gYXZvaWQgdGhlIGNhc2Ugb2YgdG hlIGRlZmF1bHQKVVVJRC1iYXNl
ZCBzZXR1cCwgd2hlcmUgcmVzaXppbmcgdGhlIHN3YXAgY2F1c2 VzIGl0IHRvIGJlIHNpbGVudGx5
CnVudXNlZCwgYW5kIG1ha2VzIGhpYmVybmF0ZSBub3Qgd29ya2 luZywgd2hpbGUgbGVhdmluZyBu
byBjbHVlIHRvIHRoZQp1c2VyIHRoYXQgaGUgc2hvdWxkIGNoYW 5nZSB0aGUgVVVJRCBpbiBvbmUg
ZmlsZSBrbm93biB0byBhbGwgVW5peAphZG1pbnMgKC9ldGMvZn N0YWIpIGFuZCBvbmUgb2JzY3Vy
ZSBmaWxlIHRoYXQgYWxtb3N0IG5vYm9keSBrbm93cwphYm91dC AoL2V0Yy9pbml0cmFtZnMtdG9v
bHMvY29uZi5kL3Jlc3VtZSkuCgo+IEhvdyBvZnRlbiBpcyBzd2 FwIHRoZSBsYXN0IHBhcnRpdGlv
biBvbiB5b3VyIGRyaXZlIGFuZAo+IHlvdSBoYXZlIHJvb20gdG 8gZXhwYW5kIGl0IHNvIHRoYXQg
eW91ciBleGFtcGxlIGlzIHZhbGlkPwoKSGF2ZSB5b3UgdXNlZC BncGFydGVkPyBJdCBkb2VzIG5v
dCBoYXZlIHRvIGJlIHRoZSBsYXN0IHBhcnRpdGlvbi4gQQp3ZW VrIGFnbyBJIGRlY2lkZWQgdG8g
bW92ZSAvaG9tZSBjb250ZW50cyB0byBhIHNlcGFyYXRlIHBhcn RpdGlvbiwgc28KSSBib290ZWQg
ZnJvbSBDRCwgc2hyYW5rIC8gYXQgL2Rldi9zZGExLCBtb3ZlZC Bzd2FwIGF0IC9kZXYvc2RhNSBk
b3duCnNocmlua2luZyBpdCBhIGxpdHRsZSBiaXQgd2hpbGUgSS B3ZXJlIGF0IGl0LCBhbmQgY3Jl
YXRlZCAvaG9tZSBhdAovZGV2L3NkYTYuIEkgaGF2ZSBub3Qgcm VhbGl6ZWQgZm9yIGEgZmV3IGRh
eXMgdGhhdCBpdCBjaGFuZ2VkIFVVSUQgYW5kCmlzIG5vdyB1bn VzZWQuIFN3YXAgd291bGQgZ2V0
IGEgbmV3IFVVSUQgYWdhaW4gaWYgSSBub3cgZGVjaWRlZCB0bw ptYWtlIGl0IGxhcmdlciB3aGls
ZSBzaHJpbmtpbmcgdGhlIG5leHQgcGFydGl0aW9uLCBvciB0aG UgY29udmVyc2UsIG9yCnRvIG1v
dmUgc29tZSBzcGFjZSBiZXR3ZWVuIHN3YXAgYW5kIHRoZSBwcm V2aW91cyBwYXJ0aXRpb24uIEkg
YXNzdW1lCnRoYXQgdGhlIHN3YXAgd291bGQga2VlcCB0aGUgc2 FtZSBVVUlEIGlmIEkganVzdCBt
b3ZlZCBpdCB3aXRob3V0CmNoYW5naW5nIGl0cyBzaXplLgoKUG VyaGFwcyBncGFydGVkIGNvdWxk
IGJlIGltcHJvdmVkIGJ5IGJlaW5nIGFibGUgdG8gcmVzaXplIH RoZSBzd2FwCndpdGhvdXQgY2hh
bmdpbmcgaXRzIFVVSUQuIEl0IGNvcGllZCBzd2FwIGNvbnRlbn RzIHRvIHRoZSBuZXcKbG9jYXRp
b24sIHZlcnkgc2xvd2x5IChzbG93ZXIgdGhhbiBleHQzIGNvbn RlbnRzIGFwcGFyZW50bHkpIOKA
lCB0aGlzCmNhbiBkZWZpbml0ZWx5IGJlIGltcHJvdmVkIGlmIG l0IGxhdGVyIGRvZXMgc2ltcGx5
IG1rc3dhcC4gSSBkb24ndAprbm93IGlmIGl0IGRvZXMgbWtzd2 FwIGFmdGVyIGNvcHlpbmcsIEkg
anVzdCBndWVzcyBmcm9tIHRoZSBmYWN0IHRoYXQKdGhlIFVVSU QgY2hhbmdlcy4gV2h5IGRvZXMg
aXQgY29weSBzd2FwIGNvbnRlbnRzIGF0IGFsbD8gUGVyaGFwcy BpdApzaG91bGQganVzdCBta3N3
YXAgYW5kIHRoZW4gd3JpdGUgYmFjayB0aGUgb2xkIFVVSUQuCg otLSAKTWFyY2luIEtvd2FsY3p5
awpxcmN6YWtAa25tLm9yZy5wbApodHRwOi8vcXJuaWsua25tLm 9yZy5wbC9+cXJjemFrLwotLSAK
dWJ1bnR1LXVzZXJzIG1haWxpbmcgbGlzdAp1YnVudHUtdXNlcn NAbGlzdHMudWJ1bnR1LmNvbQpN
b2RpZnkgc2V0dGluZ3Mgb3IgdW5zdWJzY3JpYmUgYXQ6IGh0dH BzOi8vbGlzdHMudWJ1bnR1LmNv
bS9tYWlsbWFuL2xpc3RpbmZvL3VidW50dS11c2Vycwo=
 
Old 08-14-2008, 05:07 PM
"Richard W.M. Jones"
 
Default "Launch virt-viewer" (new) browser plugin.

On Thu, Aug 14, 2008 at 03:15:19PM +0100, Daniel P. Berrange wrote:
> Am I understanding this correctly, that it'll launch the virt-viewer
> program immediately upon loading the HTML page containing the plugin
> <embed> snippet ? If so that's a huge security problem - you are
> spawning a program which is allowed to connect to any host on the
> internet. It is also a denial-of-service - malicous javascript
> could write a page containing thousands of <embed> snippets which
> would spawn thousands of processes.
>
> I'd rather expect the plugin to have a small embedded area in the
> HTML page showing the details of what host will be connected to,
> what port, and then a button which has to be explicitly pressed
> to launch the external viewer.

Yes ... The trouble is if we do this, we end up needing to embed Gtk
widgets in the browser, which takes us back to square one.

I'll raise this on #virt, see if we can talk through the issues again.

Rich.

--
Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top

_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@redhat.com
https://www.redhat.com/mailman/listinfo/et-mgmt-tools
 
Old 08-15-2008, 09:56 AM
"Daniel P. Berrange"
 
Default "Launch virt-viewer" (new) browser plugin.

On Thu, Aug 14, 2008 at 05:07:09PM +0100, Richard W.M. Jones wrote:
> On Thu, Aug 14, 2008 at 03:15:19PM +0100, Daniel P. Berrange wrote:
> > Am I understanding this correctly, that it'll launch the virt-viewer
> > program immediately upon loading the HTML page containing the plugin
> > <embed> snippet ? If so that's a huge security problem - you are
> > spawning a program which is allowed to connect to any host on the
> > internet. It is also a denial-of-service - malicous javascript
> > could write a page containing thousands of <embed> snippets which
> > would spawn thousands of processes.
> >
> > I'd rather expect the plugin to have a small embedded area in the
> > HTML page showing the details of what host will be connected to,
> > what port, and then a button which has to be explicitly pressed
> > to launch the external viewer.
>
> Yes ... The trouble is if we do this, we end up needing to embed Gtk
> widgets in the browser, which takes us back to square one.

Yeah I guess that does really :-( I must be possible to get GTK reliably
embedded though because I use Totem for movie playback and its embeding
GTK ok

Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@redhat.com
https://www.redhat.com/mailman/listinfo/et-mgmt-tools
 

Thread Tools




All times are GMT. The time now is 10:40 AM.

VBulletin, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org