gopkg.in/essentialkaos/ek.v3@v3.5.1/system/user_darwin.go (about)

     1  // +build darwin
     2  
     3  package system
     4  
     5  // ////////////////////////////////////////////////////////////////////////////////// //
     6  //                                                                                    //
     7  //                     Copyright (c) 2009-2016 Essential Kaos                         //
     8  //      Essential Kaos Open Source License <http://essentialkaos.com/ekol?en>         //
     9  //                                                                                    //
    10  // ////////////////////////////////////////////////////////////////////////////////// //
    11  
    12  import (
    13  	"errors"
    14  	"fmt"
    15  	"os/exec"
    16  	"strconv"
    17  	"strings"
    18  	"syscall"
    19  	"time"
    20  )
    21  
    22  // ////////////////////////////////////////////////////////////////////////////////// //
    23  
    24  // getTimes is copy of fsutil.GetTimes
    25  func getTimes(path string) (time.Time, time.Time, time.Time, error) {
    26  	if path == "" {
    27  		return time.Time{}, time.Time{}, time.Time{}, errors.New("Path is empty")
    28  	}
    29  
    30  	var stat = &syscall.Stat_t{}
    31  
    32  	err := syscall.Stat(path, stat)
    33  
    34  	if err != nil {
    35  		return time.Time{}, time.Time{}, time.Time{}, err
    36  	}
    37  
    38  	return time.Unix(int64(stat.Atimespec.Sec), int64(stat.Atimespec.Nsec)),
    39  		time.Unix(int64(stat.Mtimespec.Sec), int64(stat.Mtimespec.Nsec)),
    40  		time.Unix(int64(stat.Ctimespec.Sec), int64(stat.Ctimespec.Nsec)),
    41  		nil
    42  }
    43  
    44  // getUserInfo find user info by name
    45  func getUserInfo(nameOrID string) (*User, error) {
    46  	cmd := exec.Command("dscl", ".", "-read", "/Users/"+nameOrID)
    47  
    48  	out, err := cmd.Output()
    49  
    50  	if err != nil || len(out) == 0 {
    51  		return nil, fmt.Errorf("User with this name %s is not exist", nameOrID)
    52  	}
    53  
    54  	var (
    55  		lineStart = 0
    56  		uid       int
    57  		gid       int
    58  		home      string
    59  		shell     string
    60  	)
    61  
    62  	for i, b := range out {
    63  		if b != '\n' {
    64  			continue
    65  		}
    66  
    67  		// Skip long lines
    68  		if i-lineStart > 128 {
    69  			lineStart = i + 1
    70  			continue
    71  		}
    72  
    73  		line := string(out[lineStart:i])
    74  
    75  		lineStart = i + 1
    76  
    77  		sepIndex := strings.Index(line, ":")
    78  
    79  		if sepIndex == -1 {
    80  			continue
    81  		}
    82  
    83  		rec := line[0:sepIndex]
    84  
    85  		switch rec {
    86  		case "UniqueID":
    87  			uid, _ = strconv.Atoi(line[sepIndex+2:])
    88  		case "PrimaryGroupID":
    89  			gid, _ = strconv.Atoi(line[sepIndex+2:])
    90  		case "NFSHomeDirectory":
    91  			home = line[sepIndex+2:]
    92  		case "UserShell":
    93  			shell = line[sepIndex+2:]
    94  		}
    95  	}
    96  
    97  	return &User{
    98  		Name:     nameOrID,
    99  		UID:      uid,
   100  		GID:      gid,
   101  		HomeDir:  home,
   102  		Shell:    shell,
   103  		RealName: nameOrID,
   104  		RealUID:  uid,
   105  		RealGID:  gid,
   106  	}, nil
   107  }