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