| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // +build !build_with_native_toolchain |
| |
| package pkgfs |
| |
| import ( |
| "path/filepath" |
| "strings" |
| "time" |
| |
| "go.fuchsia.dev/fuchsia/src/lib/thinfs/fs" |
| ) |
| |
| // versionsDirectory lists packages by merkleroot and enables opening packages |
| // by merkleroot. |
| type versionsDirectory struct { |
| unsupportedDirectory |
| |
| fs *Filesystem |
| } |
| |
| func (d *versionsDirectory) Dup() (fs.Directory, error) { |
| return d, nil |
| } |
| |
| func (d *versionsDirectory) Close() error { return nil } |
| |
| func (d *versionsDirectory) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) { |
| name = clean(name) |
| |
| if name == "" { |
| return nil, d, nil, nil |
| } |
| |
| parts := strings.Split(name, "/") |
| |
| if !merklePat.MatchString(parts[0]) { |
| return nil, nil, nil, fs.ErrNotFound |
| } |
| |
| pkg, found := d.fs.index.GetRoot(parts[0]) |
| if !found { |
| return nil, nil, nil, fs.ErrNotFound |
| } |
| |
| pd, err := newPackageDirFromBlob(parts[0], d.fs, d.fs.shouldAllowExecutableOpenByPackageRoot(parts[0], pkg.Name)) |
| if err != nil { |
| return nil, nil, nil, err |
| } |
| |
| if len(parts) > 1 { |
| return pd.Open(filepath.Join(parts[1:]...), flags) |
| } |
| |
| if flags.Create() || flags.Truncate() || flags.Write() || flags.Append() || flags.File() { |
| return nil, nil, nil, fs.ErrNotSupported |
| } |
| |
| return nil, pd, nil, nil |
| } |
| |
| func (d *versionsDirectory) Read() ([]fs.Dirent, error) { |
| roots := d.fs.index.PackageBlobs() |
| |
| dents := make([]fs.Dirent, 0, len(roots)) |
| for _, m := range roots { |
| dents = append(dents, fileDirEnt(m)) |
| } |
| return dents, nil |
| } |
| |
| func (d *versionsDirectory) Stat() (int64, time.Time, time.Time, error) { |
| return 0, d.fs.mountTime, d.fs.mountTime, nil |
| } |