cprintf("\\Seen");
++num_flags_printed;
}
+ if (IMAP->flags[seq] & IMAP_ANSWERED) {
+ if (num_flags_printed > 0) cprintf(" ");
+ cprintf("\\Answered");
+ ++num_flags_printed;
+ }
cprintf(")");
}
* "RFC822.TEXT" body only (without leading blank line)
*/
void imap_fetch_rfc822(int msgnum, char *whichfmt, struct CtdlMessage *msg) {
- FILE *tmp;
char buf[1024];
char *ptr;
long headers_size, text_size, total_size;
long bytes_remaining = 0;
long blocksize;
+ FILE *tmp;
tmp = tmpfile();
if (tmp == NULL) {
- lprintf(1, "Cannot open temp file: %s\n", strerror(errno));
+ lprintf(CTDL_CRIT, "Cannot open temp file: %s\n",
+ strerror(errno));
return;
}
/*
- * Load the message into a temp file for translation and measurement
- */
+ * Load the message into a temp file for translation
+ * and measurement
+ */
CtdlRedirectOutput(tmp, -1);
- CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, HEADERS_ALL, 0, 1);
+ CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822,
+ HEADERS_ALL, 0, 1);
CtdlRedirectOutput(NULL, -1);
if (!is_valid_message(msg)) {
- lprintf(1, "WARNING: output clobbered the message!\n");
+ lprintf(CTDL_ERR, "WARNING: output clobbered the message!\n");
}
/*
ptr = fgets(buf, sizeof buf, tmp);
if (ptr != NULL) {
striplt(buf);
- if (strlen(buf) == 0) headers_size = ftell(tmp);
+ if (strlen(buf) == 0) {
+ headers_size = ftell(tmp);
+ }
}
} while ( (headers_size == 0L) && (ptr != NULL) );
fseek(tmp, 0L, SEEK_END);
void imap_output_envelope_from(struct CtdlMessage *msg) {
char user[1024], node[1024], name[1024];
+ /* For anonymous messages, it's so easy! */
+ if (!is_room_aide() && (msg->cm_anon_type == MES_ANONONLY)) {
+ cprintf("((\"----\" NIL \"x\" \"x.org\")) ");
+ return;
+ }
+ if (!is_room_aide() && (msg->cm_anon_type == MES_ANONOPT)) {
+ cprintf("((\"anonymous\" NIL \"x\" \"x.org\")) ");
+ return;
+ }
+
+ /* For everything else, we do stuff. */
cprintf("(("); /* open double-parens */
imap_strout(msg->cm_fields['A']); /* personal name */
cprintf(" NIL "); /* source route (not used) */
+
if (msg->cm_fields['F'] != NULL) {
process_rfc822_addr(msg->cm_fields['F'], user, node, name);
imap_strout(user); /* mailbox name (user id) */
}
+
+/*
+ * Output an envelope address (or set of addresses) in the official,
+ * Crispin-approved braindead format. (Note that we can't use this for
+ * the "From" address because its data may come from a number of different
+ * fields. But we can use it for "To" and possibly others.
+ */
+void imap_output_envelope_addr(char *addr) {
+ char individual_addr[SIZ];
+ int num_addrs;
+ int i;
+ char user[SIZ];
+ char node[SIZ];
+ char name[SIZ];
+
+ if (addr == NULL) {
+ cprintf("NIL ");
+ return;
+ }
+
+ if (strlen(addr) == 0) {
+ cprintf("NIL ");
+ return;
+ }
+
+ cprintf("(");
+
+ /* How many addresses are listed here? */
+ num_addrs = num_tokens(addr, ',');
+
+ /* Output them one by one. */
+ for (i=0; i<num_addrs; ++i) {
+ extract_token(individual_addr, addr, i, ',');
+ striplt(individual_addr);
+ process_rfc822_addr(individual_addr, user, node, name);
+ cprintf("(");
+ imap_strout(name);
+ cprintf(" NIL ");
+ imap_strout(user);
+ cprintf(" ");
+ imap_strout(node);
+ cprintf(")");
+ if (i < (num_addrs-1)) cprintf(" ");
+ }
+
+ cprintf(") ");
+}
+
+
/*
* Implements the ENVELOPE fetch item
*
- * FIXME ... we only output some of the fields right now. Definitely need
- * to do all of them. Accurately, too.
- *
* Note that the imap_strout() function can cleverly output NULL fields as NIL,
* so we don't have to check for that condition like we do elsewhere.
*/
else {
msgdate = time(NULL);
}
- datestring(datestringbuf, sizeof datestringbuf, msgdate, DATESTRING_IMAP);
+ datestring(datestringbuf, sizeof datestringbuf,
+ msgdate, DATESTRING_IMAP);
/* Now start spewing data fields. The order is important, as it is
* defined by the protocol specification. Nonexistent fields must
/* From */
imap_output_envelope_from(msg);
- /* Sender */
- if (0) {
- /* FIXME ... check for a *real* Sender: field */
+ /* Sender (default to same as 'From' if not present) */
+ fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Sender");
+ if (fieldptr != NULL) {
+ imap_output_envelope_addr(fieldptr);
+ phree(fieldptr);
}
else {
imap_output_envelope_from(msg);
}
/* Reply-to */
- if (0) {
- /* FIXME ... check for a *real* Reply-to: field */
+ fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Reply-to");
+ if (fieldptr != NULL) {
+ imap_output_envelope_addr(fieldptr);
+ phree(fieldptr);
}
else {
imap_output_envelope_from(msg);
}
- cprintf("NIL "); /* to */
+ /* To */
+ imap_output_envelope_addr(msg->cm_fields['R']);
- cprintf("NIL "); /* cc */
+ /* Cc */
+ fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Cc");
+ imap_output_envelope_addr(fieldptr);
+ if (fieldptr != NULL) phree(fieldptr);
- cprintf("NIL "); /* bcc */
+ /* Bcc */
+ fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Bcc");
+ imap_output_envelope_addr(fieldptr);
+ if (fieldptr != NULL) phree(fieldptr);
/* In-reply-to */
fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "In-reply-to");
/* message ID */
imap_strout(msg->cm_fields['I']);
- cprintf(") ");
+ cprintf(")");
}
if (buf[0]=='\n') done_headers = 1;
}
+ strcat(boiled_headers, "\r\n");
+
/* Now write it back */
rewind(fp);
fwrite(boiled_headers, strlen(boiled_headers), 1, fp);
for (i=0; i<strlen(section); ++i) {
if (section[i]==']') section[i] = 0;
}
- lprintf(9, "Section is %s\n", section);
+ lprintf(CTDL_DEBUG, "Section is %s\n", section);
/* extract partial */
strcpy(partial, item);
if (partial[i]=='>') partial[i] = 0;
}
if (is_partial == 0) strcpy(partial, "");
- if (strlen(partial) > 0) lprintf(9, "Partial is %s\n", partial);
+ if (strlen(partial) > 0) lprintf(CTDL_DEBUG, "Partial is %s\n", partial);
tmp = tmpfile();
if (tmp == NULL) {
- lprintf(1, "Cannot open temp file: %s\n", strerror(errno));
+ lprintf(CTDL_CRIT, "Cannot open temp file: %s\n", strerror(errno));
return;
}
}
fseek(tmp, pstart, SEEK_SET);
bytes_remaining = pbytes;
- cprintf("BODY[%s] {%ld}<%ld>\r\n",
- section, bytes_remaining, pstart);
+ cprintf("BODY[%s]<%ld> {%ld}\r\n",
+ section, pstart, bytes_remaining);
}
blocksize = sizeof(buf);
/* Mark this message as "seen" *unless* this is a "peek" operation */
if (is_peek == 0) {
- CtdlSetSeen(msgnum, 1);
+ CtdlSetSeen(msgnum, 1, ctdlsetseen_seen);
}
}
1, msg);
}
else if (!strcasecmp(itemlist[i], "BODYSTRUCTURE")) {
- buffer_output();
imap_fetch_bodystructure(IMAP->msgids[seq-1],
itemlist[i], msg);
- unbuffer_output();
}
else if (!strcasecmp(itemlist[i], "ENVELOPE")) {
- buffer_output();
imap_fetch_envelope(IMAP->msgids[seq-1], msg);
- unbuffer_output();
}
else if (!strcasecmp(itemlist[i], "FLAGS")) {
- buffer_output();
imap_fetch_flags(seq-1);
- unbuffer_output();
}
else if (!strcasecmp(itemlist[i], "INTERNALDATE")) {
imap_fetch_internaldate(msg);