Makes the Execute method function properly

This commit is contained in:
sloumdrone 2019-07-03 11:21:39 -07:00
parent 917752a0e1
commit 88eda9d6d5
1 changed files with 36 additions and 63 deletions

View File

@ -8,8 +8,6 @@ import (
"fmt"
"bufio"
"sort"
"syscall"
"path/filepath"
)
type Entry map[string]string
@ -20,45 +18,26 @@ type Mailcap struct {
}
// Creates and initializes the mailcap struct/db
// Returns a pointer to Mailcap struct
// and returns a pointer to Mailcap struct
func NewMailcap() *Mailcap {
mc := Mailcap{make(Cap)}
mc.getCaps()
return &mc
}
// Prints the mailcap db, returns nothing
func (m *Mailcap) ShowAll() {
fmt.Print(m.Caps)
fmt.Println()
}
// Prints the db entries for the mimetype in question.
// Returns Fields (an Entry slice) and an error or nil.
func (m *Mailcap) Show(mime string) (Fields, error) {
// Returns Fields for a given mimetype and an error or nil.
func (m *Mailcap) GetAllMime(mime string) (Fields, error) {
if v, ok := m.Caps[mime]; ok {
fmt.Println(mime + ":")
fmt.Print(v)
fmt.Println("")
return v, nil
}
return make(Fields, 0), fmt.Errorf("Cannot find %s\n", mime)
}
// Utility to print the mailcap files that will
// be searched.
func (m *Mailcap) ShowFiles() {
for _, s := range getMailcapFileList() {
fmt.Println(s)
fmt.Println("")
}
}
// Finds the program to run for the mimetype in question
// based on the key, common keys: view, edit, and the path.
// Returns the final command as a string and nil, or if error
// an empty string and the error
func (m *Mailcap) FindMatch(mime, key, path string) (string, error) {
// Retrieves an Entry for a given mimetype and key.
// Key is required to make sure the returned Entry has
// the capability that is desired. Common keys: "view", "edit".
// Returns and Entry and an error
func (m *Mailcap) FindMatch(mime, key string) (Entry, error) {
entries := m.lookup(mime, key)
for _, v := range entries {
exitCode := 0;
@ -78,52 +57,47 @@ func (m *Mailcap) FindMatch(mime, key, path string) (string, error) {
if exitCode != 0 {
continue
}
if val, ok := v[key]; ok {
if strings.Index(val, "%s") >= 0 {
return fmt.Sprintf(val, path), nil
} else {
return val, nil
}
}
return v, nil
}
return "", fmt.Errorf("Unable to find key %q in entries for %s", key, mime)
return make(Entry), fmt.Errorf("Unable to find key %q in entries for %s", key, mime)
}
// Runs the program that fits the mimetype with the key
// and path. Common keys: view, edit. Returns an error
// or nil if there is no error.
func (m *Mailcap) RunMatch(mime, key, path string) error {
pwd := os.Getenv("PWD")
dir := filepath.Dir(path)
// Called on an Entry type returned by FindMatch
// Executes the program associated with the key
// used to call Execute. A filepath string is
// also included in the call to Execute in order
// to declare the target of the program being
// called via the key param. Returns an error
// or nil.
func (e Entry) Execute(key, path string) error {
entryVal, ok := e[key]
if !ok {
return fmt.Errorf("The key %q does not exist", key)
}
os.Setenv("PWD", dir)
defer os.Setenv("PWD", pwd)
env := os.Environ()
match, err := m.FindMatch(mime, key, path)
if err != nil {
return err
matchFields := strings.Fields(entryVal)
for index, field := range matchFields {
if field == "%s" || field == "'%s'" {
matchFields[index] = path
}
}
matchFields := strings.Fields(match)
c := exec.Command(matchFields[0], matchFields[1:]...)
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
binary, lookErr := exec.LookPath(matchFields[0])
if lookErr != nil {
return lookErr
}
execErr := syscall.Exec(binary, []string{matchFields[0], path}, env)
execErr := c.Run()
if execErr != nil {
return execErr
}
}
return nil
}
// Private method to lookup the items for a particular
// mimetype and key, returns Fields
// Look up all of the Entry types available for
// a given mime and key. Returns an Entry slice (Fields)
func (m *Mailcap) lookup(mime, key string) Fields {
f := make(Fields, 0, 5)
if val, ok := m.Caps[mime]; ok {
@ -287,9 +261,8 @@ func parseLine(ln string) (string, Entry, error) {
return key, outputFields, nil
}
// Gets one key value pair
// Gets one key-value pair from mailcap entry
func parseField(ln string, i, n int) (string, int) {
// get one key-value pair from mailcap entry
start := i
for ;i < n; {
c := ln[i]