Back to index

lightning-sunbird  0.9+nobinonly
nsPhRemoteService.cpp
Go to the documentation of this file.
00001 /*
00002  * The contents of this file are subject to the Mozilla Public
00003  * License Version 1.1 (the "License"); you may not use this file
00004  * except in compliance with the License. You may obtain a copy of
00005  * the License at http://www.mozilla.org/MPL/
00006  * 
00007  * Software distributed under the License is distributed on an "AS
00008  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
00009  * implied. See the License for the specific language governing
00010  * rights and limitations under the License.
00011  * 
00012  * The Original Code is mozilla.org code.
00013  * 
00014  * The Initial Developer of the Original Code is Christopher Blizzard.
00015  * Portions created by Christopher Blizzard are Copyright (C)
00016  * Christopher Blizzard.  All Rights Reserved.
00017  * 
00018  * Contributor(s):
00019  *   Adrian Mardare <amardare@qnx.com>
00020  *   Max Feil <mfeil@qnx.com>
00021  */
00022 
00023 #include <stdlib.h>
00024 #include <nsIWidget.h>
00025 #include <nsCOMPtr.h>
00026 #include "nsIGenericFactory.h"
00027 #include "nsPhRemoteService.h"
00028 #include "nsIServiceManager.h"
00029 #include "nsCRT.h"
00030 
00031 #ifdef MOZ_XUL_APP
00032 #include "nsICommandLineRunner.h"
00033 #include "nsXULAppAPI.h"
00034 #else
00035 #include "nsISuiteRemoteService.h"
00036 #endif
00037 
00038 #include <Pt.h>
00039 
00040 NS_IMPL_QUERY_INTERFACE2(nsPhRemoteService,
00041                          nsIRemoteService,
00042                          nsIObserver)
00043 
00044 NS_IMETHODIMP_(nsrefcnt)
00045 nsPhRemoteService::AddRef()
00046 {
00047   return 1;
00048 }
00049 
00050 NS_IMETHODIMP_(nsrefcnt)
00051 nsPhRemoteService::Release()
00052 {
00053   return 1;
00054 }
00055 
00056 NS_IMETHODIMP
00057 nsPhRemoteService::Startup(const char* aAppName, const char* aProfileName)
00058 {
00059   NS_ASSERTION(aAppName, "Don't pass a null appname!");
00060 
00061   if (mIsInitialized)
00062     return NS_ERROR_ALREADY_INITIALIZED;
00063 
00064   mIsInitialized = PR_TRUE;
00065   mAppName = aAppName;
00066   ToLowerCase(mAppName);
00067 
00068   HandleCommandsFor(nsnull, nsnull);
00069 
00070   return NS_OK;
00071 }
00072 
00073 NS_IMETHODIMP
00074 nsPhRemoteService::RegisterWindow(nsIDOMWindow* aWindow)
00075 {
00076   return NS_OK;
00077 }
00078 
00079 NS_IMETHODIMP
00080 nsPhRemoteService::Shutdown()
00081 {
00082   if (!mIsInitialized)
00083     return NS_ERROR_NOT_INITIALIZED;
00084 
00085   mIsInitialized = PR_FALSE;
00086   return NS_OK;
00087 }
00088 
00089 NS_IMETHODIMP
00090 nsPhRemoteService::Observe(nsISupports* aSubject,
00091                             const char *aTopic,
00092                             const PRUnichar *aData)
00093 {
00094   // This can be xpcom-shutdown or quit-application, but it's the same either
00095   // way.
00096   Shutdown();
00097   return NS_OK;
00098 }
00099 
00100 #define MOZ_REMOTE_MSG_TYPE                             100
00101 
00102 static void const * RemoteMsgHandler( PtConnectionServer_t *connection, void *user_data,
00103               unsigned long type, void const *msg, unsigned len, unsigned *reply_len )
00104 {
00105     nsresult rv;
00106 
00107        if( type != MOZ_REMOTE_MSG_TYPE ) return NULL;
00108 
00109        /* we are given strings and we reply with strings */
00110        char *response = NULL;
00111 
00112        // parse the command
00113     nsCOMPtr<nsICommandLineRunner> cmdline
00114       (do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv));
00115     if (!NS_FAILED(rv)) {
00116 
00117       // 1) Make sure that it looks remotely valid with parens
00118       // 2) Treat ping() immediately and specially
00119 
00120       nsCAutoString command((char *)msg);
00121       PRInt32 p1, p2;
00122       p1 = command.FindChar('(');
00123       p2 = command.FindChar(')');
00124 
00125       if (p1 != kNotFound && p2 != kNotFound && p1 != 0 && p2 >= p1) {
00126         command.Truncate(p1);
00127         command.Trim(" ", PR_TRUE, PR_TRUE);
00128         ToLowerCase(command);
00129 
00130         //printf("Processing xremote command: %s\n", command.get());
00131 
00132         if (!command.EqualsLiteral("ping")) {
00133           char* argv[3] = {"dummyappname", "-remote", (char *)msg};
00134           rv = cmdline->Init(3, argv, nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
00135           if (!NS_FAILED(rv)) {
00136             rv = cmdline->Run();
00137             if (NS_ERROR_ABORT == rv)
00138               response = "500 command not parseable";
00139             if (NS_FAILED(rv))
00140               response = "509 internal error";
00141              } else
00142             response = "509 internal error";
00143         }
00144       } else
00145         response = "500 command not parseable";
00146        } else
00147       response = "509 internal error";
00148 
00149        PtConnectionReply( connection, response ? strlen(response) : 0, response );
00150 
00151        return ( void * ) 1; /* return any non NULL value to indicate we handled the message */
00152 }
00153 
00154 static void client_connect( PtConnector_t *cntr, PtConnectionServer_t *csrvr, void *data )
00155 {
00156        static PtConnectionMsgHandler_t handlers[] = { { 0, RemoteMsgHandler } };
00157        PtConnectionAddMsgHandlers( csrvr, handlers, sizeof(handlers)/sizeof(handlers[0]) );
00158 }
00159 
00160 
00161 void
00162 nsPhRemoteService::HandleCommandsFor( nsIWidget *aWidget, nsIWeakReference* aWindow )
00163 {
00164        static PRBool ConnectorCreated = PR_FALSE;
00165 
00167 
00168        if( !ConnectorCreated ) {
00169               char RemoteServerName[128];
00170               sprintf( RemoteServerName, "%s_RemoteServer", (char *) mAppName.get() );
00171               /* create a connector for the remote control */
00172               PtConnectorCreate( RemoteServerName, client_connect, NULL );
00173               ConnectorCreated = PR_TRUE;
00174               }
00175   return;
00176 }
00177 
00178 // {C0773E90-5799-4eff-AD03-3EBCD85624AC}
00179 #define NS_REMOTESERVICE_CID \
00180   { 0xc0773e90, 0x5799, 0x4eff, { 0xad, 0x3, 0x3e, 0xbc, 0xd8, 0x56, 0x24, 0xac } }
00181 
00182 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPhRemoteService)
00183 
00184 static const nsModuleComponentInfo components[] =
00185 {
00186   { "Remote Service",
00187     NS_REMOTESERVICE_CID,
00188     "@mozilla.org/toolkit/remote-service;1",
00189     nsPhRemoteServiceConstructor
00190   }
00191 };
00192 
00193 NS_IMPL_NSGETMODULE(RemoteServiceModule, components)