repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / send / protocols / sftp
Antonio Mika  ·  2025-03-12

writer.go

 1package sftp
 2
 3import (
 4	"fmt"
 5	"io"
 6	"sync"
 7
 8	"github.com/picosh/pico/pkg/send/utils"
 9)
10
11type buffer struct {
12	buf []byte
13	m   sync.Mutex
14	off int
15}
16
17func (b *buffer) WriteAt(p []byte, pos int64) (n int, err error) {
18	pLen := len(p)
19	expLen := pos + int64(pLen)
20	b.m.Lock()
21	defer b.m.Unlock()
22	if int64(len(b.buf)) < expLen {
23		if int64(cap(b.buf)) < expLen {
24			newBuf := make([]byte, expLen)
25			copy(newBuf, b.buf)
26			b.buf = newBuf
27		}
28		b.buf = b.buf[:expLen]
29	}
30	copy(b.buf[pos:], p)
31	return pLen, nil
32}
33
34func (b *buffer) Read(p []byte) (n int, err error) {
35	b.m.Lock()
36	defer b.m.Unlock()
37	if len(b.buf) <= b.off {
38		if len(p) == 0 {
39			return 0, nil
40		}
41		return 0, io.EOF
42	}
43	n = copy(p, b.buf[b.off:])
44	b.off += n
45	return n, nil
46}
47
48func (b *buffer) Close() error {
49	b.buf = []byte{}
50	return nil
51}
52
53type fakeWrite struct {
54	fileEntry *utils.FileEntry
55	handler   *handler
56	buf       *buffer
57}
58
59func (f fakeWrite) WriteAt(p []byte, off int64) (int, error) {
60	return f.buf.WriteAt(p, off)
61}
62
63func (f fakeWrite) Close() error {
64	msg, err := f.handler.writeHandler.Write(f.handler.session, f.fileEntry)
65	if err != nil {
66		errMsg := fmt.Sprintf("%s\r\n", err.Error())
67		_, err = f.handler.session.Stderr().Write([]byte(errMsg))
68	}
69	if msg != "" {
70		nMsg := fmt.Sprintf("%s\r\n", msg)
71		_, err = f.handler.session.Stderr().Write([]byte(nMsg))
72	}
73	f.buf.Close()
74	return err
75}