X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/25f0d77de4489c6759a497617606f2933ca76fc9..85767504e4dc622c5ff469733e49c0cebcee57f1:/hotline/transfer.go?ds=sidebyside diff --git a/hotline/transfer.go b/hotline/transfer.go index fa431ce..703dae0 100644 --- a/hotline/transfer.go +++ b/hotline/transfer.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" "errors" + "io" ) type transfer struct { @@ -26,3 +27,78 @@ func (tf *transfer) Write(b []byte) (int, error) { return len(b), nil } + +func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) error { + ffhBuf := make([]byte, 24) + if _, err := conn.Read(ffhBuf); err != nil { + return err + } + + var ffh FlatFileHeader + err := binary.Read(bytes.NewReader(ffhBuf), binary.BigEndian, &ffh) + if err != nil { + return err + } + + ffifhBuf := make([]byte, 16) + if _, err := conn.Read(ffifhBuf); err != nil { + return err + } + + var ffifh FlatFileInformationForkHeader + err = binary.Read(bytes.NewReader(ffifhBuf), binary.BigEndian, &ffifh) + if err != nil { + return err + } + + var ffif FlatFileInformationFork + + dataLen := binary.BigEndian.Uint32(ffifh.DataSize[:]) + ffifBuf := make([]byte, dataLen) + if _, err := conn.Read(ffifBuf); err != nil { + return err + } + if err := ffif.UnmarshalBinary(ffifBuf); err != nil { + return err + } + + var ffdfh FlatFileDataForkHeader + ffdfhBuf := make([]byte, 16) + if _, err := conn.Read(ffdfhBuf); err != nil { + return err + } + err = binary.Read(bytes.NewReader(ffdfhBuf), binary.BigEndian, &ffdfh) + if err != nil { + return err + } + + // this will be zero if the file only has a resource fork + fileSize := int(binary.BigEndian.Uint32(ffdfh.DataSize[:])) + + // Copy N bytes from conn to upload file + _, err = io.CopyN(targetFile, conn, int64(fileSize)) + if err != nil { + return err + } + + if ffh.ForkCount == [2]byte{0, 3} { + var resForkHeader FlatFileDataForkHeader + resForkBuf := make([]byte, 16) + + if _, err := conn.Read(resForkBuf); err != nil { + return err + } + err = binary.Read(bytes.NewReader(resForkBuf), binary.BigEndian, &resForkHeader) + if err != nil { + return err + } + + fileSize = int(binary.BigEndian.Uint32(resForkHeader.DataSize[:])) + + _, err = io.CopyN(resForkFile, conn, int64(fileSize)) + if err != nil { + return err + } + } + return nil +}