- // Check if the target folder exists. If not, create it.
- if _, err := FS.Stat(dstPath); os.IsNotExist(err) {
- s.Logger.Infow("Creating target path", "dstPath", dstPath)
- if err := FS.Mkdir(dstPath, 0777); err != nil {
- s.Logger.Error(err)
- }
- }
-
- readBuffer := make([]byte, 1024)
-
- // Begin the folder upload flow by sending the "next file action" to client
- if _, err := conn.Write([]byte{0, dlFldrActionNextFile}); err != nil {
- return err
- }
-
- fileSize := make([]byte, 4)
- itemCount := binary.BigEndian.Uint16(fileTransfer.FolderItemCount)
-
- for i := uint16(0); i < itemCount; i++ {
- if _, err := conn.Read(readBuffer); err != nil {
- return err
- }
- fu := readFolderUpload(readBuffer)
-
- s.Logger.Infow(
- "Folder upload continued",
- "transactionRef", fmt.Sprintf("%x", fileTransfer.ReferenceNumber),
- "RemoteAddr", conn.RemoteAddr().String(),
- "FormattedPath", fu.FormattedPath(),
- "IsFolder", fmt.Sprintf("%x", fu.IsFolder),
- "PathItemCount", binary.BigEndian.Uint16(fu.PathItemCount[:]),
- )
-
- if fu.IsFolder == [2]byte{0, 1} {
- if _, err := os.Stat(dstPath + "/" + fu.FormattedPath()); os.IsNotExist(err) {
- s.Logger.Infow("Target path does not exist; Creating...", "dstPath", dstPath)
- if err := os.Mkdir(dstPath+"/"+fu.FormattedPath(), 0777); err != nil {
- s.Logger.Error(err)
- }
- }
-
- // Tell client to send next file
- if _, err := conn.Write([]byte{0, dlFldrActionNextFile}); err != nil {
- s.Logger.Error(err)
- return err
- }
- } else {
- // TODO: Check if we have the full file already. If so, send dlFldrAction_NextFile to client to skip.
- // TODO: Check if we have a partial file already. If so, send dlFldrAction_ResumeFile to client to resume upload.
- // Send dlFldrAction_SendFile to client to begin transfer
- if _, err := conn.Write([]byte{0, dlFldrActionSendFile}); err != nil {
- return err
- }
-
- if _, err := conn.Read(fileSize); err != nil {
- fmt.Println("Error reading:", err.Error()) // TODO: handle
- }
-
- s.Logger.Infow("Starting file transfer", "fileNum", i+1, "totalFiles", itemCount, "fileSize", fileSize)
-
- if err := transferFile(conn, dstPath+"/"+fu.FormattedPath()); err != nil {
- s.Logger.Error(err)
- }
-
- // Tell client to send next file
- if _, err := conn.Write([]byte{0, dlFldrActionNextFile}); err != nil {
- s.Logger.Error(err)
- return err
- }
-
- // Client sends "MACR" after the file. Read and discard.
- // TODO: This doesn't seem to be documented. What is this? Maybe resource fork?
- if _, err := conn.Read(readBuffer); err != nil {
- return err
- }
- }