forked from ltpquang/goadb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsync_client.go
100 lines (85 loc) · 2.5 KB
/
sync_client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package adb
import (
"io"
"os"
"time"
"github.com/Alpa-1/goadb/errors"
"github.com/Alpa-1/goadb/wire"
)
var zeroTime = time.Unix(0, 0).UTC()
func stat(conn *wire.SyncConn, path string) (*DirEntry, error) {
if err := conn.SendOctetString("STAT"); err != nil {
return nil, err
}
if err := conn.SendBytes([]byte(path)); err != nil {
return nil, err
}
id, err := conn.ReadStatus("stat")
if err != nil {
return nil, err
}
if id != "STAT" {
return nil, errors.Errorf(errors.AssertionError, "expected stat ID 'STAT', but got '%s'", id)
}
return readStat(conn)
}
func listDirEntries(conn *wire.SyncConn, path string) (entries *DirEntries, err error) {
if err = conn.SendOctetString("LIST"); err != nil {
return
}
if err = conn.SendBytes([]byte(path)); err != nil {
return
}
return &DirEntries{scanner: conn}, nil
}
func receiveFile(conn *wire.SyncConn, path string) (io.ReadCloser, error) {
if err := conn.SendOctetString("RECV"); err != nil {
return nil, err
}
if err := conn.SendBytes([]byte(path)); err != nil {
return nil, err
}
return newSyncFileReader(conn)
}
// sendFile returns a WriteCloser than will write to the file at path on device.
// The file will be created with permissions specified by mode.
// The file's modified time will be set to mtime, unless mtime is 0, in which case the time the writer is
// closed will be used.
func sendFile(conn *wire.SyncConn, path string, mode os.FileMode, mtime time.Time) (io.WriteCloser, error) {
if err := conn.SendOctetString("SEND"); err != nil {
return nil, err
}
pathAndMode := encodePathAndMode(path, mode)
if err := conn.SendBytes(pathAndMode); err != nil {
return nil, err
}
return newSyncFileWriter(conn, mtime), nil
}
func readStat(s wire.SyncScanner) (entry *DirEntry, err error) {
mode, err := s.ReadFileMode()
if err != nil {
err = errors.WrapErrf(err, "error reading file mode: %v", err)
return
}
size, err := s.ReadInt32()
if err != nil {
err = errors.WrapErrf(err, "error reading file size: %v", err)
return
}
mtime, err := s.ReadTime()
if err != nil {
err = errors.WrapErrf(err, "error reading file time: %v", err)
return
}
// adb doesn't indicate when a file doesn't exist, but will return all zeros.
// Theoretically this could be an actual file, but that's very unlikely.
if mode == os.FileMode(0) && size == 0 && mtime == zeroTime {
return nil, errors.Errorf(errors.FileNoExistError, "file doesn't exist")
}
entry = &DirEntry{
Mode: mode,
Size: size,
ModifiedAt: mtime,
}
return
}