diff options
| -rw-r--r-- | cmd/cmd.go | 57 | ||||
| -rw-r--r-- | cmd/errors.go | 42 | ||||
| -rw-r--r-- | cmd/flag.go | 154 | ||||
| -rw-r--r-- | cmd/format.go | 0 | ||||
| -rw-r--r-- | cmd/helper.go | 20 | ||||
| -rw-r--r-- | cmd/info.go | 72 | ||||
| -rw-r--r-- | cmd/output.go | 201 | ||||
| -rw-r--r-- | cmd/strings.go | 34 | ||||
| -rw-r--r-- | cmd/templates.go | 0 | ||||
| -rw-r--r-- | cmd/version.go | 62 | ||||
| -rw-r--r-- | ext4/ext4.go | 35 | ||||
| -rw-r--r-- | util/users.go | 50 | ||||
| -rw-r--r-- | util/util.go | 11 |
13 files changed, 711 insertions, 27 deletions
@@ -17,34 +17,59 @@ * the License. */ -// Package cmd is the common library for writing fscrypt command line binaries. +// Package cmd is the common library for writing command line binaries. // This package is mainly a wrapper around github.com/urfave/cli, but provides // additional support to make the usage look similar to the man page. // -// The main componets are the `Cmd` and `Flag` types which can be used to define -// a top-level command with many potential subcommands. This package also -// presents a smaller interface than urfave/cli, making it easier to use for -// other commands. +// The main componets are the `Cmd`, `Argument`, and `Flag` types which can be +// used to define a top-level command with many potential subcommands. This +// package also presents a smaller interface than urfave/cli, making it easier +// to use for other commands. package cmd +import "os" + // Command represents a command with many potential top-level commands. This is -// trand -type Cmd struct { - Name string +// transformed into a cli.Command in Run(). +type Command struct { + Name string UsageLines []string - SubCmds []Cmd - Arguments []Argument - Flags []cli.Flag - Man *ManEntry - Action CommandFunc + SubCmds []*Command + Arguments []*Argument + Flags []Flag + ManPage *ManEntry + Action CommandFunc } +// Argument represents a parameter passed to a function. It has an optional +// usage explains how it should be used. type Argument struct { - Name string - Usage string + ArgName string + Usage string } +// ManEntry represents an entry in a man page with a name, section, and title. type ManEntry struct { - Title string + Name string Section int + Title string +} + +// CommandFunc contains the implementation of a command. The provided args have +// the flags and leading command names removed. If a normal error is returned, +// it is printed out (with an optional explanation) and exits with FailureCode. +// If a usage error is returned, it is printed out with the command's usage and +// exits with UsageFailureCode. Returning nil causes an exit with success. +type CommandFunc func(args []string) error + +// Run executes the command with os.Args, equivalent to c.RunArgs(os.Args). +func (c *Command) Run() { + c.RunArgs(os.Args) +} + +// RunArgs executes the command with the provided args. If the Name argument is +// empty, args[0]'s basename is used instead. If the command fails, this method +// will not return. +func (c *Command) RunArgs(args []string) { + // TODO(joerichey): Implement conversion to cli.Command } diff --git a/cmd/errors.go b/cmd/errors.go new file mode 100644 index 0000000..07a1d05 --- /dev/null +++ b/cmd/errors.go @@ -0,0 +1,42 @@ +/* + * errors.go - Common errors and error handling + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package cmd + +import ( + "github.com/pkg/errors" + + "github.com/google/fscrypt/util" +) + +// Common errors used across commands +var ( + ErrUnknownVersion = errors.New("unknown (missing version tag)") + ErrCanceled = errors.New("operation canceled by user") + ErrMustForce = errors.New("operation must be forced") + ErrNotRoot = errors.New("operation must be run as root") +) + +// CheckIfRoot returns an error if the current user is not the root user. +func CheckIfRoot() error { + if id := util.CurrentUserID(); id != 0 { + return errors.Wrapf(ErrNotRoot, "user %s", util.GetUser(id).Username) + } + return nil +} diff --git a/cmd/flag.go b/cmd/flag.go new file mode 100644 index 0000000..18b2a4c --- /dev/null +++ b/cmd/flag.go @@ -0,0 +1,154 @@ +/*
+ * flag.go - Definitions for flags and associated formatting functions.
+ *
+ * Copyright 2017 Google Inc.
+ * Author: Joe Richey (joerichey@google.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package cmd
+
+import (
+ "flag"
+ "fmt"
+ "strconv"
+ "time"
+)
+
+// Flag represents a command line flag that can be passed to a command. Note
+// that Flag also conforms to the cli.Flag interface. The Name, ArgName, and
+// Usage of the Flag can be used to format it in a short form with ShortFormat,
+// or in it's full format with the String method.
+type Flag interface {
+ fmt.Stringer
+ Apply(*flag.FlagSet)
+ GetName() string
+ GetArgName() string
+ GetUsage() string
+}
+
+// How the first usage line for a Flag should appear. We have two formats:
+// --name
+// --name=<argName>
+// The <argName> appears if the prettyFlag's GetArgName() method returns a
+// non-empty string. The returned string from shortFormat() does not include
+// any leading or trailing whitespace.
+func ShortFormat(f Flag) string {
+ if argName := f.GetArgName(); argName != "" {
+ return fmt.Sprintf("--%s=%s", f.GetName(), argName)
+ }
+ return fmt.Sprintf("--%s", f.GetName())
+}
+
+// How our flags should appear when displaying their usage. An example would be:
+// --help
+// Prints help screen for commands and subcommands.
+//
+// If defaultString is specified, this if appended to the usage. Example:
+//
+// --legacy
+// Allow for support of older kernels with ext4 (before v4.8) and
+// F2FS (before v4.6) filesystems. (default: true)
+func longFormat(f Flag, defaultString ...string) string {
+ usage := f.GetUsage()
+ if len(defaultString) > 0 {
+ usage += fmt.Sprintf(" (default: %v)", defaultString[0])
+ }
+
+ usage = wrapText(usage, 2)
+ return fmt.Sprintf("\t%s\n%s", ShortFormat(f), usage)
+}
+
+// BoolFlag is a Flag of type bool.
+type BoolFlag struct {
+ Name string
+ Usage string
+ Default bool
+ Value bool
+}
+
+func (f *BoolFlag) String() string {
+ if !f.Default {
+ return longFormat(f)
+ }
+ return longFormat(f, strconv.FormatBool(f.Default))
+}
+
+// Apply uses BoolFlag's value to set a flag.BoolVar on the FlagSet.
+func (f *BoolFlag) Apply(s *flag.FlagSet) { s.BoolVar(&f.Value, f.Name, f.Default, f.Usage) }
+
+// GetName just returns BoolFlag's name.
+func (f *BoolFlag) GetName() string { return f.Name }
+
+// GetArgName returns nothing as BoolFlags don't have an argument name.
+func (f *BoolFlag) GetArgName() string { return "" }
+
+// GetUsage returns BoolFlag's usage.
+func (f *BoolFlag) GetUsage() string { return f.Usage }
+
+// StringFlag is a Flag of type string.
+type StringFlag struct {
+ Name string
+ ArgName string
+ Usage string
+ Default string
+ Value string
+}
+
+func (f *StringFlag) String() string {
+ if f.Default == "" {
+ return longFormat(f)
+ }
+ return longFormat(f, strconv.Quote(f.Default))
+}
+
+// Apply uses StringFlag's value to set a flag.StringVar on the FlagSet.
+func (f *StringFlag) Apply(s *flag.FlagSet) { s.StringVar(&f.Value, f.Name, f.Default, f.Usage) }
+
+// GetName just returns StringFlag's name.
+func (f *StringFlag) GetName() string { return f.Name }
+
+// GetArgName returns StringFlag's argument name.
+func (f *StringFlag) GetArgName() string { return f.ArgName }
+
+// GetUsage returns StringFlag's usage.
+func (f *StringFlag) GetUsage() string { return f.Usage }
+
+// DurationFlag is a Flag of type time.Duration.
+type DurationFlag struct {
+ Name string
+ ArgName string
+ Usage string
+ Default time.Duration
+ Value time.Duration
+}
+
+func (f *DurationFlag) String() string {
+ if f.Default == 0 {
+ return longFormat(f)
+ }
+ return longFormat(f, f.Default.String())
+}
+
+// Apply uses DurationFlag's value to set a flag.DurationVar on the FlagSet.
+func (f *DurationFlag) Apply(s *flag.FlagSet) { s.DurationVar(&f.Value, f.Name, f.Default, f.Usage) }
+
+// GetName just returns DurationFlag's name.
+func (f *DurationFlag) GetName() string { return f.Name }
+
+// GetArgName returns DurationFlag's argument name.
+func (f *DurationFlag) GetArgName() string { return f.ArgName }
+
+// GetUsage returns DurationFlag's usage.
+func (f *DurationFlag) GetUsage() string { return f.Usage }
diff --git a/cmd/format.go b/cmd/format.go deleted file mode 100644 index e69de29..0000000 --- a/cmd/format.go +++ /dev/null diff --git a/cmd/helper.go b/cmd/helper.go index e69de29..77f6b2f 100644 --- a/cmd/helper.go +++ b/cmd/helper.go @@ -0,0 +1,20 @@ +/* + * helper.go - Helper functions for using the cmd package + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + + package cmd diff --git a/cmd/info.go b/cmd/info.go new file mode 100644 index 0000000..6257ec1 --- /dev/null +++ b/cmd/info.go @@ -0,0 +1,72 @@ +/* + * info.go - Global information about the program. + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package cmd + +import ( + "time" + + "github.com/urfave/cli" +) + +// Info contains the global info for the functions. +var Info struct { + // Program is the name of the top-level program being executed. If not + // set it is set in cmd.RunArgs(). + Program string + // VersionTag (if set) will be displayed in both the short and long + // version output. VersionTag is not parsed, so any string will work. + VersionTag string + // BuildTime (if set) will be displayed in the long version output. + BuildTime time.Time + // Authors (if non-empty) are displayed in the long version output. + Authors []cli.Author + // Copyright (if set) is displayed in the long version output. + Copyright string +} + +// Linker flags of the form "-X cmd.Info.VersionTag=1.0" do not work, so we use +// these separate files so variables can be set from the Makefile. +var ( + versionTag string + buildTime string +) + +// fscrypt specific initialization +func init() { + Info.VersionTag = versionTag + Info.BuildTime = buildTime + Info.Authors = []cli.Author{{ + Name: "Joe Richey", + Email: "joerichey@google.com", + }} + Info.Copyright = `Copyright 2017 Google, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.` +} diff --git a/cmd/output.go b/cmd/output.go new file mode 100644 index 0000000..024705d --- /dev/null +++ b/cmd/output.go @@ -0,0 +1,201 @@ +/* + * output.go - Functions for handling command line formatting and output. + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package cmd + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "strings" + "unicode/utf8" + + "github.com/google/fscrypt/util" + "golang.org/x/crypto/ssh/terminal" +) + +var ( + // TabWidth is the number of spaces used to display a tab. + TabWidth = 8 + // LineLength is the maximum length of any output. If not set, the width + // of the terminal be detected and assigned to LineLength. + LineLength int + // FallbackLineLength is the LineLength used if detection fails. By + // default we fall back to punch cards. + FallbackLineLength = 80 + // MaxLineLength is the maximum allowed detected value of LineLength. + MaxLineLength = 120 + // Output is the io.Writer all commands should use for their normal + // output (errors should just return the appropriate error). If not set, + // it is automatically set based on the provided flags. + Output io.Writer + // HelpFlag writes help to Stdout + HelpFlag = &BoolFlag{ + Name: "help", + Usage: "Prints this 🧗help text for commands and subcommands", + } + // VerboseFlag indicates that all logging output should be printed. + VerboseFlag = &BoolFlag{ + Name: "verbose", + Usage: "Prints additional debug messages.", + } + // QuietFlag indicates that no normal output should be printed. + QuietFlag = &BoolFlag{ + Name: "quiet", + Usage: `Prints nothing except for errors and uses any default + option instead of prompting the user.`, + } + // ForceFlag indicates that the operation should proceed if possible. + ForceFlag = &BoolFlag{ + Name: "force", + Usage: `Print no confirmation prompts or warnings and + automatically proceed with the requested action.`, + } +) + +// Suffixes for questions with a yes or no default +const ( + defaultYesSuffix = "[Y/n]" + defaultNoSuffix = "[y/N]" +) + +// We use the width of the terminal unless we cannot get the width. +func init() { + if LineLength > 0 { + return + } + width, _, err := terminal.GetSize(int(os.Stdout.Fd())) + if err != nil { + LineLength = FallbackLineLength + } else { + LineLength = util.MinInt(width, MaxLineLength) + } +} + +// Takes an input string text, and wraps the text so that each line begins with +// numTabs tabs and ends with a newline (except the last line), and each line +// has length less than lineLength. If the text contains a word which is too +// long, that word gets its own line. +func wrapText(text string, numTabs int) string { + // We use a buffer to format the wrapped text so we get O(n) runtime + var buffer bytes.Buffer + spaceLeft := 0 + maxTextLen := LineLength - numTabs*TabWidth + delimiter := strings.Repeat("\t", numTabs) + for i, word := range strings.Fields(text) { + wordLen := utf8.RuneCountInString(word) + if wordLen >= spaceLeft { + // If no room left, write the word on the next line. + buffer.WriteString("\n") + buffer.WriteString(delimiter) + buffer.WriteString(word) + spaceLeft = maxTextLen - wordLen + } else { + // Write word on this line + buffer.WriteByte(' ') + buffer.WriteString(word) + spaceLeft -= 1 + wordLen + } + } + + return buffer.String() +} + +// Configures the Output and log output io.Writers. Called before running +// commands but after processing flags. +func setupOutput() { + if VerboseFlag.Value { + log.SetOutput(os.Stdout) + } else { + log.SetOutput(ioutil.Discard) + } + if Output != nil { + return + } + if QuietFlag.Value { + Output = ioutil.Discard + } else { + Output = os.Stdout + } +} + +// AskQuestion asks the user a yes or no question. Returning a boolean on a +// successful answer and an error if there was not a response from the user. +// Returns the defaultChoice on empty input (or in quiet mode). +func AskQuestion(question string, defaultChoice bool) (bool, error) { + // If in quiet mode, we just use the default. + if QuietFlag.Value { + return defaultChoice, nil + } + // Loop until failure or valid input. + for { + if defaultChoice { + fmt.Fprintf(Output, "%s %s ", question, defaultYesSuffix) + } else { + fmt.Fprintf(Output, "%s %s ", question, defaultNoSuffix) + } + + input, err := util.ReadLine() + if err != nil { + return false, err + } + + switch strings.ToLower(input) { + case "y", "yes": + return true, nil + case "n", "no": + return false, nil + case "": + return defaultChoice, nil + } + } +} + +// AskConfirmation asks the user for confirmation before performing a specific +// action. An error is returned if the user declines or IO fails. +func AskConfirmation(question, warning string, defaultChoice bool) error { + // All confirmations are "yes" if we are forcing. + if ForceFlag.Value { + return nil + } + + // Defaults of "no" require forcing. + if QuietFlag.Value { + if defaultChoice { + return nil + } + return ErrMustForce + } + + if warning != "" { + fmt.Fprintln(Output, wrapText("WARNING: "+warning, 0)) + } + + confirmed, err := AskQuestion(question, defaultChoice) + if err != nil { + return err + } + if !confirmed { + return ErrCanceled + } + return nil +} diff --git a/cmd/strings.go b/cmd/strings.go new file mode 100644 index 0000000..559c60c --- /dev/null +++ b/cmd/strings.go @@ -0,0 +1,34 @@ +/* + * strings.go - Strings and templates for output formatting + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package cmd + +import ( + "io" + "text/template" +) + +// ExecuteTemplate creates an anonymous template the text, and runs it with the +// provided writer and data. Panics if text has bad format or execution fails. +func ExecuteTemplate(w io.Writer, text string, data interface{}) { + tmpl := template.Must(template.New("").Parse(text)) + if err := tmpl.Execute(w, data); err != nil { + panic(err) + } +} diff --git a/cmd/templates.go b/cmd/templates.go deleted file mode 100644 index e69de29..0000000 --- a/cmd/templates.go +++ /dev/null diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..787e2cd --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,62 @@ +/* + * version.go - Version subcommand that can be added to any binary + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package cmd + +// Templates for use with the version command, which both parse the Info var. +var ( + VersionShortTemplate = "{{.Command}} version {{.VersionTag}}\n" + VersionLongTemplate = VersionShortTemplate + `{{if .Compiled}} +Compiled: + {{.Compiled}} +{{end}}{{if len .Authors}} +Author{{with $length := len .Authors}}{{if ne 1 $length}}s{{end}}{{end}}:{{range .Authors}} + {{.}}{{end}} +{{end}}{{if .Copyright}} +Copyright: + {{.Copyright}} +{{end}}` +) + +// Version is a command which will display either the VersionTag (by default) or +// the full version information (version, copyright, authors). +var Version = &Command{ + Name: "version", + UsageLines: []string{""}, + Flags: []Flag{longFlag}, + Action: versionAction, +} + +// Using longFlag with the version command displays the longer version info. +var longFlag = &BoolFlag{ + Name: "long", + Usage: "Print the detailed version and copyright information.", +} + +func versionAction(_ []string) error { + if Info.VersionTag == "" { + return ErrUnknownVersion + } + if longFlag.Value { + + } else { + + } + return nil +} diff --git a/ext4/ext4.go b/ext4/ext4.go index 7419929..063d68c 100644 --- a/ext4/ext4.go +++ b/ext4/ext4.go @@ -25,6 +25,9 @@ import ( "io" "io/ioutil" "os" + "time" + + "github.com/urfave/cli" ) var ( @@ -77,6 +80,38 @@ func printAndExit(err error, printUsage bool) { } func main() { + // Create our command line application + app := cli.NewApp() + app.Usage = shortUsage + app.Authors = Authors + app.Copyright = apache2GoogleCopyright + + // Grab the version and compilation time passed in from the Makefile. + app.Version = version + app.Compiled, _ = time.Parse(time.UnixDate, buildTime) + app.OnUsageError = onUsageError + + // Setup global flags + cli.HelpFlag = helpFlag + cli.VersionFlag = versionFlag + cli.VersionPrinter = func(c *cli.Context) { + cli.HelpPrinter(c.App.Writer, versionInfoTemplate, c.App) + } + app.Flags = universalFlags + + // We hide the help subcommand so that "fscrypt <command> --help" works + // and "fscrypt <command> help" does not. + app.HideHelp = true + + // Initialize command list and setup all of the commands. + app.Action = defaultAction + app.Commands = []cli.Command{Setup, Encrypt, Unlock, Purge, Status, Metadata} + for i := range app.Commands { + setupCommand(&app.Commands[i]) + } + + app.Run(os.Args) + set.SetOutput(ioutil.Discard) if err := set.Parse(os.Args[1:]); err != nil { printAndExit(err, true) diff --git a/util/users.go b/util/users.go new file mode 100644 index 0000000..92affa8 --- /dev/null +++ b/util/users.go @@ -0,0 +1,50 @@ +/* + * util.go - Functions for dealing with users + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package util + +import ( + "fmt" + "os" + "os/user" + "strconv" +) + +// CurrentUserID returns the uid of the effective user. +func CurrentUserID() int { + return os.Geteuid() +} + +// GetUser returns the user entry corresponding to the provided uid. +func GetUser(uid int) *user.User { + uidString := strconv.Itoa(uid) + foundUser, err := user.LookupId(uidString) + if err != nil { + return &user.User{ + Uid: uidString, + Username: fmt.Sprintf("[uid=%d]", uid), + } + } + return foundUser +} + +// CurrentUser returns the user entry for the effective user. +func CurrentUser() *user.User { + return GetUser(CurrentUserID()) +} diff --git a/util/util.go b/util/util.go index 3de4a1a..9f62b45 100644 --- a/util/util.go +++ b/util/util.go @@ -27,7 +27,6 @@ import ( "bufio" "math" "os" - "os/user" "strconv" "unsafe" ) @@ -117,13 +116,3 @@ func AtoiOrPanic(input string) int { } return i } - -// EffectiveUser returns the user entry corresponding to the effective user. -func EffectiveUser() (*user.User, error) { - return user.LookupId(strconv.Itoa(os.Geteuid())) -} - -// IsUserRoot checks if the effective user is root. -func IsUserRoot() bool { - return os.Geteuid() == 0 -} |