UNPKG

ftpd.js

Version:
253 lines (232 loc) 7.12 kB
//Imports var util = require( "util" ), path = require( "path" ), EventEmitter = require( "events" ).EventEmitter, Interface = require( "./interface.js" ); /** * * @access public * @constructor * @since 0.6.0 * @type {Server} */ function Server( ftpdjs, options ) { this.ftpdjs = ftpdjs; this.id = options.id; this.options = options; //Check if the interface path have been defined or not if ( undefined === this.getOptions().interfacePath ) { //Add the default interface path this.getOptions().interfacePath = [ "./interfaces" ]; } this.interfaces = []; this.closeIndex = 0; this.setupCounter = 0; EventEmitter.call( this ); } util.inherits( Server, EventEmitter ); /** * * This callback will get invoked when the server have finished setting up all of the interfaces it wished to utilize * * @callback Server~finishSetup * @since 0.6.0 */ /** * * This function will be invoked by the application when the server instance have been successfully stored * in the application's main class. Use this to start and listen the interfaces needed. * * Setup Process * - Setup User Manager * - Setup All Interfaces * * @access public * @param {Server~finishSetup} callback the callback to invoke when finished * @since 0.6.0 */ Server.prototype.setup = function ( callback ) { //Get the array of available interface configurations var interfaceConfigurations = this.getOptions().interfaces || [], that = this; this.getFtpdjs().log( this.getBaseMessage() + ": Setting up" ); function setupCallback( theInterface ) { that.getInterfaces().push( theInterface ); that.setupCounter++; if ( that.setupCounter === that.getOptions().interfaces.length ) { that.emit( "state", "setup" ); that.getFtpdjs().log( that.getBaseMessage() + ": Finished setting up" ); if ( undefined !== callback ) { try { callback(); } catch ( e ) { } } } } //Loop through all of the interface configurations for ( var i = 0; i < interfaceConfigurations.length; i++ ) { var interfaceOptions = interfaceConfigurations[ i ], type = interfaceOptions.type; interfaceOptions.id = that.getID() + i; if ( undefined === interfaceOptions.type ) { var theInterface = new Interface( this, interfaceOptions ); theInterface.setup( setupCallback ); } else { this.getInterfaceFile( type, function ( path ) { if ( undefined !== path ) { var interfaceModule = require( path ), theInterface = new interfaceModule( this, interfaceOptions ); theInterface.setup( setupCallback ); } } ); } } }; /** * * @callback Server~finishClose * @since 0.6.0 */ /** * * This method is used to close all of the interfaces the server is currently utilizing * * @access public * @param {Supervisor~finishClose} callback the callback to invoke upon completed closure of the interfaces * @since 0.6.0 */ Server.prototype.close = function ( callback ) { //Check if we've been through all of the interfaces or if there even is interface in use if ( this.getInterfaces().length === (this.closeIndex) || 0 == this.getInterfaces().length ) { //Invoke the callback as there's nothing more to close this.interfaces = []; this.getFtpdjs().log( this.getBaseMessage() + ": Closed" ); try { callback(); } catch ( e ) { } return; } //Get the next interface and increment the interface close counter var serverInterface = this.getInterfaces()[ this.closeIndex++ ], //Setup a this reference as we can't use this within a callback that = this; try { //Close the interface serverInterface.close( function () { //Continue to the next interface that.close( callback ); } ) } catch ( exception ) { //@TODO Error Handling } }; /** * * This callback will be invoked when the server finished looking for the wanted interface class * * @callback Server~interfaceFile * @param {string|undefined} interfacePath this will be the full path if the class was found otherwise it'll be * undefined * @since 0.6.0 */ /** * * This function is used to search for the wanted interface class in the interfaces paths provided by the server's * options * * @param {string} name the name of the interface * @param {Server~interfaceFile} callback the callback to invoke when finished looking for the class * @param {int} index the current path index. Use this if you want to ignore the paths defined before index */ Server.prototype.getInterfaceFile = function ( name, callback, index ) { index = index || 0; try { var interfacePath = path.join( this.getOptions().interfacePath[ index ], type + ".js" ), that = this; fs.exists( interfacePath, function ( exists ) { if ( !exists ) { that.getInterfaceFile( type, callback, index + 1 ); } else { callback( interfacePath ); } } ) } catch ( e ) { callback( undefined ); } }; /** * * @access public * @returns {ftpdjs} the ftpdjs instance using the server * @since 0.6.0 */ Server.prototype.getFtpdjs = function () { return this.ftpdjs; }; /** * * This function is used to get the id of the server * * @access public * @returns {string} the id of the server * @since 0.6.0 */ Server.prototype.getID = function () { return this.id; }; /** * * This function is used to get the server's options * * @access public * @returns {Object} the server's options * @since 0.6.0 */ Server.prototype.getOptions = function () { return this.options; }; /** * * This function is used to get the array of interfaces the server is utilizing * * @access public * @returns {Array} the initialized interfaces * @since 0.6.0 */ Server.prototype.getInterfaces = function () { return this.interfaces; }; /** * * This function is used to tell wether or not all of the interfaces the server have to utilize have been setup * * @access public * @returns {boolean} wether or not all of the interfaces have been setup * @since 0.6.0 */ Server.prototype.isSetup = function () { return this.getInterfaces().length === this.setupCounter; }; /** * * This function is used to get the base logging message for the server * * @access public * @returns {string} the base log message * @since 0.6.o */ Server.prototype.getBaseMessage = function () { return "[Server " + this.getID() + "]"; }; Server.prototype.getUserManager = function(){ return this.userManager; } /** * * @access public * @type {Server} * @since 0.6.0 */ module.exports = Server;