diff options
Diffstat (limited to 'file/file.go')
| -rw-r--r-- | file/file.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/file/file.go b/file/file.go index f8fa2839..16067161 100644 --- a/file/file.go +++ b/file/file.go @@ -3,6 +3,8 @@ package file import ( "io/ioutil" "os" + "path/filepath" + "strings" "github.com/pkg/errors" @@ -43,3 +45,51 @@ func ReadDir(path string) ([]string, error) { } return nil, errors.New("file is not a directory") } + +// Write a +func Write(filename string, content []byte) error { + err := assertPathInWD(filename) + if err != nil { + return errors.Wrapf(err, "failed to open %s", filename) + } + + fi, err := os.Stat(filename) + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "failed to stat %s", filename) + } + mode := os.FileMode(0644) + if fi != nil { + mode = fi.Mode() + } + inFile, err := fs.OpenFile(filename, os.O_RDWR|os.O_CREATE, mode) + if err != nil { + return errors.Wrapf(err, "failed to open %s", filename) + } + n, err := inFile.Write(content) + if err != nil { + return errors.Wrapf(err, "failed to write %s", filename) + } + if n != len(content) { + return errors.Wrapf(err, "short write on %s (%d bytes)", filename, n) + } + return nil +} + +func assertPathInWD(filename string) error { + wd, err := os.Getwd() + if err != nil { + return err + } + f, err := filepath.Abs(filename) + if err != nil { + return err + } + r, err := filepath.Rel(wd, f) + if err != nil { + return err + } + if strings.HasPrefix(r, "..") { + return errors.Errorf("path %s not contained by working directory %s (rel: %s)", filename, wd, r) + } + return nil +} |
