You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since I had some trouble getting scp working, I'd thought I'd better share my examples.
In the regular examples there is only a scp_update, which doesn't work, not on OpenBSD at least, and getting a scp_download working was even a bit more awkward. (it now looks so simple though, but I didn't want to use sftp at first...)
Because no EOF is set when downloading, I had to keep an eye on filesize. In the C examples of the libssh2 package, that is the way it is done anyhow.
One would expect that after reading the last block of a file the next read would return "", which could be used to detect the eof. But it doesn't. It just hangs somewhere in a waiting loop, and I couldn't determine how to prevent that.
channel.close() will close the channel, but might generate an error. This is caused by a bug in channel.c line 46, which schould be: if (rc && rc != LIBSSH2_ERROR_EAGAIN)
To upload a file I've rewritten the send routine in the scp_upload.py example as follows. Reading and writing blocks instead of lines.
import os
...
def send(self, remote_path, mode=0644):
file_size = os.path.getsize(remote_path)
channel = self.session.scp_send(remote_path, mode, file_size)
f=open(remote_path, "rb")
send = 0
while True:
data = f.read(1024)
channel.write(data)
send = send + len(data)
if send >= file_size:
break
f.close()
channel.close()
To download a file I used the same scp_upload.py example with putting in a receive routine, reading blocks over the channel.
The last block get an extra 0 - eof byte, increasing the filesize, so I strip that (checking if it really is a 0, which can probably be omitted)
The only problem now is to determine the filesize. In C, it comes with the scp_recv call, but pylibssh2 puts a NULL in the fileinfo field :-(. So it has to be done with sftp:
import os
def _prepare_sock(self):
...
self.sftp = self.session._session.sftp_init()
...
def receive(self, remote_path, mode=0644):
file_size = self.sftp.get_stat(remote_path)[0]
channel = self.session.scp_recv(remote_path)
f=open(remote_path, "wb")
got = 0
while True:
data = channel.read(1024)
got = got + len(data)
if got > file_size:
if (data[-1:]=="\0"): # probably not needed
f.write(data[:-1])
break
else:
f.write(data)
f.close()
channel.close()
os.chmod(remote_path,mode)
...
...
myscp.receive(sys.argv[4])
It would be nice if the regular examples can be updated with these.
Regards
The text was updated successfully, but these errors were encountered:
Since I had some trouble getting scp working, I'd thought I'd better share my examples.
In the regular examples there is only a scp_update, which doesn't work, not on OpenBSD at least, and getting a scp_download working was even a bit more awkward. (it now looks so simple though, but I didn't want to use sftp at first...)
Because no EOF is set when downloading, I had to keep an eye on filesize. In the C examples of the libssh2 package, that is the way it is done anyhow.
One would expect that after reading the last block of a file the next read would return "", which could be used to detect the eof. But it doesn't. It just hangs somewhere in a waiting loop, and I couldn't determine how to prevent that.
channel.close() will close the channel, but might generate an error. This is caused by a bug in channel.c line 46, which schould be: if (rc && rc != LIBSSH2_ERROR_EAGAIN)
To upload a file I've rewritten the send routine in the scp_upload.py example as follows. Reading and writing blocks instead of lines.
To download a file I used the same scp_upload.py example with putting in a receive routine, reading blocks over the channel.
The last block get an extra 0 - eof byte, increasing the filesize, so I strip that (checking if it really is a 0, which can probably be omitted)
The only problem now is to determine the filesize. In C, it comes with the scp_recv call, but pylibssh2 puts a NULL in the fileinfo field :-(. So it has to be done with sftp:
It would be nice if the regular examples can be updated with these.
Regards
The text was updated successfully, but these errors were encountered: