/*
* Functions which deal with the fetching and displaying of messages.
+ *
+ * Copyright (c) 1996-2011 by the citadel.org team
+ *
+ * This program is open source software. You can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "webcit.h"
#include "webserver.h"
#include "groupdav.h"
+#include "calendar.h"
HashList *MsgHeaderHandler = NULL;
HashList *MsgEvaluators = NULL;
StrBuf *FoundCharset,
StrBuf **Error)
{
- wcsession *WCC = WC;
StrBuf *Buf;
StrBuf *HdrToken;
headereval *Hdr;
*Error = NewStrBuf();
StrBufAppendPrintf(*Error, "<strong>");
StrBufAppendPrintf(*Error, _("ERROR:"));
- StrBufAppendPrintf(*Error, "</strong> %s<br />\n", &buf[4]);
+ StrBufAppendPrintf(*Error, "</strong> %s<br>\n", &buf[4]);
FreeStrBuf(&Buf);
return 0;
}
Msg->MsgBody->ContentType = NewStrBufPlain(HKEY("text/html"));
StrBufAppendPrintf(Msg->MsgBody->Data, "<div><i>");
StrBufAppendPrintf(Msg->MsgBody->Data, _("Empty message"));
- StrBufAppendPrintf(Msg->MsgBody->Data, "</i><br /><br />\n");
+ StrBufAppendPrintf(Msg->MsgBody->Data, "</i><br><br>\n");
StrBufAppendPrintf(Msg->MsgBody->Data, "</div>\n");
}
break;
StrBufExtract_token(HdrToken, Buf, 0, '=');
StrBufCutLeft(Buf, StrLength(HdrToken) + 1);
-#ifdef TECH_PREVIEW
- if (dbg_analyze_msg) lprintf(1, ":: [%s] = [%s]\n", ChrPtr(HdrToken), ChrPtr(Buf));
-#endif
/* look up one of the examine_* functions to parse the content */
if (GetHash(MsgHeaderHandler, SKEY(HdrToken), &vHdr) &&
(vHdr != NULL)) {
StrBufExtract_token(HdrToken, Buf, 0, ':');
if (StrLength(HdrToken) > 0) {
StrBufCutLeft(Buf, StrLength(HdrToken) + 1);
-#ifdef TECH_PREVIEW
- if (dbg_analyze_msg) lprintf(1, ":: [%s] = [%s]\n", ChrPtr(HdrToken), ChrPtr(Buf));
-#endif
/* the examine*'s know how to do with mime headers too... */
if (GetHash(MsgHeaderHandler, SKEY(HdrToken), &vHdr) &&
(vHdr != NULL)) {
/* now we put the body mimepart we read above into the mimelist */
Put(Msg->AllAttach, SKEY(Msg->MsgBody->PartNum), Msg->MsgBody, DestroyMime);
- /* Generate a reply-to address */
- if (StrLength(Msg->Rfca) > 0) {
- if (Msg->reply_to == NULL)
- Msg->reply_to = NewStrBuf();
- if (StrLength(Msg->from) > 0) {
- StrBufPrintf(Msg->reply_to, "%s <%s>", ChrPtr(Msg->from), ChrPtr(Msg->Rfca));
- }
- else {
- FlushStrBuf(Msg->reply_to);
- StrBufAppendBuf(Msg->reply_to, Msg->Rfca, 0);
- }
- }
- else
- {
- if ((StrLength(Msg->OtherNode)>0) &&
- (strcasecmp(ChrPtr(Msg->OtherNode), ChrPtr(WCC->serv_info->serv_nodename))) &&
- (strcasecmp(ChrPtr(Msg->OtherNode), ChrPtr(WCC->serv_info->serv_humannode)) ))
- {
- if (Msg->reply_to == NULL)
- Msg->reply_to = NewStrBuf();
- StrBufPrintf(Msg->reply_to,
- "%s @ %s",
- ChrPtr(Msg->from),
- ChrPtr(Msg->OtherNode));
- }
- else {
- if (Msg->reply_to == NULL)
- Msg->reply_to = NewStrBuf();
- FlushStrBuf(Msg->reply_to);
- StrBufAppendBuf(Msg->reply_to, Msg->from, 0);
- }
- }
FreeStrBuf(&Buf);
FreeStrBuf(&HdrToken);
return 1;
}
-void
+long
HttpStatus(long CitadelStatus)
{
long httpstatus = 502;
break;
}
-
+ return httpstatus;
}
/*
serv_printf("MOVE %ld|_TRASH_|0", msgnum);
}
StrBuf_ServGetln(CmdBuf);
- FlushStrBuf(WCC->ImportantMsg);
- StrBufAppendBuf(WCC->ImportantMsg, CmdBuf, 4);
- GetServerStatus(CmdBuf, &CitStatus);
+ GetServerStatusMsg(CmdBuf, &CitStatus, 1, 0);
HttpStatus(CitStatus);
break;
case eCOPY:
Destination = (StrBuf*) vLine;
serv_printf("MOVE %ld|%s|%d", msgnum, ChrPtr(Destination), CopyMessage);
StrBuf_ServGetln(CmdBuf);
- FlushStrBuf(WCC->ImportantMsg);
- StrBufAppendBuf(WCC->ImportantMsg, CmdBuf, 4);
+ GetServerStatusMsg(CmdBuf, NULL, 1, 0);
GetServerStatus(CmdBuf, &CitStatus);
HttpStatus(CitStatus);
}
StrBuf *CmdBuf = NULL;
msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
+ if (msgnum <= 0) return;
+
switch (WCC->Hdr->HR.eReqType)
{
case eGET:
serv_printf("MOVE %ld|_TRASH_|0", msgnum);
}
StrBuf_ServGetln(CmdBuf);
- FlushStrBuf(WCC->ImportantMsg);
- StrBufAppendBuf(WCC->ImportantMsg, CmdBuf, 4);
+ GetServerStatusMsg(CmdBuf, NULL, 1, 0);
break;
default:
break;
wDumpContent(0);
}
-/*
- * Mobile browser view of message
- */
-void mobile_message_view(void)
-{
- long msgnum = 0L;
- const StrBuf *Mime;
-
- msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/');
- output_headers(1, 0, 0, 0, 0, 1);
- begin_burst();
- do_template("msgcontrols", NULL);
- read_message(WC->WBuf, HKEY("view_message"), msgnum, NULL, &Mime);
- wDumpContent(0);
-}
-
/*
* Display a message's headers
*/
Msg = (message_summary*)malloc(sizeof(message_summary));
memset(Msg, 0, sizeof(message_summary));
while (len = StrBuf_ServGetln(Buf),
+ (len >= 0) &&
((len != 3) ||
- strcmp(ChrPtr(Buf), "000")== 0)){
+ strcmp(ChrPtr(Buf), "000")))
+ {
buf = ChrPtr(Buf);
ebuf = strchr(ChrPtr(Buf), '=');
nBuf = ebuf - buf;
StrBufCutLeft(Buf, nBuf + 1);
Eval->f(Msg, Buf);
}
- else lprintf(1, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
+ else syslog(1, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
}
return Msg;
}
return (Stat->nummsgs);
}
Buf2 = NewStrBuf();
- while (len = StrBuf_ServGetln(Buf), ((len != 3) || strcmp(ChrPtr(Buf), "000")!= 0))
+ while (len = StrBuf_ServGetln(Buf),
+ ((len >= 0) &&
+ ((len != 3) ||
+ strcmp(ChrPtr(Buf), "000")!= 0)))
{
if (Stat->nummsgs < Stat->maxload) {
skipit = 0;
return;
}
+ if (WCC->CurRoom.view == VIEW_WIKI) {
+ http_redirect("wiki?page=home");
+ return;
+ }
+
memset(&Stat, 0, sizeof(SharedMessageStatus));
Stat.maxload = 10000;
Stat.lowest_found = (-1);
GetHash(ReadLoopHandler, IKEY(WCC->CurRoom.view), &vViewMsg);
}
if (vViewMsg == NULL) {
- return; // TODO: print message
+ return; /* TODO: print message */
}
ViewMsg = (RoomRenderer*) vViewMsg;
text_to_server_qp(txtmail); /* Transmit message in quoted-printable encoding */
free(txtmail);
- serv_printf("--%s", alt_boundary);
+ serv_printf("\n--%s", alt_boundary);
}
serv_puts("Content-type: text/html; charset=utf-8");
char buf[1024];
StrBuf *encoded_subject = NULL;
static long dont_post = (-1L);
- wc_mime_attachment *att;
int is_anonymous = 0;
const StrBuf *display_name = NULL;
wcsession *WCC = WC;
}
}
- if (WCC->upload_length > 0) {
- const char *pch;
- int n;
- const char *newn;
- long newnlen;
- void *v;
-
- /* There's an attachment. Save it to this struct... */
- lprintf(9, "Client is uploading %d bytes\n", WCC->upload_length);
- att = malloc(sizeof(wc_mime_attachment));
- memset(att, 0, sizeof(wc_mime_attachment ));
- att->length = WCC->upload_length;
- att->ContentType = NewStrBufPlain(WCC->upload_content_type, -1);
- att->FileName = NewStrBufDup(WCC->upload_filename);
-
- if (WCC->attachments == NULL) {
- WCC->attachments = NewHash(1, Flathash);
- }
-
- /* And add it to the list. */
- n = 0;
- if ((GetCount(WCC->attachments) > 0) &&
- GetHashAt(WCC->attachments,
- GetCount(WCC->attachments) -1,
- &newnlen, &newn, &v))
- n = *((int*) newn) + 1;
- Put(WCC->attachments, IKEY(n), att, DestroyMime);
-
- /*
- * Mozilla sends a simple filename, which is what we want,
- * but Satan's Browser sends an entire pathname. Reduce
- * the path to just a filename if we need to.
- */
- pch = strrchr(ChrPtr(att->FileName), '/');
- if (pch != NULL) {
- StrBufCutLeft(att->FileName, pch - ChrPtr(att->FileName) + 1);
- }
- pch = strrchr(ChrPtr(att->FileName), '\\');
- if (pch != NULL) {
- StrBufCutLeft(att->FileName, pch - ChrPtr(att->FileName) + 1);
- }
-
- /*
- * Transfer control of this memory from the upload struct
- * to the attachment struct.
- */
- att->Data = WCC->upload;
- WCC->upload = NULL;
- WCC->upload_length = 0;
-
- /* and keep going, because we don't do attachments in two posts anymore */
- }
-
if (!strcasecmp(bstr("submit_action"), "cancel")) {
- sprintf(WCC->ImportantMessage,
- _("Cancelled. Message was not posted."));
+ AppendImportantMessage(_("Cancelled. Message was not posted."), -1);
} else if (lbstr("postseq") == dont_post) {
- sprintf(WCC->ImportantMessage,
+ AppendImportantMessage(
_("Automatically cancelled because you have already "
- "saved this message."));
+ "saved this message."), -1);
} else {
const char CMD[] = "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s|%s";
StrBuf *Recp = NULL;
const StrBuf *my_email_addr = NULL;
StrBuf *CmdBuf = NULL;
StrBuf *references = NULL;
- int save_to_drafts;
- long HeaderLen;
+ int saving_to_drafts = 0;
+ long HeaderLen = 0;
- save_to_drafts = !strcasecmp(bstr("submit_action"), "drafts");
+ saving_to_drafts = !strcasecmp(bstr("submit_action"), "draft");
Buf = NewStrBuf();
- if (save_to_drafts) {
+ if (saving_to_drafts) {
/* temporarily change to the drafts room */
serv_puts("GOTO _DRAFTS_");
StrBuf_ServGetln(Buf);
- if (GetServerStatus(Buf, NULL) != 2) {
+ if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
/* You probably don't even have a dumb Drafts folder */
- StrBufCutLeft(Buf, 4);
- lprintf(9, "%s:%d: server save to drafts error: %s\n", __FILE__, __LINE__, ChrPtr(Buf));
- StrBufAppendBufPlain(WCC->ImportantMsg, _("Saved to Drafts failed: "), -1, 0);
- StrBufAppendBuf(WCC->ImportantMsg, Buf, 0);
+ syslog(9, "%s:%d: server save to drafts error: %s\n", __FILE__, __LINE__, ChrPtr(Buf) + 4);
+ AppendImportantMessage(_("Saved to Drafts failed: "), -1);
display_enter();
FreeStrBuf(&Buf);
return;
CmdBuf = NewStrBufPlain(NULL, sizeof (CMD) + HeaderLen);
StrBufPrintf(CmdBuf,
CMD,
- save_to_drafts?"":ChrPtr(Recp),
+ saving_to_drafts?"":ChrPtr(Recp),
is_anonymous,
ChrPtr(encoded_subject),
ChrPtr(display_name),
- save_to_drafts?"":ChrPtr(Cc),
- save_to_drafts?"":ChrPtr(Bcc),
+ saving_to_drafts?"":ChrPtr(Cc),
+ saving_to_drafts?"":ChrPtr(Bcc),
ChrPtr(Wikipage),
ChrPtr(my_email_addr),
ChrPtr(references));
if ((HeaderLen + StrLength(sbstr("msgtext")) < 10) &&
(GetCount(WCC->attachments) == 0)){
- StrBufAppendBufPlain(WCC->ImportantMsg, _("Refusing to post empty message.\n"), -1, 0);
+ AppendImportantMessage(_("Refusing to post empty message.\n"), -1);
FreeStrBuf(&CmdBuf);
}
else
{
- lprintf(9, "%s\n", ChrPtr(CmdBuf));
+ syslog(9, "%s\n", ChrPtr(CmdBuf));
serv_puts(ChrPtr(CmdBuf));
FreeStrBuf(&CmdBuf);
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) == 4) {
- if (save_to_drafts) {
+ if (saving_to_drafts) {
if ( (havebstr("recp"))
|| (havebstr("cc" ))
|| (havebstr("bcc" )) ) {
}
}
post_mime_to_server();
- if (save_to_drafts) {
- StrBufAppendBufPlain(WCC->ImportantMsg, _("Message has been saved to Drafts.\n"), -1, 0);
+ if (saving_to_drafts) {
+ AppendImportantMessage(_("Message has been saved to Drafts.\n"), -1);
gotoroom(WCC->CurRoom.name);
- display_enter();
+ readloop(readnew, eUseDefault);
FreeStrBuf(&Buf);
return;
} else if ( (havebstr("recp"))
|| (havebstr("cc" ))
|| (havebstr("bcc" ))
) {
- StrBufAppendBufPlain(WCC->ImportantMsg, _("Message has been sent.\n"), -1, 0);
+ AppendImportantMessage(_("Message has been sent.\n"), -1);
}
else {
- StrBufAppendBufPlain(WCC->ImportantMsg, _("Message has been posted.\n"), -1, 0);
+ AppendImportantMessage(_("Message has been posted.\n"), -1);
}
dont_post = lbstr("postseq");
} else {
- StrBufCutLeft(Buf, 4);
-
- lprintf(9, "%s:%d: server post error: %s\n", __FILE__, __LINE__, ChrPtr(Buf));
- StrBufAppendBuf(WCC->ImportantMsg, Buf, 0);
- if (save_to_drafts) gotoroom(WCC->CurRoom.name);
+ syslog(9, "%s:%d: server post error: %s", __FILE__, __LINE__, ChrPtr(Buf) + 4);
+ AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
display_enter();
+ if (saving_to_drafts) gotoroom(WCC->CurRoom.name);
+ FreeStrBuf(&Recp);
FreeStrBuf(&Buf);
FreeStrBuf(&Cc);
FreeStrBuf(&Bcc);
}
+/*
+ * Client is uploading an attachment
+ */
+void upload_attachment(void) {
+ wcsession *WCC = WC;
+ const char *pch;
+ int n;
+ const char *newn;
+ long newnlen;
+ void *v;
+ wc_mime_attachment *att;
+
+ syslog(9, "upload_attachment()\n");
+ wc_printf("upload_attachment()<br>\n");
+
+ if (WCC->upload_length <= 0) {
+ syslog(9, "ERROR no attachment was uploaded\n");
+ wc_printf("ERROR no attachment was uploaded<br>\n");
+ return;
+ }
+
+ syslog(9, "Client is uploading %d bytes\n", WCC->upload_length);
+ wc_printf("Client is uploading %d bytes<br>\n", WCC->upload_length);
+ att = malloc(sizeof(wc_mime_attachment));
+ memset(att, 0, sizeof(wc_mime_attachment ));
+ att->length = WCC->upload_length;
+ att->ContentType = NewStrBufPlain(WCC->upload_content_type, -1);
+ att->FileName = NewStrBufDup(WCC->upload_filename);
+
+ if (WCC->attachments == NULL) {
+ WCC->attachments = NewHash(1, Flathash);
+ }
+
+ /* And add it to the list. */
+ n = 0;
+ if ((GetCount(WCC->attachments) > 0) &&
+ GetHashAt(WCC->attachments,
+ GetCount(WCC->attachments) -1,
+ &newnlen, &newn, &v))
+ n = *((int*) newn) + 1;
+ Put(WCC->attachments, IKEY(n), att, DestroyMime);
+
+ /*
+ * Mozilla sends a simple filename, which is what we want,
+ * but Satan's Browser sends an entire pathname. Reduce
+ * the path to just a filename if we need to.
+ */
+ pch = strrchr(ChrPtr(att->FileName), '/');
+ if (pch != NULL) {
+ StrBufCutLeft(att->FileName, pch - ChrPtr(att->FileName) + 1);
+ }
+ pch = strrchr(ChrPtr(att->FileName), '\\');
+ if (pch != NULL) {
+ StrBufCutLeft(att->FileName, pch - ChrPtr(att->FileName) + 1);
+ }
+
+ /*
+ * Transfer control of this memory from the upload struct
+ * to the attachment struct.
+ */
+ att->Data = WCC->upload;
+ WCC->upload = NULL;
+ WCC->upload_length = 0;
+}
+
+
+/*
+ * Remove an attachment from the message currently being composed.
+ *
+ * Currently we identify the attachment to be removed by its filename.
+ * There is probably a better way to do this.
+ */
+void remove_attachment(void) {
+ wcsession *WCC = WC;
+ wc_mime_attachment *att;
+ void *vAtt;
+ StrBuf *WhichAttachment;
+ HashPos *at;
+ long len;
+ const char *key;
+
+ WhichAttachment = NewStrBufDup(sbstr("which_attachment"));
+ StrBufUnescape(WhichAttachment, 0);
+ at = GetNewHashPos(WCC->attachments, 0);
+ do {
+ GetHashPos(WCC->attachments, at, &len, &key, &vAtt);
+
+ att = (wc_mime_attachment*) vAtt;
+ if ((att != NULL) &&
+ (strcmp(ChrPtr(WhichAttachment),
+ ChrPtr(att->FileName) ) == 0))
+ {
+ DeleteEntryFromHash(WCC->attachments, at);
+ break;
+ }
+ }
+ while (NextHashPos(WCC->attachments, at));
+ FreeStrBuf(&WhichAttachment);
+ wc_printf("remove_attachment() completed\n");
+}
+long FourHash(const char *key, long length)
+{
+ int i;
+ long ret = 0;
+ const unsigned char *ptr = (const unsigned char*)key;
+
+ for (i = 0; i < 4; i++, ptr ++)
+ ret = (ret << 8) |
+ ( ((*ptr >= 'a') &&
+ (*ptr <= 'z'))?
+ *ptr - 'a' + 'A':
+ *ptr);
+
+ return ret;
+}
+
+long l_subj;
+long l_wefw;
+long l_msgn;
+long l_from;
+long l_rcpt;
+long l_cccc;
+long l_node;
+long l_rfca;
+
/*
* display the message entry screen
*/
void display_enter(void)
{
- char buf[SIZ];
- long now;
+ StrBuf *Line;
+ long Result;
+ int rc;
const StrBuf *display_name = NULL;
int recipient_required = 0;
int subject_required = 0;
- int recipient_bad = 0;
int is_anonymous = 0;
wcsession *WCC = WC;
-
- now = time(NULL);
+ int i = 0;
+ long replying_to;
if (havebstr("force_room")) {
gotoroom(sbstr("force_room"));
is_anonymous = 1;
}
- /* First test to see whether this is a room that requires recipients to be entered */
+ /*
+ * First, do we have permission to enter messages in this room at all?
+ */
+ Line = NewStrBuf();
serv_puts("ENT0 0");
- serv_getln(buf, sizeof buf);
+ StrBuf_ServGetln(Line);
+ rc = GetServerStatusMsg(Line, &Result, 0, 2);
- if (!strncmp(buf, "570", 3)) { /* 570 means that we need a recipient here */
+ if (Result == 570) { /* 570 means that we need a recipient here */
recipient_required = 1;
}
- else if (buf[0] != '2') { /* Any other error means that we cannot continue */
- sprintf(WCC->ImportantMessage, "%s", &buf[4]);
+ else if (rc != 2) { /* Any other error means that we cannot continue */
+ rc = GetServerStatusMsg(Line, &Result, 0, 2);
readloop(readnew, eUseDefault);
+ FreeStrBuf(&Line);
return;
}
/* Is the server strongly recommending that the user enter a message subject? */
- if ((buf[3] != '\0') && (buf[4] != '\0')) {
- subject_required = extract_int(&buf[4], 1);
+ if (StrLength(Line) > 4) {
+ subject_required = extract_int(ChrPtr(Line) + 4, 1);
}
/*
*/
if (WCC->CurRoom.defview == VIEW_ADDRESSBOOK) {
do_edit_vcard(-1, "", NULL, NULL, "", ChrPtr(WCC->CurRoom.name));
+ FreeStrBuf(&Line);
return;
}
*/
if (WCC->CurRoom.defview == VIEW_CALENDAR) {
display_edit_event();
+ FreeStrBuf(&Line);
return;
}
*/
if (WCC->CurRoom.defview == VIEW_TASKS) {
display_edit_task();
+ FreeStrBuf(&Line);
return;
}
+
+ /*
+ * If the "replying_to" variable is set, it refers to a message
+ * number from which we must extract some header fields...
+ */
+ replying_to = lbstr("replying_to");
+ if (replying_to > 0) {
+ long len;
+ StrBuf *wefw = NULL;
+ StrBuf *msgn = NULL;
+ StrBuf *from = NULL;
+ StrBuf *node = NULL;
+ StrBuf *rfca = NULL;
+ StrBuf *rcpt = NULL;
+ StrBuf *cccc = NULL;
+ serv_printf("MSG0 %ld|1", replying_to);
+
+ StrBuf_ServGetln(Line);
+ if (GetServerStatusMsg(Line, NULL, 0, 0) == 1)
+ while (len = StrBuf_ServGetln(Line),
+ (len >= 0) &&
+ ((len != 3) ||
+ strcmp(ChrPtr(Line), "000")))
+ {
+ long which = 0;
+ if ((StrLength(Line) > 4) &&
+ (ChrPtr(Line)[4] == '='))
+ which = FourHash(ChrPtr(Line), 4);
+
+ if (which == l_subj)
+ {
+ StrBuf *subj = NewStrBuf();
+ StrBuf *FlatSubject;
+
+ if (!strcasecmp(bstr("replying_mode"), "forward")) {
+ if (strncasecmp(ChrPtr(Line) + 5, "Fw:", 3)) {
+ StrBufAppendBufPlain(subj, HKEY("Fw: "), 0);
+ }
+ }
+ else {
+ if (strncasecmp(ChrPtr(Line) + 5, "Re:", 3)) {
+ StrBufAppendBufPlain(subj, HKEY("Re: "), 0);
+ }
+ }
+ StrBufAppendBufPlain(subj,
+ ChrPtr(Line) + 5,
+ StrLength(Line) - 5, 0);
+ FlatSubject = NewStrBufPlain(NULL, StrLength(subj));
+ StrBuf_RFC822_to_Utf8(FlatSubject, subj, NULL, NULL);
+
+ PutBstr(HKEY("subject"), FlatSubject);
+ }
+
+ else if (which == l_wefw)
+ {
+ int rrtok;
+ int rrlen;
+
+ wefw = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+
+ /* Trim down excessively long lists of thread references. We eliminate the
+ * second one in the list so that the thread root remains intact.
+ */
+ rrtok = num_tokens(ChrPtr(wefw), '|');
+ rrlen = StrLength(wefw);
+ if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) {
+ StrBufRemove_token(wefw, 1, '|');
+ }
+ }
+
+ else if (which == l_msgn) {
+ msgn = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ }
+
+ else if (which == l_from) {
+ StrBuf *FlatFrom;
+ from = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ FlatFrom = NewStrBufPlain(NULL, StrLength(from));
+ StrBuf_RFC822_to_Utf8(FlatFrom, from, NULL, NULL);
+ FreeStrBuf(&from);
+ from = FlatFrom;
+ for (i=0; i<StrLength(from); ++i) {
+ if (ChrPtr(from)[i] == ',')
+ StrBufPeek(from, NULL, i, ' ');
+ }
+ }
+
+ else if (which == l_rcpt) {
+ rcpt = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ }
+
+ else if (which == l_cccc) {
+ cccc = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ }
+
+ else if (which == l_node) {
+ node = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ }
+
+ else if (which == l_rfca) {
+ StrBuf *FlatRFCA;
+ rfca = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5);
+ FlatRFCA = NewStrBufPlain(NULL, StrLength(rfca));
+ StrBuf_RFC822_to_Utf8(FlatRFCA, rfca, NULL, NULL);
+ FreeStrBuf(&rfca);
+ rfca = FlatRFCA;
+ }
+ }
+
+
+ if (StrLength(wefw) + StrLength(msgn) > 0) {
+ StrBuf *refs = NewStrBuf();
+ if (StrLength(wefw) > 0) {
+ StrBufAppendBuf(refs, wefw, 0);
+ }
+ if ( (StrLength(wefw) > 0) &&
+ (StrLength(msgn) > 0) )
+ {
+ StrBufAppendBufPlain(refs, HKEY("|"), 0);
+ }
+ if (StrLength(msgn) > 0) {
+ StrBufAppendBuf(refs, msgn, 0);
+ }
+ PutBstr(HKEY("references"), refs);
+ }
+
+ /*
+ * If this is a Reply or a ReplyAll, copy the sender's email into the To: field
+ */
+ if ( (!strcasecmp(bstr("replying_mode"), "reply"))
+ || (!strcasecmp(bstr("replying_mode"), "replyall"))
+ ) {
+ StrBuf *to_rcpt;
+ if (StrLength(rfca) > 0) {
+ to_rcpt = NewStrBuf();
+ StrBufAppendBuf(to_rcpt, from, 0);
+ StrBufAppendBufPlain(to_rcpt, HKEY(" <"), 0);
+ StrBufAppendBuf(to_rcpt, rfca, 0);
+ StrBufAppendBufPlain(to_rcpt, HKEY(">"), 0);
+ }
+ else {
+ to_rcpt = from;
+ from = NULL;
+ if ( (StrLength(node) > 0)
+ && (strcasecmp(ChrPtr(node), ChrPtr(WC->serv_info->serv_nodename)))
+ ) {
+ StrBufAppendBufPlain(to_rcpt, HKEY(" @ "), 0);
+ StrBufAppendBuf(to_rcpt, node, 0);
+ }
+ }
+ PutBstr(HKEY("recp"), to_rcpt);
+ }
+
+ /*
+ * Only if this is a ReplyAll, copy all recipients into the Cc: field
+ */
+ if ( (!strcasecmp(bstr("replying_mode"), "replyall"))
+ ) {
+ StrBuf *cc_rcpt = rcpt;
+ rcpt = NULL;
+ if (StrLength(cccc) > 0) {
+ if (cc_rcpt != NULL) {
+ StrBufAppendPrintf(cc_rcpt, ", ");
+ StrBufAppendBuf(cc_rcpt, cccc, 0);
+ } else {
+ cc_rcpt = cccc;
+ cccc = NULL;
+ }
+ }
+ if (cc_rcpt != NULL)
+ PutBstr(HKEY("cc"), cc_rcpt);
+ }
+ FreeStrBuf(&wefw);
+ FreeStrBuf(&msgn);
+ FreeStrBuf(&from);
+ FreeStrBuf(&node);
+ FreeStrBuf(&rfca);
+ FreeStrBuf(&rcpt);
+ FreeStrBuf(&cccc);
+ }
+ FreeStrBuf(&Line);
/*
* Otherwise proceed normally.
* Do a custom room banner with no navbar...
ChrPtr(Bcc),
ChrPtr(Wikipage));
serv_puts(ChrPtr(CmdBuf));
- serv_getln(buf, sizeof buf);
- FreeStrBuf(&CmdBuf);
+ StrBuf_ServGetln(CmdBuf);
- if (!strncmp(buf, "570", 3)) { /* 570 means we have an invalid recipient listed */
- if (havebstr("recp") &&
- havebstr("cc" ) &&
- havebstr("bcc" )) {
- recipient_bad = 1;
- }
+ rc = GetServerStatusMsg(CmdBuf, &Result, 0, 0);
+
+ if ( (Result == 570) /* invalid or missing recipient(s) */
+ || (Result == 550) /* higher access required to send Internet mail */
+ ) {
+ /* These errors will have been displayed and are excusable */
}
- else if (buf[0] != '2') { /* Any other error means that we cannot continue */
- wc_printf("<em>%s</em><br />\n", &buf[4]); /* TODO -> important message */
+ else if (rc != 2) { /* Any other error means that we cannot continue */
+ AppendImportantMessage(ChrPtr(CmdBuf) + 4, StrLength(CmdBuf) - 4);
+ FreeStrBuf(&CmdBuf);
+ readloop(readnew, eUseDefault);
return;
}
+ FreeStrBuf(&CmdBuf);
}
if (recipient_required)
PutBstr(HKEY("__RCPTREQUIRED"), NewStrBufPlain(HKEY("1")));
void delete_msg(void)
{
long msgid;
- char buf[SIZ];
-
+ StrBuf *Line;
+
msgid = lbstr("msgid");
-
+ Line = NewStrBuf();
if ((WC->CurRoom.RAFlags & UA_ISTRASH) != 0) { /* Delete from Trash is a real delete */
serv_printf("DELE %ld", msgid);
}
serv_printf("MOVE %ld|_TRASH_|0", msgid);
}
- serv_getln(buf, sizeof buf);
- sprintf(WC->ImportantMessage, "%s", &buf[4]);
+ StrBuf_ServGetln(Line);
+ GetServerStatusMsg(Line, NULL, 1, 0);
+
readloop(readnew, eUseDefault);
}
void move_msg(void)
{
long msgid;
- char buf[SIZ];
msgid = lbstr("msgid");
if (havebstr("move_button")) {
- sprintf(buf, "MOVE %ld|%s", msgid, bstr("target_room"));
- serv_puts(buf);
- serv_getln(buf, sizeof buf);
- sprintf(WC->ImportantMessage, "%s", &buf[4]);
+ StrBuf *Line;
+ serv_printf("MOVE %ld|%s", msgid, bstr("target_room"));
+ Line = NewStrBuf();
+ StrBuf_ServGetln(Line);
+ GetServerStatusMsg(Line, NULL, 1, 0);
+ FreeStrBuf(&Line);
} else {
- sprintf(WC->ImportantMessage, (_("The message was not moved.")));
+ AppendImportantMessage(_("The message was not moved."), -1);
}
readloop(readnew, eUseDefault);
}
-/*
- * Confirm move of a message
- */
-void confirm_move_msg(void)
-{
- long msgid;
- char buf[SIZ];
- char targ[SIZ];
-
- msgid = lbstr("msgid");
-
-
- output_headers(1, 1, 2, 0, 0, 0);
- wc_printf("<div id=\"banner\">\n");
- wc_printf("<h1>");
- wc_printf(_("Confirm move of message"));
- wc_printf("</h1>");
- wc_printf("</div>\n");
-
- wc_printf("<div id=\"content\" class=\"service\">\n");
-
- wc_printf("<CENTER>");
-
- wc_printf(_("Move this message to:"));
- wc_printf("<br />\n");
-
- wc_printf("<form METHOD=\"POST\" action=\"move_msg\">\n");
- wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
- wc_printf("<INPUT TYPE=\"hidden\" NAME=\"msgid\" VALUE=\"%s\">\n", bstr("msgid"));
-
- wc_printf("<SELECT NAME=\"target_room\" SIZE=5>\n");
- serv_puts("LKRA");
- serv_getln(buf, sizeof buf);
- if (buf[0] == '1') {
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- extract_token(targ, buf, 0, '|', sizeof targ);
- wc_printf("<OPTION>");
- escputs(targ);
- wc_printf("\n");
- }
- }
- wc_printf("</SELECT>\n");
- wc_printf("<br />\n");
-
- wc_printf("<INPUT TYPE=\"submit\" NAME=\"move_button\" VALUE=\"%s\">", _("Move"));
- wc_printf(" ");
- wc_printf("<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">", _("Cancel"));
- wc_printf("</form></CENTER>\n");
-
- wc_printf("</CENTER>\n");
- wDumpContent(1);
-}
-
/*
* Generic function to output an arbitrary MIME attachment from
}
+
+void show_num_attachments(void) {
+ wc_printf("%d", GetCount(WC->attachments));
+}
+
+
void h_readnew(void) { readloop(readnew, eUseDefault);}
void h_readold(void) { readloop(readold, eUseDefault);}
void h_readfwd(void) { readloop(readfwd, eUseDefault);}
WebcitAddUrlHandler(HKEY("post"), "", 0, post_message, PROHIBIT_STARTPAGE);
WebcitAddUrlHandler(HKEY("move_msg"), "", 0, move_msg, PROHIBIT_STARTPAGE);
WebcitAddUrlHandler(HKEY("delete_msg"), "", 0, delete_msg, PROHIBIT_STARTPAGE);
- WebcitAddUrlHandler(HKEY("confirm_move_msg"), "", 0, confirm_move_msg, PROHIBIT_STARTPAGE);
WebcitAddUrlHandler(HKEY("msg"), "", 0, embed_message, NEED_URL);
WebcitAddUrlHandler(HKEY("message"), "", 0, handle_one_message, NEED_URL|XHTTP_COMMANDS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
WebcitAddUrlHandler(HKEY("printmsg"), "", 0, print_message, NEED_URL);
- WebcitAddUrlHandler(HKEY("mobilemsg"), "", 0, mobile_message_view, NEED_URL);
WebcitAddUrlHandler(HKEY("msgheaders"), "", 0, display_headers, NEED_URL);
WebcitAddUrlHandler(HKEY("mimepart"), "", 0, view_mimepart, NEED_URL);
WebcitAddUrlHandler(HKEY("mimepart_download"), "", 0, download_mimepart, NEED_URL);
WebcitAddUrlHandler(HKEY("postpart"), "", 0, view_postpart, NEED_URL|PROHIBIT_STARTPAGE);
WebcitAddUrlHandler(HKEY("postpart_download"), "", 0, download_postpart, NEED_URL|PROHIBIT_STARTPAGE);
+ WebcitAddUrlHandler(HKEY("upload_attachment"), "", 0, upload_attachment, AJAX);
+ WebcitAddUrlHandler(HKEY("remove_attachment"), "", 0, remove_attachment, AJAX);
+ WebcitAddUrlHandler(HKEY("show_num_attachments"), "", 0, show_num_attachments, AJAX);
/* json */
WebcitAddUrlHandler(HKEY("roommsgs"), "", 0, jsonMessageList,0);
+
+ l_subj = FourHash("subj", 4);
+ l_wefw = FourHash("wefw", 4);
+ l_msgn = FourHash("msgn", 4);
+ l_from = FourHash("from", 4);
+ l_rcpt = FourHash("rcpt", 4);
+ l_cccc = FourHash("cccc", 4);
+ l_node = FourHash("node", 4);
+ l_rfca = FourHash("rfca", 4);
+
return ;
}