102 lines
2.7 KiB
JavaScript
102 lines
2.7 KiB
JavaScript
var Parser = require("parse-listing");
|
|
var async = require("async");
|
|
|
|
var RE_RES = /^(\d\d\d)\s(.*)/;
|
|
var RE_MULTI = /^(\d\d\d)-/;
|
|
var RE_SERVER_RESPONSE = /^(\d\d\d)(.*)/;
|
|
|
|
var Utils = module.exports = {
|
|
// Codes from 100 to 200 are FTP marks
|
|
isMark: function(code) {
|
|
code = parseInt(code, 10);
|
|
return code > 100 && code < 200;
|
|
},
|
|
|
|
/**
|
|
* Parse raw output of a file listing, trying in to clean up broken listings in
|
|
* the process
|
|
* @param {String} listing Raw file listing coming from a 'list' or 'stat'
|
|
* @returns {Object[]}
|
|
*/
|
|
parseEntry: function(listing) {
|
|
var t, parsedEntry;
|
|
var i = 0;
|
|
var parsed = [];
|
|
var splitEntries = listing.split(/\r\n|\n/);
|
|
async.eachSeries(splitEntries, function(entry, next) {
|
|
function _next() {
|
|
i += 1;
|
|
next();
|
|
}
|
|
|
|
// Some servers include an official code-multiline sign at the beginning of
|
|
// every string. We must strip it if that's the case.
|
|
if (RE_MULTI.test(entry))
|
|
entry = entry.substr(3);
|
|
|
|
entry = entry.trim();
|
|
|
|
// Filter file-listing results from 'STAT' command, since they include
|
|
// server responses before and after the file listing.
|
|
// Issue: https://github.com/sergi/jsftp/issues/3
|
|
if (RE_SERVER_RESPONSE.test(entry) ||
|
|
RE_RES.test(entry) || RE_MULTI.test(entry)) {
|
|
return _next();
|
|
}
|
|
|
|
parsedEntry = Parser.parseEntry(entry);
|
|
if (parsedEntry === null) {
|
|
if (splitEntries[i + 1]) {
|
|
t = Parser.parseEntry(entry + splitEntries[i + 1]);
|
|
if (t !== null) {
|
|
splitEntries[i + 1] = entry + splitEntries[i + 1];
|
|
return _next();
|
|
}
|
|
}
|
|
|
|
if (splitEntries[i - 1] && parsed.length > 0) {
|
|
t = Parser.parseEntry(splitEntries[i - 1] + entry);
|
|
if (t !== null) {
|
|
parsed[parsed.length - 1] = t;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (parsedEntry)
|
|
parsed.push(parsedEntry)
|
|
}
|
|
_next();
|
|
});
|
|
|
|
return parsed;
|
|
},
|
|
|
|
getPasvPort: function(text) {
|
|
var RE_PASV = /([-\d]+,[-\d]+,[-\d]+,[-\d]+),([-\d]+),([-\d]+)/;
|
|
var match = RE_PASV.exec(text);
|
|
if (!match) return false;
|
|
|
|
// Array containing the passive host and the port number
|
|
return [match[1].replace(/,/g, "."),
|
|
(parseInt(match[2], 10) & 255) * 256 + (parseInt(match[3], 10) & 255)];
|
|
},
|
|
|
|
/**
|
|
* Cleans up commands with potentially insecure data in them, such as
|
|
* passwords, personal info, etc.
|
|
*
|
|
* @param cmd {String} Command to be sanitized
|
|
* @returns {String} Sanitized command
|
|
*/
|
|
sanitize: function(cmd) {
|
|
if (!cmd) return "";
|
|
|
|
var _cmd = cmd.slice(0, 5);
|
|
if (_cmd === "pass ")
|
|
cmd = _cmd + Array(cmd.length - 5).join("*");
|
|
|
|
return cmd;
|
|
}
|
|
}
|
|
|