+static void parse_user(const char *t, char **name, char **email, unsigned long *date, int *tz)
+{
+ struct ident_split ident;
+ unsigned email_len;
+
+ if (!split_ident_line(&ident, t, strchrnul(t, '\n') - t)) {
+ *name = substr(ident.name_begin, ident.name_end);
+
+ email_len = ident.mail_end - ident.mail_begin;
+ *email = xmalloc(strlen("<") + email_len + strlen(">") + 1);
+ xsnprintf(*email, email_len + 3, "<%.*s>", email_len, ident.mail_begin);
+
+ if (ident.date_begin)
+ *date = strtoul(ident.date_begin, NULL, 10);
+ if (ident.tz_begin)
+ *tz = atoi(ident.tz_begin);
+ }
+}
+
+#ifdef NO_ICONV
+#define reencode(a, b, c)
+#else
+static const char *reencode(char **txt, const char *src_enc, const char *dst_enc)
+{
+ char *tmp;
+
+ if (!txt)
+ return NULL;
+
+ if (!*txt || !src_enc || !dst_enc)
+ return *txt;
+
+ /* no encoding needed if src_enc equals dst_enc */
+ if (!strcasecmp(src_enc, dst_enc))
+ return *txt;
+
+ tmp = reencode_string(*txt, dst_enc, src_enc);
+ if (tmp) {
+ free(*txt);
+ *txt = tmp;
+ }
+ return *txt;
+}
+#endif
+
+static const char *next_header_line(const char *p)
+{
+ p = strchr(p, '\n');
+ if (!p)
+ return NULL;
+ return p + 1;
+}
+
+static int end_of_header(const char *p)
+{
+ return !p || (*p == '\n');
+}
+