diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /shell/source/unix | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'shell/source/unix')
-rw-r--r-- | shell/source/unix/exec/shellexec.cxx | 291 | ||||
-rw-r--r-- | shell/source/unix/exec/shellexec.hxx | 58 | ||||
-rw-r--r-- | shell/source/unix/exec/shellexec_em.cxx | 28 | ||||
-rw-r--r-- | shell/source/unix/exec/syssh.component | 26 | ||||
-rwxr-xr-x | shell/source/unix/misc/senddoc.sh | 446 | ||||
-rw-r--r-- | shell/source/unix/misc/uri-encode.c | 44 |
6 files changed, 893 insertions, 0 deletions
diff --git a/shell/source/unix/exec/shellexec.cxx b/shell/source/unix/exec/shellexec.cxx new file mode 100644 index 000000000..195a69788 --- /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, + static_cast< cppu::OWeakObject * >(this)); + } + +#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, + static_cast< cppu::OWeakObject * >(this), 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.makeStringAndClear() + " ) &"; +#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 000000000..fd084a567 --- /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 000000000..219eac969 --- /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 000000000..a41328d34 --- /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 000000000..c37a2dcf8 --- /dev/null +++ b/shell/source/unix/misc/senddoc.sh @@ -0,0 +1,446 @@ +#!/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 +case $sd_platform in + AIX) + unset LIBPATH + ;; + *) + unset LD_LIBRARY_PATH + ;; +esac + +# 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 000000000..f7bca6ff6 --- /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: */ |