diff --git a/main.go b/main.go index b55bb36..d756c3d 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,51 @@ package main import ( - "github.com/schollz/croc/src/cli" + "fmt" + + "github.com/schollz/croc/v5/src/cli" ) -var Version string - func main() { - cli.Version = Version - cli.Run() + // f, _ := os.Create("test.1") + // f.Truncate(8096) + // f.Close() + + // file, _ := os.Open("test.1") + // defer file.Close() + + // buffer := make([]byte, 4096) + // emptyBuffer := make([]byte, 4096) + // for { + // bytesread, err := file.Read(buffer) + // if err != nil { + // break + // } + // log.Debugln(bytes.Equal(buffer[:bytesread], emptyBuffer[:bytesread])) + // } + // var sender bool + // flag.BoolVar(&sender, "sender", false, "sender") + // flag.Parse() + // c, err := croc.New(sender, "foo") + // if err != nil { + // panic(err) + // } + // if sender { + // err = c.Send(croc.TransferOptions{ + // // PathToFile: "../wskeystore/README.md", + // // PathToFile: "./src/croc/croc.go", + // // PathToFiles: []string{"C:\\Users\\zacks\\go\\src\\github.com\\schollz\\croc\\src\\croc\\croc.go", "croc.exe"}, + // PathToFiles: []string{"croc2.exe", "croc3.exe"}, //,"croc2.exe", "croc3.exe"}, + // //PathToFiles: []string{"README.md"}, //,"croc2.exe", "croc3.exe"}, + // KeepPathInRemote: false, + // }) + // } else { + // err = c.Receive() + // } + // if err != nil { + // fmt.Println(err) + // } + if err := cli.Run(); err != nil { + fmt.Println(err) + } } diff --git a/src/cli/cli.go b/src/cli/cli.go index 4e24cb1..ff8047f 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "io" "io/ioutil" @@ -11,18 +12,15 @@ import ( "strings" "time" - humanize "github.com/dustin/go-humanize" - "github.com/pkg/errors" - "github.com/schollz/croc/src/croc" - "github.com/schollz/croc/src/utils" - "github.com/skratchdot/open-golang/open" + "github.com/schollz/croc/v6/src/croc" + "github.com/schollz/croc/v6/src/utils" "github.com/urfave/cli" ) var Version string -var cr *croc.Croc -func Run() { +func Run() (err error) { + runtime.GOMAXPROCS(runtime.NumCPU()) app := cli.NewApp() app.Name = "croc" @@ -42,8 +40,6 @@ func Run() { Description: "send a file over the relay", ArgsUsage: "[filename]", Flags: []cli.Flag{ - cli.BoolFlag{Name: "no-compress, o", Usage: "disable compression"}, - cli.BoolFlag{Name: "no-encrypt, e", Usage: "disable encryption"}, cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"}, }, HelpName: "croc send", @@ -51,41 +47,12 @@ func Run() { return send(c) }, }, - { - Name: "relay", - Usage: "start a croc relay", - Description: "the croc relay will handle websocket and TCP connections", - Flags: []cli.Flag{}, - HelpName: "croc relay", - Action: func(c *cli.Context) error { - return relay(c) - }, - }, - { - Name: "config", - Usage: "generates a config file", - Description: "the croc config can be used to set static parameters", - Flags: []cli.Flag{}, - HelpName: "croc config", - Action: func(c *cli.Context) error { - return saveDefaultConfig(c) - }, - }, } app.Flags = []cli.Flag{ - cli.StringFlag{Name: "addr", Value: "croc4.schollz.com", Usage: "address of the public relay"}, - cli.StringFlag{Name: "addr-ws", Value: "8153", Usage: "port of the public relay websocket server to connect"}, - cli.StringFlag{Name: "addr-tcp", Value: "8154,8155,8156,8157,8158,8159,8160,8161", Usage: "tcp ports of the public relay server to connect"}, - cli.BoolFlag{Name: "no-local", Usage: "disable local mode"}, - cli.BoolFlag{Name: "local", Usage: "use only local mode"}, cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"}, cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"}, cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"}, - cli.BoolFlag{Name: "force-tcp", Usage: "force TCP"}, - cli.BoolFlag{Name: "force-web", Usage: "force websockets"}, - cli.StringFlag{Name: "port", Value: "8153", Usage: "port that the websocket listens on"}, - cli.StringFlag{Name: "tcp-port", Value: "8154,8155,8156,8157,8158,8159,8160,8161", Usage: "ports that the tcp server listens on"}, - cli.StringFlag{Name: "curve", Value: "siec", Usage: "specify elliptic curve to use for PAKE (p256, p384, p521, siec)"}, + cli.StringFlag{Name: "relay", Value: "198.199.67.130:6372", Usage: "address of the relay"}, cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"}, } app.EnableBashCompletion = true @@ -105,44 +72,18 @@ func Run() { } return receive(c) } - app.Before = func(c *cli.Context) error { - cr = croc.Init(c.GlobalBool("debug")) - cr.Version = Version - cr.AllowLocalDiscovery = true - cr.Address = c.GlobalString("addr") - cr.AddressTCPPorts = strings.Split(c.GlobalString("addr-tcp"), ",") - cr.AddressWebsocketPort = c.GlobalString("addr-ws") - cr.NoRecipientPrompt = c.GlobalBool("yes") - cr.Stdout = c.GlobalBool("stdout") - cr.LocalOnly = c.GlobalBool("local") - cr.NoLocal = c.GlobalBool("no-local") - cr.ShowText = true - cr.RelayWebsocketPort = c.String("port") - cr.RelayTCPPorts = strings.Split(c.String("tcp-port"), ",") - cr.CurveType = c.String("curve") - if c.GlobalBool("force-tcp") { - cr.ForceSend = 2 - } - if c.GlobalBool("force-web") { - cr.ForceSend = 1 - } - return nil - } - err := app.Run(os.Args) - if err != nil { - fmt.Fprintf(os.Stderr, "\r\n%s", err.Error()) - } - fmt.Fprintf(os.Stderr, "\r\n") + return app.Run(os.Args) } -func saveDefaultConfig(c *cli.Context) error { - return croc.SaveDefaultConfig() -} +// func saveDefaultConfig(c *cli.Context) error { +// return croc.SaveDefaultConfig() +// } -func send(c *cli.Context) error { +func send(c *cli.Context) (err error) { + + var fnames []string stat, _ := os.Stdin.Stat() - var fname string if (stat.Mode() & os.ModeCharDevice) == 0 { f, err := ioutil.TempFile(".", "croc-stdin-") if err != nil { @@ -156,102 +97,117 @@ func send(c *cli.Context) error { if err != nil { return err } - fname = f.Name() + fnames = []string{f.Name()} defer func() { - err = os.Remove(fname) + err = os.Remove(fnames[0]) if err != nil { log.Println(err) } }() } else { - fname = c.Args().First() + fnames = append([]string{c.Args().First()}, c.Args().Tail()...) } - if fname == "" { + if len(fnames) == 0 { return errors.New("must specify file: croc send [filename]") } - cr.UseCompression = !c.Bool("no-compress") - cr.UseEncryption = !c.Bool("no-encrypt") + + var sharedSecret string if c.String("code") != "" { - cr.Codephrase = c.String("code") + sharedSecret = c.String("code") } - cr.LoadConfig() - if len(cr.Codephrase) == 0 { + // cr.LoadConfig() + if len(sharedSecret) == 0 { // generate code phrase - cr.Codephrase = utils.GetRandomName() + sharedSecret = utils.GetRandomName() } - // print the text - finfo, err := os.Stat(fname) - if err != nil { - return err - } - fname, _ = filepath.Abs(fname) - fname = filepath.Clean(fname) - _, filename := filepath.Split(fname) - fileOrFolder := "file" - fsize := finfo.Size() - if finfo.IsDir() { - fileOrFolder = "folder" - fsize, err = dirSize(fname) + haveFolder := false + paths := []string{} + for _, fname := range fnames { + stat, err := os.Stat(fname) if err != nil { return err } + if stat.IsDir() { + haveFolder = true + err = filepath.Walk(fname, + func(pathName string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + paths = append(paths, filepath.ToSlash(pathName)) + } + return nil + }) + if err != nil { + return err + } + } else { + paths = append(paths, filepath.ToSlash(fname)) + } } - fmt.Fprintf(os.Stderr, - "Sending %s %s named '%s'\nCode is: %s\nOn the other computer, please run:\n\ncroc %s\n\n", - humanize.Bytes(uint64(fsize)), - fileOrFolder, - filename, - cr.Codephrase, - cr.Codephrase, - ) - if cr.Debug { - croc.SetDebugLevel("debug") + cr, err := croc.New(croc.Options{ + SharedSecret: sharedSecret, + IsSender: true, + Debug: c.GlobalBool("debug"), + NoPrompt: c.GlobalBool("yes"), + AddressRelay: c.GlobalString("relay"), + Stdout: c.GlobalBool("stdout"), + }) + if err != nil { + return } - return cr.Send(fname, cr.Codephrase) + + err = cr.Send(croc.TransferOptions{ + PathToFiles: paths, + KeepPathInRemote: haveFolder, + }) + + return } -func receive(c *cli.Context) error { +func receive(c *cli.Context) (err error) { + var sharedSecret string if c.GlobalString("code") != "" { - cr.Codephrase = c.GlobalString("code") + sharedSecret = c.GlobalString("code") } if c.Args().First() != "" { - cr.Codephrase = c.Args().First() + sharedSecret = c.Args().First() + } + if sharedSecret == "" { + sharedSecret = utils.GetInput("Enter receive code: ") } if c.GlobalString("out") != "" { os.Chdir(c.GlobalString("out")) } - cr.LoadConfig() - openFolder := false - if len(os.Args) == 1 { - // open folder since they didn't give any arguments - openFolder = true - } - if cr.Codephrase == "" { - cr.Codephrase = utils.GetInput("Enter receive code: ") - } - if cr.Debug { - croc.SetDebugLevel("debug") - } - err := cr.Receive(cr.Codephrase) - if err == nil && openFolder { - cwd, _ := os.Getwd() - open.Run(cwd) - } - return err -} -func relay(c *cli.Context) error { - return cr.Relay() -} - -func dirSize(path string) (int64, error) { - var size int64 - err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { - if !info.IsDir() { - size += info.Size() - } - return err + cr, err := croc.New(croc.Options{ + SharedSecret: sharedSecret, + IsSender: false, + Debug: c.GlobalBool("debug"), + NoPrompt: c.GlobalBool("yes"), + AddressRelay: c.GlobalString("relay"), + Stdout: c.GlobalBool("stdout"), }) - return size, err + if err != nil { + return + } + err = cr.Receive() + return } + +// func relay(c *cli.Context) error { +// return cr.Relay() +// } + +// func dirSize(path string) (int64, error) { +// var size int64 +// err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { +// if !info.IsDir() { +// size += info.Size() +// } +// return err +// }) +// return size, err +// }