Source: lib/command.js

/**
 * FTPimp Response Handler
 * @author Nicholas Riley
 * @module lib/command
 */
"use strict";
var ftp,
    cmd,
    dbg = function () {
        return undefined;
    },
    CMD = function () {
        cmd = this;
    };


/**
 * Create and return a new CMD instance
 * @param {object} ftpObject - The FTP instance object
 * @returns New CMD object
 */
CMD.create = function (ftpObject) {
    ftp = ftpObject;
    if (ftp.config.debug) {
        dbg = function (msg) {
            console.log(msg);
        };
    }
    return new CMD();
};


/**
 * List of command response codes and their
 * attributing event that will be fired;
 * you can add your own event listeners to 
 * listen to these codes
 * @member {object} CMD#codes
 * @property {number} 150 - dataPortReady
 * @property {number} 220 - login
 * @property {number} 226 - transferComplete
 * @property {number} 227 - startPassive
 * @property {number} 230 - ready
 * @property {number} 250 - fileActionComplete [default: disabled]
 * @property {number} 257 - data capture [default: disabled]
 * @property {number} 331 - sendPass [default: disabled]
 * @property {number} 500 - unkownCommand
 * @property {number} 550 - transferError
 * @property {number} 553 - transferError
 */
CMD.prototype.codes = {
    125: 'dataPortReady',
    150: 'dataPortReady',
    220: 'login',
    //we will call the cmd from the ftp function
    226: 'transferComplete',
    227: 'startPassive',
    230: 'ready',
    //250: 'fileActionComplete',
    //257: data capture
    //331: 'sendPass',
    500: 'unknownCommand',
    550: 'transferError',
	553: 'transferError'
};

CMD.prototype.keys = CMD.prototype.codes;

CMD.prototype.transferError = function (data) {
    ftp.emit('transferError', data);
};

/** @fires FTP#fileTransferComplete */
CMD.prototype.fileActionComplete = function (data) {
    ftp.emit('fileActionComplete', data);
};


/**
 * Emit a fileTransferComplete or dataTransferComplete event on the {@link FTP#events} object
 * @fires FTP#dataTransferComplete
 * @function CMD#transferComplete
 */
CMD.prototype.transferComplete = function (data) {//{{{
    /**
     * Fired when we receive a remote acknowledgement
     * of the files successful transfer
     * @event FTP#fileTransferComplete
     */
    //dbg('file transfer complete');
    //ftp.emit('fileTransferComplete', data);
    if (ftp.cueDataTransfer) {
        dbg('CMD> data transfer complete');
        ftp.cueDataTransfer = false;
        ftp.emit('dataTransferComplete');//, data);
        //ftp.emit('endproc');
    }
};//}}}


/**
 * Sets the cueDataTransfer so we know we are
 * specifically performing data fetching
 * @function CMD#dataPortReady
 */
CMD.prototype.dataPortReady = function (data) {//{{{
    dbg('---data port ready---');
    ftp.cueDataTransfer = true;
    ftp.openPipes += 1;
    ftp.totalPipes += 1;
    //ftp.emit('dataPortReady');
};//}}}


/**
 * Emit an error on the {@link FTP#socket} object
 * @fires FTP#socket#error
 * @function CMD#error
 */
CMD.prototype.error = function (data) {//{{{
    /**
     * Fired at the onset of a socket error
     * @event FTP#socket#error
     */
    ftp.socket.emit('error', data);
};//}}}


/**
 * Emit an error on the {@link FTP#socket} object
 * @fires FTP#socket#error
 * @function CMD#unknownCommand
 */
CMD.prototype.unknownCommand = CMD.prototype.error;


/**
 * Emit a <b>"ready"</b> event on the {@link FTP#socket} object
 * @fires FTP#socket#ready
 * @function CMD#ready
 */
CMD.prototype.ready = function () {//{{{
    /**
     * Fired at the onset of a socket error
     * @event FTP#socket#ready
     */
    //ftp.emit('ready');
};//}}}


/**
 * Log in to the FTP server with set configuration
 * @function CMD#login
 */
CMD.prototype.login = function () {//{{{
    dbg('>Authenticating...');
    ftp.user(ftp.config.user, function (err, data) {
        if (err) {
            dbg(err);
            dbg('an error occured sending the user');
            return;
        }
        dbg(data);
        dbg('user sent');
        ftp.pass(ftp.config.pass, function (err, data) {
            if (err) {
                dbg(err);
                return;
            }
            dbg('password sent');
			ftp.raw('CWD', function (res) {
				var dir = res.indexOf('/');
				dir = res.slice(dir - 1).trim();
				ftp.cwd = ftp.baseDir = dir;
				dbg('current dir: ' + ftp.cwd);
				ftp.emit('ready');
				ftp.isReady = true;
			});
        });
    });
};//}}}

/**
 * Opens a passive (PASV) connection to the FTP server
 * with the data received from the socket that made the
 * <b>"PASV"</b> request
 * @function CMD#startPassive
 * @param {string} data - The returned socket data
 */
CMD.prototype.startPassive = function (data) {//{{{
    var matches = data.match(/(([0-9]{1,3},){4})([0-9]{1,3}),([0-9]{1,3})?/),
        port;
    if (null === matches) {
        throw new Error('could not establish a passive connection');
    }
    port = ftp.config.pasvPort = Number(matches[3] * 256) + Number(matches[4]);
    ftp.config.pasvString = matches[0];
    ftp.pipeClosed = false;
    dbg('passive settings updated');
    ftp.emit('commandComplete');
};//}}}



module.exports = CMD;