Skip to content
Snippets Groups Projects
Commit 5434b904 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add "Auto" Local Time Zone option and make that the default for new install

As Deon pointed out in DOVE-Net / Synchronet Discussion, having a local time
zone configured with a different UTC offset than your system time zone can
produce strange/unexpected results (e.g. displayed age of messages). Since
it's possible that not all sysops will complete the configuration wizard or
actually set their timezone to the correct value (and ignore the startup
warning message), we now make the default Local Time Zone to be
"automatic" - query the OS every time the local time zone is needed/used.

This has the downside of only storing (e.g. in message headers) the UTC
offset of the current time zone (not the time zone abbreviation/name as
encoded by SMB). I considered making an option to dynamically figure out
the actual time zone (not just the UTC offset) and while I think that's
doable, Deon just wanted his UTC offset (e.g. UTC+11:00) and not his
time zone name (e.g. AEDT) stored in message headers, so this setting
would be the behavior he expected/wanted.

I'm using the sentinel time zone value of -1 for this new behavior.

Existing configurations (behavior of existing systems) aren't changed.
parent 7a02ba30
No related branches found
No related tags found
No related merge requests found
...@@ -6,7 +6,7 @@ operator=Sysop ...@@ -6,7 +6,7 @@ operator=Sysop
guru=The Guru guru=The Guru
password=SYSPASS password=SYSPASS
password_timeout=15 password_timeout=15
timezone=0 timezone=-1
settings=0x611f848 settings=0x611f848
date_fmt=0 date_fmt=0
date_sep=/ date_sep=/
......
...@@ -167,12 +167,10 @@ static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) ...@@ -167,12 +167,10 @@ static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
p=cfg->sys_location; p=cfg->sys_location;
break; break;
case SYS_PROP_TIMEZONE: case SYS_PROP_TIMEZONE:
sys_timezone(cfg); *vp = INT_TO_JSVAL(sys_timezone(cfg));
*vp = INT_TO_JSVAL(cfg->sys_timezone);
break; break;
case SYS_PROP_TZ_OFFSET: case SYS_PROP_TZ_OFFSET:
sys_timezone(cfg); *vp = INT_TO_JSVAL(smb_tzutc(sys_timezone(cfg)));
*vp = INT_TO_JSVAL(smb_tzutc(cfg->sys_timezone));
break; break;
case SYS_PROP_NODES: case SYS_PROP_NODES:
*vp = INT_TO_JSVAL(cfg->sys_nodes); *vp = INT_TO_JSVAL(cfg->sys_nodes);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "str_util.h" #include "str_util.h"
#include "nopen.h" #include "nopen.h"
#include "datewrap.h" #include "datewrap.h"
#include "xpdatetime.h"
#include "text.h" /* TOTAL_TEXT */ #include "text.h" /* TOTAL_TEXT */
#include "ini_file.h" #include "ini_file.h"
#if defined(SBBS) && defined(USE_CRYPTLIB) #if defined(SBBS) && defined(USE_CRYPTLIB)
...@@ -534,6 +535,9 @@ ushort sys_timezone(scfg_t* cfg) ...@@ -534,6 +535,9 @@ ushort sys_timezone(scfg_t* cfg)
time_t now; time_t now;
struct tm tm; struct tm tm;
if(cfg->sys_timezone == SYS_TIMEZONE_AUTO)
return xpTimeZone_local();
if(cfg->sys_misc&SM_AUTO_DST && SMB_TZ_HAS_DST(cfg->sys_timezone)) { if(cfg->sys_misc&SM_AUTO_DST && SMB_TZ_HAS_DST(cfg->sys_timezone)) {
now=time(NULL); now=time(NULL);
if(localtime_r(&now,&tm)!=NULL) { if(localtime_r(&now,&tm)!=NULL) {
......
...@@ -185,6 +185,10 @@ static int configure_dst(int page, int total) ...@@ -185,6 +185,10 @@ static int configure_dst(int page, int total)
return i; return i;
} }
#define UTC_OFFSET_HELP \
"The UTC offset alone can be ambiguous as some time zones share the same\n" \
"offset from UTC as other time zones for some or all months of the year.\n"
int edit_sys_timezone(int page, int total) int edit_sys_timezone(int page, int total)
{ {
int mode = WIN_SAV | WIN_MID; int mode = WIN_SAV | WIN_MID;
...@@ -192,6 +196,32 @@ int edit_sys_timezone(int page, int total) ...@@ -192,6 +196,32 @@ int edit_sys_timezone(int page, int total)
int i; int i;
int bar; int bar;
i = cfg.sys_timezone != SYS_TIMEZONE_AUTO;
uifc.helpbuf=
"`Automatically Determine Time Zone:`\n"
"\n"
"Query the operating system for the current local time zone as an offset\n"
"(i.e. minutes east or west) from UTC.\n"
"\n"
UTC_OFFSET_HELP
"\n"
"If enabled, this query will occur automatically each time the local time\n"
"zone is needed, so any affect of daylight saving time will be applied\n"
"automatically as well.\n"
;
if(page)
mode = wiz_help(page, total, uifc.helpbuf);
i = uifc.list(mode, 0, 15, 0, &i, 0
,"Automatically Determine Time Zone (as offset from UTC)"
,uifcYesNoOpts);
if(i==-1)
return -1;
if(i==0) {
cfg.sys_timezone = SYS_TIMEZONE_AUTO;
return 0;
}
if(cfg.sys_timezone == SYS_TIMEZONE_AUTO)
cfg.sys_timezone = 0;
i = OTHER_ZONE(cfg.sys_timezone) || !(cfg.sys_timezone & US_ZONE); i = OTHER_ZONE(cfg.sys_timezone) || !(cfg.sys_timezone & US_ZONE);
uifc.helpbuf= uifc.helpbuf=
"`United States Time Zone:`\n" "`United States Time Zone:`\n"
...@@ -430,6 +460,8 @@ int edit_sys_timezone(int page, int total) ...@@ -430,6 +460,8 @@ int edit_sys_timezone(int page, int total)
"\n" "\n"
"Enter your local time zone offset from Universal Time (UTC/GMT) in\n" "Enter your local time zone offset from Universal Time (UTC/GMT) in\n"
"`HH:MM` format.\n" "`HH:MM` format.\n"
"\n"
UTC_OFFSET_HELP
; ;
if(page) if(page)
mode = wiz_help(page, total, uifc.helpbuf); mode = wiz_help(page, total, uifc.helpbuf);
...@@ -1705,8 +1737,9 @@ void sys_cfg(void) ...@@ -1705,8 +1737,9 @@ void sys_cfg(void)
i=0; i=0;
snprintf(opt[i++],MAX_OPLN,"%-20s%s","BBS Name",cfg.sys_name); snprintf(opt[i++],MAX_OPLN,"%-20s%s","BBS Name",cfg.sys_name);
snprintf(opt[i++],MAX_OPLN,"%-20s%s","Location",cfg.sys_location); snprintf(opt[i++],MAX_OPLN,"%-20s%s","Location",cfg.sys_location);
snprintf(opt[i++],MAX_OPLN,"%-20s%s %s","Local Time Zone" snprintf(opt[i++],MAX_OPLN,"%-20s%s%s %s","Local Time Zone"
,smb_zonestr(cfg.sys_timezone,NULL) ,cfg.sys_timezone == SYS_TIMEZONE_AUTO ? "Auto: " : ""
,smb_zonestr(sys_timezone(&cfg),NULL)
,SMB_TZ_HAS_DST(cfg.sys_timezone) && cfg.sys_misc&SM_AUTO_DST ? "(Auto-DST)" : ""); ,SMB_TZ_HAS_DST(cfg.sys_timezone) && cfg.sys_misc&SM_AUTO_DST ? "(Auto-DST)" : "");
snprintf(opt[i++],MAX_OPLN,"%-20s%s (e.g. %s)","Short Date Format" snprintf(opt[i++],MAX_OPLN,"%-20s%s (e.g. %s)","Short Date Format"
,date_format(&cfg, str, sizeof str) ,date_format(&cfg, str, sizeof str)
......
...@@ -466,6 +466,7 @@ typedef struct ...@@ -466,6 +466,7 @@ typedef struct
char sys_id[LEN_QWKID+1];/* System ID for QWK Packets */ char sys_id[LEN_QWKID+1];/* System ID for QWK Packets */
char sys_inetaddr[128]; /* System's internet address */ char sys_inetaddr[128]; /* System's internet address */
char sys_location[41]; /* System Location */ char sys_location[41]; /* System Location */
#define SYS_TIMEZONE_AUTO -1
int16_t sys_timezone; /* Time Zone of BBS */ int16_t sys_timezone; /* Time Zone of BBS */
enum date_fmt sys_date_fmt; enum date_fmt sys_date_fmt;
char sys_date_sep; char sys_date_sep;
......
// rss.ssjs
// $Id: rss.ssjs,v 1.22 2016/10/20 19:13:38 rswindell Exp $
// Tested successfully with SharpReader v0.9.5.1
load("sbbsdefs.js");
var REVISION = "$Revision: 1.22 $".split(' ')[1];
//log(LOG_INFO,"Synchronet RSS " + REVISION);
var link_root = "http://" + http_request.header.host + http_request.request_string;
var ini_fname = file_cfgname(system.ctrl_dir, "rss.ini");
var ini_file = new File(ini_fname);
if(!ini_file.open("r")) {
log(LOG_ERR,format("!ERROR %d opening ini_file: %s"
,ini_file.error, ini_fname));
exit();
}
var channel_list = ini_file.iniGetAllObjects();
var defaults = ini_file.iniGetObject();
ini_file.close();
/* Set default max from the NetScapes original RSS 0.91 implementation
http://my.netscape.com/publish/formats/rss-spec-0.91.html#item */
if(defaults.maxmessages==undefined)
defaults.maxmessages=15;
if(defaults.maxdesclength==undefined)
defaults.maxdesclength=500;
var channel;
for(c in channel_list)
if(channel_list[c].name == http_request.query["channel"]) {
channel=channel_list[c];
break;
}
if(channel==undefined) {
writeln('<html>');
writeln('<body>');
writeln('<h1>' + system.name + " News (RSS) Channels" + '</h1>');
writeln('<ul>');
for(c in channel_list)
writeln('<li>'
+ channel_list[c].name.link(link_root + "?channel=" + channel_list[c].name));
writeln('</ul>');
writeln('</body>');
writeln('</html>');
exit();
}
var sub = msg_area.sub[channel.sub.toLowerCase()];
if(sub==undefined) {
writeln(log(LOG_ERR,"!unknown sub-board: " + channel.sub));
exit();
}
if(http_request.query["item"]) {
load("../web/lib/template.ssjs");
load("../web/lib/mime_decode.ssjs");
var msgbase=new MsgBase(channel.sub);
if(!msgbase.open())
writeln(log(LOG_ERR,'Error: ' + msgbase.error));
else {
template.hdr = msgbase.get_msg_header(false,Number(http_request.query["item"]));
if(!template.hdr)
writeln(log(LOG_ERR,'Error: ' + msgbase.error));
else
template.body= msgbase.get_msg_body(false, template.hdr.number);
}
msg=mime_decode(template.hdr,template.body);
template.body=msg.body;
if(msg.type=="plain") {
/* ANSI */
if(template.body.indexOf('\x1b[')>=0 || template.body.indexOf('\x01')>=0) {
template.body=html_encode(template.body,true,false,true,true);
}
/* Plain text */
else {
template.body=word_wrap(template.body);
template.body=html_encode(template.body,true,false,false,false);
}
}
if(msg.attachments!=undefined) {
template.attachments=new Object;
for(att in msg.attachments) {
template.attachments[att]=new Object;
template.attachments[att].name=msg.attachments[att];
}
}
write_template("header.inc");
write_template("msgs/msg.inc");
write_template("footer.inc");
if(0) {
writeln('<html>');
writeln('<body>');
var msgbase=new MsgBase(channel.sub);
if(!msgbase.open())
writeln(log(LOG_ERR,'Error: ' + msgbase.error));
else {
var hdr = msgbase.get_msg_header(false,Number(http_request.query["item"]));
if(!hdr)
writeln(log(LOG_ERR,'Error: ' + msgbase.error));
else {
for(h in hdr)
writeln(h + ": " + hdr[h] + '<br>');
}
}
writeln('</body>');
writeln('</html>');
}
exit();
}
/* Setup default values (over-rideable in rss.ini) */
if(channel.title==undefined) channel.title =sub.name;
if(channel.description==undefined) channel.description =sub.description;
if(channel.link==undefined) channel.link =link_root;
if(channel.language==undefined) channel.language ='en-us';
if(channel.image_url==undefined) channel.image_url ='/images/default/sync_pbgj1_white_bg.gif';
if(channel.image_title==undefined) channel.image_title =channel.title;
if(channel.image_link==undefined) channel.image_link =channel.link;
if(channel.maxmessages==undefined) channel.maxmessages =defaults.maxmessages;
if(channel.maxdesclength==undefined) channel.maxdesclength =defaults.maxdesclength;
http_reply.header["Content-Type"]='application/rss+xml';
writeln('<?xml version="1.0" ?>');
writeln('<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">');
writeln('<rss version="0.91">');
writeln('\t<channel>');
writeln('\t\t<title>' + channel.title + '</title>');
writeln('\t\t<description>' + channel.description + '</description>');
writeln('\t\t<link>' + channel.link + '</link>');
writeln('\t\t<language>' + channel.language + '</language>');
writeln('\t\t<image>');
writeln('\t\t\t<url>' + channel.image_url + '</url>');
writeln('\t\t\t<title>' + channel.image_title + '</title>');
writeln('\t\t\t<link>' + channel.image_link + '</link>');
writeln('\t\t</image>');
function encode(str, wspace)
{
return(html_encode(strip_ctrl(str.replace(/\s+/g," "))
,true /* ex-ASCII */
,wspace /* white-space */
,false /* ANSI */
,false /* Ctrl-A */
));
}
var msgbase=new MsgBase(channel.sub);
if(msgbase.open()) {
var last_msg;
var msgs=0;
if(last_msg = msgbase.get_msg_header(false, msgbase.last_msg)) {
writeln('\t\t<lastBuildDate>' + last_msg.date + '</lastBuildDate>');
}
var total_msgs = msgbase.total_msgs;
for(i=0;i<total_msgs;i++) {
var hdr = msgbase.get_msg_header(true,total_msgs-i);
if(!hdr || hdr.attr&MSG_DELETE)
continue;
var body = msgbase.get_msg_body(true,total_msgs-i);
body=body.replace(/\r\n/g,'<br />');
if(!body)
continue;
writeln('\t\t\t<item>');
writeln('\t\t\t\t<pubDate>' + hdr.date + '</pubDate>');
writeln('\t\t\t\t<title>' + encode(hdr.subject) + '</title>');
writeln('\t\t\t\t<author>' + encode(hdr.from) + '</author>');
writeln('\t\t\t\t<guid>' + encode(hdr.id) + '</guid>');
writeln('\t\t\t\t<description>' + encode(body.slice(0,channel.maxdesclength)) + '</description>');
if(this.login==undefined) // v3.12a
writeln('\t\t\t\t<link>' + link_root + (defaults.useentities ? '&amp;' : '&') + 'item=' + hdr.number + '</link>');
else // v3.12b
writeln('\t\t\t\t<link>' + 'http://' + http_request.header.host + '/msgs/msg.ssjs?msg_sub=' +
channel.sub + (defaults.useentities ? '&amp;' : '&') + 'message=' + hdr.number + '</link>');
writeln('\t\t\t</item>');
msgs++;
if(msgs>=channel.maxmessages)
break;
}
msgbase.close();
}
writeln('\t</channel>');
writeln('</rss>');
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment