Fix more TZ bugs; warn if TZ name looks suspicious.

This commit is contained in:
Dianne Skoll
2025-10-08 23:07:37 -04:00
parent 21f5462657
commit a19b79951e
6 changed files with 99 additions and 41 deletions

View File

@@ -20,9 +20,6 @@
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "types.h"
#include "globals.h"
#include "err.h"
@@ -38,24 +35,6 @@ static int ComputeTrigDuration(TimeTrig const *t);
static int CalledEnterTimezone = 0;
static int HaveZoneinfoDir = -1;
#define ZONE_DIR "/usr/share/zoneinfo"
static int have_zoneinfo_dir(void)
{
struct stat sb;
if (HaveZoneinfoDir < 0) {
if (stat(ZONE_DIR, &sb) < 0) {
HaveZoneinfoDir = 0;
} else if ((sb.st_mode & S_IFMT) != S_IFDIR) {
HaveZoneinfoDir = 0;
} else {
HaveZoneinfoDir = 1;
}
}
return HaveZoneinfoDir;
}
int AdjustTriggerForTimeZone(Trigger *trig, int dse, TimeTrig *tim)
{
int y, m, d, hour, minute;
@@ -164,6 +143,7 @@ void EnterTimezone(char const *tz)
CurYear = tm.tm_year + 1900;
DSEToday = DSE(CurYear, CurMon, CurDay);
/* Adjust DSEToday back by a day if midnight in our time zone requires it */
if (SysTime < LocalSysTime) {
DSEToday--;
@@ -1287,24 +1267,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
}
/* Check that TZ looks plausible */
if (trig->tz && (*trig->tz != '!') && have_zoneinfo_dir()) {
if (* (trig->tz) != '!') {
DynamicBuffer zfile;
struct stat sb;
int r;
DBufInit(&zfile);
DBufPuts(&zfile, ZONE_DIR);
DBufPuts(&zfile, "/");
DBufPuts(&zfile, trig->tz);
r = stat(DBufValue(&zfile), &sb);
DBufFree(&zfile);
if (r < 0) {
if (warning_level("06.01.05")) {
Wprint(tr("No time zone file found for TZ `%s'... is it valid?"),
trig->tz);
}
}
}
if (trig->tz && (*trig->tz != '!')) {
warn_if_timezone_bad(trig->tz);
}
/* Remove leading ! from TZ spec */

View File

@@ -304,3 +304,5 @@ int AdjustTriggerForTimeZone(Trigger *trig, int dse, TimeTrig *tim);
void EnterTimezone(char const *tz);
void ExitTimezone(char const *tz);
int warning_level(char const *which);
void warn_if_timezone_bad(char const *tz);

View File

@@ -621,11 +621,15 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig const *tim
if (trig->tz) {
TimeTrig copy = *tim;
int new_result;
int force_retry = 0;
ExitTimezone(trig->tz);
new_result = AdjustTriggerForTimeZone(trig, result, &copy);
if (trig->scanfrom == NO_SCANFROM && new_result < DSEToday) {
force_retry = 1;
}
EnterTimezone(trig->tz);
if (result + duration_days >= today &&
new_result + duration_days < today) {
if (force_retry ||
(result + duration_days >= today &&new_result + duration_days < today)) {
/* If we are not making progress, then give up: It's expired */
if (nextstart <= save_nextstart) {
trig->expired = 1;

View File

@@ -28,10 +28,31 @@ static char const DontEscapeMe[] =
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "types.h"
#include "globals.h"
#include "protos.h"
static int HaveZoneinfoDir = -1;
#define ZONE_DIR "/usr/share/zoneinfo"
static int have_zoneinfo_dir(void)
{
struct stat sb;
if (HaveZoneinfoDir < 0) {
if (stat(ZONE_DIR, &sb) < 0) {
HaveZoneinfoDir = 0;
} else if ((sb.st_mode & S_IFMT) != S_IFDIR) {
HaveZoneinfoDir = 0;
} else {
HaveZoneinfoDir = 1;
}
}
return HaveZoneinfoDir;
}
/* Call this instead of system() so if called ignores return code,
we don't get a compiler warning. Also redirect stdin to /dev/null */
int system1(char const *cmd)
@@ -378,3 +399,34 @@ warning_level(char const *which)
if (!WarningLevel) return 1;
return strcmp(WarningLevel, which) >= 0;
}
void
warn_if_timezone_bad(char const *tz)
{
DynamicBuffer zfile;
struct stat sb;
int r;
if (!tz) {
return;
}
if (*tz == '!') {
return;
}
if (!have_zoneinfo_dir()) {
return;
}
DBufInit(&zfile);
DBufPuts(&zfile, ZONE_DIR);
DBufPuts(&zfile, "/");
DBufPuts(&zfile, tz);
r = stat(DBufValue(&zfile), &sb);
DBufFree(&zfile);
if (r < 0) {
if (warning_level("06.01.05")) {
Wprint(tr("No time zone file found for TZ `%s'... is it valid?"),
tz);
}
}
}