if (!account && prefs_common.forward_account_autosel) {
gchar cc[BUFFSIZE];
- if (!get_header_from_msginfo(msginfo,cc,sizeof(cc),"CC:")){ /* Found a CC header */
+ if (!procheader_get_header_from_msginfo(msginfo,cc,sizeof(cc),"CC:")){ /* Found a CC header */
extract_address(cc);
account = account_find_from_address(cc);
}
gint id;
/* Select Account from queue headers */
- if (!get_header_from_msginfo(msginfo, queueheader_buf,
+ if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf,
sizeof(queueheader_buf), "X-Sylpheed-Account-Id:")) {
id = atoi(&queueheader_buf[22]);
account = account_find_from_id(id);
}
- if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
+ if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
sizeof(queueheader_buf), "NAID:")) {
id = atoi(&queueheader_buf[5]);
account = account_find_from_id(id);
}
- if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
+ if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
sizeof(queueheader_buf), "MAID:")) {
id = atoi(&queueheader_buf[5]);
account = account_find_from_id(id);
}
- if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
+ if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
sizeof(queueheader_buf), "S:")) {
account = account_find_from_address(queueheader_buf);
}
if (!account && prefs_common.reedit_account_autosel) {
gchar from[BUFFSIZE];
- if (!get_header_from_msginfo(msginfo, from, sizeof(from), "FROM:")){
+ if (!procheader_get_header_from_msginfo(msginfo, from, sizeof(from), "FROM:")){
extract_address(from);
account = account_find_from_address(from);
}
gchar queueheader_buf[BUFFSIZE];
/* Set message save folder */
- if (!get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
+ if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
gint startpos = 0;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
g_warning("can't change file mode\n");
}
- while (procheader_get_unfolded_line(buf, sizeof(buf), fp)) {
+ while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
/* should filter returnpath, delivered-to */
if (g_strncasecmp(buf, "Return-Path:",
strlen("Return-Path:")) == 0 ||
#define BUFFSIZE 8192
+typedef char *(*getlinefunc)(char *, int, void *);
+typedef int (*peekcharfunc)(void *);
+typedef gint (*get_one_field_func)(gchar *, gint, void *, HeaderEntry[]);
+
+static gint string_get_one_field(gchar *buf, gint len, char **str,
+ HeaderEntry hentry[]);
+
+static char *string_getline(char *buf, int len, char **str);
+static int string_peekchar(char **str);
+static int fpeekchar(FILE *fp);
+static gint generic_get_one_field(gchar *buf, gint len, void *data,
+ HeaderEntry hentry[],
+ getlinefunc getline, peekcharfunc peekchar);
+static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
+ gboolean full, gboolean decrypted);
+
+
gint procheader_get_one_field(gchar *buf, gint len, FILE *fp,
HeaderEntry hentry[])
+{
+ return generic_get_one_field(buf, len, fp, hentry,
+ (getlinefunc)fgets, (peekcharfunc)fpeekchar);
+}
+
+static gint string_get_one_field(gchar *buf, gint len, char **str,
+ HeaderEntry hentry[])
+{
+ return generic_get_one_field(buf, len, str, hentry,
+ (getlinefunc)string_getline,
+ (peekcharfunc)string_peekchar);
+}
+
+static char *string_getline(char *buf, int len, char **str)
+{
+ if (!**str)
+ return NULL;
+
+ for (; **str && len > 1; --len)
+ if ((*buf++ = *(*str)++) == '\n')
+ break;
+ *buf = '\0';
+
+ return buf;
+}
+
+static int string_peekchar(char **str)
+{
+ return **str;
+}
+
+static int fpeekchar(FILE *fp)
+{
+ return ungetc(getc(fp), fp);
+}
+
+static gint generic_get_one_field(gchar *buf, gint len, void *data,
+ HeaderEntry *hentry,
+ getlinefunc getline, peekcharfunc peekchar)
{
gint nexthead;
gint hnum = 0;
/* skip non-required headers */
do {
do {
- if (fgets(buf, len, fp) == NULL)
+ if (getline(buf, len, data) == NULL)
return -1;
if (buf[0] == '\r' || buf[0] == '\n')
return -1;
}
} while (hp->name == NULL);
} else {
- if (fgets(buf, len, fp) == NULL) return -1;
+ if (getline(buf, len, data) == NULL) return -1;
if (buf[0] == '\r' || buf[0] == '\n') return -1;
}
- /* unfold the specified folded line */
- if (hp && hp->unfold) {
- gboolean folded = FALSE;
- gchar *bufp = buf + strlen(buf);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- while (1) {
- nexthead = fgetc(fp);
-
- /* folded */
- if (nexthead == ' ' || nexthead == '\t')
- folded = TRUE;
- else if (nexthead == EOF)
- break;
- else if (folded == TRUE) {
- if (nexthead == '\r' || nexthead == '\n') {
- folded = FALSE;
- continue;
- }
-
- if ((len - (bufp - buf)) <= 2) break;
-
- /* replace return code on the tail end
- with space */
- *bufp++ = ' ';
- *bufp++ = nexthead;
- *bufp = '\0';
- /* concatenate next line */
- if (fgets(bufp, len - (bufp - buf), fp)
- == NULL) break;
- bufp += strlen(bufp);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- folded = FALSE;
- } else {
- ungetc(nexthead, fp);
- break;
- }
- }
-
- return hnum;
- }
-
+ /* unfold line */
while (1) {
- nexthead = fgetc(fp);
+ nexthead = peekchar(data);
if (nexthead == ' ' || nexthead == '\t') {
size_t buflen = strlen(buf);
/* concatenate next line */
if ((len - buflen) > 2) {
- gchar *p = buf + buflen;
-
- *p++ = nexthead;
- *p = '\0';
- buflen++;
- if (fgets(p, len - buflen, fp) == NULL)
+ if (getline(buf + buflen, len - buflen, data) == NULL)
break;
+
+ if (hp && hp->unfold)
+ strretchomp(buf);
} else
break;
- } else {
- if (nexthead != EOF)
- ungetc(nexthead, fp);
+ } else
break;
- }
}
- /* remove trailing return code */
+ /* remove trailing new line */
strretchomp(buf);
return hnum;
}
+#if 0
gchar *procheader_get_unfolded_line(gchar *buf, gint len, FILE *fp)
{
gboolean folded = FALSE;
return buf;
}
+#endif
+#if 0
GSList *procheader_get_header_list_from_file(const gchar *file)
{
FILE *fp;
return hlist;
}
+#endif
+#if 0
GPtrArray *procheader_get_header_array(FILE *fp)
{
gchar buf[BUFFSIZE];
return headers;
}
+#endif
GPtrArray *procheader_get_header_array_asis(FILE *fp)
{
return headers;
}
+#if 0
void procheader_header_list_destroy(GSList *hlist)
{
Header *header;
hlist = g_slist_remove(hlist, header);
}
}
+#endif
void procheader_header_array_destroy(GPtrArray *harray)
{
MsgInfo *procheader_parse_str(const gchar *str, MsgFlags flags, gboolean full,
gboolean decrypted)
{
- FILE *fp;
- MsgInfo *msginfo;
-
- if ((fp = str_open_as_stream(str)) == NULL)
- return NULL;
-
- msginfo = procheader_parse_stream(fp, flags, full, decrypted);
- fclose(fp);
- return msginfo;
+ return parse_stream(&str, TRUE, flags, full, decrypted);
}
enum
return full ? hentry_full : hentry_short;
}
-MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full,
+MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full,
gboolean decrypted)
+{
+ return parse_stream(fp, FALSE, flags, full, decrypted);
+}
+
+static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
+ gboolean full, gboolean decrypted)
{
MsgInfo *msginfo;
gchar buf[BUFFSIZE], tmp[BUFFSIZE];
gchar *hp;
HeaderEntry *hentry;
gint hnum;
+ get_one_field_func get_one_field =
+ isstring ? (get_one_field_func)string_get_one_field
+ : (get_one_field_func)procheader_get_one_field;
hentry = procheader_get_headernames(full);
if (MSG_IS_QUEUED(flags) || MSG_IS_DRAFT(flags)) {
- while (fgets(buf, sizeof(buf), fp) != NULL)
- if (buf[0] == '\r' || buf[0] == '\n') break;
+ while (get_one_field(buf, sizeof(buf), data, NULL) != -1)
+ ; /* loop */
}
msginfo = procmsg_msginfo_new();
msginfo->inreplyto = NULL;
- while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
+ while ((hnum = get_one_field(buf, sizeof(buf), data, hentry))
!= -1) {
hp = buf + strlen(hentry[hnum].name);
while (*hp == ' ' || *hp == '\t') hp++;
strftime(dest, len, default_format, lt);
}
-gint get_header_from_msginfo(MsgInfo *msginfo, gchar *buf, gint len, gchar *header)
+/* Added by Mel Hadasht on 27 Aug 2001 */
+/* Get a header from msginfo */
+gint procheader_get_header_from_msginfo(MsgInfo *msginfo, gchar *buf, gint len, gchar *header)
{
gchar *file;
FILE *fp;