123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- package caplets
- import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "sync"
- "github.com/evilsocket/islazy/fs"
- )
- var (
- cache = make(map[string]*Caplet)
- cacheLock = sync.Mutex{}
- )
- func List() []*Caplet {
- caplets := make([]*Caplet, 0)
- for _, searchPath := range LoadPaths {
- files, _ := filepath.Glob(searchPath + "/*" + Suffix)
- files2, _ := filepath.Glob(searchPath + "/*/*" + Suffix)
- for _, fileName := range append(files, files2...) {
- if _, err := os.Stat(fileName); err == nil {
- base := strings.Replace(fileName, searchPath+string(os.PathSeparator), "", -1)
- base = strings.Replace(base, Suffix, "", -1)
- if caplet, err := Load(base); err != nil {
- fmt.Fprintf(os.Stderr, "wtf: %v\n", err)
- } else {
- caplets = append(caplets, caplet)
- }
- }
- }
- }
- sort.Slice(caplets, func(i, j int) bool {
- return strings.Compare(caplets[i].Name, caplets[j].Name) == -1
- })
- return caplets
- }
- func Load(name string) (*Caplet, error) {
- cacheLock.Lock()
- defer cacheLock.Unlock()
- if caplet, found := cache[name]; found {
- return caplet, nil
- }
- baseName := name
- names := []string{}
- if !strings.HasSuffix(name, Suffix) {
- name += Suffix
- }
- if !filepath.IsAbs(name) {
- for _, path := range LoadPaths {
- names = append(names, filepath.Join(path, name))
- }
- } else {
- names = append(names, name)
- }
- for _, fileName := range names {
- if stats, err := os.Stat(fileName); err == nil {
- cap := &Caplet{
- Script: newScript(fileName, stats.Size()),
- Name: baseName,
- Scripts: make([]Script, 0),
- }
- cache[name] = cap
- if reader, err := fs.LineReader(fileName); err != nil {
- return nil, fmt.Errorf("error reading caplet %s: %v", fileName, err)
- } else {
- for line := range reader {
- cap.Code = append(cap.Code, line)
- }
- // the caplet has a dedicated folder
- if strings.Contains(baseName, "/") || strings.Contains(baseName, "\\") {
- dir := filepath.Dir(fileName)
- // get all secondary .cap and .js files
- if files, err := ioutil.ReadDir(dir); err == nil && len(files) > 0 {
- for _, f := range files {
- subFileName := filepath.Join(dir, f.Name())
- if subFileName != fileName && (strings.HasSuffix(subFileName, ".cap") || strings.HasSuffix(subFileName, ".js")) {
- if reader, err := fs.LineReader(subFileName); err == nil {
- script := newScript(subFileName, f.Size())
- for line := range reader {
- script.Code = append(script.Code, line)
- }
- cap.Scripts = append(cap.Scripts, script)
- }
- }
- }
- }
- }
- }
- return cap, nil
- }
- }
- return nil, fmt.Errorf("caplet %s not found", name)
- }
|