From 07440b10d00bddc789b921814ecd039d541a530c Mon Sep 17 00:00:00 2001 From: Clement Sam Date: Sat, 29 Oct 2022 06:28:00 +0000 Subject: [PATCH 1/3] fix windows long list support --- ls/display_windows.go | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/ls/display_windows.go b/ls/display_windows.go index f88ed2d..a9c6f88 100644 --- a/ls/display_windows.go +++ b/ls/display_windows.go @@ -3,25 +3,48 @@ package ls import ( + "os" "os/user" "syscall" + "unsafe" "github.com/profclems/glab/pkg/tableprinter" ) func (l *LS) _display(table *tableprinter.TablePrinter, name string, dir *Dir) (int, error) { - stat := dir.Info.Sys().(*syscall.Win32FileAttributeData) + //stat := dir.Info.Sys().(*syscall.Win32FileAttributeData) usr, err := user.Current() if err != nil { return 0, err } - blocks := stat.FileSizeLow - nlink := 1 + var data syscall.ByHandleFileInformation + handle, err := syscall.Open(dir.Path, os.O_RDONLY, 0600) + if err != nil { + return 0, err + } + + err = getFileInformationByHandle(handle, &data) + if err != nil { + return 0, err + } + + blocks := data.FileSizeLow + //nlink := 1 timeStr := dir.Info.ModTime().UTC().Format("Jan 02 15:04") - table.AddRow(dir.Info.Mode(), nlink, usr.Username, usr.Gid, l.minifySize(dir.Info.Size()), timeStr, name) + table.AddRow(dir.Info.Mode(), data.NumberOfLinks, usr.Username, usr.Gid, l.minifySize(dir.Info.Size()), timeStr, name) return int(blocks), nil } + +func getFileInformationByHandle(handle syscall.Handle, data *syscall.ByHandleFileInformation) (err error) { + modKernel32 := syscall.NewLazyDLL("kernel32.dll") + procGetFileInformationByHandle := modKernel32.NewProc("GetFileInformationByHandle") + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + err = syscall.Errno(e1) + } + return +} From b8fb0530936815ffed548ab57051fc7d842468b8 Mon Sep 17 00:00:00 2001 From: Bostigger Date: Sat, 29 Oct 2022 07:57:04 +0000 Subject: [PATCH 2/3] minor fixes --- ls/display_windows.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/ls/display_windows.go b/ls/display_windows.go index a9c6f88..6a51db6 100644 --- a/ls/display_windows.go +++ b/ls/display_windows.go @@ -3,12 +3,11 @@ package ls import ( + "github.com/profclems/glab/pkg/tableprinter" + "log" "os" "os/user" "syscall" - "unsafe" - - "github.com/profclems/glab/pkg/tableprinter" ) func (l *LS) _display(table *tableprinter.TablePrinter, name string, dir *Dir) (int, error) { @@ -19,32 +18,25 @@ func (l *LS) _display(table *tableprinter.TablePrinter, name string, dir *Dir) ( } var data syscall.ByHandleFileInformation - handle, err := syscall.Open(dir.Path, os.O_RDONLY, 0600) + + f, err := os.Open(dir.Path) if err != nil { return 0, err } + log.Println(f.Fd(), dir.Path) - err = getFileInformationByHandle(handle, &data) + err = syscall.GetFileInformationByHandle(syscall.Handle(f.Fd()), &data) if err != nil { return 0, err } blocks := data.FileSizeLow + size := uint64(data.FileSizeHigh)<<32 | uint64(data.FileSizeLow) //nlink := 1 timeStr := dir.Info.ModTime().UTC().Format("Jan 02 15:04") - table.AddRow(dir.Info.Mode(), data.NumberOfLinks, usr.Username, usr.Gid, l.minifySize(dir.Info.Size()), timeStr, name) + table.AddRow(dir.Info.Mode(), data.NumberOfLinks, usr.Username, usr.Gid, l.minifySize(int64(size)), timeStr, name) return int(blocks), nil } - -func getFileInformationByHandle(handle syscall.Handle, data *syscall.ByHandleFileInformation) (err error) { - modKernel32 := syscall.NewLazyDLL("kernel32.dll") - procGetFileInformationByHandle := modKernel32.NewProc("GetFileInformationByHandle") - r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) - if r1 == 0 { - err = syscall.Errno(e1) - } - return -} From 0adc69d22d257865227f5553fae60fb5218eeb5c Mon Sep 17 00:00:00 2001 From: braswelljr Date: Wed, 4 Jan 2023 18:52:16 +0000 Subject: [PATCH 3/3] Fix shit I created --- ls/display.go | 17 ++++++++++- ls/display_unix.go | 2 +- ls/display_windows.go | 2 +- ls/ls.go | 67 ++++++++++++++++++++++++++++++++++++++++--- main.go | 1 + 5 files changed, 82 insertions(+), 7 deletions(-) diff --git a/ls/display.go b/ls/display.go index 2535d1b..bf9151d 100644 --- a/ls/display.go +++ b/ls/display.go @@ -2,7 +2,9 @@ package ls import ( "fmt" + "io/fs" "os" + "path/filepath" "github.com/pee2pee/lse/ls/color" "github.com/profclems/glab/pkg/tableprinter" @@ -19,7 +21,20 @@ func (l *LS) display(dirs []Dir) (err error) { for i := range dirs { dir := dirs[i] name := dir.Info.Name() - + if l.F { + if dir.Info.IsDir() { + name = fmt.Sprintf(name + "/") + } else if dir.Info.Mode()&os.ModeSymlink == os.ModeSymlink { + originalPath, _ := filepath.EvalSymlinks(dir.Path) + name = fmt.Sprintf(name + "@" + " -> " + originalPath) + } else if dir.Info.Mode().Type() == fs.ModeSocket { + name = fmt.Sprintf(name + "=") + } else if isExecAll(dir.Info.Mode()) { + name = fmt.Sprintf(name + "*") + } else { + dir.Info.Name() + } + } if l.Q { name = fmt.Sprintf("%q", name) } diff --git a/ls/display_unix.go b/ls/display_unix.go index 8ec00a6..7e4a1e6 100644 --- a/ls/display_unix.go +++ b/ls/display_unix.go @@ -25,7 +25,7 @@ func (l *LS) _display(table *tableprinter.TablePrinter, name string, dir *Dir) ( timeStr := dir.Info.ModTime().UTC().Format("Jan 02 15:04") - table.AddRow(dir.Info.Mode(), stat.Nlink, usr.Username, group.Name, l.minifySize(dir.Info.Size()), timeStr, name) + table.AddRow(dir.Info.Mode(), stat.Nlink, usr.Username, group.Name, l.evaluateFileAndDirSize(*dir), timeStr, name) return int(stat.Blocks), nil } diff --git a/ls/display_windows.go b/ls/display_windows.go index 6a51db6..e338af1 100644 --- a/ls/display_windows.go +++ b/ls/display_windows.go @@ -37,6 +37,6 @@ func (l *LS) _display(table *tableprinter.TablePrinter, name string, dir *Dir) ( timeStr := dir.Info.ModTime().UTC().Format("Jan 02 15:04") table.AddRow(dir.Info.Mode(), data.NumberOfLinks, usr.Username, usr.Gid, l.minifySize(int64(size)), timeStr, name) - + return int(blocks), nil } diff --git a/ls/ls.go b/ls/ls.go index f013471..24fed3e 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -15,10 +15,13 @@ import ( ) const dotCharacter = 46 +const expValue = 3 +const threshold = 1.0 type Flags struct { A bool // ls -a D bool // ls -d + F bool // ls -F G bool // ls --group L bool // ls -l Q bool // ls --quote @@ -133,7 +136,6 @@ func (l *LS) listDir(dirs []fs.DirEntry) error { }) d = append(dirs, fileDirs...) } - return l.display(d) } @@ -200,7 +202,7 @@ func (l *LS) showDirStructure() error { return nil } -func getFilesAndDirs(d []Dir) (dirs []Dir, fileDirs []Dir) { +func getFilesAndDirs(d []Dir) (dirs, fileDirs []Dir) { for _, file := range d { if file.Info.IsDir() { dirs = append(dirs, file) @@ -222,9 +224,9 @@ func (l *LS) minifySize(size int64) (sizeString string) { } for i := len(units) - 1; i >= 0; i-- { - divisor := math.Pow(10, float64(3*i)) + divisor := math.Pow(10, float64(expValue*i)) result := float64(size) / divisor - if result > 1.0 { + if result >= threshold { if int64(result) == size { sizeString = fmt.Sprintf("%d%s", size, units[i]) } else { @@ -235,3 +237,60 @@ func (l *LS) minifySize(size int64) (sizeString string) { } return } + +func (l *LS) calculateDirSize(dir Dir) (size int64) { + dirContent, filesContents := getFilesAndDirsForSize(dir) + + for _, subDir := range dirContent { + size += l.calculateDirSize(subDir) + } + + for _, file := range filesContents { + size += file.Info.Size() + } + + return +} + +func getFilesAndDirsForSize(dirP Dir) (dirs, files []Dir) { + dirContent, dirReadErr := os.ReadDir(dirP.Path) + + if dirReadErr != nil { + return nil, nil + } + + for _, dir := range dirContent { + dirInfo, dirInfoErr := dir.Info() + + if dirInfoErr != nil { + return nil, nil + } + + dirD := Dir{ + Info: dirInfo, + Path: filepath.Join(dirP.Path, dir.Name()), + } + + if dir.IsDir() { + dirs = append(dirs, dirD) + } else { + files = append(files, dirD) + } + + } + return +} + +func (l *LS) evaluateFileAndDirSize(dir Dir) string { + var size int64 + if dir.Info.IsDir() { + size = l.calculateDirSize(dir) + } else { + size = dir.Info.Size() + } + return l.minifySize(size) +} + +func isExecAll(mode os.FileMode) bool { + return mode&0100 != 0 +} diff --git a/main.go b/main.go index ee7a3a3..ee87f81 100644 --- a/main.go +++ b/main.go @@ -31,6 +31,7 @@ func main() { cmd.Flags().BoolVarP(&lsf.One, "force-entry-per-line", "1", false, "(The numeric digit “one”.) Force output to be one entry per line. This is the default when output is not to a terminal. (-l) output, and don't materialize dataless directories when listing them.") cmd.Flags().BoolVarP(&lsf.A, "all", "a", false, "show all files including hidden files") cmd.Flags().BoolVarP(&lsf.D, "directory", "d", false, "show directory structure") + cmd.Flags().BoolVarP(&lsf.F, "classify", "F", false, "classify directory files") cmd.Flags().BoolVarP(&lsf.G, "group", "g", false, "group directories before files") cmd.Flags().BoolVarP(&lsf.L, "tabular", "l", false, "show detailed directory structure in tabular form") cmd.Flags().BoolVarP(&lsf.Q, "quote", "q", false, "enclose entry names in double quotes")