]>
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" |
9067f234 JH |
9 | "os" |
10 | "path/filepath" | |
6988a057 JH |
11 | ) |
12 | ||
df2735b2 | 13 | type transfer struct { |
6988a057 JH |
14 | Protocol [4]byte // "HTXF" 0x48545846 |
15 | ReferenceNumber [4]byte // Unique ID generated for the transfer | |
16 | DataSize [4]byte // File size | |
17 | RSVD [4]byte // Not implemented in Hotline Protocol | |
18 | } | |
19 | ||
df2735b2 | 20 | var HTXF = [4]byte{0x48, 0x54, 0x58, 0x46} // (HTXF) is the only supported transfer protocol |
6988a057 | 21 | |
df2735b2 JH |
22 | func (tf *transfer) Write(b []byte) (int, error) { |
23 | if err := binary.Read(bytes.NewReader(b), binary.BigEndian, tf); err != nil { | |
24 | return 0, err | |
6988a057 JH |
25 | } |
26 | ||
df2735b2 JH |
27 | if tf.Protocol != HTXF { |
28 | return 0, errors.New("invalid protocol") | |
6988a057 JH |
29 | } |
30 | ||
df2735b2 | 31 | return len(b), nil |
6988a057 | 32 | } |
85767504 | 33 | |
7cd900d6 | 34 | const fileCopyBufSize = 4096 |
85767504 | 35 | |
7cd900d6 JH |
36 | func receiveFile(r io.Reader, targetFile, resForkFile, infoFork io.Writer) error { |
37 | var ffo flattenedFileObject | |
38 | if _, err := ffo.ReadFrom(r); err != nil { | |
85767504 JH |
39 | return err |
40 | } | |
41 | ||
7cd900d6 JH |
42 | // Write the information fork |
43 | _, err := infoFork.Write(ffo.FlatFileInformationFork.MarshalBinary()) | |
85767504 JH |
44 | if err != nil { |
45 | return err | |
46 | } | |
47 | ||
7cd900d6 | 48 | // read and write the data fork |
165b7ac9 | 49 | bw := bufio.NewWriterSize(targetFile, fileCopyBufSize) |
7cd900d6 | 50 | if _, err = io.CopyN(bw, r, ffo.dataSize()); err != nil { |
85767504 JH |
51 | return err |
52 | } | |
165b7ac9 JH |
53 | if err := bw.Flush(); err != nil { |
54 | return err | |
55 | } | |
85767504 | 56 | |
7cd900d6 JH |
57 | if ffo.FlatFileHeader.ForkCount == [2]byte{0, 3} { |
58 | if err := binary.Read(r, binary.BigEndian, &ffo.FlatFileResForkHeader); err != nil { | |
85767504 JH |
59 | return err |
60 | } | |
ba29c43b | 61 | |
7cd900d6 JH |
62 | bw = bufio.NewWriterSize(resForkFile, fileCopyBufSize) |
63 | _, err = io.CopyN(resForkFile, r, ffo.rsrcSize()) | |
64 | if err != nil { | |
85767504 JH |
65 | return err |
66 | } | |
7cd900d6 | 67 | if err := bw.Flush(); err != nil { |
ba29c43b JH |
68 | return err |
69 | } | |
7cd900d6 JH |
70 | } |
71 | return nil | |
72 | } | |
ba29c43b | 73 | |
7cd900d6 JH |
74 | func sendFile(w io.Writer, r io.Reader, offset int) (err error) { |
75 | br := bufio.NewReader(r) | |
76 | if _, err := br.Discard(offset); err != nil { | |
77 | return err | |
78 | } | |
85767504 | 79 | |
7cd900d6 JH |
80 | rSendBuffer := make([]byte, 1024) |
81 | for { | |
82 | var bytesRead int | |
83 | ||
84 | if bytesRead, err = br.Read(rSendBuffer); err == io.EOF { | |
85 | if _, err := w.Write(rSendBuffer[:bytesRead]); err != nil { | |
86 | return err | |
87 | } | |
88 | return nil | |
89 | } | |
85767504 JH |
90 | if err != nil { |
91 | return err | |
92 | } | |
7cd900d6 JH |
93 | // totalSent += int64(bytesRead) |
94 | ||
95 | // fileTransfer.BytesSent += bytesRead | |
96 | ||
97 | if _, err := w.Write(rSendBuffer[:bytesRead]); err != nil { | |
165b7ac9 JH |
98 | return err |
99 | } | |
85767504 | 100 | } |
9067f234 JH |
101 | } |
102 | ||
103 | func (s *Server) bannerDownload(w io.Writer) error { | |
104 | bannerBytes, err := os.ReadFile(filepath.Join(s.ConfigDir, s.Config.BannerFile)) | |
105 | if err != nil { | |
106 | return err | |
107 | } | |
108 | _, err = w.Write(bannerBytes) | |
7cd900d6 | 109 | |
9067f234 | 110 | return err |
85767504 | 111 | } |