Red-M / RedSSH

Use SSH in python easily with C speed!
Other
20 stars 3 forks source link

Is flags from SFTPFileAttributes correct? #2

Closed piperun closed 4 years ago

piperun commented 4 years ago

I've tried my hardest to research just what "flags" are supposed to represent, my educated guess was its file mode, but the issue is that every file whenever it's a folder or file returns the int 15, which to me looks quite suspiciously either as a bug or that it's not intended to be libssh2 way of giving you the type of a file object.

Red-M commented 4 years ago

This is a little convoluted but flag is actually the flag modes that the SFTP object is opened with. Please see these lines for an example.

I'll have to see what documentation I can put up to solve this issue. This may take a bit longer to correct, as there are patches in my fork of ssh2-python that would change how this documentation would be presented.

piperun commented 4 years ago

Aha, I could've sworn I saw somewhere in libssh2 that you could get the inode (7) info from a file.

Red-M commented 4 years ago

You might be able to get that with redssh.sftp.RedSFTP.stat() as per this documentation in libssh2 but I'm not sure the right symbols/functions are exposed for that.

Let me know if something needs to be done to enable this request.

piperun commented 4 years ago

From what I've deciphered from ssh2-python, you need an ssh2.sftp_handle.SFTPHandle object to call it's internal fstat(self), the issue is afaik the only way to get an ssh2.sftp_handle.SFTPHandle object is to open the file/folder.

So unless I'm doing something very wrong:

path = sftp.opendir("/path") # We get a SFTPHandle
 # we can get this folder's file stats
# Although everytime I try fstat it just gives me -37 i.e. "file/folder" is empty, 
# even with a simple open()
print(path.fstat())

#However if we want all folders/files stats
for fileobject in path.readdir():
    print(fileobject) # Will return (int, name, SFTPAttributes)
# SFTPAttributes will not be from fstat() afaik.

And so it becomes a bit of a chicken and egg problem since I need to know if it's a file or folder before I can open the file/folder with either open() or opendir() and get the SFTPHandle which supposedly has fstat().

Red-M commented 4 years ago

-37 is EAGAIN, you need to do the call again, try looking at the other redssh.sftp.RedSFTP functions and use the _block() calls like that on your fstat calls. I'll make something up in about 12 hours that will be able to get this done.

On Sat., 21 Mar. 2020, 2:59 am piperun, notifications@github.com wrote:

From what I've deciphered from ssh2-python, you need an ssh2.sftp_handle.SFTPHandle object to call it's internal fstat(self), the issue is afaik the only way to get an ssh2.sftp_handle.SFTPHandle object is to open the file/folder.

So unless I'm doing something very wrong:

path = sftp.opendir("/path") # We get a SFTPHandle

we can get this folder's file stats

Although everytime I try fstat it just gives me -37 i.e. "file/folder" is empty,

even with a simple open()

print(path.fstat())

However if we want all folders/files stats

for fileobject in path.readdir(): print(fileobject) # Will return (int, name, SFTPAttributes)

However SFTPAttributes will not be from fstat() afaik.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Red-M/RedSSH/issues/2#issuecomment-601807251, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALGQEIOUTSHYL2UMLUDYD3RIOOFJANCNFSM4LPO36FA .

piperun commented 4 years ago

Ah I see, one more thing is that I'm getting AttributeError: __enter__ if I do:

with ssh.sftp.open(
         "file", 
         redssh.libssh2.LIBSSH2_FXF_READ, 
         redssh.libssh2.LIBSSH2_SFTP_S_IRUSR, 
         True) as remote_file: `

So, so far I've been stuck with ssh2 fileobject.

Red-M commented 4 years ago

So I tested this out.

Directories will not allow an fstat() call, files will work.

Just be aware that this code below is not how the library should be used. I need to make a wrapping class for ssh2.sftp_handle.SFTPHandle so that it will work with non-blocking mode for RedSSH.

import redssh
usr = "user"
passw = None
rs = redssh.RedSSH()
rs.connect(hostname="hostname", username=usr, password=passw)
rs.start_sftp()
fs = rs.sftp.open_dir("/home")
rs._block(fs.fstat)
# Failure
fs = rs.sftp.open("/home/"+usr+"/.bashrc",redssh.sftp.DEFAULT_READ_MODE,redssh.sftp.DEFAULT_FILE_MODE)
rs._block(fs.fstat)
# Success
Red-M commented 4 years ago

I've added some functions to address this however, they do not have access to inodes. I think some patches in libssh2 or ssh2-python will be required to get access to inode information over SFTP.

Red-M commented 4 years ago

So reading through the documentation from libssh2 for fstat() shows that libssh2 would require changes to support inode data over SFTP.

piperun commented 4 years ago

Ah that's unfortunate, I could be mistaking what VFS does but I did see it returning inodes info from statvfs().

Red-M commented 4 years ago

Yeah statvfs() does support inodes.

If ssh2-python doesn't support it, let me know and I'll update my fork to include the required data.

Red-M commented 4 years ago

Please re-open if this isn't resolved.