Basic working Run method is added. Small bits of cleanup.

This commit is contained in:
sloumdrone 2019-06-29 13:37:56 -07:00
parent 834cc175ba
commit 917752a0e1
1 changed files with 58 additions and 24 deletions

View File

@ -8,6 +8,8 @@ import (
"fmt"
"bufio"
"sort"
"syscall"
"path/filepath"
)
type Entry map[string]string
@ -17,27 +19,34 @@ type Mailcap struct {
Caps Cap
}
// Creates and initializes the mailcap struct/db
// 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()
}
func (m *Mailcap) Show(mime string) {
// 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) {
if v, ok := m.Caps[mime]; ok {
fmt.Println(mime + ":")
fmt.Print(v)
fmt.Println("")
} else {
fmt.Printf("Cannot find %s\n", mime)
}
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)
@ -45,18 +54,20 @@ func (m *Mailcap) ShowFiles() {
}
}
// 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) {
entries := m.lookup(mime, key)
for _, v := range entries {
exitCode := 0;
if _, ok := v["needsterminal"]; ok {
continue
}
if t, ok := v["test"]; ok {
cmdArgs := strings.Split(t, " ")
if len(cmdArgs) < 2 {
continue
}
com := exec.Command(cmdArgs[0], cmdArgs[1:]...)
if err := com.Run(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
@ -79,24 +90,40 @@ func (m *Mailcap) FindMatch(mime, key, path string) (string, error) {
return "", fmt.Errorf("Unable to find key %q in entries for %s", key, mime)
}
func (m *Mailcap) RunMatch(mime, key, path string) {
// 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)
os.Setenv("PWD", dir)
defer os.Setenv("PWD", pwd)
env := os.Environ()
match, err := m.FindMatch(mime, key, path)
var command *exec.Cmd
if err == nil {
matchFields := strings.Fields(match)
if len(matchFields) > 1 {
command = exec.Command(matchFields[0], matchFields[1:]...)
} else {
command = exec.Command(match)
}
e := command.Run()
fmt.Println(err)
if e != nil {
fmt.Println("There was an issue...")
}
if err != nil {
return err
}
matchFields := strings.Fields(match)
binary, lookErr := exec.LookPath(matchFields[0])
if lookErr != nil {
return lookErr
}
execErr := syscall.Exec(binary, []string{matchFields[0], path}, env)
if execErr != nil {
return execErr
}
return nil
}
// Private method to lookup the items for a particular
// mimetype and key, returns Fields
func (m *Mailcap) lookup(mime, key string) Fields {
f := make(Fields, 0, 5)
if val, ok := m.Caps[mime]; ok {
@ -123,10 +150,12 @@ func (m *Mailcap) lookup(mime, key string) Fields {
return output
}
// Top level private initialization method
// Creates the mailcap db and loads it into the
// Caps paramater of the Mailcap struct in question
func (m *Mailcap) getCaps() {
lnNum := 0
var moreCaps Cap
moreCaps = make(Cap)
moreCaps := make(Cap)
for _, mailcapFile := range getMailcapFileList() {
file, err := os.Open(mailcapFile)
if err != nil {
@ -167,6 +196,8 @@ func getMailcapFileList() (mCapSlice []string) {
return
}
// Reads an individual mailcap file and returns a Cap
// and a line number
func readMailcapFile(f *os.File,ln int) (Cap, int) {
caps := make(Cap)
reader := bufio.NewReader(f)
@ -216,6 +247,8 @@ func readMailcapFile(f *os.File,ln int) (Cap, int) {
return caps, ln
}
// Parses an individual mailcap line, returns the key
// as a string, all of the fields, and an error or nil.
func parseLine(ln string) (string, Entry, error) {
outputFields := make(Entry)
i := 0
@ -254,6 +287,7 @@ func parseLine(ln string) (string, Entry, error) {
return key, outputFields, nil
}
// Gets one key value pair
func parseField(ln string, i, n int) (string, int) {
// get one key-value pair from mailcap entry
start := i