github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/permissions.go (about)

     1  package sshfx
     2  
     3  // FileMode represents a file’s mode and permission bits.
     4  // The bits are defined according to POSIX standards,
     5  // and may not apply to the OS being built for.
     6  type FileMode uint32
     7  
     8  // Permission flags, defined here to avoid potential inconsistencies in individual OS implementations.
     9  const (
    10  	ModePerm       FileMode = 0o0777 // S_IRWXU | S_IRWXG | S_IRWXO
    11  	ModeUserRead   FileMode = 0o0400 // S_IRUSR
    12  	ModeUserWrite  FileMode = 0o0200 // S_IWUSR
    13  	ModeUserExec   FileMode = 0o0100 // S_IXUSR
    14  	ModeGroupRead  FileMode = 0o0040 // S_IRGRP
    15  	ModeGroupWrite FileMode = 0o0020 // S_IWGRP
    16  	ModeGroupExec  FileMode = 0o0010 // S_IXGRP
    17  	ModeOtherRead  FileMode = 0o0004 // S_IROTH
    18  	ModeOtherWrite FileMode = 0o0002 // S_IWOTH
    19  	ModeOtherExec  FileMode = 0o0001 // S_IXOTH
    20  
    21  	ModeSetUID FileMode = 0o4000 // S_ISUID
    22  	ModeSetGID FileMode = 0o2000 // S_ISGID
    23  	ModeSticky FileMode = 0o1000 // S_ISVTX
    24  
    25  	ModeType       FileMode = 0xF000 // S_IFMT
    26  	ModeNamedPipe  FileMode = 0x1000 // S_IFIFO
    27  	ModeCharDevice FileMode = 0x2000 // S_IFCHR
    28  	ModeDir        FileMode = 0x4000 // S_IFDIR
    29  	ModeDevice     FileMode = 0x6000 // S_IFBLK
    30  	ModeRegular    FileMode = 0x8000 // S_IFREG
    31  	ModeSymlink    FileMode = 0xA000 // S_IFLNK
    32  	ModeSocket     FileMode = 0xC000 // S_IFSOCK
    33  )
    34  
    35  // IsDir reports whether m describes a directory.
    36  // That is, it tests for m.Type() == ModeDir.
    37  func (m FileMode) IsDir() bool {
    38  	return (m & ModeType) == ModeDir
    39  }
    40  
    41  // IsRegular reports whether m describes a regular file.
    42  // That is, it tests for m.Type() == ModeRegular
    43  func (m FileMode) IsRegular() bool {
    44  	return (m & ModeType) == ModeRegular
    45  }
    46  
    47  // Perm returns the POSIX permission bits in m (m & ModePerm).
    48  func (m FileMode) Perm() FileMode {
    49  	return (m & ModePerm)
    50  }
    51  
    52  // Type returns the type bits in m (m & ModeType).
    53  func (m FileMode) Type() FileMode {
    54  	return (m & ModeType)
    55  }
    56  
    57  // String returns a `-rwxrwxrwx` style string representing the `ls -l` POSIX permissions string.
    58  func (m FileMode) String() string {
    59  	var buf [10]byte
    60  
    61  	switch m.Type() {
    62  	case ModeRegular:
    63  		buf[0] = '-'
    64  	case ModeDir:
    65  		buf[0] = 'd'
    66  	case ModeSymlink:
    67  		buf[0] = 'l'
    68  	case ModeDevice:
    69  		buf[0] = 'b'
    70  	case ModeCharDevice:
    71  		buf[0] = 'c'
    72  	case ModeNamedPipe:
    73  		buf[0] = 'p'
    74  	case ModeSocket:
    75  		buf[0] = 's'
    76  	default:
    77  		buf[0] = '?'
    78  	}
    79  
    80  	const rwx = "rwxrwxrwx"
    81  	for i, c := range rwx {
    82  		if m&(1<<uint(9-1-i)) != 0 {
    83  			buf[i+1] = byte(c)
    84  		} else {
    85  			buf[i+1] = '-'
    86  		}
    87  	}
    88  
    89  	if m&ModeSetUID != 0 {
    90  		if buf[3] == 'x' {
    91  			buf[3] = 's'
    92  		} else {
    93  			buf[3] = 'S'
    94  		}
    95  	}
    96  
    97  	if m&ModeSetGID != 0 {
    98  		if buf[6] == 'x' {
    99  			buf[6] = 's'
   100  		} else {
   101  			buf[6] = 'S'
   102  		}
   103  	}
   104  
   105  	if m&ModeSticky != 0 {
   106  		if buf[9] == 'x' {
   107  			buf[9] = 't'
   108  		} else {
   109  			buf[9] = 'T'
   110  		}
   111  	}
   112  
   113  	return string(buf[:])
   114  }