X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fmessages.c;h=2915ce1480d5b623c2320395ee8e7cad63830c56;hb=7ba7f73f95cad7f4ecd7f986e12095e9bb546126;hp=f96b4ffae52421bb14211a795af77d2cc47c7d9e;hpb=cadd9be730bf9f4a6e4894b1ee2bf2e3256930b0;p=citadel.git diff --git a/webcit/messages.c b/webcit/messages.c index f96b4ffae..2915ce148 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -20,7 +20,7 @@ #include "webcit.h" #include "webserver.h" -#include "groupdav.h" +#include "dav.h" #include "calendar.h" HashList *MsgHeaderHandler = NULL; @@ -362,9 +362,7 @@ void handle_one_message(void) 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: @@ -375,8 +373,7 @@ void handle_one_message(void) 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); } @@ -402,6 +399,8 @@ void embed_message(void) { StrBuf *CmdBuf = NULL; msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/'); + if (msgnum <= 0) return; + switch (WCC->Hdr->HR.eReqType) { case eGET: @@ -422,8 +421,7 @@ void embed_message(void) { 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; @@ -995,12 +993,11 @@ void post_message(void) } 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; @@ -1010,22 +1007,20 @@ void post_message(void) 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); - syslog(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; @@ -1076,12 +1071,12 @@ void post_message(void) 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)); @@ -1090,7 +1085,7 @@ void post_message(void) 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); } @@ -1102,7 +1097,7 @@ void post_message(void) StrBuf_ServGetln(Buf); if (GetServerStatus(Buf, NULL) == 4) { - if (save_to_drafts) { + if (saving_to_drafts) { if ( (havebstr("recp")) || (havebstr("cc" )) || (havebstr("bcc" )) ) { @@ -1115,29 +1110,28 @@ void post_message(void) } } 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); - - syslog(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); @@ -1277,16 +1271,42 @@ void remove_attachment(void) { } +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]; + 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; int i = 0; @@ -1302,22 +1322,27 @@ void display_enter(void) 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); } /* @@ -1326,6 +1351,7 @@ void display_enter(void) */ if (WCC->CurRoom.defview == VIEW_ADDRESSBOOK) { do_edit_vcard(-1, "", NULL, NULL, "", ChrPtr(WCC->CurRoom.name)); + FreeStrBuf(&Line); return; } @@ -1335,6 +1361,7 @@ void display_enter(void) */ if (WCC->CurRoom.defview == VIEW_CALENDAR) { display_edit_event(); + FreeStrBuf(&Line); return; } @@ -1344,6 +1371,7 @@ void display_enter(void) */ if (WCC->CurRoom.defview == VIEW_TASKS) { display_edit_task(); + FreeStrBuf(&Line); return; } @@ -1354,87 +1382,121 @@ void display_enter(void) */ replying_to = lbstr("replying_to"); if (replying_to > 0) { - char wefw[1024] = ""; - char msgn[256] = ""; - char from[256] = ""; - char node[256] = ""; - char rfca[256] = ""; - char rcpt[SIZ] = ""; - char cccc[SIZ] = ""; + 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); - serv_getln(buf, sizeof buf); - if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - - if ( (!strncasecmp(buf, "subj=", 5)) && (strlen(buf) > 5) ) { - StrBuf *subj = NewStrBuf(); - if (!strcasecmp(bstr("replying_mode"), "forward")) { - if (strncasecmp(&buf[5], "Fw:", 3)) { - StrBufAppendBufPlain(subj, HKEY("Fw: "), 0); + + 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(&buf[5], "Re:", 3)) { - StrBufAppendBufPlain(subj, HKEY("Re: "), 0); + else { + if (strncasecmp(ChrPtr(Line) + 5, "Re:", 3)) { + StrBufAppendBufPlain(subj, HKEY("Re: "), 0); + } } - } - StrBufAppendBufPlain(subj, &buf[5], -1, 0); - PutBstr(HKEY("subject"), subj); - } + StrBufAppendBufPlain(subj, + ChrPtr(Line) + 5, + StrLength(Line) - 5, 0); + FlatSubject = NewStrBufPlain(NULL, StrLength(subj)); + StrBuf_RFC822_to_Utf8(FlatSubject, subj, NULL, NULL); - else if (!strncasecmp(buf, "wefw=", 5)) { - int rrtok; - int rrlen; - safestrncpy(wefw, &buf[5], sizeof wefw); - - /* 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(wefw, '|'); - rrlen = strlen(wefw); - if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) { - remove_token(wefw, 1, '|'); + PutBstr(HKEY("subject"), FlatSubject); } - } - else if (!strncasecmp(buf, "msgn=", 5)) { - safestrncpy(msgn, &buf[5], sizeof msgn); - } - - else if (!strncasecmp(buf, "from=", 5)) { - safestrncpy(from, &buf[5], sizeof from); - for (i=0; i= 3) && (rrlen > 900)) || (rrtok > 10) ) { + StrBufRemove_token(wefw, 1, '|'); + } } - } - else if (!strncasecmp(buf, "rcpt=", 5)) { - safestrncpy(rcpt, &buf[5], sizeof rcpt); - } - - else if (!strncasecmp(buf, "cccc=", 5)) { - safestrncpy(cccc, &buf[5], sizeof cccc); - } - - else if (!strncasecmp(buf, "node=", 5)) { - safestrncpy(node, &buf[5], sizeof node); - } + else if (which == l_msgn) { + msgn = NewStrBufPlain(ChrPtr(Line) + 5, StrLength(Line) - 5); + } - else if (!strncasecmp(buf, "rfca=", 5)) { - safestrncpy(rfca, &buf[5], sizeof rfca); + 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 0) { + if (StrLength(wefw) + StrLength(msgn) > 0) { StrBuf *refs = NewStrBuf(); - if (!IsEmptyStr(wefw)) { - StrBufAppendBufPlain(refs, wefw, -1, 0); + if (StrLength(wefw) > 0) { + StrBufAppendBuf(refs, wefw, 0); } - if ( (!IsEmptyStr(wefw)) && (!IsEmptyStr(msgn)) ) { + if ( (StrLength(wefw) > 0) && + (StrLength(msgn) > 0) ) + { StrBufAppendBufPlain(refs, HKEY("|"), 0); } - if (!IsEmptyStr(msgn)) { - StrBufAppendBufPlain(refs, msgn, -1, 0); + if (StrLength(msgn) > 0) { + StrBufAppendBuf(refs, msgn, 0); } PutBstr(HKEY("references"), refs); } @@ -1445,16 +1507,22 @@ void display_enter(void) if ( (!strcasecmp(bstr("replying_mode"), "reply")) || (!strcasecmp(bstr("replying_mode"), "replyall")) ) { - StrBuf *to_rcpt = NewStrBuf(); - if (!IsEmptyStr(rfca)) { - StrBufAppendPrintf(to_rcpt, "%s <%s>", from, rfca); + 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 { - StrBufAppendPrintf(to_rcpt, "%s", from); - if ( (!IsEmptyStr(node)) - && (strcasecmp(node, ChrPtr(WC->serv_info->serv_nodename))) + to_rcpt = from; + from = NULL; + if ( (StrLength(node) > 0) + && (strcasecmp(ChrPtr(node), ChrPtr(WC->serv_info->serv_nodename))) ) { - StrBufAppendPrintf(to_rcpt, " @ %s", node); + StrBufAppendBufPlain(to_rcpt, HKEY(" @ "), 0); + StrBufAppendBuf(to_rcpt, node, 0); } } PutBstr(HKEY("recp"), to_rcpt); @@ -1465,21 +1533,29 @@ void display_enter(void) */ if ( (!strcasecmp(bstr("replying_mode"), "replyall")) ) { - StrBuf *cc_rcpt = NewStrBuf(); - if (!IsEmptyStr(rcpt)) { - StrBufAppendPrintf(cc_rcpt, "%s", rcpt); - } - if ( (!IsEmptyStr(rcpt)) && (!IsEmptyStr(cccc)) ) { - StrBufAppendPrintf(cc_rcpt, ", "); - } - if (!IsEmptyStr(cccc)) { - StrBufAppendPrintf(cc_rcpt, "%s", cccc); + 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; + } } - PutBstr(HKEY("cc"), cc_rcpt); + 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... @@ -1515,20 +1591,22 @@ void display_enter(void) 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; /* TODO: and now????? */ - } + 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("%s
\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"))); @@ -1549,10 +1627,10 @@ void display_enter(void) 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); } @@ -1560,8 +1638,9 @@ void delete_msg(void) 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); } @@ -1572,17 +1651,18 @@ void delete_msg(void) 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); @@ -1641,6 +1721,7 @@ void postpart(StrBuf *partnum, StrBuf *filename, int force_download) void mimepart(int force_download) { long msgnum; + long ErrorDetail; StrBuf *att; wcsession *WCC = WC; StrBuf *Buf; @@ -1654,7 +1735,7 @@ void mimepart(int force_download) serv_printf("OPNA %ld|%s", msgnum, ChrPtr(att)); StrBuf_ServGetln(Buf); - if (GetServerStatus(Buf, NULL) == 2) { + if (GetServerStatus(Buf, &ErrorDetail) == 2) { StrBufCutLeft(Buf, 4); bytes = StrBufExtract_long(Buf, 0, '|'); if (!force_download) { @@ -1678,7 +1759,23 @@ void mimepart(int force_download) http_transmit_thing(CT, 0); } else { StrBufCutLeft(Buf, 4); - hprintf("HTTP/1.1 404 %s\n", ChrPtr(Buf)); + switch (ErrorDetail) { + default: + case ERROR + MESSAGE_NOT_FOUND: + hprintf("HTTP/1.1 404 %s\n", ChrPtr(Buf)); + break; + case ERROR + NOT_LOGGED_IN: + hprintf("HTTP/1.1 401 %s\n", ChrPtr(Buf)); + break; + + case ERROR + HIGHER_ACCESS_REQUIRED: + hprintf("HTTP/1.1 403 %s\n", ChrPtr(Buf)); + break; + case ERROR + INTERNAL_ERROR: + case ERROR + TOO_BIG: + hprintf("HTTP/1.1 500 %s\n", ChrPtr(Buf)); + break; + } output_headers(0, 0, 0, 0, 0, 0); hprintf("Content-Type: text/plain\r\n"); begin_burst(); @@ -1894,6 +1991,16 @@ InitModule_MSG /* 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 ; }