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
>> [email protected]:/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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en