1// Copyright 2016 Keybase Inc. All rights reserved.
2// Use of this source code is governed by a BSD
3// license that can be found in the LICENSE file.
4
5package libdokan
6
7import (
8	"runtime/pprof"
9
10	"github.com/keybase/client/go/kbfs/dokan"
11	"github.com/keybase/client/go/kbfs/libfs"
12	"golang.org/x/net/context"
13)
14
15// TODO: Also have a file for CPU profiles.
16
17// ProfileList is a node that can list all of the available profiles.
18type ProfileList struct {
19	fs *FS
20	emptyFile
21}
22
23// GetFileInformation for dokan.
24func (ProfileList) GetFileInformation(ctx context.Context, fi *dokan.FileInfo) (st *dokan.Stat, err error) {
25	return defaultDirectoryInformation()
26}
27
28// open tries to open a file.
29func (pl ProfileList) open(ctx context.Context, oc *openContext, path []string) (dokan.File, dokan.CreateStatus, error) {
30	if len(path) == 0 {
31		return oc.returnDirNoCleanup(ProfileList{})
32	}
33	if len(path) > 1 || !libfs.IsSupportedProfileName(path[0]) {
34		return nil, 0, dokan.ErrObjectNameNotFound
35	}
36	f := libfs.ProfileGet(path[0])
37	if f == nil {
38		return nil, 0, dokan.ErrObjectNameNotFound
39	}
40	return oc.returnFileNoCleanup(&SpecialReadFile{read: f, fs: pl.fs})
41}
42
43// FindFiles does readdir for dokan.
44func (ProfileList) FindFiles(ctx context.Context, fi *dokan.FileInfo, ignored string, callback func(*dokan.NamedStat) error) (err error) {
45	// TODO: eventually this should use `libfs.ListProfileNames`, but
46	// first we have to figure out how to use the dokan API to handle
47	// the timed profiles (i.e., only read them once on open, and not
48	// trigger the timed wait on every read).
49	profiles := pprof.Profiles()
50	var ns dokan.NamedStat
51	ns.FileAttributes = dokan.FileAttributeReadonly
52	for _, p := range profiles {
53		ns.Name = p.Name()
54		if !libfs.IsSupportedProfileName(ns.Name) {
55			continue
56		}
57		err := callback(&ns)
58		if err != nil {
59			return err
60		}
61	}
62	return nil
63}
64