Sync/Main.go

125 lines
3.3 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"log"
2017-07-02 11:45:34 +00:00
"net"
"os"
"runtime"
2017-07-02 11:45:34 +00:00
"time"
2017-03-04 10:27:20 +00:00
"github.com/SommerEngineering/Sync/Sync"
"github.com/howeyc/gopass"
"golang.org/x/crypto/ssh"
)
func main() {
// Show the current version:
2017-07-02 11:45:34 +00:00
log.Println(`Sync v1.3.1`)
// Allow Go to use all CPUs:
runtime.GOMAXPROCS(runtime.NumCPU())
// Read the configuration from the command-line args:
readFlags()
// Check if the directories are provided:
if localDir == `` || remoteDir == `` {
log.Println(`Please provide the local and remote directory.`)
os.Exit(1)
return
}
// Should I use the current working dir?
if localDir == `.` {
if currentWD, currentWDError := os.Getwd(); currentWDError != nil {
log.Println("Cannot use the current working directory as local directory: " + currentWDError.Error())
os.Exit(2)
return
} else {
log.Println("I use the current working directory as local directory: " + currentWD)
localDir = currentWD
}
}
// Remove trailing separators from both directories
localDir = correctPath(localDir)
remoteDir = correctPath(remoteDir)
// Check if local dir exist
if dirInfo, dirError := os.Stat(localDir); dirError != nil {
log.Println("There is an error with the local directory: " + dirError.Error())
os.Exit(3)
return
} else {
if !dirInfo.IsDir() {
log.Println("There is an error with the local directory: You provided a file instead!")
os.Exit(4)
return
}
}
// Check if the password was provided:
for true {
if password == `` {
// Promt for the password:
fmt.Print(`Please provide the password for the connection: `)
if pass, errPass := gopass.GetPasswd(); errPass != nil {
log.Println(`There was an error reading the password securely: ` + errPass.Error())
os.Exit(5)
return
} else {
password = string(pass)
}
} else {
break
}
}
// Give some information about the state
if supervised {
log.Println("I use the supervised mode.")
} else {
log.Println("I do not use the supervised mode.")
}
if pushOnly {
log.Println("I use the push only mode i.e. backup mode. Any remote change will be ignored.")
} else {
log.Println("I use the full mode and consider also remote changes.")
}
// Create the SSH configuration:
Sync.SetPassword4Callback(password)
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
ssh.PasswordCallback(Sync.PasswordCallback),
ssh.KeyboardInteractive(Sync.KeyboardInteractiveChallenge),
},
2017-07-02 11:45:34 +00:00
HostKeyCallback: showHostKey(),
}
// Connect to the SSH server:
ssh := Sync.ConnectSSH(config, serverAddrString)
if ssh == nil {
log.Println(`It was not possible to connect to the SSH server.`)
os.Exit(6)
return
}
defer ssh.Close()
Sync.Synchronise(ssh, supervised, pushOnly, localDir, remoteDir)
log.Println("Synchronising done.")
}
2017-07-02 11:45:34 +00:00
func showHostKey() ssh.HostKeyCallback {
return func(hostname string, remote net.Addr, key ssh.PublicKey) error {
log.Printf("Your server's hostname is %s (%s) and its public key is %s. If this is wrong, please abort the program now! Wait 16 seconds for your check.", hostname, remote.String(), ssh.FingerprintSHA256(key))
time.Sleep(16 * time.Second)
return nil
}
}