+ /* if we got no . in the hostname, try to canonicalize it,
+ * else assume it is a FQDN */
+ if (strchr(tmpbuf, '.') == NULL)
+ {
+ /* if we got a basename without dots, as we often do in Linux,
+ * look up canonical name (make a FQDN of it) */
+ struct addrinfo hints, *res;
+ int e;
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+
+ e = fm_getaddrinfo(tmpbuf, NULL, &hints, &res);
+ if (e) {
+ /* exit with error message */
+ fprintf(stderr,
+ GT_("gethostbyname failed for %s\n"), tmpbuf);
+ fprintf(stderr, "%s", gai_strerror(e));
+ fprintf(stderr, GT_("Cannot find my own host in hosts database to qualify it!\n"));
+ if (required)
+ exit(PS_DNS);
+ else {
+ fprintf(stderr, GT_("Trying to continue with unqualified hostname.\nDO NOT report broken Received: headers, HELO/EHLO lines or similar problems!\nDO repair your /etc/hosts, DNS, NIS or LDAP instead.\n"));
+ return xstrdup(tmpbuf);
+ }
+ }
+
+ result = xstrdup(res->ai_canonname ? res->ai_canonname : tmpbuf);
+ fm_freeaddrinfo(res);
+ }
+ else
+ result = xstrdup(tmpbuf);
+
+ return result;
+}
+
+static char *tzoffset(time_t *now)
+/* calculate timezone offset */
+{
+ static char offset_string[6];
+ struct tm gmt, *lt;
+ int off;
+ char sign = '+';
+
+ gmt = *gmtime(now);
+ lt = localtime(now);
+ off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
+ if (lt->tm_year < gmt.tm_year)
+ off -= 24 * 60;
+ else if (lt->tm_year > gmt.tm_year)
+ off += 24 * 60;
+ else if (lt->tm_yday < gmt.tm_yday)
+ off -= 24 * 60;
+ else if (lt->tm_yday > gmt.tm_yday)
+ off += 24 * 60;
+ if (off < 0) {
+ sign = '-';
+ off = -off;
+ }
+ if (off >= 24 * 60) /* should be impossible */
+ off = 23 * 60 + 59; /* if not, insert silly value */
+ snprintf(offset_string, sizeof(offset_string),
+ "%c%02d%02d", sign, off / 60, off % 60);
+ return (offset_string);
+}
+
+char *rfc822timestamp(void)
+/* return a timestamp in RFC822 form */
+{
+ time_t now;
+ static char buf[50];
+
+ time(&now);
+#ifdef HAVE_STRFTIME
+ /*
+ * Conform to RFC822. We generate a 4-digit year here, avoiding
+ * Y2K hassles. Max length of this timestamp in an English locale
+ * should be 29 chars. The only things that should vary by locale
+ * are the day and month abbreviations. The set_locale calls prevent
+ * weird multibyte i18n characters (such as kanji) from showing up
+ * in your Received headers.
+ */
+#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+ setlocale (LC_TIME, "C");
+#endif
+ strftime(buf, sizeof(buf)-1,
+ "%a, %d %b %Y %H:%M:%S XXXXX (%Z)", localtime(&now));
+#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+ setlocale (LC_TIME, "");
+#endif
+ strncpy(strstr(buf, "XXXXX"), tzoffset(&now), 5);
+#else
+ /*
+ * This is really just a portability fallback, as the
+ * date format ctime(3) emits is not RFC822
+ * conformant.
+ */
+ strlcpy(buf, ctime(&now), sizeof(buf));
+ buf[strlen(buf)-1] = '\0'; /* remove trailing \n */
+#endif /* HAVE_STRFTIME */
+
+ return(buf);