* Progress on parsing/extracting FTN packets
This commit is contained in:
parent
5e55ce4bee
commit
8f33a9a067
|
@ -53,7 +53,7 @@ function FTNMailPacket(options) {
|
|||
};
|
||||
};
|
||||
|
||||
this.getNetworkForAddress = function(addr) {
|
||||
this.getNetworkNameForAddress = function(addr) {
|
||||
var nodeAddr;
|
||||
for(var network in self.nodeAddresses) {
|
||||
nodeAddr = self.nodeAddresses[network];
|
||||
|
@ -67,7 +67,7 @@ function FTNMailPacket(options) {
|
|||
}
|
||||
};
|
||||
|
||||
this.loadPacketHeader = function(packetBuffer, cb) {
|
||||
this.parseFtnPacketHeader = function(packetBuffer, cb) {
|
||||
assert(Buffer.isBuffer(packetBuffer));
|
||||
|
||||
if(packetBuffer.length < 58) {
|
||||
|
@ -93,7 +93,7 @@ function FTNMailPacket(options) {
|
|||
.buffer('password', 8) // null terminated C style string
|
||||
.word16lu('origZone')
|
||||
.word16lu('destZone')
|
||||
// where is the rest of the spec?
|
||||
// :TODO: Document the various specs/fields more
|
||||
.word16lu('auxNet')
|
||||
.word16lu('capWordA')
|
||||
.word8('prodCodeHi')
|
||||
|
@ -107,37 +107,131 @@ function FTNMailPacket(options) {
|
|||
.tap(function tapped(packetHeader) {
|
||||
packetHeader.password = ftn.stringFromFTN(packetHeader.password);
|
||||
|
||||
// :TODO: Don't hard code magic # here
|
||||
if(2 !== packetHeader.packetType) {
|
||||
cb(new Error('Packet is not Type-2'));
|
||||
return;
|
||||
}
|
||||
|
||||
// :TODO: validate & pass error if failure
|
||||
cb(null, packetHeader);
|
||||
});
|
||||
};
|
||||
|
||||
this.loadMessagesFromPacketBuffer = function(packetBuffer, cb) {
|
||||
async.series(
|
||||
this.parseFtnMessageBody = function(msgBodyBuffer, cb) {
|
||||
|
||||
};
|
||||
|
||||
this.parseFtnMessages = function(buffer, cb) {
|
||||
var nullTermBuf = new Buffer( [ 0 ] );
|
||||
var fidoMessages = [];
|
||||
|
||||
binary.stream(buffer).loop(function looper(end, vars) {
|
||||
this
|
||||
.word16lu('messageType')
|
||||
.word16lu('originNode')
|
||||
.word16lu('destNode')
|
||||
.word16lu('originNet')
|
||||
.word16lu('destNet')
|
||||
.word8('attrFlags1')
|
||||
.word8('attrFlags2')
|
||||
.word16lu('cost')
|
||||
.scan('modDateTime', nullTermBuf)
|
||||
.scan('toUserName', nullTermBuf)
|
||||
.scan('fromUserName', nullTermBuf)
|
||||
.scan('subject', nullTermBuf)
|
||||
.scan('message', nullTermBuf)
|
||||
.tap(function tapped(msgData) {
|
||||
if(!msgData.originNode) {
|
||||
end();
|
||||
cb(null, fidoMessages);
|
||||
return;
|
||||
}
|
||||
|
||||
// buffer to string conversion
|
||||
// :TODO: What is the real encoding here?
|
||||
[ 'modDateTime', 'toUserName', 'fromUserName', 'subject', ].forEach(function field(f) {
|
||||
msgData[f] = msgData[f].toString();
|
||||
});
|
||||
|
||||
|
||||
|
||||
fidoMessages.push(_.clone(msgData));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
this.loadMessageHeader = function(msgHeaderBuffer, cb) {
|
||||
assert(Buffer.isBuffer(msgHeaderBuffer));
|
||||
|
||||
if(msgHeaderBuffer.length < 14) {
|
||||
cb(new Error('Buffer too small'));
|
||||
return;
|
||||
}
|
||||
|
||||
binary.parse(msgHeaderBuffer)
|
||||
.word16lu('messageType')
|
||||
.word16lu('originNode')
|
||||
.word16lu('destNode')
|
||||
.word16lu('originNet')
|
||||
.word16lu('destNet')
|
||||
.word8('attrFlags1')
|
||||
.word8('attrFlags2')
|
||||
.word16lu('cost')
|
||||
.tap(function tapped(msgHeader) {
|
||||
console.log(msgHeader)
|
||||
|
||||
var nullTermBuf = new Buffer( [ 0 ] );
|
||||
var offset = 14;
|
||||
binary.parse(msgHeaderBuffer.slice(offset))
|
||||
.scan('modDateTime', nullTermBuf)
|
||||
.scan('toUserName', nullTermBuf)
|
||||
.tap(function tapped(varMsgHeader) {
|
||||
console.log(varMsgHeader.modDateTime.toString())
|
||||
console.log(varMsgHeader.toUserName.toString())
|
||||
});
|
||||
|
||||
cb(null, msgHeader);
|
||||
});
|
||||
};
|
||||
|
||||
this.loadMessage = function(buf, cb) {
|
||||
var bufPosition = 0;
|
||||
async.waterfall(
|
||||
[
|
||||
function loadHdr(callback) {
|
||||
self.loadPacketHeader(packetBuffer, function headerLoaded(err, packetHeader) {
|
||||
self.loadMessageHeader(buf.slice(bufPosition), function headerLoaded(err, msgHeader) {
|
||||
callback(err, msgHeader);
|
||||
});
|
||||
}
|
||||
]
|
||||
);
|
||||
};
|
||||
*/
|
||||
|
||||
this.loadMessagesFromPacketBuffer = function(packetBuffer, cb) {
|
||||
async.waterfall(
|
||||
[
|
||||
function parseHeader(callback) {
|
||||
self.parseFtnPacketHeader(packetBuffer, function headerParsed(err, packetHeader) {
|
||||
self.packetHeader = packetHeader;
|
||||
callback(err);
|
||||
});
|
||||
},
|
||||
function validateType(callback) {
|
||||
// :TODO: don't use a magic # here....
|
||||
if(2 !== self.packetHeader.packetType) {
|
||||
callback(new Error('Packet is not Type-2'));
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
function validateDesinationAddress(callback) {
|
||||
self.localNetworkName = self.getNetworkNameForAddress(self.getPacketHeaderAddress());
|
||||
callback(self.localNetworkName ? null : new Error('Packet not addressed do this system'));
|
||||
},
|
||||
function checkAddress(callback) {
|
||||
/*
|
||||
if(0 !== self.packetHeader.destPoint) {
|
||||
self.packetNodeAddress = ftn.getFormattedFTNAddress(self.getPacketHeaderAddress(), '4D');
|
||||
} else {
|
||||
self.packetNodeAddress = ftn.getFormattedFTNAddress(self.getPacketHeaderAddress(), '3D');
|
||||
}*/
|
||||
|
||||
var network = self.getNetworkForAddress(self.getPacketHeaderAddress());
|
||||
callback(network ? null : new Error('Packet not addressed do this system'));
|
||||
function parseMessages(callback) {
|
||||
self.parseFtnMessages(packetBuffer.slice(58), function messagesParsed(err, fidoMessages) {
|
||||
callback(err, fidoMessages);
|
||||
});
|
||||
},
|
||||
function createMessageObjects(fidoMessages, callback) {
|
||||
fidoMessages.forEach(function msg(fmsg) {
|
||||
console.log(fmsg.subject);
|
||||
});
|
||||
}
|
||||
],
|
||||
function complete(err) {
|
||||
|
@ -185,6 +279,6 @@ var mailPacket = new FTNMailPacket(
|
|||
}
|
||||
);
|
||||
|
||||
mailPacket.parse('/home/nuskooler/ownCloud/Projects/ENiGMA½ BBS/FTNPackets/27000425.pkt', function parsed(err, messages) {
|
||||
mailPacket.parse('/home/bashby/ownCloud/Projects/ENiGMA½ BBS/FTNPackets/27000425.pkt', function parsed(err, messages) {
|
||||
|
||||
});
|
|
@ -13,6 +13,8 @@ var util = require('util');
|
|||
exports.stringFromFTN = stringFromFTN;
|
||||
exports.getFormattedFTNAddress = getFormattedFTNAddress;
|
||||
|
||||
// See list here: https://github.com/Mithgol/node-fidonet-jam
|
||||
|
||||
|
||||
function stringFromFTN(buf, encoding) {
|
||||
var nullPos = buf.length;
|
||||
|
@ -67,7 +69,7 @@ function getFormattedFTNAddress(address, dimensions) {
|
|||
return addr;
|
||||
}
|
||||
|
||||
function getFTNMessageSerialNumber(messageId) {
|
||||
function getFtnMessageSerialNumber(messageId) {
|
||||
return ((Math.floor((Date.now() - Date.UTC(2015, 1, 1)) / 1000) + messageId)).toString(16);
|
||||
}
|
||||
|
||||
|
@ -75,6 +77,21 @@ function getFTNMessageID(messageId, areaId) {
|
|||
return messageId + '.' + areaId + '@' + getFTNAddress() + ' ' + getFTNMessageSerialNumber(messageId)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Specs:
|
||||
// * http://ftsc.org/docs/fts-0009.001
|
||||
// *
|
||||
//
|
||||
function getFtnMsgIdKludgeLine(origAddress, messageId) {
|
||||
if(_.isObject(origAddress)) {
|
||||
origAddress = getFormattedFTNAddress(origAddress, '5D');
|
||||
}
|
||||
|
||||
return '\x01MSGID: ' + origAddress + ' ' + getFtnMessageSerialNumber(messageId);
|
||||
}
|
||||
|
||||
|
||||
function getFTNOriginLine() {
|
||||
//
|
||||
// Specs:
|
||||
|
|
Loading…
Reference in New Issue