]>
Commit | Line | Data |
---|---|---|
6988a057 JH |
1 | package hotline |
2 | ||
3 | import ( | |
165b7ac9 | 4 | "bufio" |
6988a057 JH |
5 | "bytes" |
6 | "encoding/binary" | |
7 | "errors" | |
85767504 | 8 | "io" |
6988a057 JH |
9 | ) |
10 | ||
df2735b2 | 11 | type transfer struct { |
6988a057 JH |
12 | Protocol [4]byte // "HTXF" 0x48545846 |
13 | ReferenceNumber [4]byte // Unique ID generated for the transfer | |
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 | |
165b7ac9 | 32 | const fileCopyBufSize = 524288 // 512k |
85767504 JH |
33 | func receiveFile(conn io.Reader, targetFile io.Writer, resForkFile io.Writer) error { |
34 | ffhBuf := make([]byte, 24) | |
ba29c43b | 35 | if _, err := io.ReadFull(conn, ffhBuf); err != nil { |
85767504 JH |
36 | return err |
37 | } | |
38 | ||
39 | var ffh FlatFileHeader | |
40 | err := binary.Read(bytes.NewReader(ffhBuf), binary.BigEndian, &ffh) | |
41 | if err != nil { | |
42 | return err | |
43 | } | |
44 | ||
45 | ffifhBuf := make([]byte, 16) | |
ba29c43b | 46 | if _, err := io.ReadFull(conn, ffifhBuf); err != nil { |
85767504 JH |
47 | return err |
48 | } | |
49 | ||
50 | var ffifh FlatFileInformationForkHeader | |
51 | err = binary.Read(bytes.NewReader(ffifhBuf), binary.BigEndian, &ffifh) | |
52 | if err != nil { | |
53 | return err | |
54 | } | |
55 | ||
56 | var ffif FlatFileInformationFork | |
57 | ||
58 | dataLen := binary.BigEndian.Uint32(ffifh.DataSize[:]) | |
59 | ffifBuf := make([]byte, dataLen) | |
ba29c43b | 60 | if _, err := io.ReadFull(conn, ffifBuf); err != nil { |
85767504 JH |
61 | return err |
62 | } | |
63 | if err := ffif.UnmarshalBinary(ffifBuf); err != nil { | |
64 | return err | |
65 | } | |
66 | ||
67 | var ffdfh FlatFileDataForkHeader | |
68 | ffdfhBuf := make([]byte, 16) | |
ba29c43b | 69 | if _, err := io.ReadFull(conn, ffdfhBuf); err != nil { |
85767504 JH |
70 | return err |
71 | } | |
72 | err = binary.Read(bytes.NewReader(ffdfhBuf), binary.BigEndian, &ffdfh) | |
73 | if err != nil { | |
74 | return err | |
75 | } | |
76 | ||
77 | // this will be zero if the file only has a resource fork | |
78 | fileSize := int(binary.BigEndian.Uint32(ffdfh.DataSize[:])) | |
79 | ||
165b7ac9 JH |
80 | bw := bufio.NewWriterSize(targetFile, fileCopyBufSize) |
81 | _, err = io.CopyN(bw, conn, int64(fileSize)) | |
85767504 JH |
82 | if err != nil { |
83 | return err | |
84 | } | |
165b7ac9 JH |
85 | if err := bw.Flush(); err != nil { |
86 | return err | |
87 | } | |
85767504 JH |
88 | |
89 | if ffh.ForkCount == [2]byte{0, 3} { | |
90 | var resForkHeader FlatFileDataForkHeader | |
ba29c43b | 91 | if _, err := io.ReadFull(conn, resForkHeader.ForkType[:]); err != nil { |
85767504 JH |
92 | return err |
93 | } | |
ba29c43b JH |
94 | |
95 | if _, err := io.ReadFull(conn, resForkHeader.CompressionType[:]); err != nil { | |
85767504 JH |
96 | return err |
97 | } | |
98 | ||
ba29c43b JH |
99 | if _, err := io.ReadFull(conn, resForkHeader.RSVD[:]); err != nil { |
100 | return err | |
101 | } | |
102 | ||
103 | if _, err := io.ReadFull(conn, resForkHeader.DataSize[:]); err != nil { | |
104 | return err | |
105 | } | |
85767504 | 106 | |
165b7ac9 | 107 | bw = bufio.NewWriterSize(resForkFile, fileCopyBufSize) |
ba29c43b | 108 | _, err = io.CopyN(resForkFile, conn, int64(binary.BigEndian.Uint32(resForkHeader.DataSize[:]))) |
85767504 JH |
109 | if err != nil { |
110 | return err | |
111 | } | |
165b7ac9 JH |
112 | if err := bw.Flush(); err != nil { |
113 | return err | |
114 | } | |
85767504 JH |
115 | } |
116 | return nil | |
117 | } |