Browse Source

[checksum] Micro optimisations; [node] Renamed nodes to receiving and sending; [fsys] ftu now DOES NOT die on 'permission denied's

main v2.2.3
Unbewohnte 3 years ago
parent
commit
700811b179
  1. 2
      README.md
  2. 14
      src/checksum/checksum.go
  3. 6
      src/fsys/dir.go
  4. 2
      src/fsys/file.go
  5. 12
      src/main.go
  6. 23
      src/node/node.go
  7. 8
      src/node/options.go
  8. 2
      src/protocol/send.go

2
README.md

@ -46,7 +46,7 @@ Now you have ftu installed !
## ● Usage ## ● Usage
`ftu -h` - to print a usage message `ftu -h` - to print a usage message
`ftu [FLAGS]` `ftu [FLAGs]`
### ● FLAGs ### ● FLAGs
- -p [uint] for port - -p [uint] for port

14
src/checksum/checksum.go

@ -21,6 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
package checksum package checksum
import ( import (
"bytes"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"io" "io"
@ -36,8 +37,8 @@ import (
// GetPartialCheckSum is default method used to get a file checksum by sender and receiver // GetPartialCheckSum is default method used to get a file checksum by sender and receiver
func GetPartialCheckSum(file *os.File) (string, error) { func GetPartialCheckSum(file *os.File) (string, error) {
// "capturing" CHUNKSIZE bytes and then skipping STEP bytes before the next chunk until the last one // "capturing" CHUNKSIZE bytes and then skipping STEP bytes before the next chunk until the last one
const CHUNKS uint = 100 const CHUNKS uint = 50
const CHUNKSIZE uint = 100 const CHUNKSIZE uint = 50
const STEP uint = 250 const STEP uint = 250
fileStats, err := file.Stat() fileStats, err := file.Stat()
@ -48,7 +49,7 @@ func GetPartialCheckSum(file *os.File) (string, error) {
fileSize := fileStats.Size() fileSize := fileStats.Size()
if fileSize < int64(CHUNKS*CHUNKSIZE+STEP*(CHUNKS-1)) { if fileSize < int64(CHUNKS*CHUNKSIZE+STEP*(CHUNKS-1)) {
// file is too small to chop it in chunks, so just doing full checksum // file is too small to chop it in chunks, so just get the full checksum
checksum, err := getFullCheckSum(file) checksum, err := getFullCheckSum(file)
if err != nil { if err != nil {
@ -62,19 +63,20 @@ func GetPartialCheckSum(file *os.File) (string, error) {
return "", err return "", err
} }
var capturedChunks string // var capturedChunks string
var capturedChunks bytes.Buffer
var read uint64 = 0 var read uint64 = 0
for i := 0; uint(i) < CHUNKS; i++ { for i := 0; uint(i) < CHUNKS; i++ {
buffer := make([]byte, CHUNKSIZE) buffer := make([]byte, CHUNKSIZE)
r, _ := file.ReadAt(buffer, int64(read)) r, _ := file.ReadAt(buffer, int64(read))
capturedChunks += string(buffer) capturedChunks.Write(buffer)
read += uint64(r) read += uint64(r)
read += uint64(STEP) read += uint64(STEP)
} }
checksumBytes := sha256.Sum256([]byte(capturedChunks)) checksumBytes := sha256.Sum256(capturedChunks.Bytes())
checksum := hex.EncodeToString(checksumBytes[:]) checksum := hex.EncodeToString(checksumBytes[:])
return checksum, nil return checksum, nil

6
src/fsys/dir.go

@ -22,6 +22,7 @@ package fsys
import ( import (
"fmt" "fmt"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
) )
@ -63,7 +64,7 @@ func GetDir(path string, recursive bool) (*Directory, error) {
// loop through each entry in the directory // loop through each entry in the directory
entries, err := os.ReadDir(absPath) entries, err := os.ReadDir(absPath)
if err != nil { if err != nil && err != fs.ErrPermission {
return nil, err return nil, err
} }
@ -96,7 +97,8 @@ func GetDir(path string, recursive bool) (*Directory, error) {
innerFile, err := GetFile(innerFilePath) innerFile, err := GetFile(innerFilePath)
if err != nil { if err != nil {
return nil, err // skip this file
continue
} }
directory.Size += innerFile.Size directory.Size += innerFile.Size

2
src/fsys/file.go

@ -45,7 +45,7 @@ var ErrorNotFile error = fmt.Errorf("not a file")
// Get general information about a file with the // Get general information about a file with the
// future ability to open it. // future ability to open it.
// NOTE that Handler field is nil BY DEFAULT until you // NOTE that Handler field is nil BY DEFAULT until you
// manually call a (file *File) Open() function to open it ! // manually call (file *File).Open() to open it !
func GetFile(path string) (*File, error) { func GetFile(path string) (*File, error) {
absPath, err := filepath.Abs(path) absPath, err := filepath.Abs(path)
if err != nil { if err != nil {

12
src/main.go

@ -30,9 +30,9 @@ import (
) )
var ( var (
VERSION string = "v2.2.2" VERSION string = "v2.2.3"
versionInformation string = fmt.Sprintf("ftu %s\n\nCopyright (C) 2021,2022 Kasyanov Nikolay Alexeevich (Unbewohnte (https://unbewohnte.xyz/))\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions; type \"ftu -l\" for details.\n", VERSION) versionInformation string = fmt.Sprintf("ftu %s\nfile transferring utility\n\nCopyright (C) 2021,2022 Kasyanov Nikolay Alexeevich (Unbewohnte (me@unbewohnte.xyz))\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions; type \"ftu -l\" for details.\n", VERSION)
//go:embed COPYING //go:embed COPYING
licenseInformation string licenseInformation string
@ -52,7 +52,7 @@ var (
func init() { func init() {
flag.Usage = func() { flag.Usage = func() {
fmt.Printf("ftu -[FLAG]...\n\n") fmt.Printf("ftu -[FLAGs]\n\n")
fmt.Printf("[FLAGs]\n\n") fmt.Printf("[FLAGs]\n\n")
fmt.Printf("| -p [Uinteger_here] for port\n") fmt.Printf("| -p [Uinteger_here] for port\n")
@ -122,11 +122,11 @@ func main() {
VerboseOutput: *VERBOSE, VerboseOutput: *VERBOSE,
IsSending: isSending, IsSending: isSending,
WorkingPort: *PORT, WorkingPort: *PORT,
ServerSide: &node.ServerSideNodeOptions{ SenderSide: &node.SenderNodeOptions{
ServingPath: *SEND, ServingPath: *SEND,
Recursive: *RECUSRIVE, Recursive: *RECUSRIVE,
}, },
ClientSide: &node.ClientSideNodeOptions{ ReceiverSide: &node.ReceiverNodeOptions{
ConnectionAddr: *ADDRESS, ConnectionAddr: *ADDRESS,
DownloadsFolderPath: *DOWNLOADS_DIR, DownloadsFolderPath: *DOWNLOADS_DIR,
}, },
@ -134,7 +134,7 @@ func main() {
node, err := node.NewNode(&nodeOptions) node, err := node.NewNode(&nodeOptions)
if err != nil { if err != nil {
fmt.Printf("Error constructing a new node: %s\n", err) fmt.Printf("[ERROR] Error constructing a new node: %s\n", err)
os.Exit(-1) os.Exit(-1)
} }

23
src/node/node.go

@ -91,7 +91,7 @@ func NewNode(options *NodeOptions) (*Node, error) {
var isDir bool var isDir bool
if options.IsSending { if options.IsSending {
// sending node preparation // sending node preparation
sendingPathStats, err := os.Stat(options.ServerSide.ServingPath) sendingPathStats, err := os.Stat(options.SenderSide.ServingPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -106,12 +106,12 @@ func NewNode(options *NodeOptions) (*Node, error) {
} else { } else {
// receiving node preparation // receiving node preparation
var err error var err error
options.ClientSide.DownloadsFolderPath, err = filepath.Abs(options.ClientSide.DownloadsFolderPath) options.ReceiverSide.DownloadsFolderPath, err = filepath.Abs(options.ReceiverSide.DownloadsFolderPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = os.MkdirAll(options.ClientSide.DownloadsFolderPath, os.ModePerm) err = os.MkdirAll(options.ReceiverSide.DownloadsFolderPath, os.ModePerm)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -125,22 +125,22 @@ func NewNode(options *NodeOptions) (*Node, error) {
isSending: options.IsSending, isSending: options.IsSending,
netInfo: &netInfo{ netInfo: &netInfo{
Port: options.WorkingPort, Port: options.WorkingPort,
ConnAddr: options.ClientSide.ConnectionAddr, ConnAddr: options.ReceiverSide.ConnectionAddr,
EncryptionKey: nil, EncryptionKey: nil,
Conn: nil, Conn: nil,
}, },
stopped: false, stopped: false,
transferInfo: &transferInfo{ transferInfo: &transferInfo{
Sending: &sending{ Sending: &sending{
ServingPath: options.ServerSide.ServingPath, ServingPath: options.SenderSide.ServingPath,
Recursive: options.ServerSide.Recursive, Recursive: options.SenderSide.Recursive,
IsDirectory: isDir, IsDirectory: isDir,
TotalTransferSize: 0, TotalTransferSize: 0,
SentBytes: 0, SentBytes: 0,
}, },
Receiving: &receiving{ Receiving: &receiving{
AcceptedFiles: nil, AcceptedFiles: nil,
DownloadsPath: options.ClientSide.DownloadsFolderPath, DownloadsPath: options.ReceiverSide.DownloadsFolderPath,
ReceivedBytes: 0, ReceivedBytes: 0,
TotalDownloadSize: 0, TotalDownloadSize: 0,
}, },
@ -512,7 +512,7 @@ func (node *Node) send() {
default: default:
node.stopped = true node.stopped = true
fmt.Printf("\nAn error occured while sending a piece of \"%s\": %s", node.transferInfo.Sending.FilesToSend[currentFileIndex].Name, err) fmt.Printf("\n[ERROR] An error occured while sending a piece of \"%s\": %s", node.transferInfo.Sending.FilesToSend[currentFileIndex].Name, err)
panic(err) panic(err)
} }
} }
@ -525,7 +525,7 @@ func (node *Node) receive() {
// connect to the sending node // connect to the sending node
err := node.connect() err := node.connect()
if err != nil { if err != nil {
fmt.Printf("\nCould not connect to %s:%d", node.netInfo.ConnAddr, node.netInfo.Port) fmt.Printf("\n[ERROR] Could not connect to %s:%d", node.netInfo.ConnAddr, node.netInfo.Port)
os.Exit(-1) os.Exit(-1)
} }
@ -823,7 +823,10 @@ func (node *Node) receive() {
} }
if realChecksum != acceptedFile.Checksum { if realChecksum != acceptedFile.Checksum {
fmt.Printf("\n| \"%s\" is corrupted", acceptedFile.Name) if node.verboseOutput {
fmt.Printf("\n[ERROR] \"%s\" is corrupted", acceptedFile.Name)
}
acceptedFile.Close() acceptedFile.Close()
break break
} else { } else {

8
src/node/options.go

@ -20,12 +20,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
package node package node
type ServerSideNodeOptions struct { type SenderNodeOptions struct {
ServingPath string ServingPath string
Recursive bool Recursive bool
} }
type ClientSideNodeOptions struct { type ReceiverNodeOptions struct {
ConnectionAddr string ConnectionAddr string
DownloadsFolderPath string DownloadsFolderPath string
} }
@ -35,6 +35,6 @@ type NodeOptions struct {
IsSending bool IsSending bool
WorkingPort uint WorkingPort uint
VerboseOutput bool VerboseOutput bool
ServerSide *ServerSideNodeOptions SenderSide *SenderNodeOptions
ClientSide *ClientSideNodeOptions ReceiverSide *ReceiverNodeOptions
} }

2
src/protocol/send.go

@ -174,7 +174,7 @@ func SendPiece(file *fsys.File, connection net.Conn, encrKey []byte) (uint64, er
if encrKey != nil { if encrKey != nil {
// account for padding // account for padding
canSendBytes -= 32 canSendBytes -= 48
} }
if (file.Size - file.SentBytes) < canSendBytes { if (file.Size - file.SentBytes) < canSendBytes {

Loading…
Cancel
Save