]>
Commit | Line | Data |
---|---|---|
6988a057 JH |
1 | package hotline |
2 | ||
3 | import ( | |
4 | "bytes" | |
5 | "encoding/binary" | |
6 | "errors" | |
6e4935b3 | 7 | "fmt" |
85767504 | 8 | "io" |
6988a057 JH |
9 | ) |
10 | ||
df2735b2 | 11 | type transfer struct { |
6988a057 | 12 | Protocol [4]byte // "HTXF" 0x48545846 |
d9bc63a1 | 13 | ReferenceNumber [4]byte // Unique Type generated for the transfer |
6988a057 JH |
14 | DataSize [4]byte // File size |
15 | RSVD [4]byte // Not implemented in Hotline Protocol | |
16 | } | |
17 | ||
df2735b2 | 18 | var HTXF = [4]byte{0x48, 0x54, 0x58, 0x46} // (HTXF) is the only supported transfer protocol |
6988a057 | 19 | |
df2735b2 JH |
20 | func (tf *transfer) Write(b []byte) (int, error) { |
21 | if err := binary.Read(bytes.NewReader(b), binary.BigEndian, tf); err != nil { | |
22 | return 0, err | |
6988a057 JH |
23 | } |
24 | ||
df2735b2 JH |
25 | if tf.Protocol != HTXF { |
26 | return 0, errors.New("invalid protocol") | |
6988a057 JH |
27 | } |
28 | ||
df2735b2 | 29 | return len(b), nil |
6988a057 | 30 | } |
85767504 | 31 | |
df1ade54 | 32 | func receiveFile(r io.Reader, targetFile, resForkFile, infoFork, counterWriter io.Writer) error { |
7cd900d6 JH |
33 | var ffo flattenedFileObject |
34 | if _, err := ffo.ReadFrom(r); err != nil { | |
6e4935b3 | 35 | return fmt.Errorf("read flatted file object: %v", err) |
85767504 JH |
36 | } |
37 | ||
7cd900d6 | 38 | // Write the information fork |
9cf66aea | 39 | _, err := io.Copy(infoFork, &ffo.FlatFileInformationFork) |
85767504 | 40 | if err != nil { |
6e4935b3 | 41 | return fmt.Errorf("write the information fork: %v", err) |
85767504 JH |
42 | } |
43 | ||
1a7d1fb9 | 44 | if _, err = io.CopyN(targetFile, io.TeeReader(r, counterWriter), ffo.dataSize()); err != nil { |
6e4935b3 | 45 | return fmt.Errorf("copy file data to partial file: %v", err) |
165b7ac9 | 46 | } |
85767504 | 47 | |
7cd900d6 JH |
48 | if ffo.FlatFileHeader.ForkCount == [2]byte{0, 3} { |
49 | if err := binary.Read(r, binary.BigEndian, &ffo.FlatFileResForkHeader); err != nil { | |
6e4935b3 | 50 | return fmt.Errorf("read resource fork header: %v", err) |
85767504 | 51 | } |
ba29c43b | 52 | |
1a7d1fb9 | 53 | if _, err = io.CopyN(resForkFile, io.TeeReader(r, counterWriter), ffo.rsrcSize()); err != nil { |
6e4935b3 | 54 | return fmt.Errorf("read resource fork: %v", err) |
ba29c43b | 55 | } |
7cd900d6 JH |
56 | } |
57 | return nil | |
58 | } |