package main import ( "flag" "fmt" "os" "os/signal" "path/filepath" "strings" "syscall" "nymdrop/internal/reader" ) func main() { keyFile := flag.String("key", "", "path to X25519 private key file (hex, 32 bytes); generated if missing") inboxID := flag.String("id", "nymdrop-inbox", "nym-client identity id") wsPort := flag.Int("ws-port", 1977, "nym-client websocket port") outDir := flag.String("out", "", "directory to save submissions (default: ~/nymdrop-inbox, or /nymdrop-inbox)") dataDir := flag.String("data-dir", "", "self-contained data directory (key, nym-client state, inbox all live here instead of $HOME — for portable/USB use, no trace left on the host)") guiMode := flag.Bool("gui", false, "launch the graphical reader instead of the headless/CLI mode") flag.Parse() cfg := reader.Config{ KeyFile: *keyFile, InboxID: *inboxID, WSPort: *wsPort, OutDir: *outDir, DataDir: *dataDir, Debug: os.Getenv("NYMDROP_DEBUG") != "", } if *guiMode { runGUI(cfg) return } runCLI(cfg) } func runCLI(cfg reader.Config) { hooks := reader.Hooks{ Log: func(format string, args ...any) { fmt.Printf(format+"\n", args...) }, SelfAddress: func(addr string) { fmt.Printf("Nym inbox address: %s\n\n", addr) }, Submission: func(path, preview string) { ts := strings.TrimSuffix(filepath.Base(path), ".txt") fmt.Printf("\n[%s] New submission -> %s\n", ts, path) fmt.Printf(" %s\n", strings.ReplaceAll(preview, "\n", "\n ")) }, Attachment: func(path string, size int) { fmt.Printf(" attachment -> %s (%d bytes)\n", path, size) }, Error: func(err error) { fmt.Fprintln(os.Stderr, err) }, } in, err := reader.Start(cfg, hooks) if err != nil { fatalf("%v", err) } defer in.Close() fmt.Printf("nymdrop-reader listening -- submissions saved to %s\n", in.OutDir()) fmt.Println("Press Ctrl+C to quit.") go in.ReceiveLoop() sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) <-sig fmt.Println("\nShutting down.") } func fatalf(format string, args ...any) { fmt.Fprintf(os.Stderr, "nymdrop-reader: "+format+"\n", args...) os.Exit(1) }