lf/main.go

203 lines
3.9 KiB
Go
Raw Normal View History

2016-08-13 12:49:04 +00:00
package main
import (
"flag"
"fmt"
"log"
"net"
2016-08-13 12:49:04 +00:00
"os"
"path/filepath"
"runtime"
2016-09-01 20:49:56 +00:00
"runtime/pprof"
"strconv"
2016-08-13 12:49:04 +00:00
)
var (
2018-07-31 21:21:55 +00:00
envPath = os.Getenv("PATH")
envLevel = os.Getenv("LF_LEVEL")
2016-08-13 12:49:04 +00:00
)
var (
2016-12-17 21:47:37 +00:00
gClientID int
2017-08-06 08:05:46 +00:00
gHostname string
2016-08-14 12:45:24 +00:00
gLastDirPath string
2016-08-13 12:49:04 +00:00
gSelectionPath string
gSocketProt string
2016-08-13 12:49:04 +00:00
gSocketPath string
gLogPath string
gServerLogPath string
gSelect string
gCommand string
2018-03-22 17:42:15 +00:00
gVersion string
2016-08-13 12:49:04 +00:00
)
func init() {
2017-11-19 18:55:13 +00:00
h, err := os.Hostname()
2017-08-06 08:05:46 +00:00
if err != nil {
log.Printf("hostname: %s", err)
}
2017-11-19 18:55:13 +00:00
gHostname = h
if envLevel == "" {
envLevel = "0"
}
2016-08-13 12:49:04 +00:00
}
func exportEnvVars() {
os.Setenv("id", strconv.Itoa(gClientID))
os.Setenv("OPENER", envOpener)
os.Setenv("EDITOR", envEditor)
os.Setenv("PAGER", envPager)
os.Setenv("SHELL", envShell)
os.Setenv("TCELL_TRUECOLOR", envTcellTruecolor)
level, err := strconv.Atoi(envLevel)
if err != nil {
log.Printf("reading lf level: %s", err)
}
level++
os.Setenv("LF_LEVEL", strconv.Itoa(level))
}
2016-08-13 12:49:04 +00:00
func startServer() {
2018-07-31 21:21:55 +00:00
cmd := detachedCommand(os.Args[0], "-server")
cmd.Dir = gUser.HomeDir
2016-08-17 20:28:42 +00:00
if err := cmd.Start(); err != nil {
2016-08-17 20:06:45 +00:00
log.Printf("starting server: %s", err)
2016-08-13 12:49:04 +00:00
}
}
func checkServer() {
if gSocketProt == "unix" {
if _, err := os.Stat(gSocketPath); os.IsNotExist(err) {
startServer()
} else if _, err := net.Dial(gSocketProt, gSocketPath); err != nil {
os.Remove(gSocketPath)
startServer()
}
} else {
if _, err := net.Dial(gSocketProt, gSocketPath); err != nil {
startServer()
}
}
}
2016-08-13 12:49:04 +00:00
func main() {
2017-11-19 18:55:13 +00:00
showDoc := flag.Bool(
"doc",
false,
"show documentation")
2018-03-22 17:42:15 +00:00
showVersion := flag.Bool(
"version",
false,
"show version")
2017-11-19 18:55:13 +00:00
remoteCmd := flag.String(
"remote",
"",
"send remote command to server")
serverMode := flag.Bool(
"server",
false,
"start server (automatic)")
cpuprofile := flag.String(
"cpuprofile",
"",
"path to the file to write the CPU profile")
memprofile := flag.String(
"memprofile",
"",
"path to the file to write the memory profile")
2017-11-19 18:55:13 +00:00
flag.StringVar(&gLastDirPath,
"last-dir-path",
"",
"path to the file to write the last dir on exit (to use for cd)")
flag.StringVar(&gSelectionPath,
"selection-path",
"",
"path to the file to write selected files on open (to use as open file dialog)")
2016-08-13 12:49:04 +00:00
flag.StringVar(&gCommand,
"command",
"",
"command to execute on client initialization")
2016-08-13 12:49:04 +00:00
flag.Parse()
gSocketProt = gDefaultSocketProt
gSocketPath = gDefaultSocketPath
2017-11-19 18:55:13 +00:00
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatalf("could not create CPU profile: %s", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatalf("could not start CPU profile: %s", err)
}
defer pprof.StopCPUProfile()
}
switch {
case *showDoc:
2016-09-15 14:08:05 +00:00
fmt.Print(genDocString)
2018-03-22 17:42:15 +00:00
case *showVersion:
fmt.Println(gVersion)
2017-11-19 18:55:13 +00:00
case *remoteCmd != "":
2019-02-26 18:27:04 +00:00
if err := remote(*remoteCmd); err != nil {
log.Fatalf("remote command: %s", err)
}
2017-11-19 18:55:13 +00:00
case *serverMode:
2017-08-06 08:05:46 +00:00
gServerLogPath = filepath.Join(os.TempDir(), fmt.Sprintf("lf.%s.server.log", gUser.Username))
2016-08-13 12:49:04 +00:00
serve()
2017-11-19 18:55:13 +00:00
default:
checkServer()
2016-08-13 12:49:04 +00:00
2017-08-06 08:05:46 +00:00
gClientID = 1000
gLogPath = filepath.Join(os.TempDir(), fmt.Sprintf("lf.%s.%d.log", gUser.Username, gClientID))
2017-11-19 18:55:13 +00:00
for _, err := os.Stat(gLogPath); !os.IsNotExist(err); _, err = os.Stat(gLogPath) {
2017-08-06 08:05:46 +00:00
gClientID++
gLogPath = filepath.Join(os.TempDir(), fmt.Sprintf("lf.%s.%d.log", gUser.Username, gClientID))
}
switch flag.NArg() {
case 0:
_, err := os.Getwd()
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(2)
}
case 1:
gSelect = flag.Arg(0)
default:
fmt.Fprintf(os.Stderr, "only single file or directory is allowed\n")
os.Exit(2)
}
exportEnvVars()
2017-11-19 18:55:13 +00:00
run()
2016-08-13 12:49:04 +00:00
}
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
runtime.GC()
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
2016-08-13 12:49:04 +00:00
}