Thanks for the responses, after reading those and doing some additional 
reading on the tube I understand the difference between callbacks and 
eventEmitters better.

I'll go away and have a think about how to handle the data event, I'll also 
try and kick start the node-sftp library that I was using, I think it was 
fairly close to working properly.

So am I right in thinking that I need to parse the stdout data to figure 
out what command has been run and handle it accordingly? I think that's 
what the node-sftp library does (example code below).
This seems like an alien way of doing things for me but I guess it's 
similar to handling a request from a browser and determining what script 
needs to handle the request.

    /**
     * Parse the STDOUT of the sftp child process, collect the lines of 
data for
     * the active command and detect if the active command has finished 
executing.
     * If the active command is done, respective callbacks are called.
     * 
     * @param {String} data
     * @type  {void}
     * @private
     */
    function parseReply(data) {
        //console.log("data: ", data, data.split("\n").length + " parts");
        this.emit("data", data);
        if (!this.activeCmd && !(this.state & Sftp.STATE_CONNECTING))
            return;
        var cbdone, cbprogress;
        if (data.indexOf("sftp>") > -1 || (this.activeCmd == "bye" && 
data.indexOf("bye") > -1)) {
            if (this.state & Sftp.STATE_CONNECTING && 
this.callbacks["connect"]) {
                this.callbacks["connect"]();
                delete this.callbacks["connect"];
            }
            // check if a command has finished executing:
            else if (cbdone = this.callbacks[this.activeCmd]) {
                delete this.callbacks[this.activeCmd];
                delete this.callbacks[this.activeCmd + "_progress"];
                this.activeCmd = null;
                cbdone((this.activeCmdBuffer + 
data).split(/[\n\r]+/).filter(function(line) {
                    return line.indexOf("sftp>") === -1;
                }));
                this.activeCmdBuffer = "";
            }
            if (!this.activeCmd && this.queue.length && this.state & 
Sftp.STATE_CONNECTED)
                this.exec.apply(this, this.queue.shift());
        }
        else if (cbprogress = this.callbacks[this.activeCmd + "_progress"]) 
{
            this.activeCmdBuffer += data;
            cbprogress(data);
        }
    }


On Monday, 30 July 2012 21:23:35 UTC+1, rhasson wrote:
>
> "stdin" and "stdout" available on the child process are buffer that 
> inherit from EventEmitter (well they are streams, unless you change their 
> behavior when creating the spawned child).  As mentioned by Dominic you 
> need to add event listeners to the data events of the stdout and stderr so 
> you can see what the FTP process writes.  You then need to parse it and 
> write to the stdin stream while again listening to the stdout and making 
> sure you received the complete response to the command you sent.
>
> just  be careful not to get into a situation, as you have in your example, 
> where you register multiple listeners to the same event performing 
> different tasks.  In your example, the outer and inner listeners on stdout 
> data event will be called when you write "ls" and when you write "rename". 
>  You'll get into an infinite loop very quickly.
>
> I think you need to create a single data handler that will deal with 
> processing of all expected output from the FTP process based on all 
> possible FTP commands you plan to use.  Try to make it as generic as 
> possible so regardless if you did "ls /tmp" or "ls /home" the processing 
> within the data handler will be the same.  You'll need to maintain some 
> structure outside of the data handler to deal with passing that information 
> back to the calling function (via callbacks or events).
>
> If you really want to you can build a TCP server instead that implements 
> the FTP protocol.  Maybe even easier is to copy what other FTP modules did 
> and just refresh the code and make it your own.
>
> Roy
>
> On Monday, July 30, 2012 7:01:43 AM UTC-4, carlton wrote:
>>
>> Hi there,
>>
>> I am trying to implent a nodejs script that connects to one of our 
>> servers using sftp.
>>
>> So far I can connect using child process and spawning a command such as...
>>
>> sftp -o Port=22-o PasswordAuthentication=no-o 
>> UserKnownHostsFile=/home/carlton/.ssh/known_hosts-o 
>> IdentityFile=private_key-o StrictHostKeyChecking=no-o 
>> BatchMode=nodeploy@46.x.x.x:/home/carlton/to_process
>>
>> Now this is the part that has me confused...
>>
>> I then need to execute commands on the ftp server (e.g. list files, 
>> rename files) so I listen to the 'data' event....
>>
>> sftp.stdout.on('data', function (data) {
>>     console.log('stdout: ' + data);
>>
>>     sftp.stdin.write("ls -l\r\n");
>>
>>     sftp.stdout.on('data', function(data){
>>         console.log('File list:', data.toString());
>>         
>>          // Parse file names here
>>          
>>         sftp.stdin.write("rename 
>> /home/carlton/FTP_test/to_process/old.php /home/ carlton 
>> /FTP_test/processed/new.php\n");
>>     });
>> });
>>
>> Is this the correct way to structure things (i.e. creatiung event 
>> listener again for the 'data' event within the callback of the previous 
>> 'data' event listener)?
>> I found it hard to find any examples similar to what I need to do which 
>> made me think I haven't built this as it should have been.
>>
>

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to