Select Git revision
gopherservice.js
-
Rob Swindell authored
Fix issue #693
Rob Swindell authoredFix issue #693
gopherservice.js 8.56 KiB
// gopherservice.js
// Synchronet Service for the Gopher Protocol (RFC 1436)
// Example configuration (in ctrl/services.ini):
// [Gopher]
// Port=70
// MaxClients=10
// Options=0
// Command=gopherservice.js
load("sbbsdefs.js");
load("nodedefs.js");
"use strict";
const REVISION = "1.18";
const GOPHER_PORT = client.socket.local_port;
var debug = false;
// Parse arguments
for(i=0;i<argc;i++)
if(argv[i].toLowerCase()=="-d")
debug = true;
// Write a string to the client socket
function write(str)
{
if(debug)
log(LOG_DEBUG,"rsp: " + str);
client.socket.send(str);
}
function writeln(str)
{
write(str + "\r\n");
}
// Send the contents of a text file to the client socket
function send_file(fname)
{
f = new File(fname);
if(!f.open("r"))
return;
txt = f.readAll();
f.close();
for(l in txt)
writeln(strip_ctrl(txt[l]));
}
function getQwkBulletins() {
var dir = system.text_dir + 'qwk';
if (!file_isdir(dir)) return [];
var bulletins = directory(backslash(dir) + '*');
return bulletins;
}
var msgbase=null;
if(!login("guest"))
log(LOG_WARNING,"!WARNING: NO GUEST ACCOUNT CONFIGURED");
// Get Request
request = client.socket.recvline(512 /*maxlen*/, 10 /*timeout*/);
if(request==null) {
log(LOG_WARNING,"!TIMEOUT waiting for request");
exit();
}
log(LOG_DEBUG,"client request: '" + request + "'");
var prefix="";
var gopher_plus=false;
if((term=request.indexOf("\t+"))>=0) {
gopher_plus=true;
request=request.substr(0,term);
} else if((term=request.indexOf("\t$"))>=0) {
prefix="+INFO: ";
gopher_plus=true;
request=request.substr(0,term);
}
if(gopher_plus)
writeln("+-1"); // indicates '.' terminated data
if(request[0] == '/')
request = request.slice(1);
if(request=="") { /* "root" */
if (msg_area.grp_list.length) {
writeln(prefix + 'iMessage Groups\t\tfake\t1');
for(g in msg_area.grp_list) {
writeln(
prefix
+ "1" + msg_area.grp_list[g].description
+ "\tgrp:" + msg_area.grp_list[g].name.toLowerCase()
+ "\t" + system.host_name
+ "\t" + GOPHER_PORT
);
}
writeln(prefix + 'i \t\tfake\t1');
}
if (file_area.lib_list.length) {
writeln(prefix + 'iFile Libraries\t\tfake\t1');
for(l in file_area.lib_list) {
writeln(format("1%s\tlib:%s\t%s\t%u"
,file_area.lib_list[l].description
,file_area.lib_list[l].name.toLowerCase()
,system.host_name
,GOPHER_PORT
));
}
writeln(prefix + 'i \t\tfake\t1');
}
var qwkBulletins = getQwkBulletins();
if (qwkBulletins.length) {
writeln(prefix + 'iQWK Bulletins\t\tfake\t1');
qwkBulletins.forEach(function (e) {
var f = file_getname(e);
writeln(prefix + '0' + f + '\tqwkbulletin:' + f + '\t' + system.host_name + '\t' + GOPHER_PORT);
});
writeln(prefix + 'i \t\tfake\t1');
}
writeln(prefix + 'iSystem Information\t\tfake\t1');
writeln(prefix
+ "0Node List\tnodelist"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(prefix
+ "0Logon List\tlogonlist"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(prefix
+ "0Auto-Message\tautomsg"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(prefix
+ "0System Statistics\tstats"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(prefix
+ "0System Time\ttime"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(prefix
+ "0Version Information\tver"
+"\t" + system.host_name
+"\t" + GOPHER_PORT);
writeln(".");
exit();
}
switch(request) {
case "nodelist":
var u = new User(1);
for(n=0;n<system.node_list.length;n++) {
write(format("Node %2d ",n+1));
if(system.node_list[n].status==NODE_INUSE) {
u.number=system.node_list[n].useron;
//write(format("%s (%u %s) ", u.alias, u.age, u.gender));
write(u.alias + " (" + u.age + " " + u.gender +") ");
if(system.node_list[n].action==NODE_XTRN && system.node_list[n].aux)
write("running %s" + u.curxtrn);
else
write(format(NodeAction[system.node_list[n].action],system.node_list[n].aux));
} else
write(format(NodeStatus[system.node_list[n].status],system.node_list[n].aux));
write("\r\n");
}
break;
case "logonlist":
send_file(system.data_dir + "logon.lst");
break;
case "automsg":
send_file(system.data_dir + "msgs/auto.msg");
break;
case "ver":
writeln("Synchronet Gopher Service " + REVISION);
writeln(server.version);
writeln(system.version_notice + system.revision + system.beta_version);
writeln("Compiled " + system.compiled_when + " with " + system.compiled_with);
writeln(system.js_version);
writeln(system.os_version);
break;
case "time":
t=time();
writeln(system.timestr(t) + " " + system.zonestr() + " 0x" + t.toString(16));
break;
case "stats": /* Statistics */
for(i in system.stats)
writeln(format("%-25s = ", i) + system.stats[i]);
total = time()-system.uptime;
days = Math.floor(total/(24*60*60));
if(days)
total%=(24*60*60);
hours = Math.floor(total/(60*60));
min = (Math.floor(total/60))%60;
sec = total%60;
writeln(format("uptime = %u days, %u hours, %u minutes and %u seconds"
,days,hours,min,sec));
break;
}
field = request.split(':');
switch(field[0]) {
case "grp":
for(g in msg_area.grp_list)
if(msg_area.grp_list[g].name.toLowerCase()==field[1]) {
for(s in msg_area.grp_list[g].sub_list)
writeln(prefix
+ "1[" + msg_area.grp_list[g].name + "] "
+ msg_area.grp_list[g].sub_list[s].description
+ "\tsub:"
+ msg_area.grp_list[g].sub_list[s].code.toLowerCase()
+ "\t"
+ system.host_name
+ "\t"
+ GOPHER_PORT
);
break;
}
break;
case "lib":
for(l in file_area.lib_list)
if(file_area.lib_list[l].name.toLowerCase()==field[1]) {
for(d in file_area.lib_list[l].dir_list) {
if(file_area.lib_list[l].dir_list[d].can_download
&& file_area.lib_list[l].dir_list[d].settings&DIR_FREE)
writeln(format(prefix
+ "1[%s] %s\tdir:%s\t%s\t%u"
,file_area.lib_list[l].name
,file_area.lib_list[l].dir_list[d].description
,file_area.lib_list[l].dir_list[d].code.toLowerCase()
,system.host_name
,GOPHER_PORT
));
}
break;
}
break;
case "sub":
if(!msg_area.sub[field[1]]) {
writeln(log(LOG_NOTICE, "Invalid message area: " + field[1]));
break;
}
msgbase = new MsgBase(field[1]);
if(msgbase.open!=undefined && msgbase.open()==false) {
writeln("!ERROR " + msgbase.last_error);
break;
}
if(Number(field[2])) {
hdr=msgbase.get_msg_header(false,Number(field[2]));
if(hdr==null || hdr.attr&MSG_DELETE)
break;
writeln("Subj : " + hdr.subject);
writeln("To : " + hdr.to);
writeln("From : " + hdr.from);
writeln("Date : " + system.timestr(hdr.when_written_time));
writeln("");
body=msgbase.get_msg_body(false,Number(field[2]),true,true)
writeln(body);
msgbase.close();
break;
}
/**
msginfo=format("%-25.25s %-25.25s %-25.25s %s"
,"Subject"
,"From"
,"To"
,"Date"
);
writeln(format("0%s\tnull\tnull\tnull\r\n",msginfo));
**/
var hdr_list = msgbase.get_all_msg_headers();
first = msgbase.first_msg;
for(i=msgbase.last_msg; hdr_list != null && i>=first; i--) {
hdr = hdr_list[i];
if(hdr==null)
continue;
if(hdr.attr&MSG_DELETE)
continue;
date = system.timestr(hdr.when_written_time);
msginfo=format("%-25.25s %-25.25s %-25.25s %s"
,hdr.subject
,hdr.from
,hdr.to
,date
);
writeln("0" + msginfo + "\tsub:"
+ field[1] + ":" + i + "\t"
+ system.host_name + "\t"
+ GOPHER_PORT
);
}
msgbase.close();
break;
case "dir":
var code=field[1];
if((dir = file_area.dir[code]) != undefined) {
var files = directory(dir.path + '*');
for(i in files) {
var fileinfo=format("%-25.25s %10u %s"
,file_getname(files[i])
,file_size(files[i])
,system.timestr(file_date(files[i]))
);
writeln("9" + fileinfo + "\tfile:"
+ code + "/" + file_getname(files[i]) + "\t"
+ system.host_name + "\t"
+ GOPHER_PORT
);
}
}
break;
case "file":
var args=field[1].split('/');
var code=args[0];
if((dir = file_area.dir[code]) != undefined) {
if(dir.can_download && dir.settings&DIR_FREE) {
var fname = dir.path + file_getname(args[1]);
if(file_exists(fname)) {
log(LOG_INFO,format("Downloading file: %s (%u bytes)"
,fname, file_size(fname)));
if(client.socket.sendfile(fname))
log(LOG_INFO,"Sent file: " + fname);
else
log(LOG_NOTICE,"!ERROR sending file: " + fname);
}
}
}
break;
case "qwkbulletin":
if (field.length == 2) {
var fname = backslash(system.text_dir + 'qwk') + field[1];
if (file_exists(fname)) client.socket.sendfile(fname);
}
break;
}
writeln(".");
/* End of gopherservice.js */