2019-01-05 12:02:50 +01:00
|
|
|
var net = require( 'net' );
|
|
|
|
var fs = require( 'fs' );
|
|
|
|
var path = require( 'path' );
|
|
|
|
var os = require( 'os' );
|
|
|
|
|
|
|
|
var config = require( './configuration.json' );
|
|
|
|
|
|
|
|
var TAB = "\t";
|
|
|
|
var EOF = ".\r\n";
|
|
|
|
var NL = "\r\n";
|
|
|
|
|
|
|
|
if ( config.jsonPath[0] === "~" ) {
|
|
|
|
config.jsonPath = path.join( os.homedir(), config.jsonPath.slice( 1 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
var hugoJson = null;
|
|
|
|
|
|
|
|
loadJson();
|
|
|
|
|
2019-01-05 20:36:49 +01:00
|
|
|
fs.watch( config.jsonPath, function( ev, filename ) {
|
|
|
|
if ( filename ) {
|
|
|
|
console.log( 'JSON File has been updated and will be reloaded' );
|
|
|
|
loadJson();
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
2019-01-05 12:02:50 +01:00
|
|
|
function loadJson() {
|
|
|
|
fs.readFile( config.jsonPath, 'utf8', function( err, data ) {
|
|
|
|
if ( err ) {
|
|
|
|
console.log( err );
|
|
|
|
} else {
|
|
|
|
hugoJson = JSON.parse( data );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
function processQuery( query, sock ) {
|
|
|
|
if ( query.length == 0 ) {
|
|
|
|
writeInfo( sock, '------------------------------------------------------------------------' );
|
|
|
|
writeInfo( sock, config.siteName );
|
|
|
|
|
|
|
|
config.siteDescription.split( NL ).forEach( function( line ) {
|
|
|
|
writeInfo( sock, line );
|
|
|
|
} );
|
|
|
|
|
|
|
|
writeInfo( sock, '------------------------------------------------------------------------' );
|
|
|
|
writeInfo( sock, '' );
|
|
|
|
|
|
|
|
hugoJson.forEach( function( blog ) {
|
|
|
|
writeFile( sock, '0', blog[ config.titleAttr ].charAt( 0 ).toUpperCase() + blog[ config.titleAttr ].slice( 1 ), blog[ config.urlAttr ] );
|
|
|
|
} );
|
|
|
|
|
|
|
|
sock.end();
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sock.write( query + NL );
|
|
|
|
|
|
|
|
var hasBlog = false;
|
|
|
|
|
|
|
|
hugoJson.forEach( function( blog ) {
|
|
|
|
if ( blog[ config.urlAttr ].trim().toLowerCase() == query.trim().toLowerCase() ) {
|
|
|
|
blog[ config.bodyAttr ].split( ".\n" ).forEach( function( line ) {
|
|
|
|
sock.write( line + "." + NL + NL );
|
|
|
|
} );
|
|
|
|
|
|
|
|
sock.end();
|
|
|
|
hasBlog = true;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
if ( hasBlog === false ) {
|
|
|
|
sock.write( "No such file" );
|
|
|
|
sock.end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function writeFile( sock, type, title, path ) {
|
|
|
|
sock.write( type + title + TAB + path + TAB + config.gopherDomain + TAB + config.gopherPort + NL );
|
|
|
|
}
|
|
|
|
|
|
|
|
function writeInfo( sock, text ) {
|
|
|
|
sock.write( 'i' + text + TAB + TAB + TAB + NL );
|
|
|
|
}
|
|
|
|
|
|
|
|
function writeError( sock, text ) {
|
|
|
|
sock.end( '3' + text + EOF );
|
|
|
|
}
|
|
|
|
|
|
|
|
var server = net.createServer( function( sock ) {
|
|
|
|
var query = "";
|
|
|
|
|
|
|
|
console.log( 'Connection from', sock.remoteAddress, sock.remotePort );
|
|
|
|
|
|
|
|
sock.on( 'data', function( buf ) {
|
|
|
|
var ready = false;
|
|
|
|
|
|
|
|
for ( var i = 0; i < buf.length; i++ ) {
|
|
|
|
var bChar = buf.readUInt8( i );
|
|
|
|
switch (bChar) {
|
|
|
|
case 0x0:
|
|
|
|
ready = false;
|
|
|
|
break;
|
|
|
|
case 0xD:
|
|
|
|
ready = true;
|
|
|
|
break;
|
|
|
|
case 0xA:
|
|
|
|
if ( ready === true) {
|
|
|
|
processQuery( query, sock );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ready = false;
|
|
|
|
query += String.fromCharCode( bChar );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
server.listen( {
|
|
|
|
"host": config.gopherInterface,
|
|
|
|
"port": config.gopherPort,
|
|
|
|
"exclusive": true
|
|
|
|
}, function() {
|
|
|
|
console.log( 'hugo-gopher ready' );
|
|
|
|
console.log( config.gopherDomain + ' at gopher://' + config.gopherInterface + ":" + config.gopherPort );
|
|
|
|
console.log( 'JSON: ' + config.jsonPath );
|
|
|
|
});
|