diff --git a/Multi-Upload.txt b/Multi-Upload.txt new file mode 100644 index 0000000..663cb8e --- /dev/null +++ b/Multi-Upload.txt @@ -0,0 +1,49 @@ +func _Upload(client *goftp.Client, local, remote string) { + files := make([]string, 0) + if strings.HasPrefix(local, "@") { + rdr, err := os.Open(strings.TrimPrefix(local, "@")) + if err != nil { + log.Printf("[ERR] %s\r\n", err.Error()) + } + buf := bufio.NewScanner(rdr) + for buf.Scan() { + if buf.Err() != nil { + break + } + lineStr := strings.TrimSpace(buf.Text()) + if lineStr == "" { + continue + } + files = append(files, lineStr) + } + } else { + files = append(files, local) + } + + for i, f := range files { + log.Printf("[MSG] Uploading %d: %s\r\n", i+1, f) + rst := "" + for r := 0; r <= retry; r++ { + if r > 0 { + time.Sleep(time.Millisecond * 500) + log.Printf("[MSG] Retrying %d: %s\r\n", r, f) + } + rdr, err := os.Open(f) + if err != nil { + rdr.Close() + rst = err.Error() + continue + } + err = client.Store(remote, rdr) + if err != nil { + rdr.Close() + rst = err.Error() + continue + } + if rst != "" { + log.Printf("[ERR] Upload NG: %s\r\n", f) + } + log.Printf("[MSG] Upload OK: %s\r\n", f) + } + } +} diff --git a/ftpsClient.exe b/ftpsClient.exe index 9289ab6..8fcc361 100644 Binary files a/ftpsClient.exe and b/ftpsClient.exe differ diff --git a/ftpsClient.go b/ftpsClient.go index a17a275..dd0382a 100644 --- a/ftpsClient.go +++ b/ftpsClient.go @@ -4,29 +4,37 @@ import ( "crypto/tls" "flag" "fmt" + "io" "log" "os" + "path/filepath" "time" - "github.com/secsy/goftp" + "gopkg.in/dutchcoders/goftp.v1" ) var ( - host string = "" - port string = "" - user string = "" - pswd string = "" - rmt string = "" - loc string = "" + host string = "" + port string = "" + user string = "" + pswd string = "" + loc string = "" + rmt string = "" + act string = "" + retry int = 0 + intrv int = 0 ) func init() { - flag.StringVar(&host, "h", "10.60.254.52", "FTPS Server Address") + flag.StringVar(&host, "h", "203.93.100.58", "FTPS Server Address") flag.StringVar(&port, "o", "3031", "FTPS Server Port") flag.StringVar(&user, "u", "idte", "Username") flag.StringVar(&pswd, "p", "wistronTE2022", "Password") - flag.StringVar(&loc, "L", "", "Local Path") - flag.StringVar(&rmt, "R", "", "Remote Path") + flag.StringVar(&loc, "L", "./", "Local Path") + flag.StringVar(&rmt, "R", "/", "Remote Path") + flag.StringVar(&act, "A", "list", "Action: list,upld,dnld") + flag.IntVar(&intrv, "I", 10, "Retry Interval (Seconds)") + flag.IntVar(&retry, "T", 5, "Retry Times") flag.Parse() } @@ -39,37 +47,111 @@ func main() { os.Exit(1) } - cfg := goftp.Config{ - User: user, - Password: pswd, - Timeout: time.Second * 30, - TLSMode: goftp.TLSExplicit, - TLSConfig: &tls.Config{ - InsecureSkipVerify: true, - MinVersion: tls.VersionTLS10, - }, - } + var err error + var ftp *goftp.FTP - client, err := goftp.DialConfig(cfg, host+":"+port) + ftp, err = goftp.Connect(fmt.Sprintf("%s:%s", host, port)) if err != nil { log.Printf("[ERR] %s\r\n", err.Error()) os.Exit(1) } - defer client.Close() + defer ftp.Close() - cwd, err := client.Getwd() + cfg := tls.Config{ + InsecureSkipVerify: true, + MinVersion: tls.VersionTLS10, + } + + err = ftp.AuthTLS(&cfg) if err != nil { log.Printf("[ERR] %s\r\n", err.Error()) os.Exit(1) } - log.Printf("[MSG] CWD: %s\r\n", cwd) - fis, err := client.ReadDir(cwd) + err = ftp.Login(user, pswd) if err != nil { log.Printf("[ERR] %s\r\n", err.Error()) os.Exit(1) } - for _, f := range fis { - fmt.Printf("FileName=%v; FileSize=%v; ModTime=%v; IsDir=%v\r\n", f.Name(), f.Size(), f.ModTime().Format("2006-01-02 15:04:05"), f.IsDir()) + + switch act { + case "list": + _List(ftp, rmt) + case "dnld": + _Download(ftp, loc, rmt) + case "upld": + _Upload(ftp, loc, rmt) + default: + _List(ftp, loc) } } + +func _List(ftp *goftp.FTP, path string) { + files, err := ftp.List(path) + if err != nil { + log.Printf("[ERR] %s\r\n", err.Error()) + return + } + for _, f := range files { + fmt.Print(f) + } +} + +func _Download(ftp *goftp.FTP, local, remote string) { + log.Printf("[MSG] Downloading: %s\r\n", remote) + var err error + base := filepath.Base(remote) + for i := 0; i <= retry; i++ { + if i > 0 { + time.Sleep(time.Second * time.Duration(intrv)) + log.Printf("[***] Retrying Download %d/%d: %s\r\n", i, retry, remote) + } + _, err = ftp.Retr(remote, func(rdr io.Reader) error { + wtr, oserr := os.Create(local + base) + if oserr != nil { + return oserr + } + defer wtr.Close() + _, ioerr := io.Copy(wtr, rdr) + if ioerr != nil { + return ioerr + } + return nil + }) + if err == nil { + break + } + } + if err != nil { + log.Printf("[***] %s\r\n", err.Error()) + log.Printf("[ERR] Download NG: %s\r\n", remote) + return + } + log.Printf("[MSG] Download OK: %s\r\n", remote) +} + +func _Upload(ftp *goftp.FTP, local, remote string) { + log.Printf("[MSG] Uploading: %s\r\n", local) + var err error + for i := 0; i <= retry; i++ { + if i > 0 { + time.Sleep(time.Second * time.Duration(intrv)) + log.Printf("[***] Retrying Upload %d/%d: %s\r\n", i, retry, local) + } + err = ftp.Cwd(remote) + if err != nil { + continue + } + err = ftp.Upload(local) + if err != nil { + continue + } + break + } + if err != nil { + log.Printf("[***] %s\r\n", err.Error()) + log.Printf("[ERR] Upload NG: %s\r\n", local) + return + } + log.Printf("[MSG] Upload OK: %s\r\n", local) +} diff --git a/ftpsClient.txt b/ftpsClient.txt new file mode 100644 index 0000000..18ed669 --- /dev/null +++ b/ftpsClient.txt @@ -0,0 +1,160 @@ +package main + +import ( + "crypto/tls" + "flag" + "fmt" + "log" + "os" + "time" + + "github.com/secsy/goftp" +) + +var ( + host string = "" + port string = "" + user string = "" + pswd string = "" + rmt string = "" + loc string = "" + act string = "" + debug bool = false + retry int = 0 +) + +func init() { + flag.BoolVar(&debug, "d", false, "Show Debug Messages") + flag.StringVar(&host, "h", "203.93.100.58", "FTPS Server Address") + flag.StringVar(&port, "o", "3031", "FTPS Server Port") + flag.StringVar(&user, "u", "idte", "Username") + flag.StringVar(&pswd, "p", "wistronTE2022", "Password") + flag.StringVar(&loc, "L", "", "Local Path") + flag.StringVar(&rmt, "R", "", "Remote Path") + flag.StringVar(&act, "A", "list", "Action: list,upld,dnld") + flag.IntVar(&retry, "T", 5, "Retry Times") + flag.Parse() +} + +func main() { + log.SetFlags(log.Ldate | log.Ltime) + log.SetOutput(os.Stdout) + + if host == "" || port == "" || user == "" || pswd == "" { + log.Println("[ERR] Invalid Arguments.") + os.Exit(1) + } + + cfg := goftp.Config{ + User: user, + Password: pswd, + Timeout: time.Second * 30, + TLSMode: goftp.TLSExplicit, + TLSConfig: &tls.Config{ + InsecureSkipVerify: true, + MinVersion: tls.VersionTLS10, + }, + } + + client, err := goftp.DialConfig(cfg, host+":"+port) + if err != nil { + log.Printf("[ERR] %s\r\n", err.Error()) + os.Exit(1) + } + defer client.Close() + + cwd, err := client.Getwd() + if err != nil { + log.Printf("[ERR] %s\r\n", err.Error()) + os.Exit(1) + } + if debug { + log.Printf("[MSG] CWD: %s\r\n", cwd) + } + + switch act { + case "list": + _List(client, rmt) + case "dnld": + _Download(client, loc, rmt) + case "upld": + _Upload(client, loc, rmt) + default: + _List(client, loc) + } +} + +func _List(client *goftp.Client, path string) { + fis, err := client.ReadDir(path) + if err != nil { + log.Printf("[ERR] %s\r\n", err.Error()) + os.Exit(1) + } + + fmt.Println("### Name;Size;ModTime;IsDir") + for _, f := range fis { + fmt.Printf("%v;%v;%v;%v\r\n", f.Name(), f.Size(), f.ModTime().Format("2006-01-02 15:04:05"), f.IsDir()) + } +} + +func _Download(client *goftp.Client, local, remote string) { + if local == "" || remote == "" { + log.Println("[ERR] Invalid Local/Remote Path") + return + } + log.Printf("[MSG] Downloading %s\r\n", remote) + var err error + var wtr *os.File + defer wtr.Close() + for r := 0; r <= retry; r++ { + if r > 0 { + time.Sleep(time.Second * 1) + log.Printf("[MSG] Retrying %d: %s\r\n", r, remote) + } + wtr, err = os.Create(local) + if err != nil { + continue + } + err = client.Retrieve(remote, wtr) + if err != nil { + continue + } + } + if err != nil { + log.Printf("[ERR] Download NG: %s\r\n", remote) + log.Printf("[###] %s\r\n", err.Error()) + } else { + log.Printf("[MSG] Download OK: %s\r\n", remote) + } +} + +func _Upload(client *goftp.Client, local, remote string) { + if local == "" || remote == "" { + log.Println("[ERR] Invalid Local/Remote Path") + return + } + log.Printf("[MSG] Uploading %s\r\n", local) + var err error + var rdr *os.File + defer rdr.Close() + for r := 0; r <= retry; r++ { + if r > 0 { + time.Sleep(time.Second * 1) + log.Printf("[MSG] Retrying %d: %s\r\n", r, local) + } + rdr, err = os.Open(local) + if err != nil { + continue + } + err = client.Store(remote, rdr) + if err != nil { + continue + } + } + if err != nil { + log.Printf("[ERR] Upload NG: %s\r\n", local) + log.Printf("[###] %s\r\n", err.Error()) + } else { + log.Printf("[MSG] Upload OK: %s\r\n", local) + } +} diff --git a/go.mod b/go.mod index 02f250b..4c0ff6a 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module ftpsClient -go 1.20 +go 1.21.1 -require github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 +require gopkg.in/dutchcoders/goftp.v1 v1.0.0-20170301105846-ed59a591ce14 diff --git a/go.sum b/go.sum index b9b74f5..dc79cc2 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 h1:PT+ElG/UUFMfqy5HrxJxNzj3QBOf7dZwupeVC+mG1Lo= -github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4/go.mod h1:MnkX001NG75g3p8bhFycnyIjeQoOjGL6CEIsdE/nKSY= +gopkg.in/dutchcoders/goftp.v1 v1.0.0-20170301105846-ed59a591ce14 h1:tHqNpm9sPaE6BSuMLXBzgTwukQLdBEt4OYU2coQjEQQ= +gopkg.in/dutchcoders/goftp.v1 v1.0.0-20170301105846-ed59a591ce14/go.mod h1:nzmlZQ+UqB5+55CRTV/dOaiK8OrPl6Co96Ob8lH4Wxw=