Sftp protocol error 31

WinSCP is a free SFTP, SCP, Amazon S3, WebDAV, and FTP client for Windows.

Documentation » Getting Started » Protocols » SFTP »

SFTP status/error codes are a numerical codes that an SFTP server1 uses to indicate a result of a client request (i.e. a request sent by WinSCP to the server).

WinSCP translates the numerical codes to a textual description for you, so you do not have to remember them.

The SFTP server should also provide a meaningful textual description of the error itself. WinSCP includes the server-side description in its error message, labeled “Error message from server”. Such description can include more detailed information than WinSCP can possibly deduce from the numerical code.

Advertisement

  • Code 4 (Failure)
  • Codes List
  • References

Code 4 (Failure)

Note that not all servers use all codes. Most SSH/SFTP servers, including the most commonly used OpenSSH, support only SFTP version 3 that defines only codes 0 to 8.

These servers would generally use code 4 (Failure) for many errors for which there is a specific code defined in the later versions of SFTP protocol, such as:

  • Renaming a file to a name of already existing file.
  • Creating a directory that already exists.
  • Moving a remote file to a different filesystem (HDD).
  • Uploading a file to a full filesystem (HDD).
  • Exceeding a user disk quota.

In this case the server is required to provide meaningful description of the error itself (see above). Unfortunately, OpenSSH SFTP server uses always description “Failure”. Is such case, there is unfortunately no way to tell a reason of the failure.

Codes List

Code Name Description Comment
0 OK Indicates successful completion of the operation.
1 EOF An attempt to read past the end-of-file was made; or, there are no more directory entries to return.
2 No such file A reference was made to a file which does not exist.
3 Permission denied The user does not have sufficient permissions to perform the operation.
4 Failure An error occurred, but no specific error code exists to describe the failure. This error message should always have meaningful text in the the error message field. See above.
5 Bad message A badly formatted packet or other SFTP protocol incompatibility was detected.
6 No connection There is no connection to the server. This error may be used locally, but must not be return by a server. WinSCP does not use the code.
7 Connection lost The connection to the server was lost. This error may be used locally, but must not be return by a server. WinSCP does not use the code.
8 Operation unsupported An attempted operation could not be completed by the server because the server does not support the operation. It may be returned by the server if the server does not implement an operation.
9 Invalid handle The handle value was invalid.
10 No such path The file path does not exist or is invalid.
11 File already exists The file already exists.
12 Write protect The file is on read-only media, or the media is write protected.
13 No media The requested operation cannot be completed because there is no media available in the drive.
14 No space on file-system The requested operation cannot be completed because there is insufficient free space on the filesystem.
15 Quota exceeded The operation cannot be completed because it would exceed the user’s storage quota.
16 Unknown principal A principal referenced by the request (either the owner, group, or who field of an ACL), was unknown.
17 Lock conflict The file could not be opened because it is locked by another process.
18 Directory not empty The directory is not empty.
19 Not a directory The specified file is not a directory.
20 Invalid filename The filename is not valid.
21 Link loop Too many symbolic links encountered or, an SSH_FXF_NOFOLLOW open encountered a symbolic link as the final component
22 Cannot delete The file cannot be deleted. One possible reason is that the advisory read-only attribute-bit is set.
23 Invalid parameter One of the parameters was out of range, or the parameters specified cannot be used together.
24 File is a directory The specified file was a directory in a context where a directory cannot be used.
25 Range lock conflict A read or write operation failed because another process’s mandatory byte-range lock overlaps with the request. WinSCP does not use byte range locking.
26 Range lock refused A request for a byte range lock was refused. WinSCP does not use byte range locking.
27 Delete pending An operation was attempted on a file for which a delete operation is pending.
28 File corrupt The file is corrupt; an filesystem integrity check should be run.
29 Owner invalid The principal specified can not be assigned as an owner of a file.
30 Group invalid The principal specified can not be assigned as the primary group of a file.
31 No matching byte range lock The requested operation could not be completed because the specified byte range lock has not been granted. WinSCP does not use byte range locking.

Advertisement

References

  • Status response section of draft-ietf-secsh-filexfer-13;
  • SFTP specifications list in “History and development” section of SSH File Transfer Protocol.

Аватара пользователя

Zyxmon

Администратор
Сообщения: 1904
Зарегистрирован: 09 авг 2015, 15:33

Yrzorg писал(а):Источник цитаты я поставил Entware3x-alt, но использую прошивочный openssh

Как у Вас всё запущенно! Ведь при этом установлен и openssh из entware и он, скорее всего, в PATH раньше, чем прошивочный. Сходу не представляю, как разбираться с возникшем бардаком.


Yrzorg

Сообщения: 82
Зарегистрирован: 05 окт 2015, 13:23

Сообщение Yrzorg » 16 май 2017, 23:55

Честно говоря не вижу причин для паники, openssh из entware хоть и установлен, но не запущен и не используется, т.к. его использование влечёт за собой определённые проблемы. Мне больше любопытно, почему mc ищет конфиг в другом месте, считая при этом /home/admin домашней директорией


 

Код: Выделить всё

[admin@KN-ULTRA2 : /opt/home/admin]#>mc -F
Home directory: /home/admin
Profile root directory: /home/admin

[System data]
    Config directory: /opt/etc/mc/
    Data directory:   /opt/share/mc/
    File extension handlers: /opt/lib/mc/ext.d/
    VFS plugins and scripts: /opt/lib/mc/
        extfs.d:        /opt/lib/mc/extfs.d/
        fish:           /opt/lib/mc/fish/

[User data]
    Config directory: /opt/etc/mc/
    Data directory:   /opt/etc/mc/
        skins:          /opt/etc/mc/skins/
        extfs.d:        /opt/etc/mc/extfs.d/
        fish:           /opt/etc/mc/fish/
        mcedit macros:  /opt/etc/mc/mc.macros
        mcedit external macros: /opt/etc/mc/mcedit/macros.d/macro.*
    Cache directory:  /opt/etc/mc/

Keenetic Ultra II+Entware
NDMS 3.7


Аватара пользователя

Zyxmon

Администратор
Сообщения: 1904
Зарегистрирован: 09 авг 2015, 15:33

Сообщение Zyxmon » 17 май 2017, 00:12

Yrzorg писал(а):Источник цитаты его использование влечёт за собой определённые проблемы.

Какие проблемы? Думаю как раз тут решение проблемы.

Yrzorg писал(а):Источник цитаты почему mc ищет конфиг в другом месте, считая при этом /home/admin домашней директорией

Домашняя директория задается в /etc/passwd (стандартная установка) или в /opt/etc/passwd (альтернативная) или переменной HOME. Все конфиги самого mc на месте. Что не так?


kaztost

Сообщения: 223
Зарегистрирован: 17 июл 2017, 00:29

Сообщение kaztost » 18 июл 2017, 18:46

А что, я один на Entware сталкиваюсь с проблемой «Failed opening remote file (-31)» при копировании с sftp-сервера по SFTP link?


 

screen.jpg
screen.jpg (52.18 КБ) 3796 просмотров

Если нажать на Enter, то файл будет скопирован, и ошибка возникнет на следующем файле. Это похоже тикет3406. Я уже давно решил, что SFTP link в энтварных mc безнадежно сломан, и, поэтому, пользовался беспроблемным shell link. А тут смотрю, что-то обсуждается еще. Может и решение есть, которое я не знаю?


Yrzorg

Сообщения: 82
Зарегистрирован: 05 окт 2015, 13:23

Сообщение Yrzorg » 20 июл 2017, 00:51

SFTP link в энтварных mc безнадежно сломан

у меня он поломался окончательно, теперь всё время требует некий пароль


 

2017-07-19_234622.jpg
2017-07-19_234622.jpg (14.74 КБ) 3778 просмотров

Keenetic Ultra II+Entware
NDMS 3.7


kaztost

Сообщения: 223
Зарегистрирован: 17 июл 2017, 00:29

Сообщение kaztost » 20 июл 2017, 02:11

Yrzorg писал(а):Источник цитаты теперь всё время требует некий пароль

Что-то такое у меня было ранее на старых сборках. Потом как-то само починилось и стало ключи принимать. Но ошибки при копировании остались. Поэтому пользую Shell link. Хоть он и не умеет ходить по симлинкам (а для андроида это насущно), но зато работает без ошибок.


Yrzorg

Сообщения: 82
Зарегистрирован: 05 окт 2015, 13:23

Сообщение Yrzorg » 22 дек 2017, 23:00

Yrzorg писал(а):Источник цитаты у меня он поломался окончательно, теперь всё время требует некий пароль

заборол таки эту проблему, всё оказалось просто:
из-за путаницы (и моей невнимательности) с HOME — mc не там искал ключи
почему то mc упорно хочет видеть их в /opt/root/.ssh, но в тоже время признаёт, что домашняя директория в /home/admin

Код: Выделить всё

[admin@KN-ULTRA2 : /opt/home/admin]#>mc -F
Home directory: /home/admin
Profile root directory: /home/admin

терзают смутные сомнения, что это у него где-то жёстко зашито

Keenetic Ultra II+Entware
NDMS 3.7


kaztost

Сообщения: 223
Зарегистрирован: 17 июл 2017, 00:29

Сообщение kaztost » 23 дек 2017, 11:55

По идее в vfs/sftpfs/config_parser.c должно стоять

#ifndef SFTPFS_SSH_CONFIG
#define SFTPFS_SSH_CONFIG «~/.ssh/config»
#endif

Возможно проблема возникает при сборке mc не здесь, а где-то выше, где криво определяется SFTPFS_SSH_CONFIG.


Аватара пользователя

Zyxmon

Администратор
Сообщения: 1904
Зарегистрирован: 09 авг 2015, 15:33

Сообщение Zyxmon » 23 дек 2017, 12:55

Проблема скорее в том, что в прошивке Падавана суперпользователь не root, а admin. Последнее легко решается альтернативной установкой Entware-3x (для Android другой и быть не может).


Кто сейчас на конференции

Всего 3 посетителя :: 0 зарегистрированных, 0 скрытых и 3 гостя (основано на активности пользователей за последние 5 минут)
Больше всего посетителей (162) здесь было 16 ноя 2019, 18:33

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя

@Taxxodium

When you initiate an upload, the library will return an error about being unable to stat the file even though the file was uploaded successfully.

The part where this happens is in the file DLSFTPUploadRequest.m around line 275

I’ve tried fixing it but without any luck.

Here’s the code I’ve been playing with:

// stat the remote file after uploading
LIBSSH2_SFTP_ATTRIBUTES attributes;
while ( ((result = libssh2_sftp_fstat(self.handle, &attributes)) == LIBSSH2SFTP_EAGAIN)
&& self.isCancelled == NO){
waitsocket(socketFD, session);
}
if ([self ready] == NO) {
[self.connection requestDidFail:self withError:self.error];
return; }

// result is always LIBSSH2_ERROR_SFTP_PROTOCOL
if (result == LIBSSH2_ERROR_SFTP_PROTOCOL) {
result = libssh2_sftp_last_error([self.connection sftp]);

// usually result at this point is LIBSSH2_FX_FAILURE
if (result != LIBSSH2_FX_OK) {
result = libssh2_sftp_stat([self.connection sftp], [self.remotePath UTF8String], NULL);
}
}

@dleehr

Originally notified via email, responded with:

t looks like the error is coming from here. If you can set a breakpoint and confirm, that would be great:

while ( ((result = libssh2_sftp_fstat(self.handle, &attributes)) == LIBSSH2SFTP_EAGAIN)

After the file is transferred, DLSFTPClient tries to stat the file — to get its attributes on the server — file size, permissions, type, etc. http://www.libssh2.org/libssh2_sftp_fstat_ex.html. If this fails, the request fails (even though the file likely uploaded).

Error -31 is LIBSSH2_ERROR_SFTP_PROTOCOL (defined in libssh2.h). It means there was an error at the protocol level, but it looks like we need a call to libssh2_sftp_last_error to get the underlying reason.

I found a similar case here: http://www.libssh2.org/mail/libssh2-devel-archive-2010-04/0108.shtml where the underlying reason was NO_SUCH_FILE. So maybe the file is being uploaded to a symlinked directory and the stat isn’t working there?

  • Печать

Страницы: [1]   Вниз

Тема: Не могу подключиться по SFTP  (Прочитано 14363 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн
neonox

Доброго времени суток. Прошу помочь разобраться в проблеме.

Дано:
VPS — Ubuntu Server 12.04
SSH сервер
Пользователь которому нужно получить доступ к серверу по SFTP

Требуется подключиться к серверу используя WinSCP по протоколу SFTP. При попытке подключиться получаю ошибку

Cannot initialize SFTP protocol. Is the host running a SFTP server?

Вот конфиг sshd_config


Оффлайн
AnrDaemon

Port 22

И показывайте найтройки WinSCP.

Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…


Оффлайн
fisher74

видимо параноя требует порт 2222, так что надо просто перепроверить что в настройках соответствие в WinSCP
И ещё один вопрос. А ssh работает? пробовали подключаться
что показывает телнет

telnet ip-server 2222


Оффлайн
ArcFi

И на самом сервере проверяйте:

sudo ss -lnpt | grep :22


Оффлайн
neonox

Изменил порт на 22, т.к. и через SSH не смог подключиться. Через SSH подключаюсь нормально, но через WinSCP так и не могу подключиться. Ошибка происходит на этапе ввода пароля пользователя

sudo ss -lnpt | grep :22
LISTEN     0      128                      :::22                      :::*      users:(("sshd",6748,4))
LISTEN     0      128                       *:22                       *:*      users:(("sshd",6748,3))


Оффлайн
ArcFi

От меня пишет, что порт открыт:

$ nmap 146.185.166.31 -p22 -sV | grep ^22
22/tcp open  ssh     OpenSSH 5.9p1 Debian 5ubuntu1.1 (Ubuntu Linux; protocol 2.0)


Оффлайн
AnrDaemon

через WinSCP так и не могу подключиться. Ошибка происходит на этапе ввода пароля пользователя

Тогда, вероятно, проблема не в настройках? :)

Хотите получить помощь? Потрудитесь представить запрошенную информацию в полном объёме.

Прежде чем [Отправить], нажми [Просмотр] и прочти собственное сообщение. Сам-то понял, что написал?…


Оффлайн
neonox

Тогда, вероятно, проблема не в настройках? :)

Собственно, какая картина сейчас.
Подключиться под рутом получается.
При попытке подключиться одним из указанных пользователей через Putty после ввода пароль программа вылетает. WinSCP так же не подключается.

Вот что в логах, при попытке подключиться через Putty

Oct 27 11:55:42 146 sshd[11575]: Accepted password for imanit_msk from 213.145.28.xxх port 49655 ssh2
Oct 27 11:55:42 146 sshd[11575]: pam_unix(sshd:session): session opened for user imanit_msk by (uid=0)
Oct 27 11:55:42 146 sshd[11575]: pam_unix(sshd:session): session closed for user imanit_msk

Пробовал добавлять пользователей в группу ssh, пробовал разрешать доступ к SSH только этим пользователям. Увы, все безрезультатно. Не могу понять, что я делаю не так.


Пользователь решил продолжить мысль 27 Октября 2013, 16:06:33:


Всем спасибо за помощь. Решил проблему. Дело было в оболочке. Вместо /bin/bash была /bin/date.

« Последнее редактирование: 27 Октября 2013, 16:06:33 от neonox »


Оффлайн
fisher74

Подключиться под рутом получается.

Эммм, так ведь

Вот конфиг sshd_config
..
PermitRootLogin no

Или уже и до этого параметра дошли в процессе изыскания?
Не забудьте вернуть назад

Дело было в оболочке. Вместо /bin/bash была /bin/date.

Этож как надо изголиться, чтобы /bin/date в качестве оболочки выставить….?


Оффлайн
neonox

Или уже и до этого параметра дошли в процессе изыскания?
Не забудьте вернуть назад

Да, пробовал, проверял. Уже вернул обратно.

Этож как надо изголиться, чтобы /bin/date в качестве оболочки выставить….?

создавал пользователей через ISPmanager


  • Печать

Страницы: [1]   Вверх

Moderators: Stefan2, white, Hacker

User avatar

Mikefield

Power Member
Power Member
Posts: 627
Joined: 2006-02-26, 19:13 UTC
Location: Oberursel, Germany HE

Thanks Christian for the new beta. I’ve tested it, same (no) information in logfile using TC 64bit.
But additionally tested with TC 32bit, there is a
«SCP download error: CHANNEL_REQUEST_DENIED (22)»
and a
«SCP upload error: SCP_PROTOCOL (28 )»
Error message.

Today I got another download problem, there was following error message:
«Download read error: SFTP_PROTOCOL (31)» (TC 32bit)
But with winscp download was working.

Could you please check, why 64bit and 32bit have different logfile information?
Since Win8.1 I use TC 64bit only.

mf

Bankster — Word of the Year 2009

User avatar

ghisler(Author)

Site Admin
Site Admin
Posts: 44454
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post

by *ghisler(Author) » 2017-03-27, 12:30 UTC

It looks like the server (or in your case, the balabit box) disallowed the SCP calls (request denied). Does the balabit box create a log?

Could you please check, why 64bit and 32bit have different logfile information?
Since Win8.1 I use TC 64bit only.

Sorry, it looks like I included the old wfx64 in the beta.

AndrewCreator

Member
Member
Posts: 122
Joined: 2011-10-10, 23:25 UTC

Post

by *AndrewCreator » 2017-03-31, 05:36 UTC

2ghisler(Author)
Will 1.4.3 work with libssh2 from curl.haxx.se?

Meanwhile, thank you for fixing dll loading problem in 1.4.2. Version 1.4.1 32-bit was not loading zlib1.dll from plugin dir, should place it in TC dir. Btw, 1.4.1 64-bit was loading zlib1.dll from plugin64 dir.

User avatar

Mikefield

Power Member
Power Member
Posts: 627
Joined: 2006-02-26, 19:13 UTC
Location: Oberursel, Germany HE

Post

by *Mikefield » 2017-03-31, 18:24 UTC

Bankster — Word of the Year 2009

AndrewCreator

Member
Member
Posts: 122
Joined: 2011-10-10, 23:25 UTC

Post

by *AndrewCreator » 2017-04-01, 14:59 UTC

2Mikefield
Sure, that’s why I am asking whether the support for the old libssh2 will be added in a release. Beta does not work with libssh2 from curl.haxx.se, it shows the standard dialog that you should put libraries in plugin or TC dir.

UPD
Beta is not working with libssh2 from curl.haxx.se in 32-bit version only. 64-bit version is OK. Cause: zlib1.dll is not loaded from plugin dir. Very similar to 1.4.1 bug.

Code: Select all

18:42:31,9833668 totalcmd.exe   10992 Load Image D:TCpluginssftplibeay32.dll    SUCCESS Image Base: 0x63000000, Image Size: 0x1a9000
18:42:31,9836574 totalcmd.exe   10992 Load Image D:TCpluginssftplibssh2.dll     SUCCESS Image Base: 0x6ea80000, Image Size: 0x32000
18:43:06,5534560 totalcmd64.exe  3848 Load Image D:TCpluginssftp64zlib1.dll    SUCCESS Image Base: 0x62e80000, Image Size: 0x1e000
18:43:06,5538867 totalcmd64.exe  3848 Load Image D:TCpluginssftp64libeay32.dll SUCCESS Image Base: 0x63000000, Image Size: 0x16c000
18:43:06,5542937 totalcmd64.exe  3848 Load Image D:TCpluginssftp64libssh2.dll  SUCCESS Image Base: 0x6ea80000, Image Size: 0x2b000

User avatar

Mikefield

Power Member
Power Member
Posts: 627
Joined: 2006-02-26, 19:13 UTC
Location: Oberursel, Germany HE

Post

by *Mikefield » 2017-04-02, 11:40 UTC

Why did you need the old libssh2 from curl.haxx.se?
Did you use Windows XP yet?

mf

Bankster — Word of the Year 2009

User avatar

ghisler(Author)

Site Admin
Site Admin
Posts: 44454
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post

by *ghisler(Author) » 2017-04-03, 13:05 UTC

2AndrewCreator
Yes, the old dlls should still work. But you are right that zlib1.dll isn’t found in plugin dir — I will fix it.

User avatar

Horst.Epp

Power Member
Power Member
Posts: 5469
Joined: 2003-02-06, 17:36 UTC
Location: Germany

Post

by *Horst.Epp » 2017-04-03, 14:09 UTC

AndrewCreator wrote:Windows Server 2003.

No security patches for this OS since 2015 and known big security holes.

Windows 11 Home x64 Version 22H2 (OS Build 22621.1194)
TC 10.52 x64 / x86
Everything 1.5.0.1337a (x64)

AndrewCreator

Member
Member
Posts: 122
Joined: 2011-10-10, 23:25 UTC

Post

by *AndrewCreator » 2017-04-04, 12:06 UTC

2ghisler(Author), nice, thank you!

2Horst.Epp, yep, it is used standalone in my private virtual network without any access to other networks.

tmcdos

Junior Member
Junior Member
Posts: 30
Joined: 2006-05-22, 18:29 UTC
Location: Sofia, Bulgaria
Contact:

Problem with showing symlinks

Post

by *tmcdos » 2017-05-08, 18:15 UTC

One of my clients provided me an SSH access to one of its servers hosted at BraveHost. I have downloaded the latest 1.4.3beta-3 version of the plugin and tried to setup a connection. When I try to connect, I receive an error:

Error: could not initialize SFTP session!
Unable to request SFTP subsystem

So I put ticks on both checkboxes for using SCP — now I am able to connect but some symlinks are shown as regular files and so I am unable to CHDIR into those symlinked folders. WinSCP properly recognizes the problematic symlinks.

Image: http://test.ivogelov.com/working.png
Image: http://test.ivogelov.com/not_working.png
Image: http://test.ivogelov.com/win_scp.png

User avatar

ghisler(Author)

Site Admin
Site Admin
Posts: 44454
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post

by *ghisler(Author) » 2017-05-11, 09:09 UTC

I can confirm that symlinks aren’t recognized in SCP only mode. I will try to find a solution. The ~ link is added by the plugin to go quickly to the user’s home folder, it’s not provided by the server.

sevec

Junior Member
Junior Member
Posts: 5
Joined: 2016-05-19, 05:34 UTC

Post

by *sevec » 2017-06-15, 09:24 UTC

Hello, when I upload file to server (gnu linux), it gets 644 access permissions. How can I instruct SFTP plugin to set the permissions of the uploaded file to 660? Thank you.

User avatar

ghisler(Author)

Site Admin
Site Admin
Posts: 44454
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post

by *ghisler(Author) » 2017-06-15, 09:39 UTC

This should work via connection settings (Alt+Enter), you can set the permissions for files and for folders separately.

Graphity

Junior Member
Junior Member
Posts: 6
Joined: 2005-03-25, 11:10 UTC
Location: München
Contact:

Problem: fatal: no matching mac found

Post

by *Graphity » 2017-09-11, 09:19 UTC

When I try to connect to one of my Raspberry Pis, I get the following error in auth log of the Pi:

fatal: no matching mac found: client hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com server hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com [preauth]

I’m using secure ftp plugin version 1.4.2 beta 1 and have copied three DLLs from curl-7.40.0-devel-mingw64.7z to plugin’s directory.

I don’t find a log file of total commander to provide more information about this on client side.

Of all the things I’ve lost, I miss my mind the most

I’m trying to reproduce a problem where when some of our clients can receive a wrong file contents while downloading with SFTP protocol.

Based on our SFTP server (CrushFTP) logs they probably open multiple files in one session and then use some pipelining to download the files. I don’t know what kind of library they use as they are using some SAAS provider for this.

I’m trying to reproduce the behavior with libssh2, but I’m getting sftp_read() internal error when calling libssh2_sftp_read asynchronously on the second open file after the first one returned LIBSSH2_ERROR_EAGAIN — even on localhost connection to OpenSSH.

While browsing SSH File Transfer Protocol IETF Draft I can see that the protocol allows for opening multiple files simultaneously and requesting their contents with multiple SSH_FXP_READ request without waiting for response.

Below is the code I use for testing (SSCCE, but quite long — C is quite verbose) — compiled with gcc sftp_multifile.c -lssh2 -Wall -g -o sftp_multifile and tested with:

./sftp_multifile localhost 22 testusername testpassword /usr/share/dict/words /usr/share/doc/words/readme.txt

connect try: ai_family=10 ai_socktype=1 ai_protocol=6 addr=::1 port=22
opening: /usr/share/dict/words
opening: /usr/share/doc/words/readme.txt
reading: /usr/share/dict/words from 10134400 to 140736927200896
read result: -37
reading: /usr/share/doc/words/readme.txt from 10135536 to 140736927201920
read result: -31
Bad read result: -31
Read error: /usr/share/doc/words/readme.txt: sftp_read() internal error

Did I make an error in my code or does libssh2 just not support pipelining libssh2_sftp_read for multiple open files or maybe it’s just a bug in libssh2 that should be reported to its maintainer?

#include <libssh2.h>
#include <libssh2_sftp.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <poll.h>
#include <arpa/inet.h>

#define CHUNK_SIZE (1024)

int sftp_connect(char const* hostname, char const* port)
{
    struct addrinfo* addrinfo_result, *addrinfo_current;
    int sfd, s;
    struct addrinfo addrinfo_hints = {0};
    addrinfo_hints.ai_family = AF_UNSPEC;
    addrinfo_hints.ai_socktype = SOCK_STREAM;
    s = getaddrinfo(hostname, port, &addrinfo_hints, &addrinfo_result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %sn", gai_strerror(s));
        exit(EXIT_FAILURE);
    }
    
    for (addrinfo_current = addrinfo_result; addrinfo_current != NULL; addrinfo_current = addrinfo_current->ai_next) {
        char s[INET6_ADDRSTRLEN];
        sfd = socket(addrinfo_current->ai_family, addrinfo_current->ai_socktype, addrinfo_current->ai_protocol);
        if (sfd == -1) continue;
        {
            void* addr;
            in_port_t port;
            switch(addrinfo_current->ai_family) {
                case AF_INET: {
                    struct sockaddr_in* sockaddr = (struct sockaddr_in*)addrinfo_current->ai_addr;
                    addr = &(sockaddr->sin_addr);
                    port = ntohs(sockaddr->sin_port);
                    break;
                }
                case AF_INET6: {
                    struct sockaddr_in6* sockaddr = (struct sockaddr_in6*)addrinfo_current->ai_addr;
                    addr = &(sockaddr->sin6_addr);
                    port = ntohs(sockaddr->sin6_port);
                    break;
                }
                default:
                    fprintf(stderr, "unknown family: %dn", addrinfo_current->ai_family);
                    exit(EXIT_FAILURE);
            }
            inet_ntop(addrinfo_current->ai_family, addr, s, INET6_ADDRSTRLEN);
            fprintf(stderr, "connect try: ai_family=%d ai_socktype=%d ai_protocol=%d addr=%s port=%dn", addrinfo_current->ai_family, addrinfo_current->ai_socktype, addrinfo_current->ai_protocol, s, port);
        }
        if (connect(sfd, addrinfo_current->ai_addr, addrinfo_current->ai_addrlen) != 0) {
            fprintf(stderr, "connect: %sn", strerror(errno));
            close(sfd);
            continue;
        }
        break;
    }
    if (addrinfo_current == NULL) {
        fprintf(stderr, "connection failedn");
        exit(EXIT_FAILURE);
    }
    freeaddrinfo(addrinfo_result);
    return sfd;
}

void retrieve_files(int socket, LIBSSH2_SESSION* session, LIBSSH2_SFTP *sftp_session, int filec, char *filev[])
{
    LIBSSH2_SFTP_HANDLE* sftp_handles[filec];
    int finished[filec];
    int toread = filec;
    for(int i=0; i<filec; i++) {
        fprintf(stderr, "opening: %sn", filev[i]);
        sftp_handles[i] = libssh2_sftp_open(sftp_session, filev[i], LIBSSH2_FXF_READ, 0);
        if (!sftp_handles[i]) {
            char* errmsg;
            libssh2_session_last_error(session, &errmsg, NULL, 0);
            fprintf(stderr, "Failure opening remote file: %s: %sn", filev[i], errmsg);
            exit(EXIT_FAILURE);
        }
        finished[i]=0;
    }
    char buffer[CHUNK_SIZE];
    libssh2_session_set_blocking(session, 0);
    while (toread) {
        for(int i=0; i<filec; i++) {
            if (finished[i]) {
                continue;
            } else {
                int read_result;
                do {
                    fprintf(stderr, "reading: %s from %ld to %ldn", filev[i], (long)sftp_handles[i], (long)(buffer+CHUNK_SIZE*i));
                    read_result = libssh2_sftp_read(sftp_handles[i], buffer, CHUNK_SIZE);
                    fprintf(stderr, "read result: %dn", read_result);
                    if (read_result > 0) {
                        printf("%s: ", filev[i]);
                        fwrite(buffer, sizeof(char), read_result, stdout);
                        printf("n");
                    } else {
                        break;
                    }
                } while (1);
                if (read_result == LIBSSH2_ERROR_EAGAIN) {
                    continue;
                } else if (read_result == 0) {
                    finished[i] = 1;
                    toread--;
                } else {
                    fprintf(stderr, "Bad read result: %dn", read_result);
                    char* errmsg;
                    libssh2_session_last_error(session, &errmsg, NULL, 0);
                    fprintf(stderr, "Read error: %s: %sn", filev[i], errmsg);
                    exit(EXIT_FAILURE);
                }
            }
        }
        if (toread) {
            struct pollfd fds[1] = {0};
            fds[0].fd = socket;
            fds[0].events = POLLIN;
            poll(fds, 1, 3000);
        }
    }
}

int main(int argc, char *argv[])
{
    LIBSSH2_SESSION *session;
    LIBSSH2_SFTP *sftp_session;
    int rc, sock;
    
    if (argc<6) {
        fprintf(stderr, "Usage: %s hostname port username password file1 [file2] [file3...]n", argv[0]);
        return EXIT_FAILURE;
    }
    
    sock = sftp_connect(argv[1], argv[2]);
    session = libssh2_session_init();
    if (!session) {
        return EXIT_FAILURE;
    }
    rc = libssh2_session_handshake(session, sock);
    if (rc) {
        char* errmsg;
        libssh2_session_last_error(session, &errmsg, NULL, 0);
        fprintf(stderr, "Failure establishing SSH session: %sn", errmsg);
        return EXIT_FAILURE;
    }
    rc = libssh2_userauth_password(session, argv[3], argv[4]);
    if (rc) {
        char* errmsg;
        libssh2_session_last_error(session, &errmsg, NULL, 0);
        fprintf(stderr, "%sn", errmsg);
        return EXIT_FAILURE;
    }
    
    sftp_session = libssh2_sftp_init(session);
    if (sftp_session == NULL) {
        char* errmsg;
        libssh2_session_last_error(session, &errmsg, NULL, 0);
        fprintf(stderr, "Unable to init SFTP session: %sn", errmsg);
        return EXIT_FAILURE;
    }

    retrieve_files(sock, session, sftp_session, argc-5, argv+5);

    libssh2_session_set_blocking(session, 1);
    libssh2_sftp_shutdown(sftp_session);
    libssh2_session_disconnect(session, "");
    libssh2_session_free(session);
    libssh2_exit();
    return EXIT_SUCCESS;
}

Понравилась статья? Поделить с друзьями:
  • Sftp connection failed kex error
  • Sfml graphics d 2 dll ошибка
  • Sfm как изменить размер модели
  • Shippingpc bmgame exe ошибка batman как исправить
  • Shindaiwa real dual 500 ошибка e06