diff options
author | Robin Jarry <robin@jarry.cc> | 2023-09-24 21:10:19 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-10-03 22:34:39 +0200 |
commit | 39fcc300d4440cfb011356ef2f364c87b7ff712d (patch) | |
tree | 336d269120d5c0758be6c7c6e3a15e3aaaf61a22 | |
parent | 4549ac84a15f6ebada51ad7a29078713c6e149ba (diff) | |
download | aerc-39fcc300d4440cfb011356ef2f364c87b7ff712d.tar.gz aerc-39fcc300d4440cfb011356ef2f364c87b7ff712d.zip |
open: run commands with sh -c
Allow running shell commands in openers.
Requested-by: Vitaly Ovchinnikov <v@postbox.nz>
Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | commands/msg/unsubscribe.go | 2 | ||||
-rw-r--r-- | commands/msgview/open-link.go | 2 | ||||
-rw-r--r-- | commands/msgview/open.go | 4 | ||||
-rw-r--r-- | config/aerc.conf | 9 | ||||
-rw-r--r-- | config/openers.go | 13 | ||||
-rw-r--r-- | doc/aerc-config.5.scd | 9 | ||||
-rw-r--r-- | lib/open.go | 25 |
8 files changed, 28 insertions, 37 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index dc615f35..74cb6999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). *.default=true *.normal=true ``` +- Openers commands are not executed in with `sh -c`. ### Deprecated diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go index 41159f03..35bc8e25 100644 --- a/commands/msg/unsubscribe.go +++ b/commands/msg/unsubscribe.go @@ -180,7 +180,7 @@ func unsubscribeHTTP(aerc *widgets.Aerc, u *url.URL) error { go func() { defer log.PanicHandler() mime := fmt.Sprintf("x-scheme-handler/%s", u.Scheme) - if err := lib.XDGOpenMime(u.String(), mime, nil); err != nil { + if err := lib.XDGOpenMime(u.String(), mime, ""); err != nil { aerc.PushError("Unsubscribe:" + err.Error()) } }() diff --git a/commands/msgview/open-link.go b/commands/msgview/open-link.go index 2858f13c..6cec278c 100644 --- a/commands/msgview/open-link.go +++ b/commands/msgview/open-link.go @@ -12,7 +12,7 @@ import ( type OpenLink struct { Url *url.URL `opt:"URL" parse:"ParseUrl"` - Cmd []string `opt:"..." required:"false"` + Cmd string `opt:"..." required:"false"` } func init() { diff --git a/commands/msgview/open.go b/commands/msgview/open.go index b9a4745d..b36907f5 100644 --- a/commands/msgview/open.go +++ b/commands/msgview/open.go @@ -13,8 +13,8 @@ import ( ) type Open struct { - Delete bool `opt:"-d"` - Cmd []string `opt:"..." required:"false"` + Delete bool `opt:"-d"` + Cmd string `opt:"..." required:"false"` } func init() { diff --git a/config/aerc.conf b/config/aerc.conf index 4b4e7cb6..7f6532f1 100644 --- a/config/aerc.conf +++ b/config/aerc.conf @@ -540,9 +540,10 @@ message/rfc822=colorize # actions on a per-MIME-type basis. The :open-link URL scheme is used to # determine the MIME type as follows: x-scheme-handler/<scheme>. # -# {} is expanded as the temporary filename to be opened. If it is not -# encountered in the command, the temporary filename will be appened to the end -# of the command. +# {} is expanded as the temporary filename or URL to be opened with proper +# shell quoting. If it is not encountered in the command, the filename/URL will +# be appended to the end of the command. The command will then be executed with +# `sh -c`. # # Like [filters], openers support basic shell globbing. The first opener which # matches the part's MIME type (or URL scheme handler MIME type) will be used, @@ -550,7 +551,7 @@ message/rfc822=colorize # # Examples: # x-scheme-handler/irc=hexchat -# x-scheme-handler/http*=firefox +# x-scheme-handler/http*=printf '%s' {} | wl-copy # text/html=surf -dfgms # text/plain=gvim {} +125 # message/rfc822=thunderbird diff --git a/config/openers.go b/config/openers.go index e246ea64..31d99e9c 100644 --- a/config/openers.go +++ b/config/openers.go @@ -1,17 +1,15 @@ package config import ( - "fmt" "strings" "git.sr.ht/~rjarry/aerc/log" "github.com/go-ini/ini" - "github.com/google/shlex" ) type Opener struct { Mime string - Args []string + Args string } var Openers []Opener @@ -24,14 +22,7 @@ func parseOpeners(file *ini.File) error { for _, key := range openers.Keys() { mime := strings.ToLower(key.Name()) - if args, err := shlex.Split(key.Value()); err != nil { - return err - } else { - if len(args) == 0 { - return fmt.Errorf("opener command empty for %s", mime) - } - Openers = append(Openers, Opener{Mime: mime, Args: args}) - } + Openers = append(Openers, Opener{Mime: mime, Args: key.Value()}) } out: diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index b6855c7a..8c18afd4 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -892,9 +892,10 @@ actions on a per-MIME-type basis. The *:open-link* URL scheme is used to determine the MIME type as follows: _x-scheme-handler/<scheme>_. They are configured in the *[openers]* section of _aerc.conf_. -_{}_ is expanded as the temporary filename or URL to be opened. If it is not -encountered in the command, the filename/URL will be appened to the end of the -command. Environment variables are also expanded. Tilde is not expanded. +_{}_ is expanded as the temporary filename or URL to be opened with proper shell +quoting. If it is not encountered in the command, the filename/URL will be +appended to the end of the command. The command will then be executed with +_sh -c_. Like *[filters]*, openers support basic shell globbing. The first opener which matches the part's MIME type (or URL scheme handler MIME type) will be used, so @@ -905,7 +906,7 @@ Example: ``` [openers] x-scheme-handler/irc=hexchat -x-scheme-handler/http\*=firefox +x-scheme-handler/http\*=printf '%s' {} | wl-copy text/html=surf -dfgms text/plain=gvim {} +125 message/rfc822=thunderbird diff --git a/lib/open.go b/lib/open.go index b60c4165..83f26499 100644 --- a/lib/open.go +++ b/lib/open.go @@ -7,18 +7,19 @@ import ( "strings" "git.sr.ht/~rjarry/aerc/config" + "git.sr.ht/~rjarry/aerc/lib/opt" "git.sr.ht/~rjarry/aerc/log" "github.com/danwakefield/fnmatch" ) func XDGOpenMime( - uri string, mimeType string, args []string, + uri string, mimeType string, args string, ) error { if len(args) == 0 { // no explicit command provided, lookup opener from mime type for _, o := range config.Openers { if fnmatch.Match(o.Mime, mimeType, 0) { - args = append(args, o.Args...) + args = o.Args break } } @@ -26,28 +27,24 @@ func XDGOpenMime( if len(args) == 0 { // no opener defined in config, fallback to default if runtime.GOOS == "darwin" { - args = append(args, "open") + args = "open" } else { - args = append(args, "xdg-open") + args = "xdg-open" } } - i := 0 - for ; i < len(args); i++ { - if strings.Contains(args[i], "{}") { - break - } - } - if i < len(args) { + // Escape URI special characters + uri = opt.QuoteArg(uri) + if strings.Contains(args, "{}") { // found {} placeholder in args, replace with uri - args[i] = strings.Replace(args[i], "{}", uri, 1) + args = strings.Replace(args, "{}", uri, 1) } else { // no {} placeholder in args, add uri at the end - args = append(args, uri) + args = args + " " + uri } log.Tracef("running command: %v", args) - cmd := exec.Command(args[0], args[1:]...) + cmd := exec.Command("sh", "-c", args) out, err := cmd.CombinedOutput() log.Debugf("command: %v exited. err=%v out=%s", args, err, out) if err != nil { |