LCOV - code coverage report
Current view: top level - toolkit/components/remote - nsXRemoteService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 111 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:expandtab:shiftwidth=2:tabstop=8:
       3             :  */
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : #include "mozilla/ArrayUtils.h"
       9             : 
      10             : #include "nsXRemoteService.h"
      11             : #include "nsIObserverService.h"
      12             : #include "nsCOMPtr.h"
      13             : #include "nsIServiceManager.h"
      14             : #include "nsICommandLineRunner.h"
      15             : #include "nsICommandLine.h"
      16             : 
      17             : #include "nsIBaseWindow.h"
      18             : #include "nsIDocShell.h"
      19             : #include "nsIFile.h"
      20             : #include "nsIServiceManager.h"
      21             : #include "nsIWeakReference.h"
      22             : #include "nsIWidget.h"
      23             : #include "nsIAppShellService.h"
      24             : #include "nsAppShellCID.h"
      25             : #include "nsPIDOMWindow.h"
      26             : #include "mozilla/X11Util.h"
      27             : 
      28             : #include "nsCOMPtr.h"
      29             : #include "nsString.h"
      30             : #include "prenv.h"
      31             : #include "nsCRT.h"
      32             : 
      33             : #include "nsXULAppAPI.h"
      34             : 
      35             : #include <X11/Xlib.h>
      36             : #include <X11/Xatom.h>
      37             : 
      38             : using namespace mozilla;
      39             : 
      40             : #define MOZILLA_VERSION_PROP   "_MOZILLA_VERSION"
      41             : #define MOZILLA_LOCK_PROP      "_MOZILLA_LOCK"
      42             : #define MOZILLA_RESPONSE_PROP  "_MOZILLA_RESPONSE"
      43             : #define MOZILLA_USER_PROP      "_MOZILLA_USER"
      44             : #define MOZILLA_PROFILE_PROP   "_MOZILLA_PROFILE"
      45             : #define MOZILLA_PROGRAM_PROP   "_MOZILLA_PROGRAM"
      46             : #define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE"
      47             : 
      48             : const unsigned char kRemoteVersion[] = "5.1";
      49             : 
      50             : #ifdef IS_BIG_ENDIAN
      51             : #define TO_LITTLE_ENDIAN32(x) \
      52             :     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
      53             :     (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
      54             : #else
      55             : #define TO_LITTLE_ENDIAN32(x) (x)
      56             : #endif
      57             : 
      58             : // Minimize the roundtrips to the X server by getting all the atoms at once
      59             : static const char *XAtomNames[] = {
      60             :   MOZILLA_VERSION_PROP,
      61             :   MOZILLA_LOCK_PROP,
      62             :   MOZILLA_RESPONSE_PROP,
      63             :   MOZILLA_USER_PROP,
      64             :   MOZILLA_PROFILE_PROP,
      65             :   MOZILLA_PROGRAM_PROP,
      66             :   MOZILLA_COMMANDLINE_PROP
      67             : };
      68             : static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)];
      69             : 
      70             : Atom nsXRemoteService::sMozVersionAtom;
      71             : Atom nsXRemoteService::sMozLockAtom;
      72             : Atom nsXRemoteService::sMozResponseAtom;
      73             : Atom nsXRemoteService::sMozUserAtom;
      74             : Atom nsXRemoteService::sMozProfileAtom;
      75             : Atom nsXRemoteService::sMozProgramAtom;
      76             : Atom nsXRemoteService::sMozCommandLineAtom;
      77             : 
      78             : nsXRemoteService * nsXRemoteService::sRemoteImplementation = 0;
      79             : 
      80             : 
      81             : static bool
      82           0 : FindExtensionParameterInCommand(const char* aParameterName,
      83             :                                 const nsACString& aCommand,
      84             :                                 char aSeparator,
      85             :                                 nsACString* aValue)
      86             : {
      87           0 :   nsAutoCString searchFor;
      88           0 :   searchFor.Append(aSeparator);
      89           0 :   searchFor.Append(aParameterName);
      90           0 :   searchFor.Append('=');
      91             : 
      92           0 :   nsACString::const_iterator start, end;
      93           0 :   aCommand.BeginReading(start);
      94           0 :   aCommand.EndReading(end);
      95           0 :   if (!FindInReadable(searchFor, start, end))
      96           0 :     return false;
      97             : 
      98           0 :   nsACString::const_iterator charStart, charEnd;
      99           0 :   charStart = end;
     100           0 :   aCommand.EndReading(charEnd);
     101           0 :   nsACString::const_iterator idStart = charStart, idEnd;
     102           0 :   if (FindCharInReadable(aSeparator, charStart, charEnd)) {
     103           0 :     idEnd = charStart;
     104             :   } else {
     105           0 :     idEnd = charEnd;
     106             :   }
     107           0 :   *aValue = nsDependentCSubstring(idStart, idEnd);
     108           0 :   return true;
     109             : }
     110             : 
     111             : 
     112             : nsXRemoteService::nsXRemoteService() = default;
     113             : 
     114             : void
     115           0 : nsXRemoteService::XRemoteBaseStartup(const char *aAppName, const char *aProfileName)
     116             : {
     117           0 :     EnsureAtoms();
     118             : 
     119           0 :     mAppName = aAppName;
     120           0 :     ToLowerCase(mAppName);
     121             : 
     122           0 :     mProfileName = aProfileName;
     123             : 
     124           0 :     nsCOMPtr<nsIObserverService> obs(do_GetService("@mozilla.org/observer-service;1"));
     125           0 :     if (obs) {
     126           0 :       obs->AddObserver(this, "xpcom-shutdown", false);
     127           0 :       obs->AddObserver(this, "quit-application", false);
     128             :     }
     129           0 : }
     130             : 
     131             : void
     132           0 : nsXRemoteService::HandleCommandsFor(Window aWindowId)
     133             : {
     134             :   // set our version
     135           0 :   XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozVersionAtom, XA_STRING,
     136           0 :                   8, PropModeReplace, kRemoteVersion, sizeof(kRemoteVersion) - 1);
     137             : 
     138             :   // get our username
     139             :   unsigned char *logname;
     140           0 :   logname = (unsigned char*) PR_GetEnv("LOGNAME");
     141           0 :   if (logname) {
     142             :     // set the property on the window if it's available
     143           0 :     XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozUserAtom, XA_STRING,
     144           0 :                     8, PropModeReplace, logname, strlen((char*) logname));
     145             :   }
     146             : 
     147           0 :   XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozProgramAtom, XA_STRING,
     148           0 :                   8, PropModeReplace, (unsigned char*) mAppName.get(), mAppName.Length());
     149             : 
     150           0 :   if (!mProfileName.IsEmpty()) {
     151           0 :     XChangeProperty(mozilla::DefaultXDisplay(),
     152             :                     aWindowId, sMozProfileAtom, XA_STRING,
     153             :                     8, PropModeReplace,
     154           0 :                     (unsigned char*) mProfileName.get(), mProfileName.Length());
     155             :   }
     156             : 
     157           0 : }
     158             : 
     159             : NS_IMETHODIMP
     160           0 : nsXRemoteService::Observe(nsISupports* aSubject,
     161             :                           const char *aTopic,
     162             :                           const char16_t *aData)
     163             : {
     164             :   // This can be xpcom-shutdown or quit-application, but it's the same either
     165             :   // way.
     166           0 :   Shutdown();
     167           0 :   return NS_OK;
     168             : }
     169             : 
     170             : bool
     171           0 : nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay,
     172             :                                     Time aEventTime,
     173             :                                     Atom aChangedAtom,
     174             :                                     nsIWeakReference* aDomWindow)
     175             : {
     176             : 
     177           0 :   nsCOMPtr<nsIDOMWindow> window (do_QueryReferent(aDomWindow));
     178             : 
     179           0 :   if (aChangedAtom == sMozCommandLineAtom) {
     180             :     // We got a new command atom.
     181             :     int result;
     182             :     Atom actual_type;
     183             :     int actual_format;
     184             :     unsigned long nitems, bytes_after;
     185           0 :     char *data = 0;
     186             : 
     187             :     result = XGetWindowProperty (aDisplay,
     188             :                                  aWindowId,
     189             :                                  aChangedAtom,
     190             :                                  0,                        /* long_offset */
     191             :                                  (65536 / sizeof (long)),  /* long_length */
     192             :                                  True,                     /* atomic delete after */
     193             :                                  XA_STRING,                /* req_type */
     194             :                                  &actual_type,             /* actual_type return */
     195             :                                  &actual_format,           /* actual_format_return */
     196             :                                  &nitems,                  /* nitems_return */
     197             :                                  &bytes_after,             /* bytes_after_return */
     198           0 :                                  (unsigned char **)&data); /* prop_return
     199             :                                                               (we only care
     200             :                                                               about the first ) */
     201             : 
     202             :     // Failed to get property off the window?
     203           0 :     if (result != Success)
     204           0 :       return false;
     205             : 
     206             :     // Failed to get the data off the window or it was the wrong type?
     207           0 :     if (!data || !TO_LITTLE_ENDIAN32(*reinterpret_cast<int32_t*>(data)))
     208           0 :       return false;
     209             : 
     210             :     // cool, we got the property data.
     211           0 :     const char *response = HandleCommandLine(data, window, aEventTime);
     212             : 
     213             :     // put the property onto the window as the response
     214           0 :     XChangeProperty (aDisplay, aWindowId,
     215             :                      sMozResponseAtom, XA_STRING,
     216             :                      8, PropModeReplace,
     217             :                      (const unsigned char *)response,
     218           0 :                      strlen (response));
     219           0 :     XFree(data);
     220           0 :     return true;
     221             :   }
     222             : 
     223           0 :   if (aChangedAtom == sMozResponseAtom) {
     224             :     // client accepted the response.  party on wayne.
     225           0 :     return true;
     226             :   }
     227             : 
     228           0 :   else if (aChangedAtom == sMozLockAtom) {
     229             :     // someone locked the window
     230           0 :     return true;
     231             :   }
     232             : 
     233           0 :   return false;
     234             : }
     235             : 
     236             : const char*
     237           0 : nsXRemoteService::HandleCommandLine(char* aBuffer, nsIDOMWindow* aWindow,
     238             :                                     uint32_t aTimestamp)
     239             : {
     240             :   nsresult rv;
     241             : 
     242             :   nsCOMPtr<nsICommandLineRunner> cmdline
     243           0 :     (do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv));
     244           0 :   if (NS_FAILED(rv))
     245           0 :     return "509 internal error";
     246             : 
     247             :   // the commandline property is constructed as an array of int32_t
     248             :   // followed by a series of null-terminated strings:
     249             :   //
     250             :   // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
     251             :   // (offset is from the beginning of the buffer)
     252             : 
     253           0 :   int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast<int32_t*>(aBuffer));
     254           0 :   char *wd   = aBuffer + ((argc + 1) * sizeof(int32_t));
     255             : 
     256           0 :   nsCOMPtr<nsIFile> lf;
     257           0 :   rv = NS_NewNativeLocalFile(nsDependentCString(wd), true,
     258           0 :                              getter_AddRefs(lf));
     259           0 :   if (NS_FAILED(rv))
     260           0 :     return "509 internal error";
     261             : 
     262           0 :   nsAutoCString desktopStartupID;
     263             : 
     264           0 :   char **argv = (char**) malloc(sizeof(char*) * argc);
     265           0 :   if (!argv) return "509 internal error";
     266             : 
     267           0 :   int32_t  *offset = reinterpret_cast<int32_t*>(aBuffer) + 1;
     268             : 
     269           0 :   for (int i = 0; i < argc; ++i) {
     270           0 :     argv[i] = aBuffer + TO_LITTLE_ENDIAN32(offset[i]);
     271             : 
     272           0 :     if (i == 0) {
     273           0 :       nsDependentCString cmd(argv[0]);
     274             :       FindExtensionParameterInCommand("DESKTOP_STARTUP_ID",
     275             :                                       cmd, ' ',
     276           0 :                                       &desktopStartupID);
     277             :     }
     278             :   }
     279             : 
     280           0 :   rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO);
     281             : 
     282           0 :   free (argv);
     283           0 :   if (NS_FAILED(rv)) {
     284           0 :     return "509 internal error";
     285             :   }
     286             : 
     287           0 :   if (aWindow)
     288           0 :     cmdline->SetWindowContext(aWindow);
     289             : 
     290           0 :   if (sRemoteImplementation)
     291           0 :     sRemoteImplementation->SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp);
     292             : 
     293           0 :   rv = cmdline->Run();
     294             : 
     295           0 :   if (NS_ERROR_ABORT == rv)
     296           0 :     return "500 command not parseable";
     297             : 
     298           0 :   if (NS_FAILED(rv))
     299           0 :     return "509 internal error";
     300             : 
     301           0 :   return "200 executed command";
     302             : }
     303             : 
     304             : void
     305           0 : nsXRemoteService::EnsureAtoms(void)
     306             : {
     307           0 :   if (sMozVersionAtom)
     308           0 :     return;
     309             : 
     310           0 :   XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char**>(XAtomNames),
     311           0 :                ArrayLength(XAtomNames), False, XAtoms);
     312             : 
     313           0 :   int i = 0;
     314           0 :   sMozVersionAtom     = XAtoms[i++];
     315           0 :   sMozLockAtom        = XAtoms[i++];
     316           0 :   sMozResponseAtom    = XAtoms[i++];
     317           0 :   sMozUserAtom        = XAtoms[i++];
     318           0 :   sMozProfileAtom     = XAtoms[i++];
     319           0 :   sMozProgramAtom     = XAtoms[i++];
     320           0 :   sMozCommandLineAtom = XAtoms[i++];
     321             : }

Generated by: LCOV version 1.13