cURL / Mailing Lists / curl-library / Single Mail


Re: Converting ssh.c (sftp) to use Curl_setup_transfer()

From: James Housley <>
Date: Tue, 26 Jun 2007 17:12:08 -0400

On Jun 26, 2007, at 4:09 PM, Daniel Stenberg wrote:

> On Tue, 26 Jun 2007, James Housley wrote:
>> I am about to the point, for download lets say, to use
>> Curl_setup_transfer(). Looking at the attached lib/ssh.c at line
>> 1490. I obviously need to remove the #if 0/#endif, and add a state
>> (conn, SSH_STOP); break;
> ... and not do the sftp read loop that comes after it I take it! ;-)


>> But the problem I am having is it isn't working, and I am not sure
>> it will. The SSH protocols require both transmitting and receiving
>> to receive data (and transmit too). So the socket that gets passed
>> in for a download will only be checked for data to read, but part
>> of the time it will need to be checked that it is okay to transmit.
> Well, Curl_setup_transfer() can be told to use the same socket
> descriptor for both recv and send, and you should probably set both
> even for downloads-only since you do need to check it for
> writability (at times).


>> Is the most correct way to implement these protocols is to not use
>> Curl_setup_transfer() and just do the reads in the state machine.
>> Using the state machine will return in multi mode when blocking
>> would occur.
> If I would do it, I think I would call Curl_setup_transfer() to set
> both reading and writing, and then make sure the sftp read/write
> functions deal with both reading and writing accordingly. That may
> of course use the same or another state machine function.

I will give it a shot. I should be able to use a state to know if I
need to call libssh2_sftp_write() or libssh2_sftp_read()

After calling Curl_setup_transfer() if I call state(conn, SSH_STOP),
then Curl_sftp_do() says it is done, and I think the transfer stops.
I need to keep "done" set to false, right?

I tried this at 1490:
#if 1
         /* code left here just because this is what this function
will use the
         day libssh2 is improved */
         res = Curl_setup_transfer(conn, FIRSTSOCKET,
                                   data->reqdata.size, FALSE, NULL,
         state(conn, SSH_STOP);

But the code just hangs. The problem I see is that since there is an
"upload" socket eventually Curl_fillreadbuffer() is called, but there
is nothing to put in that buffer. I don't see where in there to put
code specific to SFTP/SCP.

(gdb) bt
#0 Curl_fillreadbuffer (conn=0x1800604, bytes=16384,
nreadp=0xbfffee10) at transfer.c:118
#1 0x00028544 in Curl_readwrite (conn=0x1800604, done=0xbfffef5c) at
#2 0x00029630 in Transfer (conn=0x1800604) at transfer.c:1864
#3 0x0002a618 in Curl_perform (data=0x325004) at transfer.c:2424
#4 0x0000f470 in curl_easy_perform (curl=0x325004) at easy.c:492
#5 0x0000b5d0 in operate (config=0xbffff4bc, argc=2,
argv=0xbffff790) at main.c:4363
#6 0x0000bf28 in main (argc=2, argv=0xbffff790) at main.c:4667

Or did I miss it?

> BTW, a totally separate note: please try to kill trailing
> whitespace in the files you're editing. This ssh.c one is full of
> them...

I try to remember to do that before final commits, but sometimes
forget. I will try harder.


/"\   ASCII Ribbon Campaign  .
\ / - NO HTML/RTF in e-mail  .
  X  - NO Word docs in e-mail .
/ \ -----------------------------------------------------------------
                 The Power to Serve
Progress (n) : What led from smart users in front of dumb terminals to
dumb users in front of smart terminals.
Received on 2007-06-26