Initial code commit

This commit is contained in:
2024-01-16 14:35:34 -05:00
parent c20c8bc349
commit af6600de80
12 changed files with 431 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
package main
import (
termy "golang.org/x/crypto/ssh/terminal"
"os"
)
// invisible variables
var home, _ = os.UserHomeDir()
// exported variables
var (
RootLength = len(EntryRoot)
Width, _, _ = termy.GetSize(int(os.Stdout.Fd()))
)
+12
View File
@@ -0,0 +1,12 @@
//go:build !windows
package main
// EntryRoot path to libmutton entry directory
var EntryRoot = home + "/.local/share/sshyp"
// exported constants
const (
PathSeparator = "/"
Windows = false
)
+12
View File
@@ -0,0 +1,12 @@
//go:build windows
package main
// exported variables
var EntryRoot = home + "\\AppData\\Local\\libmutton\\entries"
// exported constants
const (
PathSeparator = "\\"
Windows = true
)
+153
View File
@@ -0,0 +1,153 @@
package main
import (
"fmt"
"io/fs"
"path/filepath"
"strings"
)
var (
fileListRoot []string
fileListMain []string
dirListMain []string
)
// processing for printing file entries (determines color, line wrapping, and prints)
func printFileEntry(entry string, lastSlash int, charCounter int, colorAlternator int8) (int, int8) {
// determine color to print fileEntryName (alternate each time function is run)
var colorCode string
if colorAlternator > 0 {
colorCode = ""
} else {
colorCode = "\033[38;5;8m"
}
colorAlternator = -colorAlternator
// trim the containing directory and file extension from the entry to determine fileEntryName
fileEntryName := entry[lastSlash:]
fileEntryName = fileEntryName[:len(fileEntryName)-4]
// determine whether to wrap to a new line (+1 is to account for trailing spaces)
charCounter += len(fileEntryName) + 1
if charCounter >= Width {
charCounter = len(fileEntryName) + 1
fmt.Println()
}
// print fileEntryName to screen
fmt.Printf("%s%s\033[0m ", colorCode, fileEntryName)
return charCounter, colorAlternator
}
// EntryListGen generates and displays full entry list
func EntryListGen() {
fmt.Print("\nfor a list of usable commands, run \"mutn help\"\n\n\033[38;5;0;48;5;15mlibmutton entries:\033[0m")
// walk entry directory
_ = filepath.WalkDir(EntryRoot,
func(fullPath string, entry fs.DirEntry, err error) error {
// trim root path from each path before storing
trimmedPath := fullPath[RootLength:]
// create three separate slices for root-level entries, all other entries, and all subdirectories
// root-level entries get their own slice so that they can be alphabetically sorted without the chance of directories being placed in from of them
if !entry.IsDir() && strings.Count(trimmedPath, PathSeparator) == 1 {
fileListRoot = append(fileListRoot, trimmedPath)
} else if !entry.IsDir() {
fileListMain = append(fileListMain, trimmedPath)
} else {
dirListMain = append(dirListMain, trimmedPath)
}
return nil
})
// fileListRoot iteration
charCounter := 0 // set to track whether to line-wrap based on character count in line
var colorAlternator int8 = 1 // set to allow alternating colors for each printed entry name
ran := false // set to track whether the loop has been run yet
for _, file := range fileListRoot {
// print root ("/") header if this is the first run of the loop
// must be done within loop in order to allow not printing the header if there are no root-level entries
if !ran {
ran = true
fmt.Print("\n\n\033[38;5;7;48;5;8m/\033[0m\n")
}
// get index of last occurrence of pathSeparator in trimmed entry path (used to split entry's containing directory and entry's name) and pass to printFileEntry
charCounter, colorAlternator = printFileEntry(file, strings.LastIndex(file, PathSeparator)+1, charCounter, colorAlternator)
}
// DirListMain iteration
nextStartIndex := 0 // set to track where to resume when iterating through fileListMain
var containsSubdirectory bool // set to track whether the current directory contains a subdirectory - if it does, empty directory warnings will not be printed
for i, directory := range dirListMain {
// reset formatting variables for new directory
charCounter = 0
colorAlternator = 1
// check if next directory is within the current one
if len(dirListMain) > i+1 {
nextDir := dirListMain[i+1]
if directory == nextDir[:strings.LastIndex(nextDir, PathSeparator)] {
containsSubdirectory = true
} else {
containsSubdirectory = false
}
} else {
containsSubdirectory = false
}
// fileListMain iteration
ran = false // set to track whether the loop has been run yet
for _, file := range fileListMain[nextStartIndex:] {
// get index of last occurrence of pathSeparator in trimmed entry path (used to split entry's containing directory and entry's name)
lastSlash := strings.LastIndex(file, PathSeparator) + 1
// print the current file if it belongs in the current directory - otherwise, break the loop and move on to the next directory
if file[:lastSlash-1] == directory {
// print directory header if this is the first run of the loop
// must be done within loop in order to allow not printing the header if its directory contains no entries
if !ran {
ran = true
// for consistency, format directories with UNIX-style path separators on all platforms
if !Windows {
fmt.Printf("\n\n\033[38;5;7;48;5;8m%s/\033[0m\n", directory)
} else {
fmt.Printf("\n\n\033[38;5;7;48;5;8m%s/\033[0m\n", strings.ReplaceAll(directory, PathSeparator, "/"))
}
}
nextStartIndex++ // increment to prevent having to iterate through ALL of fileListMain each time
charCounter, colorAlternator = printFileEntry(file, lastSlash, charCounter, colorAlternator)
} else {
break
}
}
// display empty directory warning if the last printed directory contained no entries or subdirectories
if !ran && !containsSubdirectory {
// for consistency, format directories with UNIX-style path separators on all platforms
if !Windows {
fmt.Printf("\n\n\033[38;5;7;48;5;8m%s/\033[0m\n", directory)
} else {
fmt.Printf("\n\n\033[38;5;7;48;5;8m%s/\033[0m\n", strings.ReplaceAll(directory, PathSeparator, "/"))
}
fmt.Print("\033[38;5;9m-empty directory-\033[0m")
}
}
// print trailing new lines for proper spacing after entry list is complete
fmt.Print("\n\n")
}
+10
View File
@@ -0,0 +1,10 @@
module main
go 1.21.6
require golang.org/x/crypto v0.18.0
require (
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
)
+29
View File
@@ -0,0 +1,29 @@
package main
import (
"os"
)
func main() {
args := os.Args[1:]
argsCount := len(args)
if argsCount == 0 {
EntryListGen()
} else if argsCount == 1 {
switch args[0] {
case "help", "--help", "-h":
HelpMain()
case "version", "-v":
Version()
default:
HelpMain()
}
}
}
+91
View File
@@ -0,0 +1,91 @@
package main
import "fmt"
func HelpMain() {
fmt.Print("\n\033[1mMUTN | Copyright (c) 2024 Randall Winkhart\033[0m\n" + `
This software exists under the MIT license; you may redistribute it under certain conditions.
This program comes with absolutely no warranty; type "mutn version" for details.
` + "\033[1mUsage:\033[0m" + ` mutn [/<entry name> [argument] [option]] | [argument]
` + "\033[1mArguments:\033[0m" + `
help/--help/-h Bring up this menu
version/-v Display version and license information
init Set up MUTN
tweak Change configuration options
add Add an entry
gen Generate a new password
edit Edit an existing entry
copy Copy details of an entry to your clipboard
shear Delete an existing entry
sync Manually sync the entry directory
` + "\033[1mOptions:\033[0m" + `
add:
password/-p Add a password entry
note/-n Add a note entry
folder/-f Add a new folder for entries
edit:
rename/relocate/-r Rename or relocate an entry
username/-u Change the username of an entry
password/-p Change the password of an entry
url/-l Change the url attached to an entry
note/-n Change the note attached to an entry
copy:
username/-u Copy the username of an entry to your clipboard
password/-p Copy the password of an entry to your clipboard
url/-l Copy the url of an entry to your clipboard
note/-n Copy the note of an entry to your clipboard
gen:
update/-u Generate a password for an existing entry
` + "\033[1mTip 1:\033[0m" + ` You can quickly read an entry with "mutn /<entry name>"
` + "\033[1mTip 2:\033[0m" + ` Type "mutn" to view a list of saved entries` + "\n\n")
}
func Version() {
fmt.Print("\n\033[1mMUTN | Copyright (c) 2024 Randall Winkhart\033[0m" + `
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.` +
"\n\n---------------------------------------------------------" +
"\n\n MUTN is a simple, self-hosted,\n SSH-synchronized password manager based on libmutton\n\n" +
" .. \033[38;2;206;48;98m♥♥ ♥♥\033[0m ..\n" +
" /()\\''.''. \033[38;2;206;48;98m♥♥♥♥♥♥♥\033[0m .''.''/()\\ _)\n" +
" _. : * \033[38;2;206;48;98m♥♥♥♥♥\033[0m * : <[◎]|_|=\n" +
" }-}-*] `..'..' \033[38;2;206;48;98m♥♥♥\033[0m `..'..' |\n" +
" ◎-◎ // \\\\ \033[38;2;206;48;98m♥\033[0m // \\\\ /|\\\n" +
"\033[38;2;1;173;216m<><><><><><><><><><><><><><>-<><><><><><><><><><><><><><>\n" +
"\\\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"\\\033[38;5;15;48;5;15m \033[0mMUTN Version 0.0.1\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"\\\033[38;5;15;48;5;15m \033[0mThe Butchered Update\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"\\\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"\\\033[38;5;15;48;5;15m \033[0mCopyright (C) 2024 Randall Winkhart\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"\\\033[38;5;15;48;5;15m \033[0m\033[38;2;1;173;216m/\n" +
"<><><><><><><><><><><><><><>-<><><><><><><><><><><><><><>\033[0m\n" +
"\nFor more information, see:\n" +
"https://github.com/rwinkhart/MUTN\n" +
"https://github.com/rwinkhart/libmutton\n\n")
}