From libssh2-devel-bounces@cool.haxx.se Sat Jul 1 18:52:36 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v61GptJv032253; Sat, 1 Jul 2017 18:52:27 +0200 Received: from mail-qk0-x235.google.com (mail-qk0-x235.google.com [IPv6:2607:f8b0:400d:c09:0:0:0:235]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v61GpqZg032232 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Sat, 1 Jul 2017 18:51:52 +0200 Received: by mail-qk0-x235.google.com with SMTP id 16so121511147qkg.2 for ; Sat, 01 Jul 2017 09:51:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=EJxfzPBKG/QpMGONA9lIx4UnK/hWNw8O89XUAyWSp70=; b=DafPbML+A/Ix+4dkfxJpiFH8hPuE1pVf9Os+NH8qrh5UUmHHVzGdNDC2PGY8KjdC9I j2zVUdAadpztVSpimNczUkfu3intFOhiCwgTMxGf4mZilQKNvsbd0V7yC7+j4r8IETpU suVwvHM32VqELIf9lR6YN7WkwayqsF2HbdNPhK6eZ1gW1ZZGvO529iFfe6cf+6i/SZVY CNIYmWxIVbES/4GE2kIakTDxeVIlzO3/07vA6XTex8fjb9im3TUmg1j0XCpDuMcRFSco NYaPseNheePAv7bysqBKJsMdig7nBU+c1X+iPgUX59Vnz4XPOvflOc86F7J161vR56A6 MTUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=EJxfzPBKG/QpMGONA9lIx4UnK/hWNw8O89XUAyWSp70=; b=bsGUNkMlBtbCNYw/6ZQRQCgFe+Y8ljElJoFE2CHKEMK2m0jAo5DJJIGU5EUrNTWxiO 1F7mxVmKgMpjH+Tu6K96bPpnIUBEQ+abDbiNZBnMB1M7M/vhC3yWJxzdh0Onm5QkKgM2 vkXmu031AAefbd8AS2d9c6Vsg4zcQ6/cAIszf8uEXHyPRvrNgy2Yr+SoKVhFx+6XIkXF kUvtkTdH32GxcLfClLHSVzyNXLTtrrkrUdbgnWIQOrLwsngqDcn/SS+f+mlThgeRVsCy bYMv8uW0WnrnOo+rjZR3NX98G1aGTMzHFtvB/z4xLOaOpUL1zbsh2dMZV1lcQ3gA/gE2 2Xeg== X-Gm-Message-State: AKS2vOzRDG1gjE092IyfJW1qZ5naBehxzj+98nUv6jGXvM33XHgGzsrT QL5Rz1IoRmP6h3iCUb/ciiqkvmxpENAp X-Received: by 10.55.111.134 with SMTP id k128mr30725171qkc.206.1498927907393; Sat, 01 Jul 2017 09:51:47 -0700 (PDT) MIME-Version: 1.0 Received: by 10.237.60.92 with HTTP; Sat, 1 Jul 2017 09:51:46 -0700 (PDT) Date: Sat, 1 Jul 2017 19:51:46 +0300 Message-ID: Subject: unsolicited data is not queued to the buffer. Am i reading a wrong stream ? To: libssh2-devel@cool.haxx.se X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sten Kultakangas via libssh2-devel Reply-To: libssh2 development Cc: Sten Kultakangas Content-Type: multipart/mixed; boundary="===============1353175874==" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" --===============1353175874== Content-Type: multipart/alternative; boundary="94eb2c059da876d544055344594d" --94eb2c059da876d544055344594d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello I am using libssh2 with libevent in my application and i ran into the following issue. I do not receive all data that is supposed to come through the terminal. Some of that data can be noticed in libssh2 debug output: =3D> libssh2_transport_read() plain (158 bytes) 0000: 5E 00 00 00 00 00 00 00 95 0A 0D 0A 0D 53 79 73 : ^............Sys 0010: 74 65 6D 3A 20 4C 61 72 67 65 20 20 20 20 20 20 : tem: Large 0020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 : 0030: 20 20 53 6F 66 74 77 61 72 65 20 56 65 72 73 69 : Software Versi 0040: 6F 6E 3A 20 52 30 31 36 78 2E 30 33 2E 30 2E 31 : on: R016x.03.0.1 0050: 32 34 2E 30 1B 5B 42 0A 0D 54 65 72 6D 69 6E 61 : 24.0.[B..Termina 0060: 6C 20 54 79 70 65 20 28 35 31 33 2C 20 37 31 35 : l Type (513, 715 0070: 2C 20 34 34 31 30 2C 20 34 34 32 35 2C 20 56 54 : , 4410, 4425, VT 0080: 32 32 30 2C 20 4E 54 54 2C 20 57 32 4B 54 54 2C : 220, NTT, W2KTT, 0090: 20 53 55 4E 54 29 3A 20 5B 35 31 33 5D 20 : SUNT): [513] [libssh2] 3.686087 Transport: Packet type 94 received, length=3D158 Only terminal sequence c [1;24r [1;1H [0J followed by "System: Large Software Version: R016x.03.0.124.0 [B" was delivered to my application, My application calls libssh2_channel_read_ex until evbuffer_remove returns nothing. This approach worked in all my network application. I tried streams 0 and 1. When i am reading stream 1, the applications does not receive any data from sshd. I opened normal ssh client and logged in to the system without choosing the terminal type. Then i opened another ssh client process and logged to the system, choiced the terminal type and issued the "wall" command. The contents of the broadcast message was displayed in both instances of the normal ssh client. However, the application does not receive that data even according to libssh2_transport_read debug output. So there are at least two questions: 1) why only "System: Large Software Version: R016x.03.0.124.0 [B" was delivered to my application, but not "Software Version: R016x.03.0.124.0.[B..Terminal Type (513, 715, 4410, 4425, VT220, NTT, W2KTT, SUNT): [513]" ? The latter was also present in libssh2 debug output. 2) why unsolicited "wall" messages are not delivered neither through standard stream nor through stderr stream ? Is there any special stream that i'm missing? How to get the list of all available streams ? Last time when i ran the application i got the following output: 16:34:57.724 BCMSMonitor::OnReadLine: Data: System: Large Software Version: R016x.03.0.124.0=E2=86=90[B 16:34:57.724 BCMSMonitor::OnReadLine: Data: 16:34:57.724 GenericClient::SSH_read_channel: Calling libssh2_channel_read_ex() with 8123 [libssh2] 3.725187 Conn: channel_read() wants 8123 bytes from channel 0/0 stream #0 16:34:57.725 GenericClient::SSH_recv: read operation result: 0, wanted 16384 bytes which indicates that "recv" notifications on the socket were re-enabled. However, sshd server is still not sending unsolicited data to my application although it is is sending it to normal ssh client. Here's the relevant code: ssize_t GenericClient::SSH_recv( libssh2_socket_t fd, void *buf, size_t len, int, void **) { auto ctx =3D reinterpret_cast(fd); Scope; if(!ctx->ssh_input) { Trace << "someone wanted to read " << len << " bytes too early"; return -EAGAIN; } auto rc =3D evbuffer_remove(ctx->ssh_input, buf, len); Trace << "read operation result: " << rc << ", wanted " << len << " bytes"; if(rc < 0) return -EAGAIN; if(rc =3D=3D 0 && len !=3D 0) return -EAGAIN; return rc; } ssize_t GenericClient::SSH_send( libssh2_socket_t fd, const void *buf, size_t len, int, void **) { auto ctx =3D reinterpret_cast(fd); if(bufferevent_write(ctx->bev, buf, len) =3D=3D 0) return len; return -1; } bool GenericClient::Reconnect() { Scope; Disconnect(); switch(security) { case Security::none: case Security::ssh: bev =3D bufferevent_socket_new( service->base, -1, BEV_OPT_CLOSE_ON_FREE); if(security =3D=3D Security::none) break; ssh =3D libssh2_session_init(); if(!ssh) { Fatal << GetName() << ": libssh2_session_init failed"; return false; } libssh2_session_set_blocking(ssh, 0); libssh2_session_callback_set(ssh, LIBSSH2_CALLBACK_SEND, (void *)SSH_send); libssh2_session_callback_set(ssh, LIBSSH2_CALLBACK_RECV, (void *)SSH_recv); libssh2_trace(ssh, ~0); break; case Security::ssl: //... default: Fatal << GetName() << ": invalid security specifier"; return false; } if(!bev) { Error << GetName() << ": socket allocation failed"; return false; } bufferevent_setcb(bev, GetReader(), GetWriter(), GetEventHandler(), this); bufferevent_enable(bev, EV_READ | EV_WRITE); if(bufferevent_socket_connect_hostname( bev, service->dns_base, AF_UNSPEC, host.c_str(), port) !=3D 0) { Error << GetName() << ": connection attempt cannot be initiated"; return false; } Trace << GetName() << ": connecting"; state =3D State::connecting; return true; } bool GenericClient::Connect(const string &new_destination, Security new_security= ) { destination =3D new_destination; security =3D new_security; auto colon =3D destination.find_last_of(':'); if(colon =3D=3D string::npos) { Scope; Error << GetName() << ": destination port not specified"; return false; } host =3D destination.substr(0, colon); port =3D strtoll(destination.substr(colon + 1).c_str(), 0, 10); return Reconnect(); } bool GenericClient::SSH_handshake() { Scope; auto rc =3D libssh2_session_handshake( ssh, reinterpret_cast(this) ); if(rc !=3D 0) { if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } // FIXME: check host fingerprint state =3D State::getting_authentication_methods; Trace << GetName() << ": getting authentication methods"; return SSH_get_authnetication_methods(); } bool GenericClient::SSH_get_authnetication_methods() { Scope; auto list =3D libssh2_userauth_list(ssh, username.c_str(), username.size())= ; if(list =3D=3D 0) { auto rc =3D libssh2_session_last_error(ssh, 0, 0, 0); if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } state =3D State::authenticating; Trace << GetName() << ": authenticating using " << list; return SSH_authenticate(); } void GenericClient::SSH_authentication_response( const char *name_str, int name_len, const char *instruction_str, int instruction_len, int num_prompts, const struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) { string name(name_str, name_len); string instruction(instruction_str, instruction_len); Scope; Info << "Name: " << name; Info << "Instruction: " << instruction; for(auto i =3D 0; i < num_prompts; i++) { string prompt(prompts[i].text, prompts[i].length); Info << "Prompt: " << prompt; responses[i].text =3D strdup("test"); responses[i].length =3D 9; } } bool GenericClient::SSH_authenticate() { Scope; auto rc =3D libssh2_userauth_keyboard_interactive_ex( ssh, username.c_str(), username.size(), SSH_authentication_response); if(rc !=3D 0) { if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } state =3D State::opening_channel; Info << GetName() << ": authenticated"; return SSH_open_channel(); } bool GenericClient::SSH_open_channel() { Scope; channel =3D libssh2_channel_open_session(ssh); if(!channel) { auto rc =3D libssh2_session_last_error(ssh, 0, 0, 0); if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } //this does not help //state =3D State::changing_channel_settings; //Info << GetName() << ": changing channel settings"; //return SSH_change_channel_settings(); state =3D State::running_shell; Info << GetName() << ": runninsh shell"; return SSH_run_shell(); } bool GenericClient::SSH_change_channel_settings() { Scope; auto rc =3D libssh2_channel_handle_extended_data2( channel, LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE ); if(rc !=3D 0) { if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } state =3D State::running_shell; Info << GetName() << ": runninsh shell"; return SSH_run_shell(); } bool GenericClient::SSH_run_shell() { Scope; auto rc =3D libssh2_channel_shell(channel); if(rc !=3D 0) { if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": error " << rc; Disconnect(); return OnConnectFailure(); } state =3D State::established; Info << GetName() << ": session established"; if(!OnConnect()) return false; return SSH_read_channel(); } bool GenericClient::SSH_read_channel() { Scope; while(true) { int len =3D GetRecvMaxSize() - recv_used; char *start =3D &recv.front(); if(len <=3D 0) { if(!truncated) { truncated =3D true; Error << GetName() << ": truncating message"; if(!OnReadLine(start, recv_used)) return false; } recv_used =3D 0; len =3D GetRecvMaxSize(); } Trace << "Calling libssh2_channel_read_ex() with " << len; char *p =3D start + recv_used; auto rc =3D libssh2_channel_read_ex(channel, 0, p, len); if(rc <=3D 0) { if(rc =3D=3D 0 || LIBSSH2_ERROR_EAGAIN) return true; Error << GetName() << ": the channel has been closed"; Disconnect(); return OnDisconnect(); } len =3D rc; char *p_bound =3D p + len; recv_used +=3D len; while(p !=3D p_bound) { if(IsTerminatingSequence(p, p_bound - p)) { if(truncated) truncated =3D false; else if(!OnReadLine(start, p - start)) return false; char *remaining =3D p + 1; len =3D start + recv_used - remaining; memcpy(start, remaining, len); recv_used =3D len; p =3D start; p_bound =3D p + len; continue; } p++; } } } void GenericClient::EventHandler( struct bufferevent *bev, short event, void *data) { Scope; bool still_active =3D true; auto client =3D static_cast(data); if(event & BEV_EVENT_CONNECTED) { if(client->state =3D=3D State::connecting) { if(client->security =3D=3D Security::ssh) { client->state =3D State::handshaking; Trace << client->GetName() << ": creating secure connection"; still_active =3D client->SSH_handshake(); } else { client->state =3D State::established; Info << client->GetName() << ": connection established"; still_active =3D client->OnConnect(); } } else { Fatal << client->GetName() << ": unexpected event " << HEX(event) << " in state " << (int)client->state; still_active =3D false; } } else if(event & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { if(client->state =3D=3D State::connecting) { Error << client->GetName() << ": connection failed"; client->Disconnect(); still_active =3D client->OnConnectFailure(); } else if(client->state =3D=3D State::established) { Info << client->GetName() << ": connection closed"; client->Disconnect(); still_active =3D client->OnDisconnect(); } else { Fatal << client->GetName() << ": unexpected event " << HEX(event) << " in state " << (int)client->state; still_active =3D false; } } else { Fatal << client->GetName() << ": unexpected event " << HEX(event) << " in state " << (int)client->state; still_active =3D false; } if(!still_active) client->service->UnregisterComponent(client); } bool GenericClient::Read(struct evbuffer *input) { if(security =3D=3D Security::ssh) { if(state =3D=3D State::handshaking) { ssh_input =3D input; bool still_active =3D SSH_handshake(); ssh_input =3D 0; return still_active; } if(state =3D=3D State::getting_authentication_methods) { ssh_input =3D input; bool still_active =3D SSH_get_authnetication_methods(); ssh_input =3D 0; return still_active; } if(state =3D=3D State::authenticating) { ssh_input =3D input; bool still_active =3D SSH_authenticate(); ssh_input =3D 0; return still_active; } if(state =3D=3D State::opening_channel) { ssh_input =3D input; bool still_active =3D SSH_open_channel(); ssh_input =3D 0; return still_active; } if(state =3D=3D State::running_shell) { ssh_input =3D input; bool still_active =3D SSH_run_shell(); ssh_input =3D 0; return still_active; } if(state =3D=3D State::established) { ssh_input =3D input; bool still_active =3D SSH_read_channel(); ssh_input =3D 0; return still_active; } } //.... } void GenericClient::Reader(struct bufferevent *bev, void *data) { auto client =3D static_cast(data); struct evbuffer *input =3D bufferevent_get_input(bev); bool still_alive =3D client->Read(input); if(!still_alive) client->service->UnregisterComponent(client); } Best regards, Sten Kultakangas --94eb2c059da876d544055344594d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello

I am using libssh2 with libevent = in my application and i ran into the following issue.

<= div>I do not receive all data that is supposed to come through the terminal= . Some of that data can be noticed in libssh2 debug output:

<= /div>
=3D> libssh2_transpor= t_read() plain (158 bytes)
0000: 5E 00 00 00 00 00 00 00 =C2=A095 0A 0D 0A 0D 53 79 73 : ^.......= .....Sys
0010: 74 65 6= D 3A 20 4C 61 72 =C2=A067 65 20 20 20 20 20 20 : tem: Large
0020: 20 20 20 20 20 20 20 20 =C2=A02= 0 20 20 20 20 20 20 20 :
0030: 20 20 53 6F 66 74 77 61 =C2=A072 65 20 56 65 72 73 69 : =C2=A0 Sof= tware Versi
0040: 6F 6= E 3A 20 52 30 31 36 =C2=A078 2E 30 33 2E 30 2E 31 : on: R016x.03.0.1=
0050: 32 34 2E 30 1B 5B 42 0= A =C2=A00D 54 65 72 6D 69 6E 61 : 24.0.[B..Termina
0060: 6C 20 54 79 70 65 20 28 =C2=A035 31 33 2= C 20 37 31 35 : l Type (513, 715
0070: 2C 20 34 34 31 30 2C 20 =C2=A034 34 32 35 2C 20 56 54 : , = 4410, 4425, VT
0080: 3= 2 32 30 2C 20 4E 54 54 =C2=A02C 20 57 32 4B 54 54 2C : 220, NTT, W2KTT,
0090: 20 53 55 4E 54 29 3= A 20 =C2=A05B 35 31 33 5D 20 =C2=A0 =C2=A0 =C2=A0 : =C2=A0SUNT): [513]
[libssh2] 3.686087 Transpo= rt: Packet type 94 received, length=3D158

Only terminal sequence=C2=A0 c [1;24r [1;1H [0J followed b= y "System: Large =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Software Version: R016x.03.0.124.0 [B" = was delivered to my application,

My application calls=C2=A0libssh2_channel_read_ex until evbuffer_= remove returns nothing. This approach worked in all my network application.= I tried streams 0 and 1. When i am reading stream 1, the applications does= not receive any data from sshd.

I opened normal ssh client and logged in to the system without ch= oosing the terminal type. Then i opened another ssh client process and logg= ed to the system, choiced the terminal type and issued the "wall"= command. The contents of the broadcast message was displayed in both insta= nces of the normal ssh client.

However, the application does not receive that data even according = to=C2=A0libssh2_tran= sport_read debug output.=

So there are at least = two questions:
1) why only=C2=A0"System: Large =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Software Version: R016x.03.0.124.0 [B&quo= t; was delivered to my application, but not=C2=A0=C2=A0 "Software Version: R016x.03.0.124.0.[B..Terminal Type (513, 715, 4410, 4425, VT220, NTT, W2KTT,=C2=A0SUNT): [513]&= quot; ? The latter was also present in libssh2 debug output.
2) why unsolicite= d "wall" messages are not delivered neither through standard stre= am nor through stderr stream ? Is there any special stream that i'm mis= sing? How to get the list of all available streams ?

Last time when i ran the application i got the following output= :

16:34:5= 7.724 BCMSMonitor::OnReadLine: Data: System: Large
=C2=A0Software Version: R016x.03.0.124.0=E2=86= =90[B
16:34:57.724 BCM= SMonitor::OnReadLine: Data:
16:34:57.724 GenericClient::SSH_read_channel: Calling libssh2_channel= _read_ex()=C2=A0with= 8123
[libssh2] 3.7251= 87 Conn: channel_read() wants 8123 bytes from channel 0/0 stream=C2=A0#0
16:34:57.725 GenericClient::SSH_recv: read o= peration result: 0, wanted 16384 bytes


which indicates that "recv" notificatio= ns on the socket were re-enabled. However,=C2=A0sshd server is still not sending unsolicited data t= o my application although=C2=A0it is is sending it to normal ssh client.

<= /span>
Here's the relevant code:

<= br>
ssize_t Generic= Client::SSH_recv(
libssh2_socket_t fd,
<= font face=3D"monospace, monospace"> = void *buf,
size_t len,
int,
= void **)
{
auto ctx =3D reinterpret_cast<GenericClient *>(fd);

Sc= ope;
if(!ctx->ssh_input) {
Trace &l= t;< "someone wanted to read " << len << " byt= es too early";
return -EAGAIN;
}<= /font>
auto rc =3D evbuffer_remove(ctx->ssh_input, buf, len);=
Trace << "read operation result: " <&= lt; rc << ", wanted " << len << " bytes&qu= ot;;
if(rc < 0) return -EAGAIN;
if(r= c =3D=3D 0 && len !=3D 0) return -EAGAIN;
return = rc;
}

ssize_t GenericClient::SSH_send(
libssh2_socket_t fd,
const void *buf,
= size_t len,
int,
void **)
=
{
auto ctx =3D r= einterpret_cast<GenericClient *>(fd);
if(buffereven= t_write(ctx->bev, buf, len) =3D=3D 0) return len;
retu= rn -1;
}
<= /div>


bool GenericClient::Reconnect()
{
Scope;
Dis= connect();

=
switch(security) {

case Security::none:
case= Security::ssh:
bev =3D bufferevent_socket_new(
service->base,
-1,
B= EV_OPT_CLOSE_ON_FREE);
if(security =3D=3D Security::none= ) break;

ssh =3D libssh2_session_init();
if(!ssh) {
Fatal << GetName() << ": libssh2_session= _init failed";
return false;
}<= /font>
libssh2_session_set_blocking(ssh, 0);
<= font face=3D"monospace, monospace"> libssh2_session_callback_set(ssh, LIBSSH2_CALLBACK_SEND, (void *)SSH_send)= ;
libssh2_session_callback_set(ssh, LIBSSH2_CALLBACK_REC= V, (void *)SSH_recv);
= libssh2_trace(ssh, ~0);
= break;

case Security::ssl:
//...
<= div>
default:
Fatal << GetName() << ": invalid security = specifier";
return false;
}

if(!= bev) {
Error << GetName() << ": socket = allocation failed";
return false;
= }

bufferevent_setcb(bev, GetReader(), GetWriter(), GetEventHandler(), thi= s);
bufferevent_enable(bev, EV_READ | EV_WRITE);

if(buff= erevent_socket_connect_hostname(
bev,
<= font face=3D"monospace, monospace"> service->dns_base,
AF_UNSPEC,
hos= t.c_str(),
port) !=3D 0) {

Error << GetName() = << ": connection attempt cannot be initiated";
=
= return false;
<= span style=3D"white-space:pre"> }

Trace << GetName() <<= ": connecting";
state =3D State::connecting;
return true;
}

<= /div>

bool
GenericClient::Connect(const string &new_destination, Secur= ity new_security)
{
destination =3D new_destination;
security= =3D new_security;
auto colon =3D destination.find_last_of(':');
if(colon =3D=3D string::npos) {
Scope;<= /font>
Error << GetName() << ": destination po= rt not specified";
return false;
<= font face=3D"monospace, monospace"> = }

host =3D destination.substr(0, colon);
port =3D strtol= l(destination.substr(colon + 1).c_str(), 0, 10);
return R= econnect();
}


bool GenericClient::SSH_handshake()
= {
Scope;
=
<= /span>auto rc =3D libssh2_session_handshake(
ssh,=
reinterpret_cast<libssh2_socket_t>(this)
);

= if(rc !=3D 0) {
if(rc =3D=3D LIBSSH2_ERROR_EAGAIN= ) return true;
Error << GetName() << ":= error " << rc;
Disconnect();
return OnConnectFailure();
}

// FIXME: check host fi= ngerprint

<= /div>
state =3D State::getting_authentication_methods;
Trace << GetName() << ": getting authentication methods= ";
return SSH_get_authnetication_methods();
}


bool Gen= ericClient::SSH_get_authnetication_methods()
{
Scope;
auto li= st =3D libssh2_userauth_list(ssh, username.c_str(), username.size());
if(list =3D=3D 0) {
auto rc =3D libssh2_ses= sion_last_error(ssh, 0, 0, 0);
if(rc =3D=3D LIBSSH2_ERRO= R_EAGAIN) return true;
Error << GetName() <<= ": error " << rc;
Disconnect();<= /div>
return OnConnectFailure();
}
state =3D State::authenticating;
Trace << GetName= () << ": authenticating using " << list;
=
<= /span>return SSH_authenticate();
}


void GenericClient::SSH_authentication_resp= onse(
const char *name_str,
int name_= len,
const char *instruction_str,
int i= nstruction_len,
int num_prompts,
const = struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
struct _= LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstr= act)
{
string name(name_str, name_len);
string instruction(in= struction_str, instruction_len);

Scope;
Info << &q= uot;Name: " << name;
Info << "Instr= uction: " << instruction;

for(auto i =3D 0; i < num_prompts;= i++) {
string prompt(prompts[i].text, prompts[i].length= );
Info << "Prompt: " << prompt;

<= font face=3D"monospace, monospace"> responses[i].text =3D strdup("test");
respons= es[i].length =3D 9;
}
}

bool GenericClient::SSH_authenticate= ()
{
= Scope;
auto rc =3D libssh2_userauth_keyboard_interactive= _ex(
ssh,
username.c_str(),
username.size(),
SSH_authentication_response);=

if(rc !=3D 0) {
if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) ret= urn true;
Error << GetName() << ": err= or " << rc;
Disconnect();
= return OnConnectFailure();
}

state =3D State::opening_c= hannel;
Info << GetName() << ": authenti= cated";
return SSH_open_channel();
= }

<= br>
bool GenericClient= ::SSH_open_channel()
{=
Scope;
channel =3D libssh2_channel_ope= n_session(ssh);
if(!channel) {
auto rc= =3D libssh2_session_last_error(ssh, 0, 0, 0);
if(rc = =3D=3D LIBSSH2_ERROR_EAGAIN) return true;
Error <<= GetName() << ": error " << rc;
Di= sconnect();
return OnConnectFailure();
= }

//this does not help
//state =3D State::changing_chan= nel_settings;
//Info << GetName() << ": = changing channel settings";
//return SSH_change_chan= nel_settings();

state =3D State::running_shell;
Info <= ;< GetName() << ": runninsh shell";
re= turn SSH_run_shell();
= }


bool GenericClient::SSH_change_channel_settings()
{
Scope;=
auto rc =3D libssh2_channel_handle_extended_data2(
channel,
LIBSSH2_CHANNEL_EXTENDED_DATA_MER= GE
);
if(rc !=3D 0) {
= if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) return true;
Error = << GetName() << ": error " << rc;
<= div> <= /span>Disconnect();
return OnConnectFailure();
}
state =3D State::running_shell;
Info << GetName() << ": runninsh shell";
return SSH_run_shell();
}


bool GenericClient::SSH_run_shell()=
{
Scope;
auto rc =3D libssh2_channel_shell(channel);
if(rc !=3D 0) {
if(rc =3D=3D LIBSSH2_ERROR_EAGAIN) r= eturn true;
Error << GetName() << ": er= ror " << rc;
Disconnect();
<= font face=3D"monospace, monospace"> return OnConnectFailure();
}
state =3D= State::established;
<= span style=3D"white-space:pre"> Info << GetName() << &qu= ot;: session established";
if(!OnConnect()) return f= alse;
return SSH_read_channel();
}


bool GenericClient::SSH_r= ead_channel()
{=
Scope;
while(true) {
int l= en =3D GetRecvMaxSize() - recv_used;
char *start =3D &am= p;recv.front();
if(len <=3D 0) {
= if(!truncated) {
truncated =3D true;
= Error << GetName() << ": truncating message";
if(!OnReadLine(start, recv_used)) return false;
}

recv_used =3D 0;
len =3D GetRecvMaxSize= ();
}


Trace << "Calling libssh2_channel_read_ex() with = " << len;
<= br>
char *p =3D start + recv_used;
au= to rc =3D libssh2_channel_read_ex(channel, 0, p, len);
if(rc <=3D 0) {
if(rc =3D=3D 0 || LIBSSH2_ERROR= _EAGAIN) return true;
= Error << GetName() <<= ": the channel has been closed";
Disconnect(= );
return OnDisconnect();
}=
len =3D rc;

char *p_bound =3D p + len;
re= cv_used +=3D len;

=
while(p !=3D p_bound) {
if(IsTermin= atingSequence(p, p_bound - p)) {
if(truncated) truncat= ed =3D false;
else if(!OnReadLine(start, p - start)) r= eturn false;

char *remaining =3D p + 1;
len =3D st= art + recv_used - remaining;
memcpy(start, remaining, = len);
recv_used =3D len;
p =3D = start;
p_bound =3D p + len;
conti= nue;
}
p++;
}
}
}


void GenericClient::EventHandler(
struct= bufferevent *bev,
short event,
void *d= ata)
{
Scope;
bool still_active =3D true;
<= font face=3D"monospace, monospace"> = auto client =3D static_cast<GenericClient *>(data);
=
if(event & B= EV_EVENT_CONNECTED) {
= if(client->state =3D=3D State::= connecting) {

if(client->security =3D=3D Security::ssh) {
= client->state =3D State::handshaking;
Tra= ce << client->GetName() << ": creating secure connectio= n";
still_active =3D client->SSH_handshake()= ;

} else {
client->state =3D State::established;=
Info << client->GetName() << ": c= onnection established";
still_active =3D client-&= gt;OnConnect();
}

<= span style=3D"white-space:pre"> } else {

Fatal << client-&= gt;GetName()
<< ": unexpected event " = << HEX(event)
<< " in state " &l= t;< (int)client->state;
still_active =3D false;
}
} else if(event & (BEV_EVENT_EOF | BEV_EVENT_ERROR= )) {
if(client->state =3D=3D State::connecting) {

= Error << client->GetName() << ": connection failed"= ;;
client->Disconnect();
still_a= ctive =3D client->OnConnectFailure();

} else if(client->state =3D= =3D State::established) {

Info << client->GetName() << = ": connection closed";
client->Disconnect(= );
still_active =3D client->OnDisconnect();

} else= {

<= /span>Fatal << client->GetName()
<< &qu= ot;: unexpected event " << HEX(event)
<&= lt; " in state " << (int)client->state;
still_active =3D false;
}

} else {
Fatal << client->GetName()
<< ":= unexpected event " << HEX(event)
<< &= quot; in state " << (int)client->state;
st= ill_active =3D false;
= }

if(!still_active) client->ser= vice->UnregisterComponent(client);
}

=

bool GenericClient::Read(struct evbuff= er *input)
{
if(security =3D=3D Security::ssh) {
if(state = =3D=3D State::handshaking) {
ssh_input =3D input;
bool still_active =3D SSH_handshake();
s= sh_input =3D 0;
return still_active;
<= font face=3D"monospace, monospace"> }
if(state =3D=3D State::getting_authentication_methods= ) {
ssh_input =3D input;
bool still= _active =3D SSH_get_authnetication_methods();
ssh_inp= ut =3D 0;
return still_active;
}
if(state =3D=3D State::authenticating) {
= ssh_input =3D input;
bool still_active =3D SSH_authe= nticate();
ssh_input =3D 0;
return = still_active;
}
if(state =3D=3D State= ::opening_channel) {
<= span style=3D"white-space:pre"> ssh_input =3D input;
<= div> = bool still_active =3D SSH_open_channel();
ssh_in= put =3D 0;
return still_active;
}
if(state =3D=3D State::running_shell) {
<= font face=3D"monospace, monospace"> ssh_input =3D input;
bool still_active =3D SSH_run_sh= ell();
ssh_input =3D 0;
return stil= l_active;
}
if(state =3D=3D State::e= stablished) {
ssh_input =3D input;
= bool still_active =3D SSH_read_channel();
ssh_input =3D= 0;
return still_active;
}
}
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 //....
}

=

void GenericClient::Reader(struct bufferevent *be= v, void *data)
{
auto client =3D static_cast<GenericClient *>(data);
struct evbuffer *input =3D bufferevent_get_input(bev);=

bool still_alive =3D client->Read(input);
if(!still_alive) client->service->UnregisterComponen= t(client);
}


Best regards,
Sten Kultakangas
--94eb2c059da876d544055344594d-- --===============1353175874== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k ZXZlbCBodHRwczovL2Nvb2wuaGF4eC5zZS9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8vbGlic3No Mi1kZXZlbAo= --===============1353175874==-- From libssh2-devel-bounces@cool.haxx.se Sat Jul 1 19:00:15 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v61H0BOF004037; Sat, 1 Jul 2017 19:00:14 +0200 Received: from mail-qt0-x229.google.com (mail-qt0-x229.google.com [IPv6:2607:f8b0:400d:c0d:0:0:0:229]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v61H096U003835 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Sat, 1 Jul 2017 19:00:10 +0200 Received: by mail-qt0-x229.google.com with SMTP id r30so119368804qtc.0 for ; Sat, 01 Jul 2017 10:00:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=s5Kk0MlP7395b+WeQJbiFAhxa8StjLt+fFrFnOFq0FI=; b=Xkqn40P0GOwibaE/KH/qezyN/WBJUJyVhTW+wezRsJUuVoGKp3CT6UB6PnRubWVbNJ kebUC2apvYwCPubdJFQE+Wk8/Bn6iyCakJQ6Q/frRSLj+wMT/vBKnTMu2utIRHyV1NzY X0rnFbF4RayZa6rPgf1YIHKSXFfNqVwS0atSow8tajnOpQUNxEwpKNYNELRaMkQ6MTna eRTfXerGFMQLl48r+ZFoLI9teDRyXFFy+lMc/fhhXm9Aan+yu1t9wqs2+TN8aXIsp3Ll T2sreP6/bk/gGARm/0kN3M2Zf20jWWKtsJeD30UgUlyrQnv19x2esrid1AxSsuwivK2r 7hRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=s5Kk0MlP7395b+WeQJbiFAhxa8StjLt+fFrFnOFq0FI=; b=h0iIOub0hj29PSqg8kjStmhTmSspwed5LSGGMb8y88Po0NXSINhpWoXTh/Wdi1xFS4 sFlqJ0cm6D0MWlYJNZBYHgPB0TNxvW8eVLmdUWNly8tIt7nz2GAgCyQKlcrTNviaS6V3 zJshhppgQtLYAR2rFp2MskjMCebTFiXku7qtRXnYMHQ0Db7FJ95Ve7/Wvc90GPk309qJ Aem9QIyLO0ntX+79G03NYWPLxnzPTaMHDtsxfSzgotOgZctjML43Gt9vEl25RRkc7eRn JB6DVa5m9W2Bh1TdgcrUOIkXyF7CTKZPZPZDI2wyFWtqEjrxMoFRkKmv3Or6ScWdChQG VvJA== X-Gm-Message-State: AKS2vOwIidbF7AkrCA4RaenQ1dO8wxFSkR3YMic2WeFk8TzW4dBR4Pco xONcuVDCndPv7hqNCU7wjLPgBKFtqXnz X-Received: by 10.200.5.134 with SMTP id a6mr34927110qth.44.1498928405418; Sat, 01 Jul 2017 10:00:05 -0700 (PDT) MIME-Version: 1.0 Received: by 10.237.60.92 with HTTP; Sat, 1 Jul 2017 10:00:04 -0700 (PDT) In-Reply-To: References: Date: Sat, 1 Jul 2017 20:00:04 +0300 Message-ID: Subject: Re: unsolicited data is not queued to the buffer. Am i reading a wrong stream ? To: libssh2-devel@cool.haxx.se X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sten Kultakangas via libssh2-devel Reply-To: libssh2 development Cc: Sten Kultakangas Content-Type: multipart/mixed; boundary="===============0357388499==" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" --===============0357388499== Content-Type: multipart/alternative; boundary="089e08e53d59261752055344778a" --089e08e53d59261752055344778a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable =E2=80=8BHi again Sorry about the first question, i already found the answer. "Terminal Type (513, 715, 4410, 4425, VT220, NTT, W2KTT, SUNT): [513" was actually in the buffer, so it was delivered to the application. The only problem left is how to make sshd send unsolicited data to my application. --089e08e53d59261752055344778a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

=E2=80=8BHi again

Sorry about the f= irst question, i already found the answer. "Terminal Type (513, 715, 4410, 4425, VT220, NTT, W2KTT,=C2=A0SUNT): [513" was actua= lly in the buffer, so it was delivered to the application.
The only problem left is how to make sshd send unsolicited data to my appl= ication.
--089e08e53d59261752055344778a-- --===============0357388499== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k ZXZlbCBodHRwczovL2Nvb2wuaGF4eC5zZS9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8vbGlic3No Mi1kZXZlbAo= --===============0357388499==-- From libssh2-devel-bounces@cool.haxx.se Mon Jul 17 00:59:27 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6GMwdLN021866; Mon, 17 Jul 2017 00:59:18 +0200 Received: from mail-qt0-x22d.google.com (mail-qt0-x22d.google.com [IPv6:2607:f8b0:400d:c0d:0:0:0:22d]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6GMwb7n021748 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 17 Jul 2017 00:58:38 +0200 Received: by mail-qt0-x22d.google.com with SMTP id b40so94622320qtb.2 for ; Sun, 16 Jul 2017 15:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:from:date:message-id:subject:to; bh=Q4FUZn7hAO4XtBkIhnrD48w529xpP0PK+oW5P6K++/o=; b=HSku9A25l15N52fJZvrmedYgG7pX7TYYNVMZo7pI8YxfEMEKU3d2DVYBhtbi0fWxn8 eW2Ema/3qhgLe1+xqh4rvac4+nf1FDLsJNY/Q8AH0GBDb6W2U/uTGRvL8lhbt0FxcY7O Lbic+39996okOuPC/KTTdAmr9I6s7oBtB+H3ACTRYCn2OG3bfth3r/f5K84iLLBeeisF Fn1Y93aW2yvZMY0CwuqWTYEsC1T80HWyKUPdtMqoR/2mP8OkYrp+EwdcbiLgcn9GG+XE mpuXTX9ELH7URu5hPMZiM8caAuXWhDInoriYIkOSexU5sxGPODIacsBHr/LAcFxWV65T jsRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:from:date:message-id:subject :to; bh=Q4FUZn7hAO4XtBkIhnrD48w529xpP0PK+oW5P6K++/o=; b=aCPGug/8AoeGn7YBiYzKyNVzdNe0oslTxmBi9Cfd7qwiHLfxichs2iRvIGLju+qNjj Q1bBBwcs39R2bZxwGhzStAGr6qxJ3nrWPbVmZASmz2JUELcbsr/L8eb8KIbRG0oFSmyl zSS//5C7Dwk0/2DF7okex0QfJpjIN+sr56hzvWxQsuparggH9KmZGhw2RT12xuRVIV// W6n6c14RCN7e1bFm3tVPtJ+D878hiiyeFYRUqGdQd3ZFQG7wsTrZ/r9H/ovA7sOf34L+ t9bloF332Mamj1RoW2B+ZSCLNv1p6qlgP4P9/rmAXgFJfuMiF6gScfDf1ar1KXsaC115 r60g== X-Gm-Message-State: AIVw110q5nQW40SGOWCSEgOpC/9MjdOUdeS/w/RTZzh/gLOVmN4oBMjC p6uGM3rr5oHdIZYdhVYA3V/o+zN6sBNj X-Received: by 10.237.42.44 with SMTP id c41mr674077qtd.74.1500245912659; Sun, 16 Jul 2017 15:58:32 -0700 (PDT) MIME-Version: 1.0 Received: by 10.200.40.132 with HTTP; Sun, 16 Jul 2017 15:58:12 -0700 (PDT) From: George Nachman Date: Sun, 16 Jul 2017 15:58:12 -0700 X-Google-Sender-Auth: 7N6c0q_KsFChRpJRmXXexSXMwbs Message-ID: Subject: Recursive scp downloads? To: libssh2-devel@cool.haxx.se X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: libssh2 development Content-Type: multipart/mixed; boundary="===============1755075037==" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" --===============1755075037== Content-Type: multipart/alternative; boundary="001a114085d6b32d6e05547738b8" --001a114085d6b32d6e05547738b8 Content-Type: text/plain; charset="UTF-8" Is there any way to do a "recursive" download using libssh2, like scp -r? libssh2_scp_recv simply fails with an error when you give it a directory, but perhaps there's a trick I haven't figured out yet? --001a114085d6b32d6e05547738b8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Is there any way to do a "recursive" download us= ing libssh2, like scp -r?=C2=A0libssh2_scp_recv simply fails with an error = when you give it a directory, but perhaps there's a trick I haven't= figured out yet?
--001a114085d6b32d6e05547738b8-- --===============1755075037== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k ZXZlbCBodHRwczovL2Nvb2wuaGF4eC5zZS9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8vbGlic3No Mi1kZXZlbAo= --===============1755075037==-- From libssh2-devel-bounces@cool.haxx.se Wed Jul 19 19:49:02 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6JHmOLW001709; Wed, 19 Jul 2017 19:48:57 +0200 Received: from giant.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6JHmMIh001696 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 19 Jul 2017 19:48:22 +0200 Received: from localhost (dast@localhost) by giant.haxx.se (8.15.2/8.15.2/Submit) with ESMTP id v6JHmLYS001692 for ; Wed, 19 Jul 2017 19:48:21 +0200 X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs Date: Wed, 19 Jul 2017 19:48:21 +0200 (CEST) From: Daniel Stenberg X-X-Sender: dast@giant.haxx.se To: libssh2 development Subject: Re: Recursive scp downloads? In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) X-fromdanielhimself: yes MIME-Version: 1.0 X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: libssh2 development Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id v6JHmOLW001709 On Sun, 16 Jul 2017, George Nachman wrote: > Is there any way to do a "recursive" download using libssh2, like scp -r? > libssh2_scp_recv simply fails with an error when you give it a directory, > but perhaps there's a trick I haven't figured out yet? That's still a missing feature in libssh2. -- / daniel.haxx.se _______________________________________________ libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel From libssh2-devel-bounces@cool.haxx.se Wed Jul 19 20:06:41 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6JI6WZ1016096; Wed, 19 Jul 2017 20:06:38 +0200 Received: from mail-ua0-x234.google.com (mail-ua0-x234.google.com [IPv6:2607:f8b0:400c:c08:0:0:0:234]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6JI6T6q016050 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 19 Jul 2017 20:06:30 +0200 Received: by mail-ua0-x234.google.com with SMTP id w45so5533641uac.5 for ; Wed, 19 Jul 2017 11:06:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=8Buu85h5GiB7C6CbaUZa6Av0zh2VDmqF23C6581BTAs=; b=jvQhAjcshE0BXQmDqd1HLCrum3A4gZIwBCm4UzaP311RVPC+ORKKVT/n7V0/ebF3yB 0deikqcg48BFKvjITmqx/9KBYsfSNUkKnRS0poPdgCzEtEpHAvAKiP3x/EzcgDOjFOqo xWMFasZxPQghGdzKphX8pVZidagJ0NKoYgXb6v9LcmR5vQZomaYufqJJRCi+iluPLnbE qaSLubOby8jQwL97tBhoj1r8x0f5ci0igD+PPBawv/c2F+coOAE2N6A5vG0FMEMFVgcH /ew+f3TIB4LiTuAk8DNLEzoq7Bd7QLqyTs3o+s9i1MpM2PD2A487Oew8z9b7GW1mVQXH DbKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=8Buu85h5GiB7C6CbaUZa6Av0zh2VDmqF23C6581BTAs=; b=JAh1K2SEtAIUvrF8jmWfog0hPe0KhMcQemDhAbt8iRXlmDHyL1rm1+YhIiDfhlaoAk UJoZT+iFYO5EBKPA8EE+eSn8w+LhJc+QoP7V+u3RatwSdH0tHjFTYmj6wC20yBN1LaD4 C2Xn4CXFYmHWfyF4xTOM4oOhC/x99TELZFki4h1eRn+Z1NPaYhczyrm8GIt63tVjl8P4 p7IUvjiSOLYQDK9wJjMSABi6ELf7xuD8kJ+iFZvpw43/sLPMsU1Bqhfs5IteeqYw7jDk AaPyb+dTwdFqFY0h++Tb6ytvxX6wCWO7dK/AsdQWFJEnC19Pi5gCdrZSNmqRTXyvCGXd emJw== X-Gm-Message-State: AIVw110CyACRPb9qc/Ot9Zrunrtt42iizqFMSYuq0K2CFVQrY4grSPsq N2ctAycB9X4d+MnYUlMjkKsu/RFx0A== X-Received: by 10.31.52.74 with SMTP id b71mr522231vka.18.1500487584200; Wed, 19 Jul 2017 11:06:24 -0700 (PDT) MIME-Version: 1.0 Received: by 10.103.138.138 with HTTP; Wed, 19 Jul 2017 11:06:23 -0700 (PDT) Received: by 10.103.138.138 with HTTP; Wed, 19 Jul 2017 11:06:23 -0700 (PDT) In-Reply-To: References: Date: Wed, 19 Jul 2017 11:06:23 -0700 Message-ID: Subject: Re: Recursive scp downloads? To: libssh2 development X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: bch via libssh2-devel Reply-To: libssh2 development Cc: bch Content-Type: multipart/mixed; boundary="===============0166723703==" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" --===============0166723703== Content-Type: multipart/alternative; boundary="001a114304f6723dc70554af7dd1" --001a114304f6723dc70554af7dd1 Content-Type: text/plain; charset="UTF-8" On Jul 19, 2017 10:50, "Daniel Stenberg" wrote: On Sun, 16 Jul 2017, George Nachman wrote: Is there any way to do a "recursive" download using libssh2, like scp -r? > libssh2_scp_recv simply fails with an error when you give it a directory, > but perhaps there's a trick I haven't figured out yet? > That's still a missing feature in libssh2. Is that a thing that the sh protocol facilitates or would be worked-out as a convenience feature? -bch -- / daniel.haxx.se _______________________________________________ libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel --001a114304f6723dc70554af7dd1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Jul 19, 2017 10:50, "Daniel Stenberg" <daniel@haxx.se> wrote:
On Sun, 16 Jul 2017,= George Nachman wrote:

Is there any way to do a "recursive" download using libssh2, like= scp -r? libssh2_scp_recv simply fails with an error when you give it a dir= ectory, but perhaps there's a trick I haven't figured out yet?

That's still a missing feature in libssh2.

Is that a thing that the sh protocol facilitates or would be work= ed-out as a convenience feature?

-bch


--

=C2=A0/ daniel.haxx.se
_______________________________________________
libssh2-devel https://cool.haxx.se/cgi-bi= n/mailman/listinfo/libssh2-devel

--001a114304f6723dc70554af7dd1-- --===============0166723703== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k ZXZlbCBodHRwczovL2Nvb2wuaGF4eC5zZS9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8vbGlic3No Mi1kZXZlbAo= --===============0166723703==-- From libssh2-devel-bounces@cool.haxx.se Thu Jul 20 15:31:14 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6KDUSZb029054; Thu, 20 Jul 2017 15:31:04 +0200 Received: from foo.stuge.se (foo.stuge.se [212.116.89.98]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6KDUPRR028987 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 20 Jul 2017 15:30:25 +0200 Received: (qmail 6721 invoked by uid 1000); 20 Jul 2017 13:22:21 -0000 Date: Thu, 20 Jul 2017 13:22:21 +0000 From: Peter Stuge To: libssh2-devel@cool.haxx.se Subject: Re: Recursive scp downloads? Message-ID: <20170720132221.GI12397@stuge.se> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: libssh2 development Content-Type: text/plain; charset="utf-8" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id v6KDUSZb029054 bch via libssh2-devel wrote: > Is that a thing that the sh protocol facilitates or would be > worked-out as a convenience feature? Recursing through a hierarchy of files is not in any way part of either the SSH protocol, the SFTP protocol or the SCP protocol. It would have to be implemented entirely within the client. Recommend SFTP over SCP. //Peter _______________________________________________ libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel From libssh2-devel-bounces@cool.haxx.se Thu Jul 20 18:22:05 2017 Return-Path: Received: from www.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6KGLeA2028079; Thu, 20 Jul 2017 18:21:59 +0200 Received: from giant.haxx.se (localhost.localdomain [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6KGLd7M028073 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 20 Jul 2017 18:21:39 +0200 Received: from localhost (dast@localhost) by giant.haxx.se (8.15.2/8.15.2/Submit) with ESMTP id v6KGLc0w028068 for ; Thu, 20 Jul 2017 18:21:38 +0200 X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs Date: Thu, 20 Jul 2017 18:21:38 +0200 (CEST) From: Daniel Stenberg X-X-Sender: dast@giant.haxx.se To: libssh2 development Subject: Re: Recursive scp downloads? In-Reply-To: <20170720132221.GI12397@stuge.se> Message-ID: References: <20170720132221.GI12397@stuge.se> User-Agent: Alpine 2.20 (DEB 67 2015-01-07) X-fromdanielhimself: yes MIME-Version: 1.0 X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: libssh2 development Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id v6KGLeA2028079 On Thu, 20 Jul 2017, Peter Stuge wrote: > Recursing through a hierarchy of files is not in any way part of either the > SSH protocol, the SFTP protocol or the SCP protocol. > > It would have to be implemented entirely within the client. Not entirely right? Since the client sends the recursive scp command line to the server and then needs to correctly handle what it gets sent back. -- / daniel.haxx.se _______________________________________________ libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel From libssh2-devel-bounces@cool.haxx.se Sat Jul 29 19:29:53 2017 Return-Path: Received: from www.haxx.se (mail [127.0.0.1]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTP id v6THTIvR017384; Sat, 29 Jul 2017 19:29:46 +0200 Received: from forward21m.cmail.yandex.net (forward21m.cmail.yandex.net [IPv6:2a02:6b8:b030:0:0:0:0:17]) by giant.haxx.se (8.15.2/8.15.2/Debian-4) with ESMTPS id v6THTGEB017311 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Sat, 29 Jul 2017 19:29:16 +0200 Received: from mxback8o.mail.yandex.net (mxback8o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::22]) by forward21m.cmail.yandex.net (Yandex) with ESMTP id 2AD9821186 for ; Sat, 29 Jul 2017 20:29:11 +0300 (MSK) Received: from web36o.yandex.ru (web36o.yandex.ru [95.108.205.216]) by mxback8o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id zD1L1OTfcG-TAXieJuU; Sat, 29 Jul 2017 20:29:10 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.com; s=mail; t=1501349350; bh=HFd6OlZkpW8Q2aeZwIkeKMKRNn3A5BKIuKKsGZHYrvw=; h=From:To:Subject:Message-Id:Date; b=ODgD82DAuqwgTLvGAFjVQf8V8vfRxK7r6LkaJSQvRSBoulFNjtTJxcT5KaPf7R1yd mNrQp1NpG1XLOiUOEJ20A6YDRjuJrwyOIWH6zsVo6Ku8dZKBTrJin1RXtXGy++KaSm sjCkpRA+49Kdk6cCsDZci/Krj8wouwGhtlNOuw8w= Authentication-Results: mxback8o.mail.yandex.net; dkim=pass header.i=@yandex.com Received: by web36o.yandex.ru with HTTP; Sat, 29 Jul 2017 20:29:10 +0300 To: Libssh2 List Subject: New Python bindings for libssh2 MIME-Version: 1.0 Message-Id: <3443341501349350@web36o.yandex.ru> X-Mailer: Yamail [ http://yandex.ru ] 5.0 Date: Sat, 29 Jul 2017 18:29:10 +0100 Content-Type: multipart/mixed; boundary="----==--bound.344335.web36o.yandex.ru" X-BeenThere: libssh2-devel@cool.haxx.se X-Mailman-Version: 2.1.22 Precedence: list List-Id: libssh2 development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Pan via libssh2-devel Reply-To: libssh2 development Cc: Pan Errors-To: libssh2-devel-bounces@cool.haxx.se Sender: "libssh2-devel" ------==--bound.344335.web36o.yandex.ru Content-Transfer-Encoding: base64 Content-Type: text/html; charset=utf-8 PGRpdj5IZWxsbyBsaXN0LDwvZGl2PjxkaXY+wqA8L2Rpdj48ZGl2Pk5ldyBtZW1iZXIgb24gdGhl IGxpc3QsIGZpcnN0IG9mZiBoZWxsbyBhbmQgdGhhbmsgeW91IGZvciB0aGUgYXdlc29tZSBsaWJy YXJ5LCBpdCBoYXMgYmVlbiBhIHJlYWwgcGxlYXN1cmUgdXNpbmcgaXQuIFdlYnNpdGUgYWxzbyB2 ZXJ5IHVzZWZ1bCwgZ29vZCBkb2N1bWVudGF0aW9uIGFuZCBleGFtcGxlcy48L2Rpdj48ZGl2PsKg PC9kaXY+PGRpdj5JIHdhbnRlZCB0byB3cml0ZSB0byBsZXQgeW91IGtub3cgb2YgbmV3IFB5dGhv biBiaW5kaW5ncyBmb3IgbGlic3NoMiAtIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9QYXJh bGxlbFNTSC9zc2gyLXB5dGhvbiI+c3NoMi1weXRob248L2E+LjwvZGl2PjxkaXY+wqA8L2Rpdj48 ZGl2PkhlcmUncyBhIHNob3J0IGV4YW1wbGUsIGFsc28gYXR0YWNoZWQgYSBzY3JpcHQsIGV4YW1w bGVfZWNoby5weTo8L2Rpdj48ZGl2PsKgPC9kaXY+PGRpdj5UbyBpbnN0YWxsIHJ1biB0aGUgYmVs b3cgaW4gYSBzaGVsbCwgbmVlZHMgcHl0aG9uIGFuZCBsaWJzc2gyIGhlYWRlcnM6PC9kaXY+PGRp dj7CoDwvZGl2PjxibG9ja3F1b3RlPjxkaXY+cGlwIGluc3RhbGwgc3NoMi1weXRob248L2Rpdj48 L2Jsb2NrcXVvdGU+PGRpdj7CoDwvZGl2PjxkaXY+PGRpdj7CoDwvZGl2PjxkaXY+U2NyaXB0Ojwv ZGl2PjxkaXY+wqA8L2Rpdj48YmxvY2txdW90ZT48ZGl2PjxkaXY+PHByZT48c3Bhbj5mcm9tPC9z cGFuPiA8c3Bhbj5fX2Z1dHVyZV9fPC9zcGFuPiA8c3Bhbj5pbXBvcnQ8L3NwYW4+IHByaW50X2Z1 bmN0aW9uCgo8c3Bhbj5pbXBvcnQ8L3NwYW4+IG9zCjxzcGFuPmltcG9ydDwvc3Bhbj4gc29ja2V0 Cgo8c3Bhbj5mcm9tPC9zcGFuPiBzc2gyIDxzcGFuPmltcG9ydDwvc3Bhbj4gU2Vzc2lvbgoKaG9z dCA8c3Bhbj49PC9zcGFuPiA8c3Bhbj48c3Bhbj5iJzwvc3Bhbj5sb2NhbGhvc3Q8c3Bhbj4nPC9z cGFuPjwvc3Bhbj4KdXNlciA8c3Bhbj49PC9zcGFuPiBvcy5nZXRsb2dpbigpCgpzb2NrIDxzcGFu Pj08L3NwYW4+IHNvY2tldC5zb2NrZXQoc29ja2V0LjxzcGFuPkFGX0lORVQ8L3NwYW4+LCBzb2Nr ZXQuPHNwYW4+U09DS19TVFJFQU08L3NwYW4+KQpzb2NrLmNvbm5lY3QoKGhvc3QsIDxzcGFuPjIy PC9zcGFuPikpCgpzZXNzaW9uIDxzcGFuPj08L3NwYW4+IFNlc3Npb24oKQpzZXNzaW9uLmhhbmRz aGFrZShzb2NrKQpzZXNzaW9uLmFnZW50X2F1dGgodXNlcikKCmNoYW5uZWwgPHNwYW4+PTwvc3Bh bj4gc2Vzc2lvbi5vcGVuX3Nlc3Npb24oKQpjaGFubmVsLmV4ZWN1dGUoPHNwYW4+PHNwYW4+Yic8 L3NwYW4+ZWNobyBtZTsgZXhpdCAyPHNwYW4+Jzwvc3Bhbj48L3NwYW4+KQpzaXplLCBkYXRhIDxz cGFuPj08L3NwYW4+IGNoYW5uZWwucmVhZCgpCjxzcGFuPndoaWxlPC9zcGFuPiBzaXplIDxzcGFu PiZndDs8L3NwYW4+IDxzcGFuPjA8L3NwYW4+OgogICAgPHNwYW4+cHJpbnQ8L3NwYW4+KGRhdGEp CiAgICBzaXplLCBkYXRhIDxzcGFuPj08L3NwYW4+IGNoYW5uZWwucmVhZCgpCmNoYW5uZWwuY2xv c2UoKQo8c3Bhbj5wcmludDwvc3Bhbj4oPHNwYW4+PHNwYW4+Ijwvc3Bhbj5FeGl0IHN0YXR1czog PHNwYW4+JXM8L3NwYW4+PHNwYW4+Ijwvc3Bhbj48L3NwYW4+IDxzcGFuPiU8L3NwYW4+IGNoYW5u ZWwuZ2V0X2V4aXRfc3RhdHVzKCkpPC9wcmU+PC9kaXY+PC9kaXY+PC9ibG9ja3F1b3RlPjwvZGl2 PjxkaXY+wqA8L2Rpdj48ZGl2PjxkaXY+PGRpdj48ZGl2Pk1vc3Qgb2YgdGhlIEFQSSBoYXMgYmVl biBpbXBsZW1lbnRlZC4gQ3VycmVudGx5IDxlbT5ub3Q8L2VtPiBpbXBsZW1lbnRlZCBhcmU6PC9k aXY+PGRpdj7CoDwvZGl2PjxkaXY+KiBsaWJzc2gyX3B1YmxpY2tleV8qIG1ldGhvZHM8L2Rpdj48 ZGl2PiogU0ZUUCBWRlMgbWV0aG9kczwvZGl2PjxkaXY+KiBNb3N0IG9mIFNGVFBIYW5kbGUgbWV0 aG9kcyA8c3Ryb25nPmV4Y2VwdCA8L3N0cm9uZz5yZWFkIGFuZCBjbG9zZTwvZGl2PjxkaXY+KiBT RlRQIGF0dHJpYnV0ZXM8L2Rpdj48ZGl2PsKgPC9kaXY+PGRpdj5JdCBpcyBwdXJwb3NlZnVsbHkg YSB0aGluIHdyYXBwZXIgb3ZlciBsaWJzc2gyIGFuZCBkaXJlY3RseSBtYXBzIGl0cyBBUEkuIFRo ZSBleGFtcGxlcyBmcm9tIHRoZSBsaWJzc2gyIHNpdGUgY2FuIGJlIHBvcnRlZCBvdmVyIHRvIHB5 dGhvbiB3aXRoIG1pbmltYWwgY2hhbmdlcy48L2Rpdj48ZGl2PsKgPC9kaXY+PGRpdj5UaGUgcHl0 aG9uIGV4dGVuc2lvbnMgYXJlIHdyaXR0ZW4gaW4gQ3l0aG9uIGFuZCBhcmUgYWxzbyBhdmFpbGFi bGUgdG8gdXNlIGZyb20gQ3l0aG9uIHZpYSBpdHMgPGVtPmNpbXBvcnQ8L2VtPi48L2Rpdj48ZGl2 PsKgPC9kaXY+PGRpdj5Ob3csIGFzIHRvIG1vdGl2YXRpb24sIHlvdSBhcmUgcHJvYmFibHkgYXdh cmUgdGhhdCB0aGUgb25seSBvdGhlciBhdmFpbGFibGUgUHl0aG9uIGJpbmRpbmdzIGZvciBsaWJz c2gyLCBweWxpYnNzaDIsIGhhdmUgbm90IGJlZW4gbWFpbnRhaW5lZCBmb3IgeWVhcnMuIFRoZSBs YXN0IHJlbGVhc2Ugb2YgdGhhdCBwYWNrYWdlIHdhcyBpbiAyMDExLjwvZGl2PjxkaXY+wqA8L2Rp dj48ZGl2PkhhdmUgYmVlbiBsb29raW5nIGZvciBhbHRlcm5hdGl2ZXMgZm9yIGEgd2hpbGUgbm93 IGZvciB1c2UgaW4gYW4gPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL1BhcmFsbGVsU1NIL3Bh cmFsbGVsLXNzaCI+YXN5bmNocm9ub3VzIHBhcmFsbGVsIFNTSCBjbGllbnQ8L2E+IEkgaGF2ZSB3 cml0dGVuLiBQeWxpYnNzaDIga2luZCBvZiB3b3JrZWQgYWZ0ZXIgc29tZSBwYXRjaGVzIHdlcmUg YXBwbGllZCBmb3IgYXN5bmMgc3VwcG9ydCBhbW9uZyBvdGhlciB0aGluZ3MgYnV0IGl0IHN0aWxs IG5lZWRlZCBhIGxvdCBtb3JlIHdvcmsgdG8gYmUgdmlhYmxlLiBJdCBjb21wbGV0ZWx5IGxhY2tz IFNGVFAgc3VwcG9ydCBmb3Igb25lLCBhbmQgb25seSBoYXMgYmFzaWMgYWdlbnQgaW1wbGVtZW50 YXRpb24uIEkgYWxzbyBmb3VuZCBpdCBsZWFrcyBtZW1vcnkgaW4gbG9uZyB0ZXJtIHVzZS48L2Rp dj48ZGl2PsKgPC9kaXY+PGRpdj5TbyBkdWUgdG8gbGFjayBvZiBhbnkgb3RoZXIgb3B0aW9ucyBh cyB3ZWxsIGFzLCBqdWRnaW5nIGJ5IHRoZSBudW1iZXIgb2YgaXNzdWVzLCBmb3JrcyBhbmQgUFJz IG9uIHRoZSBweWxpYnNzaDIgZ2l0aHViIHBhZ2UsIGludGVyZXN0IGZyb20gb3RoZXJzIG9uIGV4 YWN0bHkgdGhlIHNhbWUgdGhpbmcsIEkgc3RhcnRlZCBmcm9tIHNjcmF0Y2ggdG8gbWFwIHRoZSBl bnRpcmUgbGlic3NoMiBBUEkgaW4gcHl0aG9uLCB2aWEgQ3l0aG9uIGV4dGVuc2lvbnMuPC9kaXY+ PGRpdj7CoDwvZGl2PjxkaXY+TW9zdCB0aGUgQVBJIGlzIGltcGxlbWVudGVkLCBiYXJyaW5nIGV4 Y2VwdGlvbnMgYWJvdmUsIGFzIGRpcmVjdCBtYXBwaW5nIG9mIHRoZSBsaWJzc2gyIEFQSSB3aXRo IHNvbWUgcHl0aG9uIHNlbWFudGljcywgbGlrZSBTRlRQSGFuZGxlcyBjYW4gYmUgaXRlcmF0ZWQg b24gdG8gcmVhZCB0aGVtIGFuZCBleGNlcHRpb25zIHJhaXNlZCBmb3IgY29tbW9uIGVycm9ycy48 L2Rpdj48ZGl2PsKgPC9kaXY+PGRpdj5UaGUgb2JqZWN0cyB3aWxsIGFsc28gc2FmZWx5IGFuZCBh dXRvbWF0aWNhbGx5IGNsZWFyIHRoZWlyIEMgYWxsb2NhdGlvbnMsIGluIGNvcnJlY3Qgb3JkZXIu PC9kaXY+PGRpdj7CoDwvZGl2PjxkaXY+UHlsaWJzc2gyIGRpZCBub3Qgc2VlbSB0byBkbyBhbnkg ZGUtYWxsb2NhdGlvbiwgaGVuY2UgdGhlIG1lbW9yeSBsZWFrYWdlLiBJdCBhbHNvIHNlZW1zIHRv IGJlIHF1aXRlIGEgYml0IGZhc3RlciBvbiByZWFkaW5nIGxhcmdlIGJ1ZmZlcnMgZnJvbSBhIGNo YW5uZWwgLSBweWxpYnNzaDIgaGFkIHNvbWUgaW5lZmZpY2llbmNpZXMgaW4gaXRzIGhhbmRsaW5n IHRoZXJlLjwvZGl2PjxkaXY+wqA8L2Rpdj48ZGl2PkFueSBmZWVkYmFjayBhbmQvb3IgcmV2aWV3 cyB3b3VsZCBiZSBncmVhdGx5IGFwcHJlY2lhdGVkLjwvZGl2PjxkaXY+wqA8L2Rpdj48ZGl2PlN0 aWxsIHF1aXRlIGEgYml0IHRvIGRvIGVzcGVjaWFsbHkgZG9jdW1lbnRhdGlvbiBhbmQgYmluYXJ5 IHBhY2thZ2VzLCBvdGhlciB0aGFuIGltcGxlbWVudGluZyB0aGUgbWlzc2luZyBwYXJ0cywgYnV0 IHRoZSBsaWJyYXJ5IGlzIHVzYWJsZSByaWdodCBub3cuIEFsc28gaGF2ZSB0ZXN0cyBpbiB0aGUg Y2xpZW50IGxpYnJhcnkgSSBtZW50aW9uZWQgd2hpY2ggYXJlIHBhc3NpbmcsIGhhdmluZyBvcmln aW5hbGx5IHVzZWQgcHlsaWJzc2gyLjwvZGl2PjxkaXY+wqA8L2Rpdj48ZGl2PsKgPC9kaXY+PGRp dj5JIHdvdWxkIGJlIHZlcnkgaGFwcHkgZm9yIHRoaXMgdG8gYmUgdXNlZnVsIHRvIG90aGVycyBh cyB3ZWxsLiBVbmZvcnR1bmF0ZWx5IHRoZSBjaG9pY2Ugb2YgU1NIIGxpYnJhcmllcyBpbiBQeXRo b24gaXMgc2V2ZXJlbHkgbGltaXRlZCBhbmQgdGhvc2UgdGhhdCBkbyBleGlzdCwgZXNwZWNpYWxs eSB0aGUgY3VycmVudCBkZS1mYWN0byBzdGFuZGFyZCwgcGFyYW1pa28sIGFyZSBxdWl0ZSBsYWNr aW5nIGluIHBlcmZvcm1hbmNlIGFuZCBzdGFiaWxpdHkgd2hpbGUgYWxzbyBsYWNraW5nIGluIG1h aW50YWluZXJzIHdpbGxpbmcgdG8gcmV2aWV3L21lcmdlIGNoYW5nZXMgYW5kIGZpeCByZXBvcnRl ZCBpc3N1ZXMuPC9kaXY+PGRpdj7CoDwvZGl2PjxkaXY+wqA8L2Rpdj48ZGl2Pk9uZSBxdWVzdGlv biB0aG91Z2gsIGlzIExJQlNTSDJfQ0hBTk5FTF9XSU5ET1dfREVGQVVMVCBhcHByb3ByaWF0ZSB0 byB1c2UgYXMgYW4gU0ZUUCBoYW5kbGUgcmVhZCBkZWZhdWx0IGJ1ZmZlciBsZW5ndGg/IEhhdmUg bm90aWNlZCB0aGUgZXhhbXBsZXMgb24gdGhlIHdlYnNpdGUgdXNlIGEgbXVjaCBsYXJnZXIgdmFs dWUgYnV0IG15IHRlc3RpbmcgZGlkIG5vdCBzaG93IGEgZGlzY2VybmlibGUgcGVyZm9ybWFuY2Ug YmVuZWZpdCB0byBhbnl0aGluZyBsYXJnZXIgdGhhbiBMSUJTU0gyX0NIQU5ORUxfV0lORE9XX0RF RkFVTFQuPC9kaXY+PGRpdj7CoDwvZGl2PjxkaXY+UmVnYXJkcyw8L2Rpdj48ZGl2PlBhbjwvZGl2 PjxkaXY+wqA8L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4= ------==--bound.344335.web36o.yandex.ru Content-Disposition: attachment; filename="example_echo.py" Content-Transfer-Encoding: base64 Content-Type: text/x-python; name="example_echo.py" ZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBwcmludF9mdW5jdGlvbgppbXBvcnQgb3MKaW1wb3J0IHNv Y2tldAoKZnJvbSBzc2gyIGltcG9ydCBTZXNzaW9uCmZyb20gc3NoMi51dGlscyBpbXBvcnQgdmVy c2lvbgoKIyBDb25uZWN0aW9uIHNldHRpbmdzCmhvc3QgPSAnbG9jYWxob3N0Jwp1c2VyID0gb3Mu Z2V0bG9naW4oKQoKIyBNYWtlIHNvY2tldCwgY29ubmVjdApzb2NrID0gc29ja2V0LnNvY2tldChz b2NrZXQuQUZfSU5FVCwgc29ja2V0LlNPQ0tfU1RSRUFNKQpzb2NrLmNvbm5lY3QoKGhvc3QsIDIy KSkKCiMgSW5pdGlhbGlzZQpzZXNzaW9uID0gU2Vzc2lvbigpCnNlc3Npb24uaGFuZHNoYWtlKHNv Y2spCgojIExpc3QgYXZhaWxhYmxlIGF1dGhlbnRpY2F0aW9uIG1ldGhvZHMKcHJpbnQoc2Vzc2lv bi51c2VyYXV0aF9saXN0KHVzZXIpKQoKIyBDb252ZW5pZW5jZSBmdW5jdGlvbiBmb3IgYWdlbnQg YmFzZWQgYXV0aGVudGljYXRpb24Kc2Vzc2lvbi5hZ2VudF9hdXRoKHVzZXIpCgojIEFnZW50IGNh cGFiaWxpdGllcwphZ2VudCA9IHNlc3Npb24uYWdlbnRfaW5pdCgpCmFnZW50LmNvbm5lY3QoKQpp ZGVudGl0aWVzID0gYWdlbnQuZ2V0X2lkZW50aXRpZXModXNlcikKcHJpbnQoaWRlbnRpdGllcykK cHJpbnQoaWRlbnRpdGllc1swXS5tYWdpYykKZGVsIGFnZW50CgojIFB1YmxpYyBrZXkgYmxvYiBh dmFpbGFibGUgYXMgaWRlbnRpdGllc1swXS5ibG9iCgojIENoYW5uZWwgaW5pdGlhbGlzZSwgZXhl YyBhbmQgd2FpdCBmb3IgZW5kCmNoYW5uZWwgPSBzZXNzaW9uLm9wZW5fc2Vzc2lvbigpCmNoYW5u ZWwuZXhlY3V0ZSgnZWNobyBtZScpCmNoYW5uZWwud2FpdF9lb2YoKQpjaGFubmVsLmNsb3NlKCkK Y2hhbm5lbC53YWl0X2Nsb3NlZCgpCgojIEdldCBleGl0IHN0YXR1cwpwcmludCgiRXhpdCBzdGF0 dXM6ICVzIiAlIGNoYW5uZWwuZ2V0X2V4aXRfc3RhdHVzKCkpCgojIFByaW50IG91dHB1dApzaXpl LCBkYXRhID0gY2hhbm5lbC5yZWFkKCkKd2hpbGUgc2l6ZSA+IDA6CiAgICBwcmludChkYXRhKQog ICAgc2l6ZSwgZGF0YSA9IGNoYW5uZWwucmVhZCgpCgojIFNGVFAgY2FwYWJpbGl0aWVzLCB1bmNv bW1lbnQgYW5kIGVudGVyIGEgZmlsZW5hbWUKCiMgc2Z0cCA9IHNlc3Npb24uc2Z0cF9pbml0KCkK IyBmaCA9IHNmdHAub3BlbignPG15IGZpbGU+JywgMCwgMCkKIyBmb3IgZGF0YSBpbiBmaDoKIyAg ICAgcGFzcwojIGRlbCBzZXNzaW9uCg== ------==--bound.344335.web36o.yandex.ru Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k ZXZlbCBodHRwczovL2Nvb2wuaGF4eC5zZS9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8vbGlic3No Mi1kZXZlbAo= ------==--bound.344335.web36o.yandex.ru--