/*
* free the memory used for viewing atachments
*/
-void free_attachments(struct wcsession *sess) {
- struct wc_attachment *att;
-
- while (sess->first_attachment != NULL) {
- att = sess->first_attachment;
- sess->first_attachment = sess->first_attachment->next;
- free(att->data);
- free(att);
- }
+void free_attachment(void *vattach) {
+ wc_attachment *att = (wc_attachment*) vattach;
+ FreeStrBuf(&att->content_type);
+ FreeStrBuf(&att->filename);
+ free(att->data);
+ free(att);
}
if ((*sessions_to_kill)->cache_fold != NULL) {
free((*sessions_to_kill)->cache_fold);
}
- free_attachments((*sessions_to_kill));
+ DeleteHash(&((*sessions_to_kill)->attachments));
free_march_list((*sessions_to_kill));
DeleteHash(&((*sessions_to_kill)->hash_prefs));
DeleteHash(&((*sessions_to_kill)->IconBarSetttings));
if ((msg != NULL) && (Source == NULL)) free(msg);
}
+
+
+
+
+
+/*
+ * Look for URL's embedded in a buffer and make them linkable. We use a
+ * target window in order to keep the Citadel session in its own window.
+ */
+void UrlizeText(StrBuf* Target, StrBuf *Source, StrBuf *WrkBuf)
+{
+ int len, UrlLen, Offset, TrailerLen;
+ const char *start, *end, *pos;
+
+ FlushStrBuf(Target);
+
+ start = NULL;
+ len = StrLength(Source);
+ end = ChrPtr(Source) + len;
+ for (pos = ChrPtr(Source); (pos < end) && (start == NULL); ++pos) {
+ if (!strncasecmp(pos, "http://", 7))
+ start = pos;
+ if (!strncasecmp(pos, "ftp://", 6))
+ start = pos;
+ }
+
+ if (start == NULL) {
+ StrBufAppendBuf(Target, Source, 0);
+ return;
+ }
+ FlushStrBuf(WrkBuf);
+
+ for (pos = ChrPtr(Source) + len; pos > start; --pos) {
+ if ( (!isprint(*pos))
+ || (isspace(*pos))
+ || (*pos == '{')
+ || (*pos == '}')
+ || (*pos == '|')
+ || (*pos == '\\')
+ || (*pos == '^')
+ || (*pos == '[')
+ || (*pos == ']')
+ || (*pos == '`')
+ || (*pos == '<')
+ || (*pos == '>')
+ || (*pos == '(')
+ || (*pos == ')')
+ ) {
+ end = pos;
+ }
+ }
+
+ UrlLen = end - start;
+ StrBufAppendBufPlain(WrkBuf, start, UrlLen, 0);
+
+ Offset = start - ChrPtr(Source);
+ if (Offset != 0)
+ StrBufAppendBufPlain(Target, ChrPtr(Source), Offset, 0);
+ StrBufAppendPrintf(Target, "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
+ LB, QU, ChrPtr(WrkBuf), QU, QU, TARGET,
+ QU, RB, ChrPtr(WrkBuf), LB, RB);
+
+ TrailerLen = len - (end - start);
+ if (TrailerLen > 0)
+ StrBufAppendBufPlain(Target, end, TrailerLen, 0);
+}
+void url(char *buf, size_t bufsize)
+{
+ int len, UrlLen, Offset, TrailerLen, outpos;
+ char *start, *end, *pos;
+ char urlbuf[SIZ];
+ char outbuf[SIZ];
+
+ start = NULL;
+ len = strlen(buf);
+ if (len > bufsize) {
+ lprintf(1, "URL: content longer than buffer!");
+ return;
+ }
+ end = buf + len;
+ for (pos = buf; (pos < end) && (start == NULL); ++pos) {
+ if (!strncasecmp(pos, "http://", 7))
+ start = pos;
+ if (!strncasecmp(pos, "ftp://", 6))
+ start = pos;
+ }
+
+ if (start == NULL)
+ return;
+
+ for (pos = buf+len; pos > start; --pos) {
+ if ( (!isprint(*pos))
+ || (isspace(*pos))
+ || (*pos == '{')
+ || (*pos == '}')
+ || (*pos == '|')
+ || (*pos == '\\')
+ || (*pos == '^')
+ || (*pos == '[')
+ || (*pos == ']')
+ || (*pos == '`')
+ || (*pos == '<')
+ || (*pos == '>')
+ || (*pos == '(')
+ || (*pos == ')')
+ ) {
+ end = pos;
+ }
+ }
+
+ UrlLen = end - start;
+ if (UrlLen > sizeof(urlbuf)){
+ lprintf(1, "URL: content longer than buffer!");
+ return;
+ }
+ memcpy(urlbuf, start, UrlLen);
+ urlbuf[UrlLen] = '\0';
+
+ Offset = start - buf;
+ if ((Offset != 0) && (Offset < sizeof(outbuf)))
+ memcpy(outbuf, buf, Offset);
+ outpos = snprintf(&outbuf[Offset], sizeof(outbuf) - Offset,
+ "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
+ LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
+ if (outpos >= sizeof(outbuf) - Offset) {
+ lprintf(1, "URL: content longer than buffer!");
+ return;
+ }
+
+ TrailerLen = len - (end - start);
+ if (TrailerLen > 0)
+ memcpy(outbuf + Offset + outpos, end, TrailerLen);
+ if (Offset + outpos + TrailerLen > bufsize) {
+ lprintf(1, "URL: content longer than buffer!");
+ return;
+ }
+ memcpy (buf, outbuf, Offset + outpos + TrailerLen);
+ *(buf + Offset + outpos + TrailerLen) = '\0';
+}
+
+
+
+
/*@}*/
return(0);
}
+/*
+ * qsort() compatible function to compare two longs in descending order.
+ */
+int qlongcmp_r(const void *s1, const void *s2) {
+ long l1 = (long) s1;
+ long l2 = (long) s2;
+
+ if (l1 > l2) return(-1);
+ if (l1 < l2) return(+1);
+ return(0);
+}
+
/*
* qsort() compatible function to compare two message summary structs by ascending subject.
-
-/*
- * Look for URL's embedded in a buffer and make them linkable. We use a
- * target window in order to keep the Citadel session in its own window.
- */
-void UrlizeText(StrBuf* Target, StrBuf *Source, StrBuf *WrkBuf)
-{
- int len, UrlLen, Offset, TrailerLen;
- const char *start, *end, *pos;
-
- FlushStrBuf(Target);
-
- start = NULL;
- len = StrLength(Source);
- end = ChrPtr(Source) + len;
- for (pos = ChrPtr(Source); (pos < end) && (start == NULL); ++pos) {
- if (!strncasecmp(pos, "http://", 7))
- start = pos;
- if (!strncasecmp(pos, "ftp://", 6))
- start = pos;
- }
-
- if (start == NULL) {
- StrBufAppendBuf(Target, Source, 0);
- return;
- }
- FlushStrBuf(WrkBuf);
-
- for (pos = ChrPtr(Source) + len; pos > start; --pos) {
- if ( (!isprint(*pos))
- || (isspace(*pos))
- || (*pos == '{')
- || (*pos == '}')
- || (*pos == '|')
- || (*pos == '\\')
- || (*pos == '^')
- || (*pos == '[')
- || (*pos == ']')
- || (*pos == '`')
- || (*pos == '<')
- || (*pos == '>')
- || (*pos == '(')
- || (*pos == ')')
- ) {
- end = pos;
- }
- }
-
- UrlLen = end - start;
- StrBufAppendBufPlain(WrkBuf, start, UrlLen, 0);
-
- Offset = start - ChrPtr(Source);
- if (Offset != 0)
- StrBufAppendBufPlain(Target, ChrPtr(Source), Offset, 0);
- StrBufAppendPrintf(Target, "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
- LB, QU, ChrPtr(WrkBuf), QU, QU, TARGET,
- QU, RB, ChrPtr(WrkBuf), LB, RB);
-
- TrailerLen = len - (end - start);
- if (TrailerLen > 0)
- StrBufAppendBufPlain(Target, end, TrailerLen, 0);
-}
-void url(char *buf, size_t bufsize)
-{
- int len, UrlLen, Offset, TrailerLen, outpos;
- char *start, *end, *pos;
- char urlbuf[SIZ];
- char outbuf[SIZ];
-
- start = NULL;
- len = strlen(buf);
- if (len > bufsize) {
- lprintf(1, "URL: content longer than buffer!");
- return;
- }
- end = buf + len;
- for (pos = buf; (pos < end) && (start == NULL); ++pos) {
- if (!strncasecmp(pos, "http://", 7))
- start = pos;
- if (!strncasecmp(pos, "ftp://", 6))
- start = pos;
- }
-
- if (start == NULL)
- return;
-
- for (pos = buf+len; pos > start; --pos) {
- if ( (!isprint(*pos))
- || (isspace(*pos))
- || (*pos == '{')
- || (*pos == '}')
- || (*pos == '|')
- || (*pos == '\\')
- || (*pos == '^')
- || (*pos == '[')
- || (*pos == ']')
- || (*pos == '`')
- || (*pos == '<')
- || (*pos == '>')
- || (*pos == '(')
- || (*pos == ')')
- ) {
- end = pos;
- }
- }
-
- UrlLen = end - start;
- if (UrlLen > sizeof(urlbuf)){
- lprintf(1, "URL: content longer than buffer!");
- return;
- }
- memcpy(urlbuf, start, UrlLen);
- urlbuf[UrlLen] = '\0';
-
- Offset = start - buf;
- if ((Offset != 0) && (Offset < sizeof(outbuf)))
- memcpy(outbuf, buf, Offset);
- outpos = snprintf(&outbuf[Offset], sizeof(outbuf) - Offset,
- "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
- LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
- if (outpos >= sizeof(outbuf) - Offset) {
- lprintf(1, "URL: content longer than buffer!");
- return;
- }
-
- TrailerLen = len - (end - start);
- if (TrailerLen > 0)
- memcpy(outbuf + Offset + outpos, end, TrailerLen);
- if (Offset + outpos + TrailerLen > bufsize) {
- lprintf(1, "URL: content longer than buffer!");
- return;
- }
- memcpy (buf, outbuf, Offset + outpos + TrailerLen);
- *(buf + Offset + outpos + TrailerLen) = '\0';
-}
-
-
-
-
-
-
-
-
-
-
-
/*
* I wanna SEE that message!
*
* printable_view Nonzero to display a printable view
* section Optional for encapsulated message/rfc822 submessage
*/
-void read_message(long msgnum, int printable_view, char *section) {
- struct wcsession *WCC = WC;
+void read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, int printable_view, char *section) {
StrBuf *Buf;
StrBuf *Token;
StrBuf *FoundCharset;
serv_printf("MSG4 %ld|%s", msgnum, section);
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) != 1) {
- wprintf("<strong>");
- wprintf(_("ERROR:"));
- wprintf("</strong> %s<br />\n", &buf[4]);
+ StrBufAppendPrintf(Target, "<strong>");
+ StrBufAppendPrintf(Target, _("ERROR:"));
+ StrBufAppendPrintf(Target, "</strong> %s<br />\n", &buf[4]);
FreeStrBuf(&Buf);
return;
}
{
Done = 1;
if (state < 2) {
- wprintf("<i>");
- wprintf(_("unexpected end of message"));
- wprintf(" (1)</i><br /><br />\n");
- wprintf("</div>\n");
+ StrBufAppendPrintf(Target, "<i>");
+ StrBufAppendPrintf(Target, _("unexpected end of message"));
+ StrBufAppendPrintf(Target, " (1)</i><br /><br />\n");
+ StrBufAppendPrintf(Target, "</div>\n");
FreeStrBuf(&Buf);
FreeStrBuf(&Token);
DestroyMessageSummary(Msg);
StrBufAppendBuf(Msg->reply_to, Msg->from, 0);
}
}
- DoTemplate(HKEY("view_message"), NULL, Msg, CTX_MAILSUM);
+ DoTemplate(tmpl, tmpllen, Target, Msg, CTX_MAILSUM);
*/
void embed_message(void) {
long msgnum = 0L;
+ const StrBuf *Tmpl = sbstr("template");
msgnum = StrTol(WC->UrlFragment1);
- read_message(msgnum, 0, "");
+ if (StrLength(Tmpl) > 0)
+ read_message(WC->WBuf, SKEY(Tmpl), msgnum, 0, "");
+ else
+ read_message(WC->WBuf, HKEY("view_message"), msgnum, 0, "");
}
output_headers(0, 0, 0, 0, 0, 0);
hprintf("Content-type: text/html\r\n"
- "Server: %s\r\n"
- "Connection: close\r\n",
- PACKAGE_STRING);
+ "Server: " PACKAGE_STRING "\r\n"
+ "Connection: close\r\n");
+
begin_burst();
- wprintf("\r\n<html>\n<head><title>");
- escputs(WC->wc_fullname);
- wprintf("</title></head>\n"
- "<body onLoad=\" window.print(); window.close(); \">\n"
- );
-
- read_message(msgnum, 1, "");
+ read_message(WC->WBuf, HKEY("view_message_print"), msgnum, 1, "");
- wprintf("\n</body></html>\n\n");
wDumpContent(0);
}
output_headers(1, 0, 0, 0, 0, 1);
begin_burst();
do_template("msgcontrols", NULL);
- read_message(msgnum,1, "");
+ read_message(WC->WBuf, HKEY("view_message"), msgnum,1, "");
wDumpContent(0);
}
* \param forward_attachments Nonzero if we want attachments to be forwarded
*/
void pullquote_message(long msgnum, int forward_attachments, int include_headers) {
+ struct wcsession *WCC = WC;
char buf[SIZ];
char mime_partnum[256];
char mime_filename[256];
char *attachments = NULL;
char *ptr = NULL;
int num_attachments = 0;
- struct wc_attachment *att, *aptr;
+ wc_attachment *att;
char m_subject[1024];
char from[256];
char node[256];
if ( (!strcasecmp(mime_disposition, "inline"))
|| (!strcasecmp(mime_disposition, "attachment")) ) {
+ int n;
+ char N[64];
/* Create an attachment struct from this mime part... */
- att = malloc(sizeof(struct wc_attachment));
- memset(att, 0, sizeof(struct wc_attachment));
+ att = malloc(sizeof(wc_attachment));
+ memset(att, 0, sizeof(wc_attachment));
att->length = mime_length;
- strcpy(att->content_type, mime_content_type);
- strcpy(att->filename, mime_filename);
- att->next = NULL;
+ att->content_type = NewStrBufPlain(mime_content_type, -1);
+ att->filename = NewStrBufPlain(mime_filename, -1);
att->data = load_mimepart(msgnum, mime_partnum);
+ if (WCC->attachments == NULL)
+ WCC->attachments = NewHash(1, NULL);
/* And add it to the list. */
- if (WC->first_attachment == NULL) {
- WC->first_attachment = att;
- }
- else {
- aptr = WC->first_attachment;
- while (aptr->next != NULL) aptr = aptr->next;
- aptr->next = att;
- }
+ n = snprintf(N, sizeof N, "%d", GetCount(WCC->attachments) + 1);
+ Put(WCC->attachments, N, n, att, free_attachment);
}
}
/** Output loop */
if (displayed_msgs != NULL) {
if (bbs_reverse) {
- qsort(displayed_msgs, num_displayed, sizeof(long), longcmp_r);
+ qsort(displayed_msgs, num_displayed, sizeof(long), qlongcmp_r);
}
/** if we do a split bbview in the future, begin messages div here */
for (a=0; a<num_displayed; ++a) {
- read_message(displayed_msgs[a], 0, "");
+ read_message(WC->WBuf, HKEY("view_message"), displayed_msgs[a], 0, "");
}
/** if we do a split bbview in the future, end messages div here */
* ... this is where the actual message gets transmitted to the server.
*/
void post_mime_to_server(void) {
+ struct wcsession *WCC = WC;
char top_boundary[SIZ];
char alt_boundary[SIZ];
int is_multipart = 0;
static int seq = 0;
- struct wc_attachment *att;
+ wc_attachment *att;
char *encoded;
size_t encoded_length;
size_t encoded_strlen;
serv_puts("X-Mailer: " PACKAGE_STRING);
/* If there are attachments, we have to do multipart/mixed */
- if (WC->first_attachment != NULL) {
+ if (GetCount(WCC->attachments) > 0) {
is_multipart = 1;
}
serv_printf("--%s--", alt_boundary);
if (is_multipart) {
+ long len;
+ const char *Key;
+ void *vAtt;
+ HashPos *it;
/* Add in the attachments */
- for (att = WC->first_attachment; att!=NULL; att=att->next) {
-
+ it = GetNewHashPos();
+ while (GetNextHashPos(WCC->attachments, it, &len, &Key, &vAtt)) {
+ att = (wc_attachment*)vAtt;
encoded_length = ((att->length * 150) / 100);
encoded = malloc(encoded_length);
if (encoded == NULL) break;
encoded_strlen = CtdlEncodeBase64(encoded, att->data, att->length, 1);
serv_printf("--%s", top_boundary);
- serv_printf("Content-type: %s", att->content_type);
- serv_printf("Content-disposition: attachment; filename=\"%s\"", att->filename);
+ serv_printf("Content-type: %s", ChrPtr(att->content_type));
+ serv_printf("Content-disposition: attachment; filename=\"%s\"", ChrPtr(att->filename));
serv_puts("Content-transfer-encoding: base64");
serv_puts("");
serv_write(encoded, encoded_strlen);
free(encoded);
}
serv_printf("--%s--", top_boundary);
+ DeleteHashPos(&it);
}
serv_puts("000");
char buf[1024];
StrBuf *encoded_subject = NULL;
static long dont_post = (-1L);
- struct wc_attachment *att, *aptr;
+ wc_attachment *att;
int is_anonymous = 0;
const StrBuf *display_name = NULL;
struct wcsession *WCC = WC;
}
if (WCC->upload_length > 0) {
+ const char *pch;
+ int n;
+ char N[64];
lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WCC->upload_length);
/** There's an attachment. Save it to this struct... */
- att = malloc(sizeof(struct wc_attachment));
- memset(att, 0, sizeof(struct wc_attachment));
+ att = malloc(sizeof(wc_attachment));
+ memset(att, 0, sizeof(wc_attachment));
att->length = WCC->upload_length;
- strcpy(att->content_type, WCC->upload_content_type);
- strcpy(att->filename, WCC->upload_filename);
- att->next = NULL;
-
- /** And add it to the list. */
- if (WCC->first_attachment == NULL) {
- WCC->first_attachment = att;
- }
- else {
- aptr = WCC->first_attachment;
- while (aptr->next != NULL) aptr = aptr->next;
- aptr->next = att;
- }
+ att->content_type = NewStrBufPlain(WCC->upload_content_type, -1);
+ att->filename = NewStrBufPlain(WCC->upload_filename, -1);
+
+
+ if (WCC->attachments == NULL)
+ WCC->attachments = NewHash(1, NULL);
+ /* And add it to the list. */
+ n = snprintf(N, sizeof N, "%d", GetCount(WCC->attachments) + 1);
+ Put(WCC->attachments, N, n, att, free_attachment);
/**
* 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.
*/
- while (num_tokens(att->filename, '/') > 1) {
- remove_token(att->filename, 0, '/');
+ pch = strrchr(ChrPtr(att->filename), '/');
+ if (pch != NULL) {
+ StrBufCutLeft(att->filename, pch - ChrPtr(att->filename));
}
- while (num_tokens(att->filename, '\\') > 1) {
- remove_token(att->filename, 0, '\\');
+ pch = strrchr(ChrPtr(att->filename), '\\');
+ if (pch != NULL) {
+ StrBufCutLeft(att->filename, pch - ChrPtr(att->filename));
}
/**
}
}
- free_attachments(WCC);
+ DeleteHash(&WCC->attachments);
/**
* We may have been supplied with instructions regarding the location
StrBuf *ebuf;
long now;
const StrBuf *display_name = NULL;
- struct wc_attachment *att;
+ /////wc_attachment *att;
int recipient_required = 0;
int subject_required = 0;
int recipient_bad = 0;
* Do a custom room banner with no navbar...
*/
output_headers(1, 1, 2, 0, 0, 0);
+
+/*
wprintf("<div id=\"banner\">\n");
embed_room_banner(NULL, navbar_none);
wprintf("</div>\n");
wprintf("<div id=\"content\">\n"
"<div class=\"fix_scrollbar_bug message \">");
-
+*/
/* Now check our actual recipients if there are any */
if (recipient_required) {
const StrBuf *Recp = NULL;
goto DONE;
}
}
+ DoTemplate(HKEY("edit_message"), NULL, NULL, CTX_NONE);
+ address_book_popup();
+ wDumpContent(1);
+
+
+ return;
+
/** If we got this far, we can display the message entry screen. */
wprintf(_("Attachments:"));
wprintf(" ");
wprintf("<select name=\"which_attachment\" size=1>");
+/*
for (att = WCC->first_attachment; att != NULL; att = att->next) {
wprintf("<option value=\"");
urlescputs(att->filename);
wprintf("\">");
escputs(att->filename);
- /* wprintf(" (%s, %d bytes)",att->content_type,att->length); */
+ / * wprintf(" (%s, %d bytes)",att->content_type,att->length); * /
wprintf("</option>\n");
}
+*/
wprintf("</select>");
/** Now offer the ability to attach additional files... */
StrBufAppendPrintf(Target, "%ld", mime->length);
}
+HashList *iterate_get_registered_Attachments(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ return WC->attachments;
+}
+
+void tmplput_ATT_Length(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_attachment *att = (wc_attachment*) Context;
+ StrBufAppendPrintf(Target, "%ld", att->length);
+}
+
+void tmplput_ATT_Contenttype(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_attachment *att = (wc_attachment*) Context;
+ StrBufAppendBuf(Target, att->content_type, 0);
+}
+
+void tmplput_ATT_FileName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_attachment *att = (wc_attachment*) Context;
+ StrBufAppendBuf(Target, att->filename, 0);
+}
+
+
RegisterNamespace("MAIL:SUMM:INREPLYTO", 0, 2, tmplput_MAIL_SUMM_INREPLYTO, CTX_MAILSUM);
RegisterNamespace("MAIL:BODY", 0, 2, tmplput_MAIL_BODY, CTX_MAILSUM);
+ RegisterNamespace("ATT:SIZE", 0, 1, tmplput_ATT_Length, CTX_ATT);
+ RegisterNamespace("ATT:TYPE", 0, 1, tmplput_ATT_Contenttype, CTX_ATT);
+ RegisterNamespace("ATT:FILENAME", 0, 1, tmplput_ATT_FileName, CTX_ATT);
RegisterConditional(HKEY("COND:MAIL:SUMM:UNREAD"), 0, Conditional_MAIL_SUMM_UNREAD, CTX_MAILSUM);
RegisterConditional(HKEY("COND:MAIL:SUMM:H_NODE"), 0, Conditional_MAIL_SUMM_H_NODE, CTX_MAILSUM);
RegisterNamespace("MAIL:MIME:LENGTH", 0, 2, tmplput_MIME_Length, CTX_MIME_ATACH);
RegisterNamespace("MAIL:MIME:DATA", 0, 2, tmplput_MIME_Data, CTX_MIME_ATACH);
-
+ RegisterIterator("MSG:ATTACHNAMES", 0, NULL, iterate_get_registered_Attachments,
+ NULL, NULL, CTX_ATT, CTX_NONE);
RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL);
RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard);
return (StrTol(Pref) == Token->Params[3]->lvalue);
}
+HashList *GetGVEAHash(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrBuf *Rcp;
+ HashList *List = NULL;
+ int Done = 0;
+ int i, n = 1;
+ char N[64];
+
+ Rcp = NewStrBuf();
+ serv_puts("GVEA");
+ StrBuf_ServGetln(Rcp);
+ if (ChrPtr(Rcp)[0] == '1') {
+ FlushStrBuf(Rcp);
+ List = NewHash(1, NULL);
+ while (!Done && (StrBuf_ServGetln(Rcp)>=0)) {
+ if ( (StrLength(Rcp)==3) &&
+ !strcmp(ChrPtr(Rcp), "000"))
+ {
+ Done = 1;
+ }
+ else {
+ i = snprintf(N, sizeof(N), "%d", n);
+ Put(List, N, i, Rcp, HFreeStrBuf);
+ Rcp = NewStrBuf();
+ }
+ n++;
+ }
+ }
+ FreeStrBuf(&Rcp);
+ return List;
+}
+void DeleteGVEAHash(HashList **KillMe)
+{
+ DeleteHash(KillMe);
+}
+void tmplput_EMAIL_ADDR(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ StrBuf *EmailAddr = (StrBuf*) Context;
+ StrBufAppendBuf(Target, EmailAddr, 0);
+}
+
+HashList *GetGVSNHash(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrBuf *Rcp;
+ HashList *List = NULL;
+ int Done = 0;
+ int i, n = 1;
+ char N[64];
+
+ Rcp = NewStrBuf();
+ serv_puts("GVSN");
+ StrBuf_ServGetln(Rcp);
+ if (ChrPtr(Rcp)[0] == '1') {
+ FlushStrBuf(Rcp);
+ List = NewHash(1, NULL);
+ while (!Done && (StrBuf_ServGetln(Rcp)>=0)) {
+ if ( (StrLength(Rcp)==3) &&
+ !strcmp(ChrPtr(Rcp), "000"))
+ {
+ Done = 1;
+ }
+ else {
+ i = snprintf(N, sizeof(N), "%d", n);
+ Put(List, N, i, Rcp, HFreeStrBuf);
+ Rcp = NewStrBuf();
+ }
+ n++;
+ }
+ }
+ FreeStrBuf(&Rcp);
+ return List;
+}
+void DeleteGVSNHash(HashList **KillMe)
+{
+ DeleteHash(KillMe);
+}
+void tmplput_EMAIL_NAME(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ StrBuf *EmailAddr = (StrBuf*) Context;
+ StrBufAppendBuf(Target, EmailAddr, 0);
+}
void
InitModule_PREFERENCES
RegisterPreference("default_header_charset", _("Default character set for email headers:") ,PRF_STRING);
RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO);
- RegisterNamespace("PREF:VALUE", 1, 1, tmplput_CFG_Value, CTX_SESSION);
- RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr, CTX_SESSION);
+ RegisterNamespace("PREF:VALUE", 1, 2, tmplput_CFG_Value, CTX_NONE);
+ RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr, CTX_NONE);
RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE);
RegisterConditional(HKEY("COND:PREF"), 4, ConditionalPreference, CTX_NONE);
+
+ RegisterNamespace("PREF:EMAIL:ADDR", 0, 1, tmplput_EMAIL_ADDR, CTX_GVEA);
+ RegisterIterator("PREF:VALID:EMAIL:ADDR", 0, NULL,
+ GetGVEAHash, NULL, DeleteGVEAHash, CTX_GVEA, CTX_NONE);
+ RegisterNamespace("PREF:EMAIL:NAME", 0, 1, tmplput_EMAIL_NAME, CTX_GVSN);
+ RegisterIterator("PREF:VALID:EMAIL:NAME", 0, NULL,
+ GetGVSNHash, NULL, DeleteGVSNHash, CTX_GVSN, CTX_NONE);
+
}
/*@}*/
--- /dev/null
+<div id="address_book_popup" style="display:none;">
+ <div id="address_book_popup_container_div">
+ <div id="address_book_popup_middle_div"></div>
+ <div id="address_book_inner_div"></div>
+ </div>
+</div>
--- /dev/null
+<?=("head")>
+<?=("important_msg")>
+<?ICONBAR>
+<?ROOMBANNER>
+</div>
+<div id="content">
+<div class="fix_scrollbar_bug message "><form enctype="multipart/form-data" method="POST" accept-charset="UTF-8" action="post" name="enterform">
+<input type="hidden" name="postseq" value="<?DATE:NOW:NO>">
+<input type="hidden" name="return_to" value="<?BSTR("return_to")>">
+<input type="hidden" name="nonce" value="<?NONCE>">
+<input type="hidden" name="force_room" value="<?ROOMNAME>">
+<input type="hidden" name="references" value="<?BSTR("references")>">
+
+<p class="send_edit_msg">
+ <input type="submit" name="send_button" value="<?_("Send message")>">
+ <input type="submit" name="send_button" value="<?_("Post message")>"> TODO
+ <input type="submit" name="cancel_button" value="<?_("Cancel")>">
+</p>
+<img src="static/newmess3_24x.gif" class="imgedit"> <?DATE:NOW:STR>
+<table width="100%" class="edit_msg_table">
+<TODO: anonym>
+<tr><th><label for="from_id" > <i><?_("from")></i> </label></th><td colspan="2">
+<select name="display_name" size=1 id="from_id">
+<?ITERATE("PREF:VALID:EMAIL:NAME", "section_msg_sender_name_select")>
+</select>
+<select name="my_email_addr" size=1>
+<?ITERATE("PREF:VALID:EMAIL:ADDR", "section_msg_sender_from_select")>
+</select>
+ <i><?_("in")></i> <?ROOMNAME></td></tr>
+<tr>
+ <th><label for="recp_id"> <?_("To:")></label></th>
+ <td><input autocomplete="off" type="text" name="recp" id="recp_id" value="<?BSTR("recp", "H")>" size=45 maxlength=1000 />
+ <div class="auto_complete" id="recp_name_choices"></div>
+ </td>
+ <td rowspan="3" align="left" valign="top">
+ <a href="javascript:PopOpenAddressBook('recp_id|<?_("To:")>|cc_id|<?_("CC:")>|bcc_id|<?_("BCC:")>');" title="<?_("Contacts")>">
+ <img align=middle border=0 width=24 height=24 src="static/viewcontacts_24x.gif"> <?_("Contacts")>
+ </a>
+ </td>
+</tr>
+<tr>
+ <th><label for="cc_id"><?_("CC:")></label></th>
+ <td><input autocomplete="off" type="text" name="cc" id="cc_id" value="<?BSTR("cc", "H")>" size=45 maxlength=1000 />
+ <div class="auto_complete" id="cc_name_choices"></div>
+ </td>
+</tr>
+<tr>
+ <th><label for="bcc_id"><?_("BCC:")></label></th>
+ <td><input autocomplete="off" type="text" name="bcc" id="bcc_id" value="<?BSTR("cc", "H")>" size=45 maxlength=1000 />
+ <div class="auto_complete" id="bcc_name_choices"></div>
+ </td>
+</tr>
+<script type="text/javascript">
+ activate_entmsg_autocompleters();
+
+</script>
+<tr>
+ <th><label for="subject_id" >
+ <?_("Subject:")><?_("Subject (optional):")><TODO>
+ </label></th>
+ <td colspan="2">
+ <input type="text" name="subject" id="subject_id" value="<?BSTR("subject", "U")>" size=45 maxlength=70>
+ </td>
+</tr>
+<tr><td colspan="3">
+
+
+<textarea name="msgtext" cols="80" rows="15">
+<?BSTR("msgtext")>
+<?!("COND:BSTR", 1, "fwdquote")>
+<br><div align=center><i>
+<?_("--- forwarded message ---")>
+</i></div><br>
+<?MAIL:QUOTETEXT("fwdquote")>
+<?!("X", 1)><?!("COND:BSTR", 2, "replyquote")>
+<br>
+<blockquote>
+<?MAIL:QUOTETEXT("replyquote")>
+</blockquote><br>
+<?!("X", 2)><?!("COND:BSTR", 3, "sig_inserted", "yes")>
+<?!("COND:PREF", 4, "use_sig", "yes")>
+<br>--<br>
+<?PREF:VALUE("signature","H")>
+<?!("X", 4)>
+<?!("X", 3)>
+</textarea>
+<?=("richedit")>
+
+
+<div class="attachment buttons">
+<img src="static/diskette_24x.gif" class="imgedit" ><?_("Attachments:")>
+<select name="which_attachment" size=1>
+<?ITERATE("MSG:ATTACHNAMES", "section_attach_select")><TODO>
+</select>
+ <?_("Attach file:")>
+<input name="attachfile" class="attachfile" size=16 type="file">
+ <input type="submit" name="attach_button" value="<?_("Add")>">
+
+</div></td></tr></table></form>
+
+</div>
+</div>
+<?=("addressbook_popup")>
+
+<?=("trailing")>
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
-<title><?CURRENT_USER> - <?SERV_HUMANNODE></title>
+<title><?CURRENT_USER> - <?SERV:HUMANNODE></title>
<meta name="MSSmartTagsPreventParsing" content="TRUE" >
<meta name="keywords" content="groupware messaging collaboration" >
<link href="static/niftyCorners.css" rel="stylesheet" type="text/css">
--- /dev/null
+<option value="<?ATT:FILENAME("U")>"><?ATT:FILENAME("X")> (%<?ATT:TYPE>, <?ATT:SIZE></option>
+
--- /dev/null
+<option value="willi@peza.home.net"><willi@peza.home.net></option>
--- /dev/null
+<option value="<?PREF:EMAIL:NAME("X")>"><?PREF:EMAIL:NAME("U")></option>
<?ITERATE("MAIL:MIME:ATTACH:SUBMESSAGES", "view_message_inline_attach")>
<?!("X", 3)>
-</div>
--- /dev/null
+<html>\n<head><title>
+<?CURRENT_USER>
+</title></head>
+<body onLoad=" window.print(); window.close(); ">
+<div class="fix_scrollbar_bug message"
+<div class="message_header"><span><?MAIL:SUMM:DATESTR></span>
+<?_("from ")>
+<?MAIL:SUMM:FROM("X")><??("X", 1)>
+<?!("COND:MAIL:ANON",2)>***<??("X", 2)>
+<p style="visibility: hidden;" id="msg<?MAIL:SUMM:N>" class="msgbuttons">
+
+<a href="display_enter?recp=<?MAIL:SUMM:FROM("U")>&references=<?MAIL:SUMM:INREPLYTO("U")>&subject=<?MAIL:SUMM:SUBJECT("U", 0, "Re:%%20", "Re:")>"><span>[</span><?_("Reply")><span>]</span></a>
+
+<a href="display_enter?replyquote=<?MAIL:SUMM:N>&recp=<?MAIL:SUMM:FROM("U")>&references=<?MAIL:SUMM:INREPLYTO("U")>&subject=<?MAIL:SUMM:SUBJECT("U", 0, "Re:%%20", "Re:")>"><span>[</span><?_("ReplyQuoted")><span>]</span></a>
+
+<a href="display_enter?fwdquote=<?MAIL:SUMM:N>&subject=<?MAIL:SUMM:SUBJECT("U", 0, "Fwd:%%20", "Fwd:")>"><span>[</span><?_("Forward")><span>]</span></a>
+
+<a href="confirm_move_msg?msgid=<?MAIL:SUMM:N>"><span>[</span><?_("Move")><span>]</span></a>
+
+<a href="delete_msg?msgid=<?MAIL:SUMM:N>" onclick="return confirm('<?_("Delete this message?")>');"><span>[</span><?_("Delete")><span>]</span> </a>
+
+<a href="#" onclick="window.open('msgheaders/<?MAIL:SUMM:N>', 'headers<?MAIL:SUMM:N>', 'toolbar=no,location=no,directories=no,copyhistory=no,status=yes,scrollbars=yes,resizable=yes,width=600,height=400'); "><span>[</span><?_("Headers")><span>]</span></a>
+
+<a href="#" onclick="window.open('printmsg/<?MAIL:SUMM:N>', 'print<?MAIL:SUMM:N>', 'toolbar=no,location=no,directories=no,copyhistory=no,status=yes,scrollbars=yes,resizable=yes,width=600,height=400'); "><span>[</span><?_("Print")><span>]</span></a>
+</p></div>
+
+<p class="message_subject"><?MAIL:SUMM:SUBJECT></p>
+
+<div class="message_content"><div align="justify">
+<?MAIL:BODY>
+</div>
+<?!("COND:MAIL:MIME:ATTACH:LINKS", 2)>
+<?ITERATE("MAIL:MIME:ATTACH:LINKS", "view_message_list_attach")>
+<?!("X", 2)>
+
+<?!("COND:MAIL:MIME:ATTACH:SUBMESSAGES", 3)>
+<?ITERATE("MAIL:MIME:ATTACH:SUBMESSAGES", "view_message_inline_attach")>
+<?!("X", 3)>
+
+</body>
+</html>
StrBufAppendPrintf(Target, "<pre>WARNING: \ninvalid value in SV-Hash at %s!\n</pre>", Token->pName);
}
}
+ else
+ lprintf(1, "didn't find Handler [%s] (in '%s' line %ld); "
+ " [%s]\n",
+ Token->pName,
+ ChrPtr(Token->FileName),
+ Token->Line,
+ ChrPtr(Token->FlatToken));
+
}
int CompareSubstToToken(TemplateParam *ParamToCompare, TemplateParam *ParamToLookup)
if (do_htmlhead) {
begin_burst();
- if (!access("static.local/webcit.css", R_OK)) {
- svprintf(HKEY("CSSLOCAL"), WCS_STRING,
- "<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\">"
- );
- }
do_template("head", NULL);
}
* filename Fake filename to give
* force_download Nonzero to force set the Content-Type: header to "application/octet-stream"
*/
-void postpart(const char *partnum, const char *filename, int force_download)
+void postpart(StrBuf *partnum, StrBuf *filename, int force_download)
{
+ void *vPart;
char content_type[256];
- int num = atoi(partnum);
- struct wc_attachment *part = WC->first_attachment;
-
- while(num && part) {
- num--;
- part=part->next;
- }
+ wc_attachment *part;
- if (part) {
+ if (GetHash(WC->attachments, SKEY(partnum), &vPart) &&
+ (vPart != NULL)) {
+ part = (wc_attachment*) vPart;
if (force_download) {
strcpy(content_type, "application/octet-stream");
}
else {
- strncpy(content_type, part->content_type, sizeof content_type);
+ strncpy(content_type, ChrPtr(part->content_type), sizeof content_type);
}
output_headers(0, 0, 0, 0, 0, 0);
StrBufAppendBufPlain(WC->WBuf, part->data, part->length, 0);
http_transmit_thing(content_type, 0);
} else {
- hprintf("HTTP/1.1 404 %s\n",partnum);
+ hprintf("HTTP/1.1 404 %s\n", ChrPtr(partnum));
output_headers(0, 0, 0, 0, 0, 0);
hprintf("Content-Type: text/plain\r\n");
- wprintf(_("An error occurred while retrieving this part: %s/%s\n"), partnum, filename);
+ wprintf(_("An error occurred while retrieving this part: %s/%s\n"),
+ ChrPtr(partnum), ChrPtr(filename));
end_burst();
}
}
}
void view_postpart(void) {
- postpart(ChrPtr(WC->UrlFragment1),
- ChrPtr(WC->UrlFragment2),
+ postpart(WC->UrlFragment1,
+ WC->UrlFragment2,
0);
}
void download_postpart(void) {
- postpart(ChrPtr(WC->UrlFragment1),
- ChrPtr(WC->UrlFragment2),
+ postpart(WC->UrlFragment1,
+ WC->UrlFragment2,
1);
}
int ConditionalBstr(WCTemplateToken *Tokens, void *Context, int ContextType)
{
- if(Tokens->nParameters == 1)
- return HaveBstr(Tokens->Params[0]->Start,
- Tokens->Params[0]->len);
+ if(Tokens->nParameters == 3)
+ return HaveBstr(Tokens->Params[2]->Start,
+ Tokens->Params[2]->len);
else
- return strcmp(Bstr(Tokens->Params[0]->Start,
- Tokens->Params[0]->len),
- Tokens->Params[1]->Start) == 0;
+ return strcmp(Bstr(Tokens->Params[2]->Start,
+ Tokens->Params[2]->len),
+ Tokens->Params[3]->Start) == 0;
}
void tmplput_bstr(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
Tokens->Params[0]->len), 0);
}
+
+void tmplput_csslocal(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ extern StrBuf *csslocal;
+ StrBufAppendBuf(Target,
+ csslocal, 0);
+}
+
+
+
+
+
+
void
InitModule_WEBCIT
(void)
RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE);
RegisterConditional(HKEY("COND:BSTR"), 1, ConditionalBstr, CTX_NONE);
RegisterNamespace("BSTR", 1, 2, tmplput_bstr, CTX_NONE);
+ RegisterNamespace("CSSLOCAL", 0, 0, tmplput_csslocal, CTX_NONE);
RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, CTX_NONE);
RegisterNamespace("OFFERSTARTPAGE", 0, 0, offer_start_page, CTX_NONE);
}
#define CTX_USERLIST 8
#define CTX_MAILSUM 9
#define CTX_MIME_ATACH 10
+#define CTX_ATT 11
+#define CTX_GVEA 12
+#define CTX_GVSN 13
void RegisterNS(const char *NSName, long len,
int nMinArgs,
/*
* \brief mail attachment ???
*/
-struct wc_attachment {
- struct wc_attachment *next;/* pointer to next in list */
+typedef struct _wc_attachment {
size_t length; /* length of the contenttype */
- char content_type[SIZ]; /* the content itself ???*/
- char filename[SIZ]; /* the filename hooked to this content ??? */
+ StrBuf *content_type; /* the content itself ???*/
+ StrBuf *filename; /* the filename hooked to this content ??? */
char *data; /* the data pool; aka this content */
long lvalue; /* if we put a long... */
-};
+} wc_attachment;
+void free_attachment(void *vattach);
typedef struct wc_mime_attachment wc_mime_attachment;
char http_host[512]; /**< HTTP Host: header */
HashList *hash_prefs; /**< WebCit preferences for this user */
HashList *disp_cal_items; /**< sorted list of calendar items; startdate is the sort criteria. */
- struct wc_attachment *first_attachment; /**< linked list of attachments for 'enter message' */
+ HashList *attachments; /**< list of attachments for 'enter message' */
char last_chat_user[256]; /**< ??? todo */
char ImportantMessage[SIZ]; /**< ??? todo */
int ctdl_pid; /**< Session ID on the Citadel server */
void embed_main_menu(void);
void serv_read(char *buf, int bytes);
void readloop(char *oper);
-void read_message(long msgnum, int printable_view, char *section);
+void read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, int printable_view, char *section);
void do_addrbook_view(addrbookent *addrbook, int num_ab);
void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename, long msgnum);
void text_to_server(char *ptr);
void InitTemplateCache(void);
extern int LoadTemplates;
extern void LoadZoneFiles(void);
-
+StrBuf *csslocal = NULL;
/*
* Here's where it all begins.
*/
initialize_viewdefs();
initialize_axdefs();
+ if (!access("static.local/webcit.css", R_OK)) {
+ csslocal = NewStrBufPlain(HKEY("<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\">"));
+ }
+
/* Tell libical to return an error instead of aborting if it sees badly formed iCalendar data. */
icalerror_errors_are_fatal = 0;