Bug 1080319 - Remove the -remote option. r=bsmedberg

The -remote option has existed essentially forever, but its usefulness is
questionable:
- It requires a running instance to be any useful, so any script actually
  using it should first do -remote 'ping()' and handle the response properly.
- It is not cross-application. The remote service dispatches the -remote
  commands to the command line handler, and, for example, desktop b2g builds
  don't have handlers for -remote (although thunderbird and seamonkey do).
- It is not a cross-platform option, which leads to the following point:
- There are other command line ways to do the same thing (at least in
  Firefox), without having to jump through hoops with -remote 'ping()',
  because there are command line options to do those same things on non-X11
  platforms.

For the latter, in Firefox case:
- -remote 'openURL(url)' can be replaced with firefox url
- -remote 'openURL(url,new-tab)' can be replaced with firefox -new-tab url
- -remote 'openURL(url,new-window)' can be replaced with firefox -new-window
  url
- -remote 'openfile(file,...)' is the same as -remote 'openurl(file,...) so,
  can be replaced as above
- -remote 'xfedocommand(openbrowser)' is inherited from the mozilla suite and
   doesn't make much sense, but can be replaced with firefox -new-window

The interesting part is that without changing nsBrowserContentHandler.js,
-remote still works, meaning that if people really feel strongly about
-remote, they'll still be able to write an addon to bring it back. This also
means this patch actually doesn't remove -remote for applications other than
Firefox that do support it, although -remote 'ping()' doesn't work as
expected. However, other -remote commands will now work even without a
running instance.
This commit is contained in:
Mike Hommey 2014-10-14 07:19:52 +09:00
parent 32c8131976
commit 740cec5575
14 changed files with 26 additions and 522 deletions

View File

@ -115,7 +115,6 @@
#ifdef XP_UNIX
#ifndef XP_MACOSX
@BINPATH@/run-mozilla.sh
@BINPATH@/mozilla-xremote-client
#endif
#endif

View File

@ -342,86 +342,6 @@ nsBrowserContentHandler.prototype = {
cmdLine.preventDefault = true;
}
try {
var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
}
catch (e) {
throw NS_ERROR_ABORT;
}
if (remoteCommand != null) {
try {
var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
var remoteVerb;
if (a) {
remoteVerb = a[1].toLowerCase();
var remoteParams = [];
var sepIndex = a[2].lastIndexOf(",");
if (sepIndex == -1)
remoteParams[0] = a[2];
else {
remoteParams[0] = a[2].substring(0, sepIndex);
remoteParams[1] = a[2].substring(sepIndex + 1);
}
}
switch (remoteVerb) {
case "openurl":
case "openfile":
// openURL(<url>)
// openURL(<url>,new-window)
// openURL(<url>,new-tab)
// First param is the URL, second param (if present) is the "target"
// (tab, window)
var url = remoteParams[0];
var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
if (remoteParams[1]) {
var targetParam = remoteParams[1].toLowerCase()
.replace(/^\s*|\s*$/g, "");
if (targetParam == "new-tab")
target = nsIBrowserDOMWindow.OPEN_NEWTAB;
else if (targetParam == "new-window")
target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
else {
// The "target" param isn't one of our supported values, so
// assume it's part of a URL that contains commas.
url += "," + remoteParams[1];
}
}
var uri = resolveURIInternal(cmdLine, url);
handURIToExistingBrowser(uri, target, cmdLine);
break;
case "xfedocommand":
// xfeDoCommand(openBrowser)
if (remoteParams[0].toLowerCase() != "openbrowser")
throw NS_ERROR_ABORT;
// Passing defaultArgs, so use NO_EXTERNAL_URIS
openWindow(null, this.chromeURL, "_blank",
"chrome,dialog=no,all" + this.getFeatures(cmdLine),
this.defaultArgs, NO_EXTERNAL_URIS);
break;
default:
// Somebody sent us a remote command we don't know how to process:
// just abort.
throw "Unknown remote command.";
}
cmdLine.preventDefault = true;
}
catch (e) {
Components.utils.reportError(e);
// If we had a -remote flag but failed to process it, throw
// NS_ERROR_ABORT so that the xremote code knows to return a failure
// back to the handling code.
throw NS_ERROR_ABORT;
}
}
var uriparam;
try {
while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {

View File

@ -161,7 +161,6 @@
#ifdef XP_UNIX
#ifndef XP_MACOSX
@BINPATH@/run-mozilla.sh
@BINPATH@/mozilla-xremote-client
#endif
#endif

View File

@ -104,7 +104,6 @@
@BINPATH@/blocklist.xml
#ifdef XP_UNIX
@BINPATH@/run-mozilla.sh
@BINPATH@/mozilla-xremote-client
#endif
; [Components]

View File

@ -40,7 +40,6 @@ using namespace mozilla;
#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION"
#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK"
#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND"
#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE"
#define MOZILLA_USER_PROP "_MOZILLA_USER"
#define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE"
@ -61,7 +60,6 @@ const unsigned char kRemoteVersion[] = "5.1";
static const char *XAtomNames[] = {
MOZILLA_VERSION_PROP,
MOZILLA_LOCK_PROP,
MOZILLA_COMMAND_PROP,
MOZILLA_RESPONSE_PROP,
MOZILLA_USER_PROP,
MOZILLA_PROFILE_PROP,
@ -72,7 +70,6 @@ static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)];
Atom nsXRemoteService::sMozVersionAtom;
Atom nsXRemoteService::sMozLockAtom;
Atom nsXRemoteService::sMozCommandAtom;
Atom nsXRemoteService::sMozResponseAtom;
Atom nsXRemoteService::sMozUserAtom;
Atom nsXRemoteService::sMozProfileAtom;
@ -182,7 +179,7 @@ nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay,
nsCOMPtr<nsIDOMWindow> window (do_QueryReferent(aDomWindow));
if (aChangedAtom == sMozCommandAtom || aChangedAtom == sMozCommandLineAtom) {
if (aChangedAtom == sMozCommandLineAtom) {
// We got a new command atom.
int result;
Atom actual_type;
@ -214,11 +211,7 @@ nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay,
return false;
// cool, we got the property data.
const char *response = nullptr;
if (aChangedAtom == sMozCommandAtom)
response = HandleCommand(data, window, aEventTime);
else if (aChangedAtom == sMozCommandLineAtom)
response = HandleCommandLine(data, window, aEventTime);
const char *response = HandleCommandLine(data, window, aEventTime);
// put the property onto the window as the response
XChangeProperty (aDisplay, aWindowId,
@ -243,61 +236,6 @@ nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay,
return false;
}
const char*
nsXRemoteService::HandleCommand(char* aCommand, nsIDOMWindow* aWindow,
uint32_t aTimestamp)
{
nsresult rv;
nsCOMPtr<nsICommandLineRunner> cmdline
(do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv));
if (NS_FAILED(rv))
return "509 internal error";
// 1) Make sure that it looks remotely valid with parens
// 2) Treat ping() immediately and specially
nsAutoCString command(aCommand);
int32_t p1, p2;
p1 = command.FindChar('(');
p2 = command.FindChar(')');
if (p1 == kNotFound || p2 == kNotFound || p1 == 0 || p2 < p1) {
return "500 command not parseable";
}
command.Truncate(p1);
command.Trim(" ", true, true);
ToLowerCase(command);
if (!command.EqualsLiteral("ping")) {
nsAutoCString desktopStartupID;
nsDependentCString cmd(aCommand);
FindExtensionParameterInCommand("DESKTOP_STARTUP_ID",
cmd, '\n',
&desktopStartupID);
const char* argv[3] = {"dummyappname", "-remote", aCommand};
rv = cmdline->Init(3, argv, nullptr, nsICommandLine::STATE_REMOTE_EXPLICIT);
if (NS_FAILED(rv))
return "509 internal error";
if (aWindow)
cmdline->SetWindowContext(aWindow);
if (sRemoteImplementation)
sRemoteImplementation->SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp);
rv = cmdline->Run();
if (NS_ERROR_ABORT == rv)
return "500 command not parseable";
if (NS_FAILED(rv))
return "509 internal error";
}
return "200 executed command";
}
const char*
nsXRemoteService::HandleCommandLine(char* aBuffer, nsIDOMWindow* aWindow,
uint32_t aTimestamp)
@ -378,7 +316,6 @@ nsXRemoteService::EnsureAtoms(void)
int i = 0;
sMozVersionAtom = XAtoms[i++];
sMozLockAtom = XAtoms[i++];
sMozCommandAtom = XAtoms[i++];
sMozResponseAtom = XAtoms[i++];
sMozUserAtom = XAtoms[i++];
sMozProfileAtom = XAtoms[i++];

View File

@ -41,9 +41,6 @@ protected:
static nsXRemoteService *sRemoteImplementation;
private:
void EnsureAtoms();
static const char* HandleCommand(char* aCommand, nsIDOMWindow* aWindow,
uint32_t aTimestamp);
static const char* HandleCommandLine(char* aBuffer, nsIDOMWindow* aWindow,
uint32_t aTimestamp);
@ -55,7 +52,6 @@ private:
static Atom sMozVersionAtom;
static Atom sMozLockAtom;
static Atom sMozCommandAtom;
static Atom sMozResponseAtom;
static Atom sMozUserAtom;
static Atom sMozProfileAtom;

View File

@ -1588,66 +1588,6 @@ DumpVersion()
}
#ifdef MOZ_ENABLE_XREMOTE
// use int here instead of a PR type since it will be returned
// from main - just to keep types consistent
static int
HandleRemoteArgument(const char* remote, const char* aDesktopStartupID)
{
nsresult rv;
ArgResult ar;
const char *profile = 0;
nsAutoCString program(gAppData->name);
ToLowerCase(program);
const char *username = getenv("LOGNAME");
ar = CheckArg("p", false, &profile);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -p requires a profile name\n");
return 1;
}
const char *temp = nullptr;
ar = CheckArg("a", false, &temp);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
return 1;
} else if (ar == ARG_FOUND) {
program.Assign(temp);
}
ar = CheckArg("u", false, &username);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n");
return 1;
}
XRemoteClient client;
rv = client.Init();
if (NS_FAILED(rv)) {
PR_fprintf(PR_STDERR, "Error: Failed to connect to X server.\n");
return 1;
}
nsXPIDLCString response;
bool success = false;
rv = client.SendCommand(program.get(), username, profile, remote,
aDesktopStartupID, getter_Copies(response), &success);
// did the command fail?
if (NS_FAILED(rv)) {
PR_fprintf(PR_STDERR, "Error: Failed to send command: %s\n",
response ? response.get() : "No response included");
return 1;
}
if (!success) {
PR_fprintf(PR_STDERR, "Error: No running window found\n");
return 2;
}
return 0;
}
static RemoteResult
RemoteCommandLine(const char* aDesktopStartupID)
{
@ -3610,21 +3550,11 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
}
}
const char* xremotearg;
ArgResult ar = CheckArg("remote", true, &xremotearg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
return 1;
}
const char* desktopStartupIDPtr =
mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
if (ar) {
*aExitFlag = true;
return HandleRemoteArgument(xremotearg, desktopStartupIDPtr);
}
if (!newInstance) {
// Try to remote the entire command line. If this fails, start up normally.
const char* desktopStartupIDPtr =
mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
RemoteResult rr = RemoteCommandLine(desktopStartupIDPtr);
if (rr == REMOTE_FOUND) {
*aExitFlag = true;

View File

@ -1,24 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# NOTE: This directory is part of tier 50, and is linked directly into
# the application binaries. The fact that it's under mozilla/widget is a fluke
# of tree history.
LIBCPPSRCS = XRemoteClient.cpp
OBJS = $(LIBCPPSRCS:.cpp=.$(OBJ_SUFFIX))
PROGCPPSRCS = \
mozilla-xremote-client.cpp \
XRemoteClient.cpp \
$(NULL)
PROGOBJS = $(PROGCPPSRCS:.cpp=.$(OBJ_SUFFIX))
CPPSRCS += \
$(filter-out $(LIBCPPSRCS),$(PROGCPPSRCS)) \
$(LIBCPPSRCS) \
$(NULL)

View File

@ -26,7 +26,6 @@
#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION"
#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK"
#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND"
#define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE"
#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE"
#define MOZILLA_USER_PROP "_MOZILLA_USER"
@ -62,7 +61,6 @@ XRemoteClient::XRemoteClient()
mInitialized = false;
mMozVersionAtom = 0;
mMozLockAtom = 0;
mMozCommandAtom = 0;
mMozResponseAtom = 0;
mMozWMStateAtom = 0;
mMozUserAtom = 0;
@ -83,7 +81,6 @@ XRemoteClient::~XRemoteClient()
static const char *XAtomNames[] = {
MOZILLA_VERSION_PROP,
MOZILLA_LOCK_PROP,
MOZILLA_COMMAND_PROP,
MOZILLA_RESPONSE_PROP,
"WM_STATE",
MOZILLA_USER_PROP,
@ -113,7 +110,6 @@ XRemoteClient::Init()
int i = 0;
mMozVersionAtom = XAtoms[i++];
mMozLockAtom = XAtoms[i++];
mMozCommandAtom = XAtoms[i++];
mMozResponseAtom = XAtoms[i++];
mMozWMStateAtom = XAtoms[i++];
mMozUserAtom = XAtoms[i++];
@ -144,35 +140,6 @@ XRemoteClient::Shutdown (void)
}
}
nsresult
XRemoteClient::SendCommand (const char *aProgram, const char *aUsername,
const char *aProfile, const char *aCommand,
const char* aDesktopStartupID,
char **aResponse, bool *aWindowFound)
{
PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::SendCommand"));
return SendCommandInternal(aProgram, aUsername, aProfile,
aCommand, 0, nullptr,
aDesktopStartupID,
aResponse, aWindowFound);
}
nsresult
XRemoteClient::SendCommandLine (const char *aProgram, const char *aUsername,
const char *aProfile,
int32_t argc, char **argv,
const char* aDesktopStartupID,
char **aResponse, bool *aWindowFound)
{
PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::SendCommandLine"));
return SendCommandInternal(aProgram, aUsername, aProfile,
nullptr, argc, argv,
aDesktopStartupID,
aResponse, aWindowFound);
}
static int
HandleBadWindow(Display *display, XErrorEvent *event)
{
@ -186,20 +153,21 @@ HandleBadWindow(Display *display, XErrorEvent *event)
}
nsresult
XRemoteClient::SendCommandInternal(const char *aProgram, const char *aUsername,
const char *aProfile, const char *aCommand,
int32_t argc, char **argv,
const char* aDesktopStartupID,
char **aResponse, bool *aWindowFound)
XRemoteClient::SendCommandLine (const char *aProgram, const char *aUsername,
const char *aProfile,
int32_t argc, char **argv,
const char* aDesktopStartupID,
char **aResponse, bool *aWindowFound)
{
PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::SendCommandLine"));
*aWindowFound = false;
bool isCommandLine = !aCommand;
// FindBestWindow() iterates down the window hierarchy, so catch X errors
// when windows get destroyed before being accessed.
sOldHandler = XSetErrorHandler(HandleBadWindow);
Window w = FindBestWindow(aProgram, aUsername, aProfile, isCommandLine);
Window w = FindBestWindow(aProgram, aUsername, aProfile);
nsresult rv = NS_OK;
@ -223,14 +191,8 @@ XRemoteClient::SendCommandInternal(const char *aProgram, const char *aUsername,
if (NS_SUCCEEDED(rv)) {
// send our command
if (isCommandLine) {
rv = DoSendCommandLine(w, argc, argv, aDesktopStartupID, aResponse,
&destroyed);
}
else {
rv = DoSendCommand(w, aCommand, aDesktopStartupID, aResponse,
&destroyed);
}
rv = DoSendCommandLine(w, argc, argv, aDesktopStartupID, aResponse,
&destroyed);
// if the window was destroyed, don't bother trying to free the
// lock.
@ -448,8 +410,7 @@ XRemoteClient::GetLock(Window aWindow, bool *aDestroyed)
Window
XRemoteClient::FindBestWindow(const char *aProgram, const char *aUsername,
const char *aProfile,
bool aSupportsCommandLine)
const char *aProfile)
{
Window root = RootWindowOfScreen(DefaultScreenOfDisplay(mDisplay));
Window bestWindow = 0;
@ -494,7 +455,7 @@ XRemoteClient::FindBestWindow(const char *aProgram, const char *aUsername,
double version = PR_strtod((char*) data_return, nullptr);
XFree(data_return);
if (aSupportsCommandLine && !(version >= 5.1 && version < 6))
if (!(version >= 5.1 && version < 6))
continue;
data_return = 0;
@ -638,46 +599,6 @@ XRemoteClient::FreeLock(Window aWindow)
return NS_OK;
}
nsresult
XRemoteClient::DoSendCommand(Window aWindow, const char *aCommand,
const char* aDesktopStartupID,
char **aResponse, bool *aDestroyed)
{
*aDestroyed = false;
PR_LOG(sRemoteLm, PR_LOG_DEBUG,
("(writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n",
aCommand, (unsigned int) aWindow));
// We add the DESKTOP_STARTUP_ID setting as an extra line of
// the command string. Firefox ignores all lines but the first.
static char desktopStartupPrefix[] = "\nDESKTOP_STARTUP_ID=";
int32_t len = strlen(aCommand);
if (aDesktopStartupID) {
len += sizeof(desktopStartupPrefix) - 1 + strlen(aDesktopStartupID);
}
char* buffer = (char*)malloc(len + 1);
if (!buffer)
return NS_ERROR_OUT_OF_MEMORY;
strcpy(buffer, aCommand);
if (aDesktopStartupID) {
strcat(buffer, desktopStartupPrefix);
strcat(buffer, aDesktopStartupID);
}
XChangeProperty (mDisplay, aWindow, mMozCommandAtom, XA_STRING, 8,
PropModeReplace, (unsigned char *)buffer, len);
free(buffer);
if (!WaitForResponse(aWindow, aResponse, aDestroyed, mMozCommandAtom))
return NS_ERROR_FAILURE;
return NS_OK;
}
/* like strcpy, but return the char after the final null */
static char*
estrcpy(const char* s, char* d)
@ -870,7 +791,7 @@ XRemoteClient::WaitForResponse(Window aWindow, char **aResponse,
event.xproperty.atom == aCommandAtom) {
PR_LOG(sRemoteLm, PR_LOG_DEBUG,
("(server 0x%x has accepted "
MOZILLA_COMMAND_PROP ".)\n",
MOZILLA_COMMANDLINE_PROP ".)\n",
(unsigned int) aWindow));
}

View File

@ -15,10 +15,6 @@ public:
~XRemoteClient();
virtual nsresult Init();
virtual nsresult SendCommand(const char *aProgram, const char *aUsername,
const char *aProfile, const char *aCommand,
const char* aDesktopStartupID,
char **aResponse, bool *aSucceeded);
virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername,
const char *aProfile,
int32_t argc, char **argv,
@ -34,18 +30,7 @@ private:
nsresult FreeLock (Window aWindow);
Window FindBestWindow (const char *aProgram,
const char *aUsername,
const char *aProfile,
bool aSupportsCommandLine);
nsresult SendCommandInternal(const char *aProgram, const char *aUsername,
const char *aProfile, const char *aCommand,
int32_t argc, char **argv,
const char* aDesktopStartupID,
char **aResponse, bool *aWindowFound);
nsresult DoSendCommand (Window aWindow,
const char *aCommand,
const char* aDesktopStartupID,
char **aResponse,
bool *aDestroyed);
const char *aProfile);
nsresult DoSendCommandLine(Window aWindow,
int32_t argc, char **argv,
const char* aDesktopStartupID,
@ -58,7 +43,6 @@ private:
Atom mMozVersionAtom;
Atom mMozLockAtom;
Atom mMozCommandAtom;
Atom mMozCommandLineAtom;
Atom mMozResponseAtom;
Atom mMozWMStateAtom;

View File

@ -1,32 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#define NS_XREMOTECLIENT_CID \
{ 0xcfae5900, \
0x1dd1, \
0x11b2, \
{ 0x95, 0xd0, 0xad, 0x45, 0x4c, 0x23, 0x3d, 0xc6 } \
}
/* cfae5900-1dd1-11b2-95d0-ad454c233dc6 */
#include "XRemoteClient.h"
#include "nsXRemoteClientCID.h"
#include "nsIGenericFactory.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(XRemoteClient)
static const nsModuleComponentInfo components[] =
{
{ "XRemote Client",
NS_XREMOTECLIENT_CID,
NS_XREMOTECLIENT_CONTRACTID,
XRemoteClientConstructor }
};
NS_IMPL_NSGETMODULE(XRemoteClientModule, components)

View File

@ -4,15 +4,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Program('mozilla-xremote-client')
FINAL_LIBRARY = 'xul'
DEFINES['XPCOM_GLUE'] = True
OS_LIBS += CONFIG['XLDFLAGS']
OS_LIBS += CONFIG['XLIBS']
USE_LIBS += [
'nspr',
SOURCES += [
'XRemoteClient.cpp',
]

View File

@ -1,99 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <plgetopt.h>
#include "XRemoteClient.h"
static void print_usage(void);
int main(int argc, char **argv)
{
nsresult rv;
XRemoteClient client;
char *browser = 0;
char *profile = 0;
char *username = 0;
char *command = 0;
if (argc < 2) {
print_usage();
return 4;
}
PLOptStatus os;
PLOptState *opt = PL_CreateOptState(argc, argv, "ha:u:p:");
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
if (PL_OPT_BAD == os) {
print_usage();
return 4;
}
switch (opt->option) {
case 'h':
print_usage();
return 4;
break;
case 'u':
username = strdup(opt->value);
break;
case 'a':
browser = strdup(opt->value);
break;
case 'p':
profile = strdup(opt->value);
break;
case 0:
command = strdup(opt->value);
default:
break;
}
}
rv = client.Init();
// failed to connect to the X server
if (NS_FAILED(rv))
return 1;
// send the command - it doesn't get any easier than this
bool success = false;
char *error = 0;
rv = client.SendCommand(browser, username, profile, command, nullptr,
&error, &success);
// failed to send command
if (NS_FAILED(rv)) {
fprintf(stderr, "%s: Error: Failed to send command: ", argv[0]);
if (error) {
fprintf(stderr, "%s\n", error);
free(error);
}
else {
fprintf(stderr, "No error string reported..\n");
}
return 3;
}
// no running window found
if (!success) {
fprintf(stderr, "%s: Error: Failed to find a running server.\n", argv[0]);
return 2;
}
// else, everything is fine.
return 0;
}
/* static */
void print_usage(void) {
fprintf(stderr, "Usage: mozilla-xremote-client [-a firefox|thunderbird|mozilla|any]\n");
fprintf(stderr, " [-u <username>]\n");
fprintf(stderr, " [-p <profile>] COMMAND\n");
}

View File

@ -23,15 +23,11 @@ public:
virtual nsresult Init() = 0;
/**
* Sends a command to a running instance.
* Send a complete command line to a running instance.
*
* @param aProgram This is the preferred program that we want to use
* for this particular command.
*
* @param aNoProgramFallback This boolean attribute tells the client
* code that if the preferred program isn't found that it should
* fail not send the command to another server.
*
* @param aUsername This allows someone to only talk to an instance
* of the server that's running under a particular username. If
* this isn't specified here it's pulled from the LOGNAME
@ -41,10 +37,10 @@ public:
* running under a named profile. If it is not specified the
* profile is not checked.
*
* @param aCommand This is the command that is passed to the server.
* Please see the additional information located at:
* http://www.mozilla.org/unix/remote.html
*
* @param argc The number of command-line arguments.
*
* @param argv The command-line arguments.
*
* @param aDesktopStartupID the contents of the DESKTOP_STARTUP_ID environment
* variable defined by the Startup Notification specification
* http://standards.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt
@ -54,21 +50,6 @@ public:
* string functions, so free it with free().
*
* @return true if succeeded, false if no running instance was found.
*/
virtual nsresult SendCommand(const char *aProgram, const char *aUsername,
const char *aProfile, const char *aCommand,
const char* aDesktopStartupID,
char **aResponse, bool *aSucceeded) = 0;
/**
* Send a complete command line to a running instance.
*
* @param aDesktopStartupID the contents of the DESKTOP_STARTUP_ID environment
* variable defined by the Startup Notification specification
* http://standards.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt
*
* @see sendCommand
* @param argc The number of command-line arguments.
*
*/
virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername,