summaryrefslogtreecommitdiffstats
path: root/shell/source/unix
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /shell/source/unix
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'shell/source/unix')
-rw-r--r--shell/source/unix/exec/shellexec.cxx291
-rw-r--r--shell/source/unix/exec/shellexec.hxx58
-rw-r--r--shell/source/unix/exec/shellexec_em.cxx28
-rw-r--r--shell/source/unix/exec/syssh.component26
-rwxr-xr-xshell/source/unix/misc/senddoc.sh439
-rw-r--r--shell/source/unix/misc/uri-encode.c44
6 files changed, 886 insertions, 0 deletions
diff --git a/shell/source/unix/exec/shellexec.cxx b/shell/source/unix/exec/shellexec.cxx
new file mode 100644
index 0000000000..71137c7d67
--- /dev/null
+++ b/shell/source/unix/exec/shellexec.cxx
@@ -0,0 +1,291 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/thread.h>
+#include <osl/file.hxx>
+#include <rtl/strbuf.hxx>
+#include <sal/log.hxx>
+
+#include "shellexec.hxx"
+#include <com/sun/star/system/SystemShellExecuteException.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/security/AccessControlException.hpp>
+#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/lok.hxx>
+
+#include <string.h>
+#include <errno.h>
+
+#if defined MACOSX
+#include <sys/stat.h>
+#endif
+
+#ifdef EMSCRIPTEN
+#include <rtl/uri.hxx>
+extern void execute_browser(const char* sUrl);
+#endif
+
+using com::sun::star::system::XSystemShellExecute;
+using com::sun::star::system::SystemShellExecuteException;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::system::SystemShellExecuteFlags;
+using namespace cppu;
+
+#ifndef EMSCRIPTEN
+namespace
+{
+ void escapeForShell( OStringBuffer & rBuffer, const OString & rURL)
+ {
+ sal_Int32 nmax = rURL.getLength();
+ for(sal_Int32 n=0; n < nmax; ++n)
+ {
+ // escape every non alpha numeric characters (excluding a few "known good") by prepending a '\'
+ char c = rURL[n];
+ if( ( c < 'A' || c > 'Z' ) && ( c < 'a' || c > 'z' ) && ( c < '0' || c > '9' ) && c != '/' && c != '.' )
+ rBuffer.append( '\\' );
+
+ rBuffer.append( c );
+ }
+ }
+}
+#endif
+
+ShellExec::ShellExec( const Reference< XComponentContext >& xContext ) :
+ m_xContext(xContext)
+{
+}
+
+void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aParameter, sal_Int32 nFlags )
+{
+#ifndef EMSCRIPTEN
+ OStringBuffer aBuffer, aLaunchBuffer;
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ SAL_WARN("shell", "Unusual - shell attempt to launch " << aCommand << " with params " << aParameter << " under lok");
+ return;
+ }
+
+ // DESKTOP_LAUNCH, see http://freedesktop.org/pipermail/xdg/2004-August/004489.html
+ static const char *pDesktopLaunch = getenv( "DESKTOP_LAUNCH" );
+
+ // Check whether aCommand contains an absolute URI reference:
+ css::uno::Reference< css::uri::XUriReference > uri(
+ css::uri::UriReferenceFactory::create(m_xContext)->parse(aCommand));
+ if (uri.is() && uri->isAbsolute())
+ {
+ // It seems to be a URL...
+ // We need to re-encode file urls because osl_getFileURLFromSystemPath converts
+ // to UTF-8 before encoding non ascii characters, which is not what other apps
+ // expect.
+ OUString aURL = css::uri::ExternalUriReferenceTranslator::create(
+ m_xContext)->translateToExternal(aCommand);
+ if ( aURL.isEmpty() && !aCommand.isEmpty() )
+ {
+ throw RuntimeException(
+ "Cannot translate URI reference to external format: "
+ + aCommand,
+ getXWeak());
+ }
+
+#ifdef MACOSX
+ bool dir = false;
+ if (uri->getScheme().equalsIgnoreAsciiCase("file")) {
+ OUString pathname;
+ auto const e1 = osl::FileBase::getSystemPathFromFileURL(aCommand, pathname);
+ if (e1 != osl::FileBase::E_None) {
+ throw css::lang::IllegalArgumentException(
+ ("XSystemShellExecute.execute, getSystemPathFromFileURL <" + aCommand
+ + "> failed with " + OUString::number(e1)),
+ {}, 0);
+ }
+ OString pathname8;
+ if (!pathname.convertToString(
+ &pathname8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ throw css::lang::IllegalArgumentException(
+ "XSystemShellExecute.execute, cannot convert \"" + pathname + "\" to UTF-8", {},
+ 0);
+ }
+ struct stat st;
+ auto const e2 = lstat(pathname8.getStr(), &st);
+ if (e2 != 0) {
+ auto const e3 = errno;
+ SAL_INFO("shell", "lstat(" << pathname8 << ") failed with errno " << e3);
+ }
+ if (e2 != 0) {
+ throw css::lang::IllegalArgumentException(
+ "XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
+ } else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) {
+ dir = true;
+ } else if ((nFlags & css::system::SystemShellExecuteFlags::URIS_ONLY) != 0
+ && (!S_ISREG(st.st_mode)
+ || (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0))
+ {
+ throw css::security::AccessControlException(
+ "XSystemShellExecute.execute, bad <" + aCommand + ">", {}, {});
+ } else if (pathname.endsWithIgnoreAsciiCase(".class")
+ || pathname.endsWithIgnoreAsciiCase(".dmg")
+ || pathname.endsWithIgnoreAsciiCase(".fileloc")
+ || pathname.endsWithIgnoreAsciiCase(".inetloc")
+ || pathname.endsWithIgnoreAsciiCase(".ipa")
+ || pathname.endsWithIgnoreAsciiCase(".jar")
+ || pathname.endsWithIgnoreAsciiCase(".terminal"))
+ {
+ dir = true;
+ }
+ }
+
+ //TODO: Using open(1) with an argument that syntactically is an absolute
+ // URI reference does not necessarily give expected results:
+ // 1 If the given URI reference matches a supported scheme (e.g.,
+ // "mailto:foo"):
+ // 1.1 If it matches an existing pathname (relative to CWD): Results
+ // in "mailto:foo?\n[0]\tcancel\n[1]\tOpen the file\tmailto:foo\n[2]\t
+ // Open the URL\tmailto:foo\n\nWhich did you mean? Cancelled." on
+ // stderr and SystemShellExecuteException.
+ // 1.2 If it does not match an exitsting pathname (relative to CWD):
+ // Results in the corresponding application being opened with the given
+ // document (e.g., Mail with a New Message).
+ // 2 If the given URI reference does not match a supported scheme
+ // (e.g., "foo:bar"):
+ // 2.1 If it matches an existing pathname (relative to CWD) pointing to
+ // an executable: Results in execution of that executable.
+ // 2.2 If it matches an existing pathname (relative to CWD) pointing to
+ // a non-executable regular file: Results in opening it in TextEdit.
+ // 2.3 If it matches an existing pathname (relative to CWD) pointing to
+ // a directory: Results in opening it in Finder.
+ // 2.4 If it does not match an exitsting pathname (relative to CWD):
+ // Results in "The file /.../foo:bar does not exits." (where "/..." is
+ // the CWD) on stderr and SystemShellExecuteException.
+ aBuffer.append("open");
+ if (dir) {
+ aBuffer.append(" -R");
+ }
+ aBuffer.append(" --");
+#else
+ // Just use xdg-open on non-Mac
+ aBuffer.append("xdg-open");
+#endif
+ aBuffer.append(" ");
+ escapeForShell(aBuffer, OUStringToOString(aURL, osl_getThreadTextEncoding()));
+
+ if ( pDesktopLaunch && *pDesktopLaunch )
+ {
+ aLaunchBuffer.append( pDesktopLaunch + OString::Concat(" "));
+ escapeForShell(aLaunchBuffer, OUStringToOString(aURL, osl_getThreadTextEncoding()));
+ }
+ } else if ((nFlags & css::system::SystemShellExecuteFlags::URIS_ONLY) != 0)
+ {
+ throw css::lang::IllegalArgumentException(
+ "XSystemShellExecute.execute URIS_ONLY with non-absolute"
+ " URI reference "
+ + aCommand,
+ getXWeak(), 0);
+ } else {
+ escapeForShell(aBuffer, OUStringToOString(aCommand, osl_getThreadTextEncoding()));
+ aBuffer.append(" ");
+ if( nFlags != 42 )
+ escapeForShell(aBuffer, OUStringToOString(aParameter, osl_getThreadTextEncoding()));
+ else
+ aBuffer.append(OUStringToOString(aParameter, osl_getThreadTextEncoding()));
+ }
+
+ // Prefer DESKTOP_LAUNCH when available
+ if ( !aLaunchBuffer.isEmpty() )
+ {
+ FILE *pLaunch = popen( aLaunchBuffer.makeStringAndClear().getStr(), "w" );
+ if ( pLaunch != nullptr )
+ {
+ if ( 0 == pclose( pLaunch ) )
+ return;
+ }
+ // Failed, do not try DESKTOP_LAUNCH any more
+ pDesktopLaunch = nullptr;
+ }
+
+ OString cmd =
+#ifdef LINUX
+ // avoid blocking (call it in background)
+ "( " + aBuffer + " ) &";
+#else
+ aBuffer.makeStringAndClear();
+#endif
+ FILE *pLaunch = popen(cmd.getStr(), "w");
+ if ( pLaunch != nullptr )
+ {
+ if ( 0 == pclose( pLaunch ) )
+ return;
+ }
+
+ int nerr = errno;
+ throw SystemShellExecuteException(OUString::createFromAscii( strerror( nerr ) ),
+ static_cast < XSystemShellExecute * > (this), nerr );
+#else // EMSCRIPTEN
+ (void)nFlags;
+
+ css::uno::Reference< css::uri::XUriReference > uri(
+ css::uri::UriReferenceFactory::create(m_xContext)->parse(aCommand));
+ if (!uri.is() || !uri->isAbsolute())
+ throw SystemShellExecuteException("Emscripten can just open absolute URIs.",
+ static_cast<XSystemShellExecute*>(this), 42);
+ if (!aParameter.isEmpty())
+ throw SystemShellExecuteException("Emscripten can't process parameters; encode in URI.",
+ static_cast<XSystemShellExecute*>(this), 42);
+
+ OUString sEscapedURI(rtl::Uri::encode(aCommand, rtl_UriCharClassUric,
+ rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8));
+ execute_browser(sEscapedURI.toUtf8().getStr());
+#endif
+}
+
+// XServiceInfo
+
+OUString SAL_CALL ShellExec::getImplementationName( )
+{
+ return "com.sun.star.comp.system.SystemShellExecute";
+}
+
+sal_Bool SAL_CALL ShellExec::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString > SAL_CALL ShellExec::getSupportedServiceNames( )
+{
+ return { "com.sun.star.system.SystemShellExecute" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_ShellExec_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new ShellExec(context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/unix/exec/shellexec.hxx b/shell/source/unix/exec/shellexec.hxx
new file mode 100644
index 0000000000..fd084a567f
--- /dev/null
+++ b/shell/source/unix/exec/shellexec.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SHELL_SOURCE_UNIX_EXEC_SHELLEXEC_HXX
+#define INCLUDED_SHELL_SOURCE_UNIX_EXEC_SHELLEXEC_HXX
+
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+
+
+
+
+class ShellExec : public ::cppu::WeakImplHelper< css::system::XSystemShellExecute, css::lang::XServiceInfo >
+{
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+public:
+ explicit ShellExec(const css::uno::Reference< css::uno::XComponentContext >& xContext);
+
+
+ // XSystemShellExecute
+
+
+ virtual void SAL_CALL execute( const OUString& aCommand, const OUString& aParameter, sal_Int32 nFlags ) override;
+
+
+ // XServiceInfo
+
+
+ virtual OUString SAL_CALL getImplementationName( ) override;
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/unix/exec/shellexec_em.cxx b/shell/source/unix/exec/shellexec_em.cxx
new file mode 100644
index 0000000000..219eac9694
--- /dev/null
+++ b/shell/source/unix/exec/shellexec_em.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * 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/.
+ */
+
+/**
+ * Some of our templating stuff clashes with EM_ASM / MAIN_THREAD_EM_ASM:
+ *
+ * shellexec.cxx:250:5: error: called object type 'const char *' is not a function or function pointer
+ * MAIN_THREAD_EM_ASM(
+ * ^
+ * git_emsdk/upstream/emscripten/cache/sysroot/include/emscripten/em_asm.h:208:39: note: expanded from macro 'MAIN_THREAD_EM_ASM'
+ * #define MAIN_THREAD_EM_ASM(code, ...) ((void)emscripten_asm_const_int_sync_on_main_thread(CODE_EXPR(#code) _EM_ASM_PREP_ARGS(__VA_ARGS__)))
+ * ^
+ * 1 error generated.
+ *
+ * so as a workaround the EM_ASM call is now in an extra file.
+ */
+
+#include <emscripten.h>
+
+void execute_browser(const char* sUrl) { EM_ASM("window.open(UTF8ToString($0));", sUrl); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/unix/exec/syssh.component b/shell/source/unix/exec/syssh.component
new file mode 100644
index 0000000000..a41328d342
--- /dev/null
+++ b/shell/source/unix/exec/syssh.component
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ -->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.system.SystemShellExecute"
+ constructor="shell_ShellExec_get_implementation">
+ <service name="com.sun.star.system.SystemShellExecute"/>
+ </implementation>
+</component>
diff --git a/shell/source/unix/misc/senddoc.sh b/shell/source/unix/misc/senddoc.sh
new file mode 100755
index 0000000000..f70251ecf3
--- /dev/null
+++ b/shell/source/unix/misc/senddoc.sh
@@ -0,0 +1,439 @@
+#!/bin/sh
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+#
+
+URI_ENCODE=$(dirname "$0")/uri-encode
+FOPTS=""
+sd_platform=$(uname -s)
+
+# linux file utility needs -L option to resolve symlinks
+if [ "$sd_platform" = "Linux" ] ; then
+ FOPTS="-L"
+fi
+
+# do not confuse the system mail clients with OOo and Java libraries
+unset LD_LIBRARY_PATH
+
+# tries to locate the executable specified
+# as first parameter in the user's path.
+which() {
+ if [ ! -z "$1" ]; then
+ for i in $(echo "$PATH" | sed -e 's/^:/.:/g' -e 's/:$/:./g' -e 's/::/:.:/g' -e 's/:/ /g'); do
+ if [ -x "$i/$1" -a ! -d "$i/$1" ]; then
+ echo "$i/$1"
+ break;
+ fi
+ done
+ fi
+}
+
+# checks for the original mozilla start script(s)
+# and restrict the "-remote" semantics to those.
+run_mozilla() {
+ # find mozilla script in PATH if necessary
+ if [ "$(basename "$1")" = "$1" ]; then
+ moz=$(which "$1")
+ else
+ moz=$1
+ fi
+
+ if file $FOPTS "$moz" | grep "script" > /dev/null && grep "[NM]PL" "$moz" > /dev/null; then
+ "$moz" -remote 'ping()' 2>/dev/null >/dev/null
+ if [ $? -eq 2 ]; then
+ "$1" -compose "$2" &
+ else
+ "$1" -remote "xfeDoCommand(composeMessage,$2)" &
+ fi
+ else
+ "$1" -compose "$2" &
+ fi
+}
+
+if [ "$1" = "--mailclient" ]; then
+ shift
+ MAILER=$1
+ shift
+fi
+
+# autodetect mail client from executable name
+case $(basename "$MAILER" | sed 's/-.*$//') in
+
+ iceape | mozilla | netscape | seamonkey | icedove | thunderbird | betterbird)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ TO=${TO:-}${TO:+,}$2
+ shift
+ ;;
+ --cc)
+ CC=${CC:-}${CC:+,}$2
+ shift
+ ;;
+ --bcc)
+ BCC=${BCC:-}${BCC:+,}$2
+ shift
+ ;;
+ --subject)
+ SUBJECT=$2
+ shift
+ ;;
+ --body)
+ BODY=$2
+ shift
+ ;;
+ --attach)
+ ATTACH=${ATTACH:-}${ATTACH:+,}$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ if [ "$TO" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}to=\'${TO}\'
+ fi
+ if [ "$CC" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}cc=\'${CC}\'
+ fi
+ if [ "$BCC" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}bcc=\'${BCC}\'
+ fi
+ if [ "$SUBJECT" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}subject=\'${SUBJECT}\'
+ fi
+ if [ "$BODY" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}body=\'${BODY}\'
+ fi
+ if [ "$ATTACH" != "" ]; then
+ COMMAND=${COMMAND:-}${COMMAND:+,}attachment=\'${ATTACH}\'
+ fi
+
+ run_mozilla "$MAILER" "$COMMAND"
+ ;;
+
+ kmail)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ TO="${TO:-}${TO:+,}$2"
+ shift
+ ;;
+ --cc)
+ CC="${CC:-}${CC:+,}$2"
+ shift
+ ;;
+ --bcc)
+ BCC="${BCC:-}${BCC:+,}$2"
+ shift
+ ;;
+ --subject)
+ SUBJECT="$2"
+ shift
+ ;;
+ --body)
+ BODY="$2"
+ shift
+ ;;
+ --from)
+ FROM="$2"
+ shift
+ ;;
+ --attach)
+ ATTACH="${ATTACH:-}${ATTACH:+ }--attach "$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ ${MAILER} --composer \
+ ${CC:+--cc} ${CC:+"${CC}"} \
+ ${BCC:+--bcc} ${BCC:+"${BCC}"} \
+ ${SUBJECT:+--subject} ${SUBJECT:+"${SUBJECT}"} \
+ ${BODY:+--body} ${BODY:+"${BODY}"} \
+ ${FROM:+--header} ${FROM:+"From: ${FROM}"} \
+ ${ATTACH:+${ATTACH}} \
+ ${TO:+"${TO}"}
+ ;;
+
+ mutt)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --from)
+ FROM="$2"
+ shift
+ ;;
+ --to)
+ TO="${TO:-}${TO:+,}$2"
+ shift
+ ;;
+ --cc)
+ CC="${CC:-}${CC:+,}$2"
+ shift
+ ;;
+ --bcc)
+ BCC="${BCC:-}${BCC:+,}$2"
+ shift
+ ;;
+ --subject)
+ SUBJECT="$2"
+ shift
+ ;;
+ --body)
+ TEMPLATE="$(basename "$0").mutt.XXXXXXXX"
+ BODY=$(mktemp -q -t "${TEMPLATE}")
+ echo "$2" > "$BODY"
+ shift
+ ;;
+ --attach)
+ ATTACH="$2"
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ x-terminal-emulator -e ${MAILER} \
+ ${FROM:+-e} ${FROM:+"set from=\"${FROM}\""} \
+ ${CC:+-c} ${CC:+"${CC}"} \
+ ${BCC:+-b} ${BCC:+"${BCC}"} \
+ ${SUBJECT:+-s} ${SUBJECT:+"${SUBJECT}"} \
+ ${BODY:+-i} ${BODY:+"${BODY}"} \
+ ${ATTACH:+-a} ${ATTACH:+"${ATTACH}"} \
+ ${TO:+"${TO}"} &
+ rm -f "$BODY"
+ ;;
+
+ evolution | gnome | xdg) # NB. shortened from the dash on
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ if [ "${TO}" != "" ]; then
+ MAILTO="${MAILTO:-}${MAILTO:+&}to=$2"
+ else
+ TO="$2"
+ fi
+ shift
+ ;;
+ --cc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}cc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --bcc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}bcc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --subject)
+ MAILTO="${MAILTO:-}${MAILTO:+&}subject"=$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --body)
+ MAILTO="${MAILTO:-}${MAILTO:+&}body="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --attach)
+ MAILTO="${MAILTO:-}${MAILTO:+&}attach="$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ MAILTO="mailto:${TO}?${MAILTO}"
+ ${MAILER} "${MAILTO}" &
+ ;;
+
+ groupwise)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ if [ "${TO}" != "" ]; then
+ MAILTO="${MAILTO:-}${MAILTO:+&}to=$2"
+ else
+ TO="$2"
+ fi
+ shift
+ ;;
+ --cc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}cc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --bcc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}bcc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --subject)
+ MAILTO="${MAILTO:-}${MAILTO:+&}subject"=$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --body)
+ MAILTO="${MAILTO:-}${MAILTO:+&}body="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --attach)
+ MAILTO="${MAILTO:-}${MAILTO:+&}attachment="$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ MAILTO="mailto:${TO}?${MAILTO}"
+ ${MAILER} "${MAILTO}" &
+ ;;
+
+ dtmail)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ TO=${TO:-}${TO:+,}$2
+ shift
+ ;;
+ --attach)
+ ATTACH="$2"
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ ${MAILER} ${TO:+-T} ${TO:-} ${ATTACH:+-a} ${ATTACH:+"${ATTACH}"}
+ ;;
+
+ sylpheed | claws)
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ TO=${TO:-}${TO:+,}$2
+ shift
+ ;;
+ --attach)
+ ATTACH=${ATTACH:-}${ATTACH:+,}$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ ${MAILER} ${TO:+--compose} ${TO:-} ${ATTACH:+--attach} ${ATTACH:-}
+ ;;
+
+ Mail | Thunderbird | Betterbird | *.app )
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --attach)
+ #i95688# fix filenames containing accented chars, whatever alien
+ ATTACH="${ATTACH:-}${ATTACH:+ }"$(echo "file://$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+ /usr/bin/open -a "${MAILER}" ${ATTACH}
+ ;;
+
+ *)
+
+ # LO is configured to use something we do not recognize, or is not configured.
+ # Try to be smart, and send the mail anyway, if we have the
+ # possibility to do so.
+
+ if [ -x /usr/bin/xdg-email ] ; then
+ MAILER=/usr/bin/xdg-email
+ elif [ -n "$DESKTOP_LAUNCH" ]; then
+ # http://lists.freedesktop.org/pipermail/xdg/2004-August/002873.html
+ MAILER=${DESKTOP_LAUNCH}
+ elif [ -n "$KDE_FULL_SESSION" -a -x /usr/bin/kde-open ] ; then
+ MAILER=/usr/bin/kde-open
+ elif [ -x /usr/bin/xdg-open ] ; then
+ MAILER=/usr/bin/xdg-open
+ elif command -v xdg-open >/dev/null 2>&1 ; then
+ MAILER=$(command -v xdg-open)
+ else
+ echo "Unsupported mail client: $(basename $MAILER | sed 's/-.*^//')"
+ exit 2
+ fi
+
+ while [ "$1" != "" ]; do
+ case $1 in
+ --to)
+ if [ "${TO}" != "" ]; then
+ MAILTO="${MAILTO:-}${MAILTO:+&}to=$2"
+ else
+ TO="$2"
+ fi
+ shift
+ ;;
+ --cc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}cc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --bcc)
+ MAILTO="${MAILTO:-}${MAILTO:+&}bcc="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --subject)
+ MAILTO="${MAILTO:-}${MAILTO:+&}subject"=$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --body)
+ MAILTO="${MAILTO:-}${MAILTO:+&}body="$(echo "$2" | "${URI_ENCODE}")
+ shift
+ ;;
+ --attach)
+ if [ "$MAILER" = "/usr/bin/xdg-email" ]; then
+ MAILTO="${MAILTO:-}${MAILTO:+&}attach="$(echo "file://$2" | "${URI_ENCODE}")
+ else
+ MAILTO="${MAILTO:-}${MAILTO:+&}attachment="$(echo "file://$2" | "${URI_ENCODE}")
+ fi
+ shift
+ ;;
+ *)
+ ;;
+ esac
+ shift;
+ done
+
+ MAILTO="mailto:${TO}?${MAILTO}"
+ ${MAILER} "${MAILTO}" &
+ ;;
+esac
diff --git a/shell/source/unix/misc/uri-encode.c b/shell/source/unix/misc/uri-encode.c
new file mode 100644
index 0000000000..f7bca6ff6a
--- /dev/null
+++ b/shell/source/unix/misc/uri-encode.c
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(void) {
+ for (;;) {
+ int c;
+ errno = 0;
+ c = getchar();
+ if (c == EOF) {
+ exit(errno == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ } else if (isalnum(c) || strchr("!$'()*+,-.:=@_~/\n", c) != NULL) {
+ /* valid RFC 2396 pchar characters + '/' + newline */
+ if (putchar(c) == EOF) {
+ exit(EXIT_FAILURE);
+ }
+ } else if (printf("%%%02X", (unsigned char) (char) c) < 0) {
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */