func readStat(s wire.SyncScanner) (entry *DirEntry, err error) { mode, err := s.ReadFileMode() if err != nil { err = util.WrapErrf(err, "error reading file mode: %v", err) return } size, err := s.ReadInt32() if err != nil { err = util.WrapErrf(err, "error reading file size: %v", err) return } mtime, err := s.ReadTime() if err != nil { err = util.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, util.Errorf(util.FileNoExistError, "file doesn't exist") } entry = &DirEntry{ Mode: mode, Size: size, ModifiedAt: mtime, } return }
func readLinkRecursively(device DeviceClient, path string, logEntry *LogEntry) (string, *goadb.DirEntry, error) { var result bytes.Buffer currentDepth := 0 fmt.Fprintf(&result, "attempting to resolve %s if it's a symlink\n", path) entry, err := device.Stat(path, logEntry) if err != nil { return "", nil, err } for entry.Mode&os.ModeSymlink == os.ModeSymlink { if currentDepth > MaxLinkResolveDepth { return "", nil, ErrLinkTooDeep } currentDepth++ fmt.Fprintln(&result, path) path, err = readLink(device, path) if err != nil { return "", nil, util.WrapErrf(err, "reading link: %s", result.String()) } fmt.Fprintln(&result, " ➜", path) entry, err = device.Stat(path, logEntry) if err != nil { return "", nil, util.WrapErrf(err, "stating %s: %s", path, result.String()) } } return path, entry, nil }
// read reads the file from the device into the buffer. func (f *FileBuffer) loadFromDevice(logEntry *LogEntry) error { stream, err := f.Client.OpenRead(f.Path, logEntry) if err != nil { return util.WrapErrf(err, "error opening file stream on device") } defer stream.Close() data, err := ioutil.ReadAll(stream) if err != nil { return util.WrapErrf(err, "error reading data from file (after reading %d bytes)", len(data)) } f.buffer = data return nil }
// dialDevice switches the connection to communicate directly with the device // by requesting the transport defined by the DeviceDescriptor. func (c *DeviceClient) dialDevice() (*wire.Conn, error) { conn, err := c.config.Dialer.Dial() if err != nil { return nil, err } req := fmt.Sprintf("host:%s", c.descriptor.getTransportDescriptor()) if err = wire.SendMessageString(conn, req); err != nil { conn.Close() return nil, util.WrapErrf(err, "error connecting to device '%s'", c.descriptor) } if err = wire.ReadStatusFailureAsError(conn, req); err != nil { conn.Close() return nil, err } return conn, nil }