예제 #1
0
 def format_list(self,basedir,listing,ignore_err=True):
     """Return an iterator object that yields the entries of given directory emulating the "/bin/ls -lA" UNIX command output.
      - (str) basedir: the absolute dirname.
      - (list) listing: the names of the entries in basedir
      - (bool) ignore_err: when False raise exception if os.lstat() call fails.
     On platforms which do not support the pwd and grp modules (such
     as Windows), ownership is printed as "owner" and "group" as a
     default, and number of hard links is always "1". On UNIX
     systems, the actual owner, group, and number of links are
     printed.
     This is how output appears to client:
     -rw-rw-rw-   1 owner   group    7045120 Sep 02  3:47 music.mp3
     drwxrwxrwx   1 owner   group          0 Aug 31 18:50 e-books
     -rw-rw-rw-   1 owner   group        380 Sep 02  3:40 module.py """
     assert isinstance(basedir,unicode),basedir
     if listing: assert isinstance(listing[0],unicode)
     if self.cmd_channel.use_gmt_times: timefunc=time.gmtime
     else: timefunc=time.localtime
     SIX_MONTHS=180 * 24 * 60 * 60; readlink=getattr(self,'readlink',None); now=time.time()
     for basename in listing:
         if not PY3:
         	try: file=os.path.join(basedir,basename)
         	except UnicodeDecodeError: # (Python 2 only) might happen on filesystem not # supporting UTF8 meaning os.listdir() returned a list # of mixed bytes and unicode strings: # http://goo.gl/6DLHD # http://bugs.python.org/issue683592
         		file=os.path.join(bytes(basedir),bytes(basename))
         		if not isinstance(basename,unicode): basename=unicode(basename,'utf8')
         else: file=os.path.join(basedir,basename)
         try: st=self.lstat(file)
         except (OSError,FilesystemError):
         	if ignore_err: continue
         	raise
         perms=_filemode(st.st_mode)  # permissions
         nlinks=st.st_nlink  # number of links to inode
         if not nlinks: nlinks=1 # non-posix system, let's use a bogus value
         size=st.st_size  # file size
         uname=self.get_user_by_uid(st.st_uid); gname=self.get_group_by_gid(st.st_gid); mtime=timefunc(st.st_mtime)
         # if modification time > 6 months shows "month year"
         # else "month hh:mm";  this matches proftpd format, see: # http://code.google.com/p/pyftpdlib/issues/detail?id=187
         if (now - st.st_mtime) > SIX_MONTHS: fmtstr="%d  %Y"
         else: fmtstr="%d %H:%M"
         try: mtimestr="%s %s" % (_months_map[mtime.tm_mon],time.strftime(fmtstr,mtime))
         except ValueError: mtime=timefunc(); mtimestr="%s %s" % (_months_map[mtime.tm_mon],time.strftime("%d %H:%M",mtime)) # It could be raised if last mtime happens to be too # old (prior to year 1900) in which case we return # the current time as last mtime.
         islink=(st.st_mode & 61440)==stat.S_IFLNK # same as stat.S_ISLNK(st.st_mode) but slighlty faster
         if islink and readlink is not None:
         	# if the file is a symlink, resolve it, e.g. # "symlink -> realfile"
         	try: basename=basename+" -> "+readlink(file)
         	except (OSError,FilesystemError):
         		if not ignore_err: raise
         line="%s %3s %-8s %-8s %8s %s %s\r\n" % (perms,nlinks,uname,gname,size,mtimestr,basename) # formatting is matched with proftpd ls output
         yield line.encode('utf8',self.cmd_channel.unicode_errors)
예제 #2
0
    def format_list(self, basedir, listing, ignore_err=True):
        """Return an iterator object that yields the entries of given
        directory emulating the "/bin/ls -lA" UNIX command output.

         - (str) basedir: the absolute dirname.
         - (list) listing: the names of the entries in basedir
         - (bool) ignore_err: when False raise exception if os.lstat()
         call fails.

        On platforms which do not support the pwd and grp modules (such
        as Windows), ownership is printed as "owner" and "group" as a
        default, and number of hard links is always "1". On UNIX
        systems, the actual owner, group, and number of links are
        printed.

        This is how output appears to client:

        -rw-rw-rw-   1 owner   group    7045120 Sep 02  3:47 music.mp3
        drwxrwxrwx   1 owner   group          0 Aug 31 18:50 e-books
        -rw-rw-rw-   1 owner   group        380 Sep 02  3:40 module.py
        """
        assert isinstance(basedir, unicode), basedir
        if listing:
            assert isinstance(listing[0], unicode)
        if self.cmd_channel.use_gmt_times:
            timefunc = time.gmtime
        else:
            timefunc = time.localtime
        SIX_MONTHS = 180 * 24 * 60 * 60
        readlink = getattr(self, 'readlink', None)
        now = time.time()
        for basename in listing:
            if not PY3:
                try:
                    file = os.path.join(basedir, basename)
                except UnicodeDecodeError:
                    # (Python 2 only) might happen on filesystem not
                    # supporting UTF8 meaning os.listdir() returned a list
                    # of mixed bytes and unicode strings:
                    # http://goo.gl/6DLHD
                    # http://bugs.python.org/issue683592
                    file = os.path.join(bytes(basedir), bytes(basename))
                    if not isinstance(basename, unicode):
                        basename = unicode(basename, 'utf8')
            else:
                file = os.path.join(basedir, basename)
            try:
                st = self.lstat(file)
            except (OSError, FilesystemError):
                if ignore_err:
                    continue
                raise

            perms = _filemode(st.st_mode)  # permissions
            nlinks = st.st_nlink  # number of links to inode
            if not nlinks:  # non-posix system, let's use a bogus value
                nlinks = 1
            size = st.st_size  # file size
            uname = self.get_user_by_uid(st.st_uid)
            gname = self.get_group_by_gid(st.st_gid)
            mtime = timefunc(st.st_mtime)
            # if modification time > 6 months shows "month year"
            # else "month hh:mm";  this matches proftpd format, see:
            # http://code.google.com/p/pyftpdlib/issues/detail?id=187
            if (now - st.st_mtime) > SIX_MONTHS:
                fmtstr = "%d  %Y"
            else:
                fmtstr = "%d %H:%M"
            try:
                mtimestr = "%s %s" % (_months_map[mtime.tm_mon],
                                      time.strftime(fmtstr, mtime))
            except ValueError:
                # It could be raised if last mtime happens to be too
                # old (prior to year 1900) in which case we return
                # the current time as last mtime.
                mtime = timefunc()
                mtimestr = "%s %s" % (_months_map[mtime.tm_mon],
                                      time.strftime("%d %H:%M", mtime))

            # same as stat.S_ISLNK(st.st_mode) but slighlty faster
            islink = (st.st_mode & 61440) == stat.S_IFLNK
            if islink and readlink is not None:
                # if the file is a symlink, resolve it, e.g.
                # "symlink -> realfile"
                try:
                    basename = basename + " -> " + readlink(file)
                except (OSError, FilesystemError):
                    if not ignore_err:
                        raise

            # formatting is matched with proftpd ls output
            line = "%s %3s %-8s %-8s %8s %s %s\r\n" % (
                perms, nlinks, uname, gname, size, mtimestr, basename)
            yield line.encode('utf8', self.cmd_channel.unicode_errors)
예제 #3
0
    def format_list(self,
                    basedir: str,
                    listing: List[str],
                    ignore_err: bool = True) -> Iterable[str]:
        """
        :param basedir: the absolute dirname.
        :param listing: the name of the entries in basedir.
        :param ignore_err: when False raise exception if os.lstat() call fails.
        :return: an Iterable object yields the entries of given directory
        emulating the "/bin/ls -lA" UNIX command output.

        On platform which do not support the pwd and grp modules (such as Windows),
        ownership is printed as "owner" and "group" as a default, and number of hard
        links is always "1". On UNIX systems, the actual owner, group, and number of
        links are printed.

        This is how output appears to client:

        -rw-rw-rw-   1 owner   group    7045120 Sep 02  3:47 music.mp3
        drwxrwxrwx   1 owner   group          0 Aug 31 18:50 e-books
        -rw-rw-rw-   1 owner   group        380 Sep 02  3:40 module.py
        """
        assert isinstance(basedir, str)
        timefunc = time.localtime
        readlink = getattr(self, 'readlink', None)
        now = time.time()
        for basename in listing:
            file = os.path.join(basedir, basename)
            try:
                st = self.lstat(file)
            except (OSError, FilesystemError):
                if ignore_err:
                    continue
                raise
            perms = _filemode(st.st_mode)
            nlinks = st.st_nlink
            if not nlinks:
                nlinks = 1
            size = st.st_size
            uname = self.get_user_by_uid(st.st_uid)
            gname = self.get_group_by_gid(st.st_gid)
            mtime = timefunc(st.st_mtime)
            if (now - st.st_mtime) > _SIX_MONTHS:
                fmtstr = "%d  %Y"
            else:
                fmtstr = "%d %H:%M"
            try:
                mtimestr = "%s %s" % (_months_map[mtime.tm_mon],
                                      time.strftime(fmtstr, mtime))
            except ValueError:
                mtime = timefunc()
                mtimestr = "%s %s" % (_months_map[mtime.tm_mon],
                                      time.strftime("%d %H:%M", mtime))
            islink = (st.st_mode & 61400) == stat.S_IFLNK
            if islink and readlink is not None:
                try:
                    basename = basename + " -> " + readlink(file)
                except (OSError, FilesystemError):
                    if not ignore_err:
                        raise
            line = "%s %3s %-8s %-8s %8s %s %s\r\n" % (
                perms, nlinks, uname, gname, size, mtimestr, basename)
            yield line.encode('utf8')