2018-10-16 21:23:01 +02:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
2019-04-30 01:09:37 +02:00
|
|
|
"errors"
|
2018-10-16 21:23:01 +02:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2018-10-23 05:34:04 +02:00
|
|
|
"runtime"
|
2018-10-16 21:23:01 +02:00
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
"github.com/schollz/croc/v6/src/croc"
|
2019-04-30 06:25:30 +02:00
|
|
|
"github.com/schollz/croc/v6/src/tcp"
|
2019-04-30 01:09:37 +02:00
|
|
|
"github.com/schollz/croc/v6/src/utils"
|
2018-10-16 21:23:01 +02:00
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
|
|
|
var Version string
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
func Run() (err error) {
|
2019-05-03 22:51:27 +02:00
|
|
|
// use all of the processors
|
2018-10-23 05:34:04 +02:00
|
|
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
2019-05-02 22:14:09 +02:00
|
|
|
|
2018-10-16 21:23:01 +02:00
|
|
|
app := cli.NewApp()
|
|
|
|
app.Name = "croc"
|
|
|
|
if Version == "" {
|
2019-06-04 17:31:24 +02:00
|
|
|
Version = "v6.0.7-15034cc"
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
app.Version = Version
|
|
|
|
app.Compiled = time.Now()
|
|
|
|
app.Usage = "easily and securely transfer stuff from one computer to another"
|
|
|
|
app.UsageText = "croc allows any two computers to directly and securely transfer files"
|
|
|
|
// app.ArgsUsage = "[args and such]"
|
|
|
|
app.Commands = []cli.Command{
|
|
|
|
{
|
|
|
|
Name: "send",
|
|
|
|
Usage: "send a file",
|
|
|
|
Description: "send a file over the relay",
|
|
|
|
ArgsUsage: "[filename]",
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"},
|
2019-05-03 22:51:27 +02:00
|
|
|
cli.BoolFlag{Name: "no-local", Usage: "disable local relay when sending"},
|
2019-05-01 21:48:09 +02:00
|
|
|
cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the local relay (optional)"},
|
2018-10-16 21:23:01 +02:00
|
|
|
},
|
|
|
|
HelpName: "croc send",
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
return send(c)
|
|
|
|
},
|
|
|
|
},
|
2019-04-30 06:25:30 +02:00
|
|
|
{
|
|
|
|
Name: "relay",
|
|
|
|
Description: "start relay",
|
|
|
|
HelpName: "croc relay",
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
return relay(c)
|
|
|
|
},
|
2019-05-01 21:48:09 +02:00
|
|
|
Flags: []cli.Flag{
|
|
|
|
cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
|
|
|
|
},
|
2019-04-30 06:25:30 +02:00
|
|
|
},
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
app.Flags = []cli.Flag{
|
|
|
|
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"},
|
2019-05-01 01:19:10 +02:00
|
|
|
cli.StringFlag{Name: "relay", Value: "198.199.67.130:9009", Usage: "address of the relay"},
|
2018-10-22 15:36:36 +02:00
|
|
|
cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
app.EnableBashCompletion = true
|
|
|
|
app.HideHelp = false
|
|
|
|
app.HideVersion = false
|
|
|
|
app.BashComplete = func(c *cli.Context) {
|
|
|
|
fmt.Fprintf(c.App.Writer, "send\nreceive\relay")
|
|
|
|
}
|
|
|
|
app.Action = func(c *cli.Context) error {
|
2018-11-01 15:08:57 +01:00
|
|
|
// if trying to send but forgot send, let the user know
|
|
|
|
if c.Args().First() != "" && utils.Exists(c.Args().First()) {
|
|
|
|
_, fname := filepath.Split(c.Args().First())
|
2018-11-01 15:26:18 +01:00
|
|
|
yn := utils.GetInput(fmt.Sprintf("Did you mean to send '%s'? (y/n) ", fname))
|
2018-11-01 15:08:57 +01:00
|
|
|
if strings.ToLower(yn) == "y" {
|
|
|
|
return send(c)
|
|
|
|
}
|
|
|
|
}
|
2018-10-16 21:23:01 +02:00
|
|
|
return receive(c)
|
|
|
|
}
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
return app.Run(os.Args)
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
// func saveDefaultConfig(c *cli.Context) error {
|
|
|
|
// return croc.SaveDefaultConfig()
|
|
|
|
// }
|
2018-10-21 17:21:58 +02:00
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
func send(c *cli.Context) (err error) {
|
|
|
|
|
|
|
|
var fnames []string
|
2018-10-16 21:23:01 +02:00
|
|
|
stat, _ := os.Stdin.Stat()
|
|
|
|
if (stat.Mode() & os.ModeCharDevice) == 0 {
|
|
|
|
f, err := ioutil.TempFile(".", "croc-stdin-")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err = io.Copy(f, os.Stdin)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = f.Close()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
fnames = []string{f.Name()}
|
2018-10-16 21:23:01 +02:00
|
|
|
defer func() {
|
2019-04-30 01:09:37 +02:00
|
|
|
err = os.Remove(fnames[0])
|
2018-10-16 21:23:01 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
} else {
|
2019-04-30 01:09:37 +02:00
|
|
|
fnames = append([]string{c.Args().First()}, c.Args().Tail()...)
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
if len(fnames) == 0 {
|
2018-10-16 21:23:01 +02:00
|
|
|
return errors.New("must specify file: croc send [filename]")
|
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
|
|
|
|
var sharedSecret string
|
2018-10-16 21:23:01 +02:00
|
|
|
if c.String("code") != "" {
|
2019-04-30 01:09:37 +02:00
|
|
|
sharedSecret = c.String("code")
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
// cr.LoadConfig()
|
|
|
|
if len(sharedSecret) == 0 {
|
2018-10-16 21:23:01 +02:00
|
|
|
// generate code phrase
|
2019-04-30 01:09:37 +02:00
|
|
|
sharedSecret = utils.GetRandomName()
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
haveFolder := false
|
|
|
|
paths := []string{}
|
|
|
|
for _, fname := range fnames {
|
|
|
|
stat, err := os.Stat(fname)
|
2018-10-16 21:23:01 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
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))
|
|
|
|
}
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
cr, err := croc.New(croc.Options{
|
|
|
|
SharedSecret: sharedSecret,
|
|
|
|
IsSender: true,
|
|
|
|
Debug: c.GlobalBool("debug"),
|
|
|
|
NoPrompt: c.GlobalBool("yes"),
|
2019-04-30 04:50:01 +02:00
|
|
|
RelayAddress: c.GlobalString("relay"),
|
2019-04-30 01:09:37 +02:00
|
|
|
Stdout: c.GlobalBool("stdout"),
|
2019-05-03 22:51:27 +02:00
|
|
|
DisableLocal: c.Bool("no-local"),
|
2019-05-01 21:48:09 +02:00
|
|
|
RelayPorts: strings.Split(c.String("ports"), ","),
|
2019-04-30 01:09:37 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return
|
2018-11-01 15:26:18 +01:00
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
|
|
|
|
err = cr.Send(croc.TransferOptions{
|
|
|
|
PathToFiles: paths,
|
|
|
|
KeepPathInRemote: haveFolder,
|
|
|
|
})
|
|
|
|
|
|
|
|
return
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
func receive(c *cli.Context) (err error) {
|
|
|
|
var sharedSecret string
|
2018-10-16 21:23:01 +02:00
|
|
|
if c.GlobalString("code") != "" {
|
2019-04-30 01:09:37 +02:00
|
|
|
sharedSecret = c.GlobalString("code")
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
if c.Args().First() != "" {
|
2019-04-30 01:09:37 +02:00
|
|
|
sharedSecret = c.Args().First()
|
|
|
|
}
|
|
|
|
if sharedSecret == "" {
|
|
|
|
sharedSecret = utils.GetInput("Enter receive code: ")
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
2018-10-22 15:36:36 +02:00
|
|
|
if c.GlobalString("out") != "" {
|
|
|
|
os.Chdir(c.GlobalString("out"))
|
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
|
|
|
|
cr, err := croc.New(croc.Options{
|
2019-05-01 21:49:58 +02:00
|
|
|
SharedSecret: sharedSecret,
|
|
|
|
IsSender: false,
|
|
|
|
Debug: c.GlobalBool("debug"),
|
|
|
|
NoPrompt: c.GlobalBool("yes"),
|
|
|
|
RelayAddress: c.GlobalString("relay"),
|
|
|
|
Stdout: c.GlobalBool("stdout"),
|
2019-04-30 01:09:37 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return
|
2018-10-19 19:18:49 +02:00
|
|
|
}
|
2019-04-30 01:09:37 +02:00
|
|
|
err = cr.Receive()
|
|
|
|
return
|
2018-10-16 21:23:01 +02:00
|
|
|
}
|
|
|
|
|
2019-04-30 06:25:30 +02:00
|
|
|
func relay(c *cli.Context) (err error) {
|
2019-05-02 21:08:23 +02:00
|
|
|
debugString := "info"
|
2019-04-30 06:25:30 +02:00
|
|
|
if c.GlobalBool("debug") {
|
|
|
|
debugString = "debug"
|
|
|
|
}
|
2019-05-01 21:48:09 +02:00
|
|
|
ports := strings.Split(c.String("ports"), ",")
|
2019-05-01 01:19:10 +02:00
|
|
|
tcpPorts := strings.Join(ports[1:], ",")
|
2019-04-30 06:25:30 +02:00
|
|
|
for i, port := range ports {
|
|
|
|
if i == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
go func(portStr string) {
|
2019-05-01 01:26:32 +02:00
|
|
|
err = tcp.Run(debugString, portStr)
|
2019-04-30 06:25:30 +02:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}(port)
|
|
|
|
}
|
2019-05-01 18:33:34 +02:00
|
|
|
return tcp.Run(debugString, ports[0], tcpPorts)
|
2019-04-30 06:25:30 +02:00
|
|
|
}
|
2018-10-16 21:23:01 +02:00
|
|
|
|
2019-04-30 01:09:37 +02:00
|
|
|
// 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
|
|
|
|
// }
|