2015-04-12 20:34:20 +00:00
|
|
|
// TODO(z): Implement send.
|
|
|
|
package goadb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2015-05-03 15:12:53 +00:00
|
|
|
"os"
|
|
|
|
"time"
|
2015-04-12 20:34:20 +00:00
|
|
|
|
2015-07-12 06:18:58 +00:00
|
|
|
"github.com/zach-klippenstein/goadb/util"
|
2015-04-12 20:34:20 +00:00
|
|
|
"github.com/zach-klippenstein/goadb/wire"
|
|
|
|
)
|
|
|
|
|
2015-05-03 15:12:53 +00:00
|
|
|
var zeroTime = time.Unix(0, 0).UTC()
|
|
|
|
|
2015-04-12 20:34:20 +00:00
|
|
|
func stat(conn *wire.SyncConn, path string) (*DirEntry, error) {
|
|
|
|
if err := conn.SendOctetString("STAT"); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err := conn.SendString(path); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
id, err := conn.ReadOctetString()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if id != "STAT" {
|
2015-07-12 06:18:58 +00:00
|
|
|
return nil, util.Errorf(util.AssertionError, "expected stat ID 'STAT', but got '%s'", id)
|
2015-04-12 20:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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.SendString(path); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-29 17:23:51 +00:00
|
|
|
return &DirEntries{scanner: conn}, nil
|
2015-04-12 20:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func receiveFile(conn *wire.SyncConn, path string) (io.ReadCloser, error) {
|
|
|
|
if err := conn.SendOctetString("RECV"); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err := conn.SendString(path); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return newSyncFileReader(conn), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func readStat(s wire.SyncScanner) (entry *DirEntry, err error) {
|
|
|
|
mode, err := s.ReadFileMode()
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
err = util.WrapErrf(err, "error reading file mode: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
size, err := s.ReadInt32()
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
err = util.WrapErrf(err, "error reading file size: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
mtime, err := s.ReadTime()
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
err = util.WrapErrf(err, "error reading file time: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-05-03 15:12:53 +00:00
|
|
|
// 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 {
|
2015-07-12 06:18:58 +00:00
|
|
|
return nil, util.Errorf(util.FileNoExistError, "file doesn't exist")
|
2015-05-03 15:12:53 +00:00
|
|
|
}
|
|
|
|
|
2015-04-12 20:34:20 +00:00
|
|
|
entry = &DirEntry{
|
|
|
|
Mode: mode,
|
|
|
|
Size: size,
|
|
|
|
ModifiedAt: mtime,
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|