Esempio n. 1
0
func ls(filename string, longFormat bool) {
	f, err := os.OpenFile(filename, os.O_RDONLY, 0)
	if f == nil {
		fmt.Fprintf(os.Stderr, "ls: cannot access %s: %s\n", filename,
			err.Error())
		os.Exit(1)
	}
	files, err := f.Readdir(-1)
	if files == nil {
		fmt.Fprintf(os.Stderr, "ls: could not get files in %s: %s\n",
			filename, err.Error())
		os.Exit(1)
	}
	for j := 0; j < len(files); j++ {
		if longFormat {
			timeLayout := "Jan 2 15:04"
			gid := files[j].Sys().(*syscall.Stat_t).Gid
			uid := files[j].Sys().(*syscall.Stat_t).Uid
			group, _ := user.LookupId(strconv.Itoa(int(gid)))
			user, _ := user.LookupId(strconv.Itoa(int(uid)))

			fmt.Printf("%s\t%s\t%s\t%d\t%s\t%s\n", files[j].Mode(), group.Username, user.Username, files[j].Size(), files[j].ModTime().Format(timeLayout), files[j].Name())
		} else {

			fmt.Printf("%s\n", files[j].Name())
		}
	}
	f.Close()
}
Esempio n. 2
0
func dir2Dir(path string, d os.FileInfo, dotu bool, upool p.Users) *p.Dir {
	sysMode := d.Sys().(*syscall.Stat_t)

	dir := new(Dir)
	dir.Qid = *dir2Qid(d)
	dir.Mode = dir2Npmode(d, dotu)
	dir.Atime = uint32(atime(sysMode).Unix())
	dir.Mtime = uint32(d.ModTime().Unix())
	dir.Length = uint64(d.Size())
	dir.Name = path[strings.LastIndex(path, "/")+1:]

	if dotu {
		dir.dotu(path, d, upool, sysMode)
		return &dir.Dir
	}

	unixUid := int(sysMode.Uid)
	unixGid := int(sysMode.Gid)
	dir.Uid = strconv.Itoa(unixUid)
	dir.Gid = strconv.Itoa(unixGid)
	dir.Muid = "none"

	// BUG(akumar): LookupId will never find names for
	// groups, as it only operates on user ids.
	u, err := user.LookupId(dir.Uid)
	if err == nil {
		dir.Uid = u.Username
	}
	g, err := user.LookupId(dir.Gid)
	if err == nil {
		dir.Gid = g.Username
	}

	return &dir.Dir
}
Esempio n. 3
0
File: ufs.go Progetto: wwaites/go9p
func dir2Dir(path string, d os.FileInfo, dotu bool, upool Users) (*Dir, error) {
	if r := recover(); r != nil {
		fmt.Print("stat failed: ", r)
		return nil, &os.PathError{"dir2Dir", path, nil}
	}
	sysif := d.Sys()
	if sysif == nil {
		return nil, &os.PathError{"dir2Dir: sysif is nil", path, nil}
	}
	sysMode := sysif.(*syscall.Stat_t)

	dir := new(ufsDir)
	dir.Qid = *dir2Qid(d)
	dir.Mode = dir2Npmode(d, dotu)
	dir.Atime = uint32(0 /*atime(sysMode).Unix()*/)
	dir.Mtime = uint32(d.ModTime().Unix())
	dir.Length = uint64(d.Size())
	dir.Name = path[strings.LastIndex(path, "/")+1:]

	if dotu {
		dir.dotu(path, d, upool, sysMode)
		return &dir.Dir, nil
	}

	unixUid := int(sysMode.Uid)
	unixGid := int(sysMode.Gid)
	dir.Uid = strconv.Itoa(unixUid)
	dir.Gid = strconv.Itoa(unixGid)

	// BUG(akumar): LookupId will never find names for
	// groups, as it only operates on user ids.
	u, err := user.LookupId(dir.Uid)
	if err == nil {
		dir.Uid = u.Username
	}
	g, err := user.LookupId(dir.Gid)
	if err == nil {
		dir.Gid = g.Username
	}

	/* For Akaros, we use the Muid as the link value. */
	if *Akaros && (d.Mode()&os.ModeSymlink != 0) {
		dir.Muid, err = os.Readlink(path)
		if err == nil {
			dir.Mode |= DMSYMLINK
		}
	}
	return &dir.Dir, nil
}
Esempio n. 4
0
func (b *BackupSet) newBaseFileInfo(path string, info os.FileInfo) baseFileInfo {
	stat := info.Sys()
	switch stat := stat.(type) {
	case *syscall.Stat_t:
		user, err := user.LookupId(fmt.Sprintf("%d", stat.Uid))
		var userName string
		if err != nil {
			userName = ""
		} else {
			userName = user.Username
		}
		aTime := time.Unix(stat.Atim.Sec, stat.Atim.Nsec)
		cTime := time.Unix(stat.Ctim.Sec, stat.Ctim.Nsec)
		mTime := time.Unix(stat.Mtim.Sec, stat.Mtim.Nsec)
		return baseFileInfo{name: path,
			mode:     info.Mode(), //os.FileMode(stat.Mode),
			uid:      stat.Uid,
			gid:      stat.Gid,
			userName: userName,
			aTime:    aTime,
			cTime:    cTime,
			mTime:    mTime}
	default:
		return baseFileInfo{name: path,
			mode: info.Mode()}
	}
	panic("Can't get here")
}
Esempio n. 5
0
func (up *osUsers) Uid2User(uid int) User {
	u, err := user.LookupId(strconv.Itoa(uid))
	if err != nil {
		return nil
	}
	return newUser(u)
}
Esempio n. 6
0
func uidToUserName(uid uint32) string {
	u, err := user.LookupId(fmt.Sprintf("%d", uid))
	if err != nil {
		return ""
	}
	return u.Username
}
Esempio n. 7
0
// LookupId looks up a user by userid.
func LookupId(uid string) (*User, error) {
	u, err := user.LookupId(uid)
	if err != nil {
		return nil, err
	}
	return lookupGroup(u)
}
Esempio n. 8
0
func mkKindiDir(path string) (string, error) {
	var name string

	if len(path) == 0 || path == "~/.kindi" {
		uid := syscall.Getuid()
		uid_str := strconv.Itoa(uid)
		u, err := user.LookupId(uid_str)
		if err != nil {
			return "", err
		}
		if e, g := uid_str, u.Uid; e != g {
			return "", fmt.Errorf("expected Uid of %d; got %d", e, g)
		}
		fi, err := os.Stat(u.HomeDir)
		if err != nil || !fi.IsDir() {
			return "", fmt.Errorf("expected a valid HomeDir; stat(%q): err=%v, IsDirectory=%v", err, fi.IsDir())
		}

		name = filepath.Join(u.HomeDir, ".kindi")
	} else {
		name = path
	}

	err := os.Mkdir(name, 0700)
	if err != nil {
		if pe, ok := err.(*os.PathError); ok && pe.Err == syscall.EEXIST {
			return name, nil
		}
		return "", err
	}
	return name, nil
}
Esempio n. 9
0
func main() {
	fmt.Println("Current User")
	// Lookup current user, and print out info
	u, err := user.Current()
	if err != nil {
		panic(err)
	}
	fmt.Println(u)

	fmt.Println("root User by name")
	// Lookup root user by name, and print out info
	username, err := user.Lookup("root")
	if err != nil {
		panic(err)
	}
	fmt.Println(username)

	fmt.Println("root User by UID 0")
	// Lookup root user by user name, and print out info
	// Careful here - as the type is not what you expect it to be
	u, err = user.LookupId("0")
	if err != nil {
		panic(err)
	}
	fmt.Println(u)

}
Esempio n. 10
0
func (d DATA) parseline(line string) {
	data := d.val
	l := strings.Fields(line)
	if len(l) < 3 {
		return
	}
	recv, err := strconv.ParseFloat(l[len(l)-1], 64)
	if err != nil {
		return
	}
	sent, err := strconv.ParseFloat(l[len(l)-2], 64)
	if err != nil {
		return
	}
	processCol := strings.Join(l[0:len(l)-2], "_")
	processdata := strings.Split(processCol, "/")
	if len(processdata) < 3 {
		return
	}
	pname := strings.Join(processdata[0:len(processdata)-2], "/")
	if strings.Index(pname, ":") != -1 && strings.Index(pname, "-") != -1 {
		pname = strings.Split(pname, "-")[0]
	}
	ud, err := user.LookupId(processdata[len(processdata)-1])
	if err != nil {
		ud = &user.User{"-1", "-1", "dontknow", "dontknow", "/home/dontknow"}
	}
	data[pname] = pt{
		data[pname].sent + sent,
		data[pname].recv + recv,
		data[pname].users.add(ud.Username),
	}
}
Esempio n. 11
0
func HasDirDiff(path, username, groupname string, mode os.FileMode) (bool, error) {
	fi, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			return true, nil
		}
		return false, err
	}
	if !fi.IsDir() {
		return false, errors.New("not a directory")
	}
	if (fi.Mode() - os.ModeDir) != mode {
		return true, nil
	}

	uid := fi.Sys().(*syscall.Stat_t).Uid
	gid := fi.Sys().(*syscall.Stat_t).Gid
	u, err := user.LookupId(fmt.Sprint(uid))
	if err != nil {
		return false, err
	}
	g, err := group.LookupId(fmt.Sprint(gid))
	if err != nil {
		return false, err
	}
	if u.Username != username {
		return true, nil
	}
	if g.Name != groupname {
		return true, nil
	}
	return false, nil
}
Esempio n. 12
0
func switchnsGit(cmd *cobra.Command, args []string) {
	var u *user.User
	var err error
	var repoId git.RepoIdentifier

	uid := os.Getuid()
	originalCommand := os.Getenv("SSH_ORIGINAL_COMMAND")

	if u, err = user.LookupId(strconv.Itoa(uid)); err != nil {
		os.Exit(2)
	}

	if uid != 0 {
		if !isValidGitCommand(originalCommand, !git_rw) {
			os.Exit(2)
		}
		if repoId, err = git.NewIdentifierFromUser(u); err != nil {
			os.Exit(2)
		}
		env := []string{fmt.Sprintf("HOME=%s", repoId.RepositoryPathFor())}
		runCommand("geard-githost", []string{"/usr/bin/git-shell", "-c", originalCommand}, env)
	} else {
		fmt.Println("Cannot switch into any git repo as root user")
		os.Exit(2)
	}
}
Esempio n. 13
0
// IsUIDInAny checks whether the given user belongs to any of the
// given groups
func IsUIDInAny(uid uint32, groups ...string) bool {
	usr, err := user.LookupId(strconv.FormatUint(uint64(uid), 10))
	if err != nil {
		return false
	}

	gid, err := strconv.ParseUint(usr.Gid, 10, 32)
	if err != nil {
		return false
	}

	// XXX cache the Getgrnam calls for a second or so?
	for _, groupname := range groups {
		group, err := Getgrnam(groupname)
		if err != nil {
			continue
		}

		if group.Gid == uint(gid) {
			return true
		}

		for _, member := range group.Mem {
			if member == usr.Username {
				return true
			}
		}
	}

	return false
}
Esempio n. 14
0
// printLong prints the item in the long format.
func (i listItem) printLong() error {
	uid, gid := -1, -1
	if sys, ok := i.info.Sys().(*syscall.Stat_t); ok {
		uid = int(sys.Uid)
		gid = int(sys.Gid)
	}

	userStr := strconv.Itoa(uid)
	var errs errors
	if u, err := user.LookupId(userStr); err != nil {
		errs = append(errs, err)
	} else {
		userStr = u.Username
	}

	size := i.info.Size()
	time := i.info.ModTime().Format("Jan 2 15:04")
	mode := i.info.Mode().String()
	name := i.pathName()
	if _, err := fmt.Println(mode, userStr, gid, size, time, name); err != nil {
		errs = append(errs, err)
	}

	if errs == nil {
		return nil
	}
	return errs
}
Esempio n. 15
0
func (opt *UserOption) User() (userinfo *user.User, err error) {
	nvs := strings.TrimSpace(opt.Value)
	if nvs == "" {
		// special case: empty string is the current euid.
		return nil, EmptyUserSet
	}
	// attempt to map this as a number first, in case a numeric UID
	// was provided.
	_, err = strconv.Atoi(nvs)
	if err != nil {
		switch err.(type) {
		case *strconv.NumError:
			// not a number.  do a user table lookup.
			userinfo, err = user.Lookup(nvs)
			if err != nil {
				return nil, err
			}
			return userinfo, nil
		default:
			return nil, err
		}
	}
	userinfo, err = user.LookupId(nvs)
	return userinfo, err
}
Esempio n. 16
0
func listPid(pid int) error {
	buf, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
	if err != nil {
		return err
	}
	str := string(buf)

	pi := Proc{Cmd: "?", Pid: pid}
	op := strings.IndexRune(str, '(')
	cp := strings.IndexRune(str, ')')
	if op >= 0 && cp >= 0 {
		pi.Cmd = str[op+1 : cp]
	}

	info, err := os.Stat(fmt.Sprintf("/proc/%d", pid))
	if err == nil {
		st, ok := info.Sys().(*syscall.Stat_t)
		if ok {
			user, err := user.LookupId(fmt.Sprint(st.Uid))
			if !numeric && err == nil {
				pi.User = user.Username
			} else {
				pi.User = fmt.Sprint(st.Uid)
			}
		}
	}

	visitSymlink(&pi, "cwd", "cwd")
	visitSymlink(&pi, "rtd", "root")
	visitSymlink(&pi, "txt", "exe")
	visitMaps(&pi)
	visitFds(&pi)
	return nil
}
Esempio n. 17
0
// 系统用户信息
func InitUser(config UserConfig) error {
	// 配置里的用户信息
	targetUserName := config.User
	if targetUserName == "" {
		return errors.New("invalid user config " + targetUserName)
	}

	// 在系统中寻找该用户
	targetUser, err := user.Lookup(targetUserName)
	if err != nil {
		return err
	}
	targetUserName = targetUser.Username

	// 当前系统用户
	currentUid := os.Getuid()
	currentUser, err := user.LookupId(strconv.Itoa(currentUid))
	if err != nil {
		return err
	}
	currentUserName := currentUser.Username

	// 目标用户与当前用户校验
	if targetUserName != currentUserName {
		return errors.New("invalid current user,target user is " + targetUserName + ",current user is " + currentUserName)
	}

	return nil
}
Esempio n. 18
0
func switchnsGit() {
	var u *user.User
	var err error
	var repoId git.RepoIdentifier

	uid := os.Getuid()
	originalCommand := os.Getenv("SSH_ORIGINAL_COMMAND")

	if u, err = user.LookupId(strconv.Itoa(uid)); err != nil {
		fmt.Printf("Couldn't find user with uid %n\n", uid)
		os.Exit(2)
	}

	if uid != 0 {
		if !isValidGitCommand(originalCommand, !gitRw) {
			fmt.Printf("Invalid git command: %s\n", originalCommand)
			os.Exit(2)
		}
		if repoId, err = git.NewIdentifierFromUser(u); err != nil {
			fmt.Printf("Couldn't create identifier for user %v\n", u)
			os.Exit(2)
		}
		env := []string{fmt.Sprintf("HOME=%s", repoId.RepositoryPathFor())}
		client, err := docker.GetConnection("unix:///var/run/docker.sock")
		if err != nil {
			fmt.Printf("Unable to connect to server\n")
			os.Exit(3)
		}

		runCommandInContainer(client, "geard-githost", []string{"/usr/bin/git-shell", "-c", originalCommand}, env)
	} else {
		fmt.Println("Cannot switch into any git repo as root user")
		os.Exit(2)
	}
}
Esempio n. 19
0
func switchnsExec(args []string) {
	var err error

	client, err := docker.GetConnection("unix:///var/run/docker.sock")
	if err != nil {
		fmt.Printf("Unable to connect to server\n")
		os.Exit(3)
	}

	uid := os.Getuid()

	if uid == 0 {
		runCommandInContainer(client, containerName, args, envs)
	} else {
		var u *user.User
		var containerId containers.Identifier

		if u, err = user.LookupId(strconv.Itoa(uid)); err != nil {
			fmt.Printf("Couldn't lookup uid %s\n", uid)
			os.Exit(2)
		}

		if containerId, err = containers.NewIdentifierFromUser(u); err != nil {
			fmt.Printf("Couldn't get identifier from user: %v\n", u)
			os.Exit(2)
		}
		runCommandInContainer(client, containerId.ContainerFor(), []string{"/bin/sh", "-l"}, []string{})
	}
}
Esempio n. 20
0
// Takes care of dropping privileges to the desired user
func changeUser(u string) {
	if u == "" {
		return
	}
	userent, err := user.LookupId(u)
	if err != nil {
		userent, err = user.Lookup(u)
	}
	if err != nil {
		log.Fatalf("Unable to find user %v: %v", u, err)
	}

	uid, err := strconv.Atoi(userent.Uid)
	if err != nil {
		log.Fatalf("Invalid uid: %v", userent.Uid)
	}
	gid, err := strconv.Atoi(userent.Gid)
	if err != nil {
		log.Fatalf("Invalid gid: %v", userent.Gid)
	}

	if err := syscall.Setgid(gid); err != nil {
		log.Fatalf("setgid failed: %v", err)
	}
	if err := syscall.Setuid(uid); err != nil {
		log.Fatalf("setuid failed: %v", err)
	}
}
Esempio n. 21
0
func (e *LinuxExecutor) runAs(userid string) error {
	errs := new(multierror.Error)

	// First, try to lookup the user by uid
	u, err := user.LookupId(userid)
	if err == nil {
		e.user = u
		return nil
	} else {
		errs = multierror.Append(errs, err)
	}

	// Lookup failed, so try by username instead
	u, err = user.Lookup(userid)
	if err == nil {
		e.user = u
		return nil
	} else {
		errs = multierror.Append(errs, err)
	}

	// If we got here we failed to lookup based on id and username, so we'll
	// return those errors.
	return fmt.Errorf("Failed to identify user to run as: %s", errs)
}
Esempio n. 22
0
func lookupUser(uid int) string {
	u, err := user.LookupId(strconv.Itoa(uid))
	if err != nil {
		return fmt.Sprintf("%d", uid)
	}
	return u.Name
}
Esempio n. 23
0
func getfacl(p string, recursive, header bool) error {
	a, err := acl.GetFileAccess(p)
	if err != nil {
		return fmt.Errorf("Failed to get ACL from %s (%s)", p, err)
	}

	uid, gid, err := os2.Owner(p)
	if err != nil {
		return fmt.Errorf("Failed to lookup owner and group (%s)", err)
	}
	user, err := user.LookupId(strconv.Itoa(int(uid)))
	if err != nil {
		return fmt.Errorf("Failed to lookup user (%s)", err)
	}
	group, err := group.LookupId(strconv.Itoa(int(gid)))
	if err != nil {
		return fmt.Errorf("Failed to lookup group (%s)", err)
	}

	if header {
		fmt.Printf("# file: %s\n# user: %s\n# group: %s\n", p, user.Username, group.Name)
	}
	fmt.Println(a)

	// Free ACL before recursing
	a.Free()

	if recursive {
		if err := recurse(p, header); err != nil {
			return err
		}
	}
	return nil
}
Esempio n. 24
0
File: launch.go Progetto: Safe3/oz
func (sbox *Sandbox) startXpraClient() {
	u, err := user.LookupId(fmt.Sprintf("%d", sbox.cred.Uid))
	if err != nil {
		sbox.daemon.Error("Failed to lookup user for uid=%d, cannot start xpra", sbox.cred.Uid)
		return
	}
	xpraPath := path.Join(u.HomeDir, ".Xoz", sbox.profile.Name)
	sbox.xpra = xpra.NewClient(
		&sbox.profile.XServer,
		uint64(sbox.display),
		sbox.cred,
		path.Join(sbox.daemon.config.PrefixPath, "bin", "oz-seccomp"),
		xpraPath,
		sbox.profile.Name,
		sbox.daemon.log)

	sbox.xpra.Process.Env = append(sbox.rawEnv, sbox.xpra.Process.Env...)

	//sbox.daemon.log.Debug("%s %s", strings.Join(sbox.xpra.Process.Env, " "), strings.Join(sbox.xpra.Process.Args, " "))
	if sbox.daemon.config.LogXpra {
		sbox.setupXpraLogging()
	}
	if err := sbox.xpra.Process.Start(); err != nil {
		sbox.daemon.Warning("Failed to start xpra client: %v", err)
	}
}
Esempio n. 25
0
func main() {
	user, err := user.LookupId("S-1-5-21-955939588-3462822645-4196941772-500")
	if err != nil {
		fmt.Println(err) //Unknown directory 一样的windows bug
	}
	fmt.Println(user.HomeDir)
}
Esempio n. 26
0
// Test running 'ls -l' with a symlink 'b' pointing to a file 'a'
func Test_l_File_Link2(t *testing.T) {
	setup_test_dir("l_File_Link2")

	time_now := time.Now()
	size := 13
	path := "a"
	_mkfile2(path, 0600, os.Getuid(), os.Getgid(), size, time_now)

	_mklink(path, "b")

	var output_buffer bytes.Buffer
	args := []string{"-l", "--nocolor"}
	ls_err := ls(&output_buffer, args, tw)

	output := clean_output_buffer(output_buffer)

	// remove the permissions string from each file listing
	output_line_split := strings.Split(output, "\n")
	output_noperms := ""
	for _, l := range output_line_split {
		output_line_split_noperms := strings.Split(l, " ")[1:]
		output_line_noperms := strings.Join(output_line_split_noperms, " ")
		if len(output_noperms) == 0 {
			output_noperms = output_line_noperms
		} else {
			output_noperms = output_noperms + "\n" + output_line_noperms
		}
	}

	var owner string
	owner_lookup, err := user.LookupId(fmt.Sprintf("%d", os.Getuid()))
	if err != nil {
		owner = user_map[int(os.Getuid())]
	} else {
		owner = owner_lookup.Username
	}

	group := group_map[os.Getgid()]

	expected := fmt.Sprintf(
		"1 %s %s %d %s %02d %02d:%02d a\n1 %s %s 1 %s %02d %02d:%02d b -> %s",
		owner,
		group,
		size,
		time_now.Month().String()[0:3],
		time_now.Day(),
		time_now.Hour(),
		time_now.Minute(),
		owner,
		group,
		time_now.Month().String()[0:3],
		time_now.Day(),
		time_now.Hour(),
		time_now.Minute(),
		path)

	check_output(t, output_noperms, expected)
	check_error_nil(t, ls_err)
}
Esempio n. 27
0
func lookupId(uid string) (*user.User, error) {
	u, err := user.LookupId(uid)
	if err != nil {
		return nil, err
	}
	u.HomeDir = detectHomeDir(u.Name)
	return u, nil
}
Esempio n. 28
0
func printUID(fieldValue string) (string, error) {

	name, err := user.LookupId(fieldValue)
	if err != nil {
		return fmt.Sprintf("unknown(%s)", fieldValue), nil
	}
	return name.Username, nil
}
Esempio n. 29
0
func getUser() string {
	uid := strconv.Itoa(os.Geteuid())
	u, err := user.LookupId(uid)
	if err != nil {
		fatal.Fatalf("cannot find name for user ID %s\n", uid)
	}
	return u.Username
}
Esempio n. 30
0
func dir2Dir(s string, d os.FileInfo, dotu bool, upool ninep.Users) (*ninep.Dir, error) {
	sysif := d.Sys()
	if sysif == nil {
		return nil, &os.PathError{"dir2Dir", s, nil}
	}
	var sysMode *syscall.Stat_t
	switch t := sysif.(type) {
	case *syscall.Stat_t:
		sysMode = t
	default:
		return nil, &os.PathError{"dir2Dir: sysif has wrong type", s, nil}
	}

	dir := new(Dir)
	dir.Qid = *dir2Qid(d)
	dir.Mode = dir2Npmode(d, dotu)
	dir.Atime = uint32(atime(sysMode).Unix())
	dir.Mtime = uint32(d.ModTime().Unix())
	dir.Length = uint64(d.Size())
	dir.Name = s[strings.LastIndex(s, "/")+1:]

	if dotu {
		dir.dotu(s, d, upool, sysMode)
		return &dir.Dir, nil
	}

	unixUid := int(sysMode.Uid)
	unixGid := int(sysMode.Gid)
	dir.Uid = strconv.Itoa(unixUid)
	dir.Gid = strconv.Itoa(unixGid)
	dir.Muid = "none"

	// BUG(akumar): LookupId will never find names for
	// groups, as it only operates on user ids.
	u, err := user.LookupId(dir.Uid)
	if err == nil {
		dir.Uid = u.Username
	}
	g, err := user.LookupId(dir.Gid)
	if err == nil {
		dir.Gid = g.Username
	}

	return &dir.Dir, nil
}