From: Tomas Korbar Subject: [PATCH] Fix UTC offset calculation using tm_gmtoff The UTC offset was derived via mktime(gmtime()) with a manual +1 hour DST adjustment. That breaks with modern tzdata (e.g. America/Vancouver in tzdata >= 2026b, Europe/Dublin negative DST). Use tm_gmtoff from localtime() instead, matching s-nail commit 60ed19eed5. The sendout.c change is identical to a patch proposed by Mason Loring Bliss (RHEL-232782). head.c and imap.c are updated with the same tm_gmtoff approach. Reported-by: Mason Loring Bliss Resolves: RHEL-232782 --- sendout.c | 6 ++---- head.c | 7 +------ imap.c | 17 +++++------------ 3 files changed, 8 insertions(+), 22 deletions(-) --- a/sendout.c +++ b/sendout.c @@ -1149,13 +1149,11 @@ int tzdiff, tzdiff_hour, tzdiff_min; time(&t); - tzdiff = t - mktime(gmtime(&t)); + tmptr = localtime(&t); + tzdiff = tmptr->tm_gmtoff; tzdiff_hour = (int)(tzdiff / 60); tzdiff_min = tzdiff_hour % 60; tzdiff_hour /= 60; - tmptr = localtime(&t); - if (tmptr->tm_isdst > 0) - tzdiff_hour++; return fprintf(fo, "%s: %s, %02d %s %04d %02d:%02d:%02d %+05d\n", field, weekday_names[tmptr->tm_wday], --- a/head.c +++ b/head.c @@ -1081,7 +1081,6 @@ char *fp, *xp; time_t t; int i, year, month, day, hour, minute, second; - int tzdiff; struct tm *tmptr; for (fp = from; *fp && *fp != '\n'; fp++); @@ -1116,11 +1115,8 @@ if ((t = combinetime(year, month, day, hour, minute, second)) == (time_t)-1) goto invalid; - tzdiff = t - mktime(gmtime(&t)); tmptr = localtime(&t); - if (tmptr->tm_isdst > 0) - tzdiff += 3600; - t -= tzdiff; + t += tmptr->tm_gmtoff; return t; invalid: time(&t); --- a/imap.c +++ b/imap.c @@ -3508,7 +3508,7 @@ imap_read_date(const char *cp) { time_t t; - int year, month, day, i, tzdiff; + int year, month, day, i; struct tm *tmptr; char *xp, *yp; @@ -3532,11 +3532,8 @@ return -1; if ((t = combinetime(year, month, day, 0, 0, 0)) == (time_t)-1) return -1; - tzdiff = t - mktime(gmtime(&t)); tmptr = localtime(&t); - if (tmptr->tm_isdst > 0) - tzdiff += 3600; - t -= tzdiff; + t += tmptr->tm_gmtoff; return t; } @@ -3547,13 +3544,11 @@ struct tm *tmptr; int tzdiff, tzdiff_hour, tzdiff_min; - tzdiff = t - mktime(gmtime(&t)); + tmptr = localtime(&t); + tzdiff = tmptr->tm_gmtoff; tzdiff_hour = (int)(tzdiff / 60); tzdiff_min = tzdiff_hour % 60; tzdiff_hour /= 60; - tmptr = localtime(&t); - if (tmptr->tm_isdst > 0) - tzdiff_hour++; snprintf(s, sizeof s, "\"%02d-%s-%04d %02d:%02d:%02d %+03d%02d\"", tmptr->tm_mday, month_names[tmptr->tm_mon],