mirror of https://github.com/pkg/sftp.git
				
				
				
			
		
			
				
	
	
		
			60 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
| // +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
 | |
| // +build cgo
 | |
| 
 | |
| package sftp
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"os/user"
 | |
| 	"path"
 | |
| 	"syscall"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| func runLsStatt(dirent os.FileInfo, statt *syscall.Stat_t) string {
 | |
| 	// example from openssh sftp server:
 | |
| 	// crw-rw-rw-    1 root     wheel           0 Jul 31 20:52 ttyvd
 | |
| 	// format:
 | |
| 	// {directory / char device / etc}{rwxrwxrwx}  {number of links} owner group size month day [time (this year) | year (otherwise)] name
 | |
| 
 | |
| 	typeword := runLsTypeWord(dirent)
 | |
| 	numLinks := statt.Nlink
 | |
| 	username := fmt.Sprintf("%d", statt.Uid)
 | |
| 	if usr, err := user.LookupId(username); err == nil {
 | |
| 		username = usr.Username
 | |
| 	}
 | |
| 	groupname := fmt.Sprintf("%d", statt.Gid)
 | |
| 	if grp, err := user.LookupGroupId(groupname); err == nil {
 | |
| 		groupname = grp.Name
 | |
| 	}
 | |
| 	mtime := dirent.ModTime()
 | |
| 	monthStr := mtime.Month().String()[0:3]
 | |
| 	day := mtime.Day()
 | |
| 	year := mtime.Year()
 | |
| 	now := time.Now()
 | |
| 	isOld := mtime.Before(now.Add(-time.Hour * 24 * 365 / 2))
 | |
| 
 | |
| 	yearOrTime := fmt.Sprintf("%02d:%02d", mtime.Hour(), mtime.Minute())
 | |
| 	if isOld {
 | |
| 		yearOrTime = fmt.Sprintf("%d", year)
 | |
| 	}
 | |
| 
 | |
| 	return fmt.Sprintf("%s %4d %-8s %-8s %8d %s %2d %5s %s", typeword,
 | |
| 		numLinks, username, groupname, dirent.Size(), monthStr, day,
 | |
| 		yearOrTime, dirent.Name())
 | |
| }
 | |
| 
 | |
| // ls -l style output for a file, which is in the 'long output' section of a readdir response packet
 | |
| // this is a very simple (lazy) implementation, just enough to look almost like openssh in a few basic cases
 | |
| func runLs(dirname string, dirent os.FileInfo) string {
 | |
| 	dsys := dirent.Sys()
 | |
| 	if dsys == nil {
 | |
| 	} else if statt, ok := dsys.(*syscall.Stat_t); !ok {
 | |
| 	} else {
 | |
| 		return runLsStatt(dirent, statt)
 | |
| 	}
 | |
| 
 | |
| 	return path.Join(dirname, dirent.Name())
 | |
| }
 |