michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim:expandtab:shiftwidth=2:tabstop=2:cin: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsLocalHandlerApp.h" michael@0: #include "nsIURI.h" michael@0: #include "nsIProcess.h" michael@0: michael@0: // XXX why does nsMIMEInfoImpl have a threadsafe nsISupports? do we need one michael@0: // here too? michael@0: NS_IMPL_ISUPPORTS(nsLocalHandlerApp, nsILocalHandlerApp, nsIHandlerApp) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// nsIHandlerApp michael@0: michael@0: NS_IMETHODIMP nsLocalHandlerApp::GetName(nsAString& aName) michael@0: { michael@0: if (mName.IsEmpty() && mExecutable) { michael@0: // Don't want to cache this, just in case someone resets the app michael@0: // without changing the description.... michael@0: mExecutable->GetLeafName(aName); michael@0: } else { michael@0: aName.Assign(mName); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsLocalHandlerApp::SetName(const nsAString & aName) michael@0: { michael@0: mName.Assign(aName); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::SetDetailedDescription(const nsAString & aDescription) michael@0: { michael@0: mDetailedDescription.Assign(aDescription); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::GetDetailedDescription(nsAString& aDescription) michael@0: { michael@0: aDescription.Assign(mDetailedDescription); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::Equals(nsIHandlerApp *aHandlerApp, bool *_retval) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aHandlerApp); michael@0: michael@0: *_retval = false; michael@0: michael@0: // If the handler app isn't a local handler app, then it's not the same app. michael@0: nsCOMPtr localHandlerApp = do_QueryInterface(aHandlerApp); michael@0: if (!localHandlerApp) michael@0: return NS_OK; michael@0: michael@0: // If either handler app doesn't have an executable, then they aren't michael@0: // the same app. michael@0: nsCOMPtr executable; michael@0: nsresult rv = localHandlerApp->GetExecutable(getter_AddRefs(executable)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: // Equality for two empty nsIHandlerApp michael@0: if (!executable && !mExecutable) { michael@0: *_retval = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: // At least one is set so they are not equal michael@0: if (!mExecutable || !executable) michael@0: return NS_OK; michael@0: michael@0: // Check the command line parameter list lengths michael@0: uint32_t len; michael@0: localHandlerApp->GetParameterCount(&len); michael@0: if (mParameters.Length() != len) michael@0: return NS_OK; michael@0: michael@0: // Check the command line params lists michael@0: for (uint32_t idx = 0; idx < mParameters.Length(); idx++) { michael@0: nsAutoString param; michael@0: if (NS_FAILED(localHandlerApp->GetParameter(idx, param)) || michael@0: !param.Equals(mParameters[idx])) michael@0: return NS_OK; michael@0: } michael@0: michael@0: return executable->Equals(mExecutable, _retval); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::LaunchWithURI(nsIURI *aURI, michael@0: nsIInterfaceRequestor *aWindowContext) michael@0: { michael@0: // pass the entire URI to the handler. michael@0: nsAutoCString spec; michael@0: aURI->GetAsciiSpec(spec); michael@0: return LaunchWithIProcess(spec); michael@0: } michael@0: michael@0: nsresult michael@0: nsLocalHandlerApp::LaunchWithIProcess(const nsCString& aArg) michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr process = do_CreateInstance(NS_PROCESS_CONTRACTID, &rv); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: if (NS_FAILED(rv = process->Init(mExecutable))) michael@0: return rv; michael@0: michael@0: const char *string = aArg.get(); michael@0: michael@0: return process->Run(false, &string, 1); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// nsILocalHandlerApp michael@0: michael@0: /* attribute nsIFile executable; */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::GetExecutable(nsIFile **aExecutable) michael@0: { michael@0: NS_IF_ADDREF(*aExecutable = mExecutable); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::SetExecutable(nsIFile *aExecutable) michael@0: { michael@0: mExecutable = aExecutable; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute unsigned long parameterCount; */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::GetParameterCount(uint32_t *aParameterCount) michael@0: { michael@0: *aParameterCount = mParameters.Length(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void clearParameters (); */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::ClearParameters() michael@0: { michael@0: mParameters.Clear(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void appendParameter (in AString param); */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::AppendParameter(const nsAString & aParam) michael@0: { michael@0: mParameters.AppendElement(aParam); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* AString getParameter (in unsigned long parameterIndex); */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::GetParameter(uint32_t parameterIndex, nsAString & _retval) michael@0: { michael@0: if (mParameters.Length() <= parameterIndex) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: _retval.Assign(mParameters[parameterIndex]); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* boolean parameterExists (in AString param); */ michael@0: NS_IMETHODIMP michael@0: nsLocalHandlerApp::ParameterExists(const nsAString & aParam, bool *_retval) michael@0: { michael@0: *_retval = mParameters.Contains(aParam); michael@0: return NS_OK; michael@0: }