blob: 4380290212f2db6fcdd5ca5bd7c9baeac1ce1fd6 [file] [log] [blame]
David K. Bainbridge528b3182017-01-23 08:51:59 -08001// Copyright 2013 Canonical Ltd.
2// Licensed under the LGPLv3, see LICENCE file for details.
3
4// +build !windows
5
6package utils
7
8import (
9 "fmt"
10 "os"
11 "os/user"
12 "strconv"
13 "strings"
14
15 "github.com/juju/errors"
16)
17
18func homeDir(userName string) (string, error) {
19 u, err := user.Lookup(userName)
20 if err != nil {
21 return "", errors.NewUserNotFound(err, "no such user")
22 }
23 return u.HomeDir, nil
24}
25
26// MoveFile atomically moves the source file to the destination, returning
27// whether the file was moved successfully. If the destination already exists,
28// it returns an error rather than overwrite it.
29//
30// On unix systems, an error may occur with a successful move, if the source
31// file location cannot be unlinked.
32func MoveFile(source, destination string) (bool, error) {
33 err := os.Link(source, destination)
34 if err != nil {
35 return false, err
36 }
37 err = os.Remove(source)
38 if err != nil {
39 return true, err
40 }
41 return true, nil
42}
43
44// ReplaceFile atomically replaces the destination file or directory
45// with the source. The errors that are returned are identical to
46// those returned by os.Rename.
47func ReplaceFile(source, destination string) error {
48 return os.Rename(source, destination)
49}
50
51// MakeFileURL returns a file URL if a directory is passed in else it does nothing
52func MakeFileURL(in string) string {
53 if strings.HasPrefix(in, "/") {
54 return "file://" + in
55 }
56 return in
57}
58
59// ChownPath sets the uid and gid of path to match that of the user
60// specified.
61func ChownPath(path, username string) error {
62 u, err := user.Lookup(username)
63 if err != nil {
64 return fmt.Errorf("cannot lookup %q user id: %v", username, err)
65 }
66 uid, err := strconv.Atoi(u.Uid)
67 if err != nil {
68 return fmt.Errorf("invalid user id %q: %v", u.Uid, err)
69 }
70 gid, err := strconv.Atoi(u.Gid)
71 if err != nil {
72 return fmt.Errorf("invalid group id %q: %v", u.Gid, err)
73 }
74 return os.Chown(path, uid, gid)
75}