0
0
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 21:30:16 +02:00

#463 added capability to send/receive empty folders

This commit is contained in:
iulius98 2022-04-09 01:38:22 +03:00
parent 386c99d057
commit 15d0209a29
2 changed files with 80 additions and 28 deletions

View file

@ -267,7 +267,7 @@ func send(c *cli.Context) (err error) {
crocOptions.SharedSecret = utils.GetRandomName() crocOptions.SharedSecret = utils.GetRandomName()
} }
minimalFileInfos, err := croc.GetFilesInfo(fnames) minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders, err := croc.GetFilesInfo(fnames)
if err != nil { if err != nil {
return return
} }
@ -280,7 +280,7 @@ func send(c *cli.Context) (err error) {
// save the config // save the config
saveConfig(c, crocOptions) saveConfig(c, crocOptions)
err = cr.Send(minimalFileInfos) err = cr.Send(minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders)
return return
} }

View file

@ -88,12 +88,14 @@ type Client struct {
Step1ChannelSecured bool Step1ChannelSecured bool
Step2FileInfoTransferred bool Step2FileInfoTransferred bool
Step3RecipientRequestFile bool Step3RecipientRequestFile bool
Step4FileTransfer bool Step4FileTransferred bool
Step5CloseChannels bool Step5CloseChannels bool
SuccessfulTransfer bool SuccessfulTransfer bool
// send / receive information of all files // send / receive information of all files
FilesToTransfer []FileInfo FilesToTransfer []FileInfo
EmptyFoldersToTransfer []FileInfo
TotalNumberFolders int
FilesToTransferCurrentNum int FilesToTransferCurrentNum int
FilesHasFinished map[int]struct{} FilesHasFinished map[int]struct{}
@ -155,6 +157,8 @@ type RemoteFileRequest struct {
// SenderInfo lists the files to be transferred // SenderInfo lists the files to be transferred
type SenderInfo struct { type SenderInfo struct {
FilesToTransfer []FileInfo FilesToTransfer []FileInfo
EmptyFoldersToTransfer []FileInfo
TotalNumberFolders int
MachineID string MachineID string
Ask bool Ask bool
SendingText bool SendingText bool
@ -228,11 +232,25 @@ type TransferOptions struct {
KeepPathInRemote bool KeepPathInRemote bool
} }
func isEmptyFolder(folderPath string) (bool, error) {
f, err := os.Open(folderPath)
if err != nil {
return false, err
}
defer f.Close()
_, err = f.Readdirnames(1)
if err == io.EOF {
return true, nil
}
return false, nil
}
// This function retrives the important file informations // This function retrives the important file informations
// for every file that will be transfered // for every file that will be transfered
func GetFilesInfo(fnames []string) (filesInfo []FileInfo, err error) { func GetFilesInfo(fnames []string) (filesInfo []FileInfo, emptyFolders []FileInfo, totalNumberFolders int, err error) {
// fnames: the relativ/absolute paths of files/folders that will be transfered // fnames: the relativ/absolute paths of files/folders that will be transfered
totalNumberFolders = 0
var paths []string var paths []string
for _, fname := range fnames { for _, fname := range fnames {
// Support wildcard // Support wildcard
@ -270,10 +288,9 @@ func GetFilesInfo(fnames []string) (filesInfo []FileInfo, err error) {
if err != nil { if err != nil {
return err return err
} }
if !info.IsDir() {
remoteFolder := strings.TrimPrefix(filepath.Dir(pathName), remoteFolder := strings.TrimPrefix(filepath.Dir(pathName),
filepath.Dir(absPath)+string(os.PathSeparator)) filepath.Dir(absPath)+string(os.PathSeparator))
if !info.IsDir() {
filesInfo = append(filesInfo, FileInfo{ filesInfo = append(filesInfo, FileInfo{
Name: info.Name(), Name: info.Name(),
FolderRemote: strings.Replace(remoteFolder, string(os.PathSeparator), "/", -1) + "/", FolderRemote: strings.Replace(remoteFolder, string(os.PathSeparator), "/", -1) + "/",
@ -282,6 +299,15 @@ func GetFilesInfo(fnames []string) (filesInfo []FileInfo, err error) {
ModTime: info.ModTime(), ModTime: info.ModTime(),
Mode: info.Mode(), Mode: info.Mode(),
}) })
} else {
totalNumberFolders++
isEmptyFolder, _ := isEmptyFolder(pathName)
if isEmptyFolder {
emptyFolders = append(emptyFolders, FileInfo{
FolderRemote: strings.Replace(strings.TrimPrefix(pathName,
filepath.Dir(absPath)+string(os.PathSeparator)), string(os.PathSeparator), "/", -1) + "/",
})
}
} }
return nil return nil
}) })
@ -443,8 +469,10 @@ func (c *Client) transferOverLocalRelay(errchan chan<- error) {
} }
// Send will send the specified file // Send will send the specified file
func (c *Client) Send(filesInfo []FileInfo) (err error) { func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, totalNumberFolders int) (err error) {
err = c.sendCollectFiles(filesInfo) err = c.sendCollectFiles(filesInfo)
c.EmptyFoldersToTransfer = emptyFoldersToTransfer
c.TotalNumberFolders = totalNumberFolders
if err != nil { if err != nil {
return return
} }
@ -778,7 +806,7 @@ func (c *Client) Receive() (err error) {
fmt.Fprintf(os.Stderr, "\rsecuring channel...") fmt.Fprintf(os.Stderr, "\rsecuring channel...")
err = c.transfer() err = c.transfer()
if err == nil { if err == nil {
if c.numberOfTransferredFiles == 0 { if c.numberOfTransferredFiles+len(c.EmptyFoldersToTransfer) == 0 {
fmt.Fprintf(os.Stderr, "\rNo files transferred.") fmt.Fprintf(os.Stderr, "\rNo files transferred.")
} }
} }
@ -870,6 +898,8 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
c.Options.SendingText = senderInfo.SendingText c.Options.SendingText = senderInfo.SendingText
c.Options.NoCompress = senderInfo.NoCompress c.Options.NoCompress = senderInfo.NoCompress
c.Options.HashAlgorithm = senderInfo.HashAlgorithm c.Options.HashAlgorithm = senderInfo.HashAlgorithm
c.EmptyFoldersToTransfer = senderInfo.EmptyFoldersToTransfer
c.TotalNumberFolders = senderInfo.TotalNumberFolders
if c.Options.HashAlgorithm == "" { if c.Options.HashAlgorithm == "" {
c.Options.HashAlgorithm = "xxhash" c.Options.HashAlgorithm = "xxhash"
} }
@ -882,6 +912,7 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
} }
c.FilesToTransfer = senderInfo.FilesToTransfer c.FilesToTransfer = senderInfo.FilesToTransfer
fname := fmt.Sprintf("%d files", len(c.FilesToTransfer)) fname := fmt.Sprintf("%d files", len(c.FilesToTransfer))
folderName := fmt.Sprintf("%d folders", c.TotalNumberFolders)
if len(c.FilesToTransfer) == 1 { if len(c.FilesToTransfer) == 1 {
fname = fmt.Sprintf("'%s'", c.FilesToTransfer[0].Name) fname = fmt.Sprintf("'%s'", c.FilesToTransfer[0].Name)
} }
@ -909,7 +940,7 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
machID, _ := machineid.ID() machID, _ := machineid.ID()
fmt.Fprintf(os.Stderr, "\rYour machine id is '%s'.\n%s %s (%s) from '%s'? (Y/n) ", machID, action, fname, utils.ByteCountDecimal(totalSize), senderInfo.MachineID) fmt.Fprintf(os.Stderr, "\rYour machine id is '%s'.\n%s %s (%s) from '%s'? (Y/n) ", machID, action, fname, utils.ByteCountDecimal(totalSize), senderInfo.MachineID)
} else { } else {
fmt.Fprintf(os.Stderr, "\r%s %s (%s)? (Y/n) ", action, fname, utils.ByteCountDecimal(totalSize)) fmt.Fprintf(os.Stderr, "\r%s %s and %s (%s)? (Y/n) ", action, fname, folderName, utils.ByteCountDecimal(totalSize))
} }
choice := strings.ToLower(utils.GetInput("")) choice := strings.ToLower(utils.GetInput(""))
if choice != "" && choice != "y" && choice != "yes" { if choice != "" && choice != "y" && choice != "yes" {
@ -927,6 +958,25 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
} }
fmt.Fprintf(os.Stderr, "\nReceiving (<-%s)\n", c.ExternalIPConnected) fmt.Fprintf(os.Stderr, "\nReceiving (<-%s)\n", c.ExternalIPConnected)
//after user accepted the transfer we can create empty folders
for i := 0; i < len(c.EmptyFoldersToTransfer); i += 1 {
errMkDirAll := os.MkdirAll(c.EmptyFoldersToTransfer[i].FolderRemote, os.ModePerm)
if err != nil {
err = errMkDirAll
return
}
}
if c.FilesToTransfer == nil {
c.SuccessfulTransfer = true
c.Step3RecipientRequestFile = true
c.Step4FileTransferred = true
errStopTransfer := message.Send(c.conn[0], c.Key, message.Message{
Type: message.TypeFinished,
})
if errStopTransfer != nil {
err = errStopTransfer
}
}
log.Debug(c.FilesToTransfer) log.Debug(c.FilesToTransfer)
c.Step2FileInfoTransferred = true c.Step2FileInfoTransferred = true
return return
@ -1121,14 +1171,14 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
case message.TypeCloseSender: case message.TypeCloseSender:
c.bar.Finish() c.bar.Finish()
log.Debug("close-sender received...") log.Debug("close-sender received...")
c.Step4FileTransfer = false c.Step4FileTransferred = false
c.Step3RecipientRequestFile = false c.Step3RecipientRequestFile = false
log.Debug("sending close-recipient") log.Debug("sending close-recipient")
err = message.Send(c.conn[0], c.Key, message.Message{ err = message.Send(c.conn[0], c.Key, message.Message{
Type: message.TypeCloseRecipient, Type: message.TypeCloseRecipient,
}) })
case message.TypeCloseRecipient: case message.TypeCloseRecipient:
c.Step4FileTransfer = false c.Step4FileTransferred = false
c.Step3RecipientRequestFile = false c.Step3RecipientRequestFile = false
} }
if err != nil { if err != nil {
@ -1149,8 +1199,10 @@ func (c *Client) updateIfSenderChannelSecured() (err error) {
machID, _ := machineid.ID() machID, _ := machineid.ID()
b, err = json.Marshal(SenderInfo{ b, err = json.Marshal(SenderInfo{
FilesToTransfer: c.FilesToTransfer, FilesToTransfer: c.FilesToTransfer,
EmptyFoldersToTransfer: c.EmptyFoldersToTransfer,
MachineID: machID, MachineID: machID,
Ask: c.Options.Ask, Ask: c.Options.Ask,
TotalNumberFolders: c.TotalNumberFolders,
SendingText: c.Options.SendingText, SendingText: c.Options.SendingText,
NoCompress: c.Options.NoCompress, NoCompress: c.Options.NoCompress,
HashAlgorithm: c.Options.HashAlgorithm, HashAlgorithm: c.Options.HashAlgorithm,
@ -1402,7 +1454,7 @@ func (c *Client) updateIfRecipientHasFileInfo() (err error) {
break break
} }
} }
err = c.recipientGetFileReady(finished) c.recipientGetFileReady(finished)
return return
} }
@ -1426,7 +1478,7 @@ func (c *Client) updateState() (err error) {
return return
} }
if c.Options.IsSender && c.Step3RecipientRequestFile && !c.Step4FileTransfer { if c.Options.IsSender && c.Step3RecipientRequestFile && !c.Step4FileTransferred {
log.Debug("start sending data!") log.Debug("start sending data!")
if !c.firstSend { if !c.firstSend {
@ -1457,7 +1509,7 @@ func (c *Client) updateState() (err error) {
} }
} }
} }
c.Step4FileTransfer = true c.Step4FileTransferred = true
// setup the progressbar // setup the progressbar
c.setBar() c.setBar()
c.TotalSent = 0 c.TotalSent = 0