func SelectStorages(dev *mtp.Device, pat string) ([]uint32, error) { sids := mtp.Uint32Array{} err := dev.GetStorageIDs(&sids) if err != nil { return nil, err } re, err := regexp.Compile(pat) if err != nil { return nil, err } filtered := []uint32{} for _, id := range sids.Values { var s mtp.StorageInfo err := dev.GetStorageInfo(id, &s) if err != nil { return nil, err } if !s.IsHierarchical() { log.Printf("skipping non hierarchical storage %q", s.StorageDescription) continue } if re.FindStringIndex(s.StorageDescription) == nil { log.Printf("filtering out storage %q", s.StorageDescription) continue } filtered = append(filtered, id) } return filtered, nil }
// DeviceFs is a simple filesystem interface to an MTP device. It // should be wrapped in a Locking(Raw)FileSystem to make sure it is // threadsafe. The file system assumes the device does not touch the // storage. Arguments are the opened mtp device and a directory for the // backing store. func NewDeviceFSRoot(d *mtp.Device, storages []uint32, options DeviceFsOptions) (nodefs.Node, error) { root := rootNode{Node: nodefs.NewDefaultNode()} fs := &deviceFS{ root: &root, dev: d, options: &options, } root.fs = fs fs.storages = storages if err := d.GetDeviceInfo(&fs.devInfo); err != nil { return nil, err } if !strings.Contains(fs.devInfo.MTPExtension, "android.com") { fs.options.Android = false } if !options.Android { if err := fs.setupClassic(); err != nil { return nil, err } } fs.mungeVfat = make(map[uint32]bool) for _, sid := range fs.storages { var info mtp.StorageInfo if err := fs.dev.GetStorageInfo(sid, &info); err != nil { return nil, err } fs.mungeVfat[sid] = info.IsRemovable() && fs.options.RemovableVFat } return fs.Root(), nil }
// DeviceFs is a simple filesystem interface to an MTP device. It // should be wrapped in a Locking(Raw)FileSystem to make sure it is // threadsafe. The file system assumes the device does not touch the // storage. Arguments are the opened mtp device and a directory for the // backing store. func NewDeviceFs(d *mtp.Device, storages []uint32, options DeviceFsOptions) (*DeviceFs, error) { root := rootNode{} fs := &DeviceFs{root: &root, dev: d, options: &options} root.fs = fs fs.storages = storages err := d.GetDeviceInfo(&fs.devInfo) if err != nil { return fs, nil } if !strings.Contains(fs.devInfo.MTPExtension, "android.com") { fs.options.Android = false } if !options.Android { err = fs.setupClassic() if err != nil { return nil, err } } fs.mungeVfat = make(map[uint32]bool) for _, sid := range fs.storages { var info mtp.StorageInfo if err != nil { return nil, err } fs.mungeVfat[sid] = info.IsRemovable() && fs.options.RemovableVFat } return fs, nil }
// DeviceFs is a simple filesystem interface to an MTP device. It // should be wrapped in a Locking(Raw)FileSystem to make sure it is // threadsafe. The file system assumes the device does not touch the // storage. Arguments are the opened mtp device and a directory for the // backing store. func NewDeviceFs(d *mtp.Device, storages []uint32, options DeviceFsOptions) (*DeviceFs, error) { o := options root := rootNode{} fs := &DeviceFs{root: &root, dev: d, options: &o} root.fs = fs fs.storages = storages err := d.GetDeviceInfo(&fs.devInfo) if err != nil { return fs, nil } if !strings.Contains(fs.devInfo.MTPExtension, "android.com") { return nil, fmt.Errorf("this device has no android.com extensions.") } for _, sid := range fs.storages { var info mtp.StorageInfo err := d.GetStorageInfo(sid, &info) if err != nil { return nil, err } fs.storageInfos = append(fs.storageInfos, info) } return fs, nil }