Added Ansitex Data transport
This commit is contained in:
parent
a5231cb7ff
commit
31bf9b9dd7
241
mods/ansitex_export.js
Normal file
241
mods/ansitex_export.js
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
load('texdefs.js');
|
||||||
|
load('texfuncs.js');
|
||||||
|
load('smbdefs.js');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Work out which key should be used for a page, or validate if a key used is valid
|
||||||
|
*
|
||||||
|
* @param page
|
||||||
|
* @param signed
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function getKey(page,signed) {
|
||||||
|
log(LOG_DEBUG,'+ CHECKING key:'+signed+' for page: '+page);
|
||||||
|
|
||||||
|
var f = new File(file_cfgname(system.ctrl_dir,'videotex.ini'));
|
||||||
|
var match = '';
|
||||||
|
|
||||||
|
if (f.open("r")) {
|
||||||
|
var BreakException = {};
|
||||||
|
|
||||||
|
// Default Key
|
||||||
|
var key = f.iniGetValue('prefix','key');
|
||||||
|
|
||||||
|
try {
|
||||||
|
f.iniGetSections("prefix:").forEach(function (prefix) {
|
||||||
|
var p = prefix.substr(7);
|
||||||
|
var pk = f.iniGetValue(prefix, 'Key', '');
|
||||||
|
var re = new RegExp('^' + p, 'g');
|
||||||
|
|
||||||
|
// If it was signed, is the key a value one
|
||||||
|
if (signed && signed.length) {
|
||||||
|
if (pk == signed) {
|
||||||
|
//print('SIGNED key is valid:' + signed);
|
||||||
|
key = signed;
|
||||||
|
throw BreakException;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which key should sign this page
|
||||||
|
} else if (page.toString().match(re) && (p.length > match.length)) {
|
||||||
|
match = p;
|
||||||
|
key = pk;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
if (e !== BreakException) throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
log(LOG_DEBUG,'- key:'+key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export message from message base
|
||||||
|
*
|
||||||
|
* @param msgbase
|
||||||
|
*/
|
||||||
|
function msgBaseExport(msgbase) {
|
||||||
|
var ini = new File(msgbase.file+'.ini');
|
||||||
|
var i=0;
|
||||||
|
|
||||||
|
if (ini.open("r")) {
|
||||||
|
export_ptr=ini.iniGetValue('videotex','export_ptr',0);
|
||||||
|
ini.close();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log(LOG_ERROR,'! ERROR: Unable to open INI for ['+msgbase.file+']');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If pointer doesnt exist, reset it from the message base.
|
||||||
|
if (export_ptr == undefined) {
|
||||||
|
var f = new File(file_getcase(msgbase.file+'.sbl'));
|
||||||
|
|
||||||
|
if (f.open('rb')) {
|
||||||
|
export_ptr = f.readBin(4);
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
highest = export_ptr;
|
||||||
|
var total_msgs = msgbase.total_msgs;
|
||||||
|
|
||||||
|
log(LOG_DEBUG,'| msgBaseExport: export_ptr='+export_ptr+'|last_msg='+msgbase.last_msg+'|total_msgs='+total_msgs);
|
||||||
|
|
||||||
|
if (msgbase.last_msg >= export_ptr)
|
||||||
|
i = total_msgs-(msgbase.last_msg-export_ptr);
|
||||||
|
|
||||||
|
for (; i<total_msgs; i++) {
|
||||||
|
if (js.terminated)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var idx = msgbase.get_msg_index(true,i);
|
||||||
|
if (! idx) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Reading index of msg offset ['+i+'] : ['+msgbase.error+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip message until we get to our last one read.
|
||||||
|
if (idx.number <= export_ptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (idx.number > highest)
|
||||||
|
highest = idx.number;
|
||||||
|
|
||||||
|
// Only check messages from Videotex
|
||||||
|
if (idx.from != crc16_calc('videotex')) {
|
||||||
|
log(LOG_DEBUG,'! IGNORING: Message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the message header
|
||||||
|
var hdr = msgbase.get_msg_header(true,i);
|
||||||
|
|
||||||
|
// Ignore deleted messages
|
||||||
|
if (hdr.attr&MSG_DELETE) {
|
||||||
|
log(LOG_DEBUG,'! IGNORING: Deleted message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore locally posted messages
|
||||||
|
if (! hdr.from_net_type) {
|
||||||
|
log(LOG_DEBUG,'! IGNORING: Local message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(LOG_DEBUG,'+ PROCESSING: Message offset ['+i+'] in ['+msgbase.file+'] from ['+hdr.from_net_addr+'] ('+hdr.subject+')');
|
||||||
|
|
||||||
|
var body = msgbase.get_msg_body(
|
||||||
|
/* by_offset: */true,
|
||||||
|
i,
|
||||||
|
/* strip Ctrl-A */true,
|
||||||
|
/* rfc822-encoded: */false,
|
||||||
|
/* include tails: */false);
|
||||||
|
|
||||||
|
t = new File(system.temp_dir+'videotex.gpg');
|
||||||
|
if (! t.open('w+')) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Unable to open temp file ['+system.temp_dir+'videotex.gpg'+']');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
t.write(base64_decode(body));
|
||||||
|
t.close();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
log(LOG_ERROR,error);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the signature is good
|
||||||
|
result = system.exec('gpgv --keyring /opt/sbbs/mods/keys/pubring.kbx '+system.temp_dir+'videotex.gpg');
|
||||||
|
|
||||||
|
if (result !== 0 ) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Invalid Signature for message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists(system.temp_dir+'videotex.tex'))
|
||||||
|
file_remove(system.temp_dir+'videotex.tex')
|
||||||
|
|
||||||
|
// Check that the signature is allowed to author the frames
|
||||||
|
result = system.exec('gpg --homedir /opt/sbbs/mods/keys --batch --status-fd 3 -o '+system.temp_dir+'videotex.tex '+system.temp_dir+'videotex.gpg 3>'+system.temp_dir+'videotex.log');
|
||||||
|
|
||||||
|
if (result !== 0 ) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Failed to extract message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put frame in place.
|
||||||
|
f = new File(system.temp_dir+'videotex.tex');
|
||||||
|
if (! f.exists || ! f.open('r')) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Failed to open frame for message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
frame = JSON.parse(f.read());
|
||||||
|
x = new Frame(0);
|
||||||
|
frame.render = x.render;
|
||||||
|
|
||||||
|
// @todo Figure out how to delete this duplicate code
|
||||||
|
Object.defineProperty(frame,'page', {
|
||||||
|
get: function() {return this.frame+this.index}
|
||||||
|
});
|
||||||
|
|
||||||
|
x = null;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
log(LOG_ERROR,error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the key that signed the message
|
||||||
|
f = new File(system.temp_dir+'videotex.log');
|
||||||
|
if (! f.exists || ! f.open('r')) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Failed to open gpg log for message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var signed = '';
|
||||||
|
while (string = f.readln()) {
|
||||||
|
var matches = string.match(/\s+GOODSIG\s+.*\<(.*)\>/);
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
signed = matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
if (signed != getKey(frame.frame,signed)) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Key ['+signed+' is not authorised for message offset ['+i+'] in ['+msgbase.file+']');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the frame.
|
||||||
|
log(LOG_INFO,'Updating page ['+frame.page+'] from ['+hdr.from_net_addr+'] signed with ['+signed+']');
|
||||||
|
saveFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ini.open(file_exists(ini.name) ? 'r+':'w+')) {
|
||||||
|
ini.iniSetValue('videotex','export_ptr',highest);
|
||||||
|
ini.close();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log(LOG_ERROR,'! ERROR: Unable to save to INI for ['+msgbase.file+']');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var msgbase = new MsgBase(findMsgBase(null));
|
||||||
|
log(LOG_DEBUG,'+ ANSITEX_EXPORT: Open message base in ['+msgbase.file+']');
|
||||||
|
|
||||||
|
if (! msgbase.open()) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Unable to open ['+msgbase.file+']');
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgBaseExport(msgbase);
|
||||||
|
msgbase.close();
|
@ -80,17 +80,7 @@ if (! send || ! frame || file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store the frame in file
|
// Store the frame in file
|
||||||
file = system.text_dir+'ansitex/'+frame.page+'.tex';
|
saveFrame(frame);
|
||||||
w = new File(file);
|
|
||||||
if (! w.open('w')) {
|
|
||||||
log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+frame.page);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
w.write(JSON.stringify(frame));
|
|
||||||
w.close();
|
|
||||||
|
|
||||||
printf('Saved file: %s.tex',frame.page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @NOTE: We need to use a binary signature then base64 encode it, as mailers may strip 0x0a while messages are in transit.
|
// @NOTE: We need to use a binary signature then base64 encode it, as mailers may strip 0x0a while messages are in transit.
|
||||||
|
@ -108,6 +108,8 @@ function getFrame(page) {
|
|||||||
get: function() {return this.frame+this.index}
|
get: function() {return this.frame+this.index}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
x = null;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(LOG_ERROR,error);
|
log(LOG_ERROR,error);
|
||||||
return null;
|
return null;
|
||||||
@ -155,6 +157,25 @@ function pageStr(page) {
|
|||||||
return page.frame+page.index;
|
return page.frame+page.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the frame
|
||||||
|
*
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
function saveFrame(frame) {
|
||||||
|
file = system.text_dir+'ansitex/'+frame.page+'.tex';
|
||||||
|
w = new File(file);
|
||||||
|
if (! w.open('w')) {
|
||||||
|
log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+frame.page);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
w.write(JSON.stringify(frame));
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
log(LOG_DEBUG,'Saved file: '+frame.page+'.tex');
|
||||||
|
}
|
||||||
|
|
||||||
function sendBaseline(text,reposition) {
|
function sendBaseline(text,reposition) {
|
||||||
console.pushxy();
|
console.pushxy();
|
||||||
console.gotoxy(0,24);
|
console.gotoxy(0,24);
|
||||||
|
Loading…
Reference in New Issue
Block a user