Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fallback to getpwuid when HOME env var not set #547

Merged
merged 1 commit into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ else
endif

# targets
build-all: build-darwin build-freebsd build-linux build-netbsd build-openbsd build-windows
build-all:
build-darwin build-freebsd build-linux build-netbsd build-openbsd build-windows

build-darwin: build-darwin-amd64 build-darwin-arm64
build-darwin:
build-darwin-amd64 build-darwin-arm64

build-darwin-amd64:
GOOS=darwin GOARCH=amd64 make build-binary
Expand All @@ -54,7 +56,8 @@ build-freebsd-amd64:
build-freebsd-arm:
GOOS=freebsd GOARCH=arm make build-binary

build-linux: build-linux-386 build-linux-amd64 build-linux-arm build-linux-arm64
build-linux:
build-linux-386 build-linux-amd64 build-linux-arm build-linux-arm64

build-linux-386:
GOOS=linux GOARCH=386 make build-binary
Expand All @@ -68,7 +71,8 @@ build-linux-arm:
build-linux-arm64:
GOOS=linux GOARCH=arm64 make build-binary

build-netbsd: build-netbsd-386 build-netbsd-amd64 build-netbsd-arm
build-netbsd:
build-netbsd-386 build-netbsd-amd64 build-netbsd-arm

build-netbsd-386:
GOOS=netbsd GOARCH=386 make build-binary
Expand All @@ -79,7 +83,8 @@ build-netbsd-amd64:
build-netbsd-arm:
GOOS=netbsd GOARCH=arm make build-binary

build-openbsd: build-openbsd-386 build-openbsd-amd64 build-openbsd-arm build-openbsd-arm64
build-openbsd:
build-openbsd-386 build-openbsd-amd64 build-openbsd-arm build-openbsd-arm64

build-openbsd-386:
GOOS=openbsd GOARCH=386 make build-binary
Expand All @@ -102,7 +107,7 @@ build-windows-amd64:
GOOS=windows GOARCH=amd64 make build-binary-windows

build-binary:
CGO_ENABLED="0" GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -v \
CGO_ENABLED="1" GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -v \
-ldflags "${LD_FLAGS} -X ${REPO}/pkg/version.OS=$(GOOS) -X ${REPO}/pkg/version.Arch=$(GOARCH)" \
-o ${BUILD_DIR}/$(BINARY_NAME)-$(GOOS)-$(GOARCH)

Expand Down
23 changes: 4 additions & 19 deletions cmd/legacy/logfile/logfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package logfile

import (
"fmt"
"os"
"path/filepath"

"github.com/wakatime/wakatime-cli/pkg/config"
"github.com/wakatime/wakatime-cli/pkg/vipertools"

"github.com/mitchellh/go-homedir"
Expand Down Expand Up @@ -41,24 +41,9 @@ func LoadParams(v *viper.Viper) (Params, error) {
}, nil
}

var (
home string
err error
)

home, exists := os.LookupEnv("WAKATIME_HOME")
if exists && home != "" {
home, err = homedir.Expand(home)
if err != nil {
return Params{},
ErrLogFile(fmt.Sprintf("failed parsing WAKATIME_HOME environment variable: %s", err))
}
} else {
home, err = os.UserHomeDir()
if err != nil {
return Params{},
ErrLogFile(fmt.Sprintf("failed getting user's home directory: %s", err))
}
home := config.WakaHomeDir()
if home == "" {
return Params{}, ErrLogFile("failed getting user's home directory")
}

return Params{
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/transport_windows.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build windows
//go:build windows
alanhamlett marked this conversation as resolved.
Show resolved Hide resolved

package api

Expand Down
25 changes: 17 additions & 8 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/wakatime/wakatime-cli/pkg/log"
"github.com/wakatime/wakatime-cli/pkg/pwd"
"github.com/wakatime/wakatime-cli/pkg/vipertools"

"github.com/mitchellh/go-homedir"
Expand Down Expand Up @@ -104,20 +105,28 @@ func FilePath(v *viper.Viper) (string, error) {
return p, nil
}

home := WakaHomeDir()
if home == "" {
return "", errors.New("failed getting user's home directory")
}

return filepath.Join(home, defaultFile), nil
}

// WakaHomeDir returns the current user's home directory.
func WakaHomeDir() string {
alanhamlett marked this conversation as resolved.
Show resolved Hide resolved
home, exists := os.LookupEnv("WAKATIME_HOME")
if exists && home != "" {
p, err := homedir.Expand(home)
if err != nil {
return "", fmt.Errorf("failed parsing WAKATIME_HOME environment variable: %s", err)
home, err := homedir.Expand(home)
if err == nil {
return home
}

return filepath.Join(p, defaultFile), nil
}

home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed getting user's home directory: %s", err)
if err == nil {
return home
}

return filepath.Join(home, defaultFile), nil
return pwd.Getpwuid(uint32(os.Getuid())).Dir
}
20 changes: 5 additions & 15 deletions pkg/offline/offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package offline

import (
"encoding/json"
"errors"
"fmt"
"math"
"net/http"
"os"
"path/filepath"
"time"

"github.com/wakatime/wakatime-cli/pkg/config"
"github.com/wakatime/wakatime-cli/pkg/heartbeat"
"github.com/wakatime/wakatime-cli/pkg/log"

"github.com/mitchellh/go-homedir"
bolt "go.etcd.io/bbolt"
)

Expand All @@ -37,19 +37,9 @@ const (

// QueueFilepath returns the path for offline queue db file.
func QueueFilepath() (string, error) {
home, exists := os.LookupEnv("WAKATIME_HOME")
if exists && home != "" {
p, err := homedir.Expand(home)
if err != nil {
return "", fmt.Errorf("failed parsing WAKATIME_HOME environment variable: %s", err)
}

return filepath.Join(p, dbFilename), nil
}

home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed getting user's home directory: %s", err)
home := config.WakaHomeDir()
if home == "" {
return "", errors.New("failed getting user's home directory")
}

return filepath.Join(home, dbFilename), nil
Expand Down
52 changes: 52 additions & 0 deletions pkg/pwd/pwd_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build !windows

/*
Package pwd is a thin wrapper of C library <pwd.h>.
This is designed as thin as possible, but aimed to be thread-safe.
*/
package pwd

/*
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>

// While getpwuid requires "uid_t" according to man page, it actually requires
// "__uit_t" in the source code, that causes cgo compile error ("uid_t" is
// actually aliased to __uid_t).
// Unlike Linux, getpwuid on Mac OS X requires uid_t properly. For compatibility,
// we use a C function as a bridge here.
struct passwd *getpwuid_aux(unsigned int uid) {
return getpwuid((uid_t)uid);
}
*/
import "C"

// Passwd represents an entry of the user database defined in <pwd.h>
type Passwd struct {
Name string // user name
Passwd string // user password
UID uint32 // user ID
GID uint32 // group ID
Gecos string // real name
Dir string // home directory
Shell string // shell program
}

// Getpwuid searches the user database for an entry with a matching uid.
func Getpwuid(uid uint32) *Passwd {
cpw := C.getpwuid_aux(C.uint(uid))
if cpw != nil {
return &Passwd{
Name: C.GoString(cpw.pw_name),
Passwd: C.GoString(cpw.pw_passwd),
UID: uint32(cpw.pw_uid),
GID: uint32(cpw.pw_uid),
Gecos: C.GoString(cpw.pw_gecos),
Dir: C.GoString(cpw.pw_dir),
Shell: C.GoString(cpw.pw_shell),
}
}

return nil
}
23 changes: 23 additions & 0 deletions pkg/pwd/pwd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build !windows

package pwd_test

import (
"testing"

"github.com/wakatime/wakatime-cli/pkg/pwd"

"github.com/stretchr/testify/assert"
)

func TestGetpwuid(t *testing.T) {
result := pwd.Getpwuid(0)
assert.NotNil(t, result)

assert.Equal(t, result.Name, "root")

assert.Equal(t, result.UID, uint32(0))

result = pwd.Getpwuid(1234556789) // uid which does not exit probably
assert.Nil(t, result)
}
19 changes: 19 additions & 0 deletions pkg/pwd/pwd_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build windows

package pwd

// Passwd represents an entry of the user database defined in <pwd.h>
type Passwd struct {
Name string // user name
Passwd string // user password
UID uint32 // user ID
GID uint32 // group ID
Gecos string // real name
Dir string // home directory
Shell string // shell program
}

// Getpwuid searches the user database for an entry with a matching uid.
func Getpwuid(uid uint32) *Passwd {
return &Passwd{}
}