* Supplied with a unix timestamp, generate an RFC822-compliant textual
* time and date stamp.
*/
-void datestring(char *buf, size_t n, time_t xtime, int which_format) {
+long datestring(char *buf, size_t n, time_t xtime, int which_format) {
struct tm t;
long offset;
switch(which_format) {
case DATESTRING_RFC822:
- snprintf(buf, n, "%s, %02d %s %04d %02d:%02d:%02d %c%04ld",
+ return snprintf(
+ buf, n,
+ "%s, %02d %s %04d %02d:%02d:%02d %c%04ld",
weekdays[t.tm_wday],
t.tm_mday,
months[t.tm_mon],
break;
case DATESTRING_IMAP:
- snprintf(buf, n, "%02d-%s-%04d %02d:%02d:%02d %c%04ld",
+ return snprintf(
+ buf, n,
+ "%02d-%s-%04d %02d:%02d:%02d %c%04ld",
t.tm_mday,
months[t.tm_mon],
t.tm_year + 1900,
break;
}
+ return 0;
}
-void datestring(char *buf, size_t n, time_t xtime, int which_format);
+long datestring(char *buf, size_t n, time_t xtime, int which_format);
enum {
DATESTRING_RFC822,
#include "server.h"
#include "ctdl_module.h"
-struct internet_address_list {
- struct internet_address_list *next;
- char ial_user[SIZ];
- char ial_node[SIZ];
- char ial_name[SIZ];
-};
-
-
recptypes *validate_recipients(const char *recipients,
const char *RemoteIdentifier,
int Flags);
imap_acl_flags(rights, ra);
if (StrLength(rights) > 0) {
IAPuts(" ");
- plain_imap_strout(temp.fullname);
+ IPutStr(temp.fullname, strlen(temp.fullname));
IAPuts(" ");
iaputs(SKEY( rights));
}
/* For everything else, we do stuff. */
IAPuts("(("); /* open double-parens */
- plain_imap_strout(msg->cm_fields[eAuthor]); /* personal name */
+ IPutMsgField(eAuthor); /* personal name */
IAPuts(" NIL "); /* source route (not used) */
if (!CM_IsEmpty(msg, erFc822Addr)) {
process_rfc822_addr(msg->cm_fields[erFc822Addr], user, node, name);
- plain_imap_strout(user); /* mailbox name (user id) */
+ IPutStr(user, strlen(user)); /* mailbox name (user id) */
IAPuts(" ");
if (!strcasecmp(node, config.c_nodename)) {
- plain_imap_strout(config.c_fqdn);
+ IPutStr(config.c_fqdn, strlen(config.c_fqdn));
}
else {
- plain_imap_strout(node); /* host name */
+ IPutStr(node, strlen(node)); /* host name */
}
}
else {
- plain_imap_strout(msg->cm_fields[eAuthor]); /* mailbox name (user id) */
+ IPutMsgField(eAuthor); /* mailbox name (user id) */
IAPuts(" ");
- plain_imap_strout(msg->cm_fields[eNodeName]); /* host name */
+ IPutMsgField(eNodeName); /* host name */
}
IAPuts(")) "); /* close double-parens */
striplt(individual_addr);
process_rfc822_addr(individual_addr, user, node, name);
IAPuts("(");
- plain_imap_strout(name);
+ IPutStr(name, strlen(name));
IAPuts(" NIL ");
- plain_imap_strout(user);
+ IPutStr(user, strlen(user));
IAPuts(" ");
- plain_imap_strout(node);
+ IPutStr(node, strlen(node));
IAPuts(")");
if (i < (num_addrs-1))
IAPuts(" ");
else {
msgdate = time(NULL);
}
- datestring(datestringbuf, sizeof datestringbuf,
- msgdate, DATESTRING_IMAP);
+ len = 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
IAPuts("ENVELOPE (");
/* Date */
- plain_imap_strout(datestringbuf);
+ IPutStr(datestringbuf, len);
IAPuts(" ");
/* Subject */
- plain_imap_strout(msg->cm_fields[eMsgSubject]);
+ IPutMsgField(eMsgSubject);
IAPuts(" ");
/* From */
/* In-reply-to */
fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "In-reply-to");
- plain_imap_strout(fieldptr);
+ IPutStr(fieldptr, (fieldptr)?strlen(fieldptr):0);
IAPuts(" ");
if (fieldptr != NULL) free(fieldptr);
(msg->cm_fields[emessageId][len - 1] == '>'))
)
{
- plain_imap_strout(msg->cm_fields[emessageId]);
+ IPutMsgField(emessageId);
}
else
{
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
char *cbid, void *cbuserdata
) {
-
+ long len;
char subtype[128];
IAPuts(" ");
/* disposition */
- extract_token(subtype, cbtype, 1, '/', sizeof subtype);
- plain_imap_strout(subtype);
+ len = extract_token(subtype, cbtype, 1, '/', sizeof subtype);
+ IPutStr(subtype, len);
/* body language */
/* IAPuts(" NIL"); We thought we needed this at one point, but maybe we don't... */
size_t i;
char cbmaintype[128];
char cbsubtype[128];
+ long cbmaintype_len;
+ long cbsubtype_len;
if (cbtype != NULL) if (!IsEmptyStr(cbtype)) have_cbtype = 1;
if (have_cbtype) {
- extract_token(cbmaintype, cbtype, 0, '/', sizeof cbmaintype);
- extract_token(cbsubtype, cbtype, 1, '/', sizeof cbsubtype);
+ cbmaintype_len = extract_token(cbmaintype, cbtype, 0, '/', sizeof cbmaintype);
+ cbsubtype_len = extract_token(cbsubtype, cbtype, 1, '/', sizeof cbsubtype);
}
else {
strcpy(cbmaintype, "TEXT");
+ cbmaintype_len = 4;
strcpy(cbsubtype, "PLAIN");
+ cbsubtype_len = 5;
}
IAPuts("(");
- plain_imap_strout(cbmaintype); /* body type */
+ IPutStr(cbmaintype, cbmaintype_len); /* body type */
IAPuts(" ");
- plain_imap_strout(cbsubtype); /* body subtype */
+ IPutStr(cbsubtype, cbsubtype_len); /* body subtype */
IAPuts(" ");
- IAPuts("("); /* begin body parameter list */
+ IAPuts("("); /* begin body parameter list */
/* "NAME" must appear as the first parameter. This is not required by IMAP,
* but the Asterisk voicemail application blindly assumes that NAME will be in
* the first position. If it isn't, it rejects the message.
*/
- if (name != NULL) if (!IsEmptyStr(name)) {
+ if ((name != NULL) && (!IsEmptyStr(name))) {
IAPuts("\"NAME\" ");
- plain_imap_strout(name);
+ IPutStr(name, strlen(name));
IAPuts(" ");
}
IAPuts("\"CHARSET\" ");
- if (cbcharset == NULL) {
- plain_imap_strout("US-ASCII");
- }
- else if (cbcharset[0] == 0) {
- plain_imap_strout("US-ASCII");
+ if ((cbcharset == NULL) || (cbcharset[0] == 0)){
+ IPutStr(HKEY("US-ASCII"));
}
else {
- plain_imap_strout(cbcharset);
+ IPutStr(cbcharset, strlen(cbcharset));
}
- IAPuts(") "); /* end body parameter list */
+ IAPuts(") "); /* end body parameter list */
IAPuts("NIL "); /* Body ID */
IAPuts("NIL "); /* Body description */
- if (encoding != NULL) if (encoding[0] != 0) have_encoding = 1;
+ if ((encoding != NULL) && (encoding[0] != 0)) have_encoding = 1;
if (have_encoding) {
- plain_imap_strout(encoding);
+ IPutStr(encoding, strlen(encoding));
}
else {
- plain_imap_strout("7BIT");
+ IPutStr(HKEY("7BIT"));
}
IAPuts(" ");
IAPuts("NIL ");
/* Disposition */
- if (disp == NULL) {
- IAPuts("NIL");
- }
- else if (IsEmptyStr(disp)) {
+ if ((disp == NULL) || IsEmptyStr(disp)) {
IAPuts("NIL");
}
else {
IAPuts("(");
- plain_imap_strout(disp);
- if (filename != NULL) if (!IsEmptyStr(filename)) {
+ IPutStr(disp, strlen(disp));
+ if ((filename != NULL) && (!IsEmptyStr(filename))) {
IAPuts(" (\"FILENAME\" ");
- plain_imap_strout(filename);
+ IPutStr(filename, strlen(filename));
IAPuts(")");
}
IAPuts(")");
}
if (match) {
IAPrintf("* %s (\\NoSelect \\HasChildren) \"/\" ", verb);
- plain_imap_strout(fl->f_name);
+ IPutStr(fl->f_name, (fl->f_name)?strlen(fl->f_name):0);
IAPuts("\r\n");
}
}
}
if (yes_output_this_room) {
- imap_mailboxname(MailboxName, sizeof MailboxName, qrbuf);
+ long len;
+ len = imap_mailboxname(MailboxName, sizeof MailboxName, qrbuf);
match = 0;
for (i=0; i<ImapFilter->num_patterns; ++i) {
if (imap_mailbox_matches_pattern(ChrPtr(ImapFilter->patterns[i]), MailboxName)) {
}
if (match) {
IAPrintf("* %s (%s) \"/\" ", ImapFilter->verb, return_options);
- plain_imap_strout(MailboxName);
+ IPutStr(MailboxName, len);
IAPuts("\r\n");
}
}
/* Convert a struct ctdlroom to an IMAP-compatible mailbox name. */
-void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
+long imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
{
char* bufend = buf+bufsize;
struct floor *fl;
char* p = buf;
+ const char *pend;
/* For mailboxes, just do it straight.
* Do the Cyrus-compatible thing: all private folders are
if (qrbuf->QRflags & QR_MAILBOX)
{
if (strcasecmp(qrbuf->QRname+11, MAILROOM) == 0)
- toimap(p, bufend, "INBOX");
+ {
+ pend = toimap(p, bufend, "INBOX");
+ return pend - p;
+ }
else
{
p = toimap(p, bufend, "INBOX");
if (p < bufend)
*p++ = '/';
- toimap(p, bufend, qrbuf->QRname+11);
+ pend = toimap(p, bufend, qrbuf->QRname+11);
+ return pend - p;
}
}
else
p = toimap(p, bufend, fl->f_name);
if (p < bufend)
*p++ = '/';
- toimap(p, bufend, qrbuf->QRname);
+ pend = toimap(p, bufend, qrbuf->QRname);
+ return pend - p;
}
}
return(ret);
}
-/*
- * Output a struct internet_address_list in the form an IMAP client wants
- */
-void imap_ial_out(struct internet_address_list *ialist)
-{
- struct internet_address_list *iptr;
-
- if (ialist == NULL) {
- IAPuts("NIL");
- return;
- }
- IAPuts("(");
-
- for (iptr = ialist; iptr != NULL; iptr = iptr->next) {
- IAPuts("(");
- plain_imap_strout(iptr->ial_name);
- IAPuts(" NIL ");
- plain_imap_strout(iptr->ial_user);
- IAPuts(" ");
- plain_imap_strout(iptr->ial_node);
- IAPuts(")");
- }
-
- IAPuts(")");
-}
-
-
/*
* Determine whether the supplied string is a valid message set.
}
-
-/* Output a string to the IMAP client, either as a literal or quoted.
- * (We do a literal if it has any double-quotes or backslashes.) */
-
-void plain_imap_strout(char *buf)
-{
- int i;
- int is_literal = 0;
- long Len;
- citimap *Imap = IMAP;
-
- if (buf == NULL) { /* yeah, we handle this */
- IAPuts("NIL");
- return;
- }
-
- Len = strlen(buf);
- for (i = 0; i < Len; ++i) {
- if ((buf[i] == '\"') || (buf[i] == '\\'))
- is_literal = 1;
- }
-
- if (is_literal) {
- StrBufAppendPrintf(Imap->Reply, "{%ld}\r\n", Len);
- StrBufAppendBufPlain(Imap->Reply, buf, Len, 0);
- } else {
- StrBufAppendBufPlain(Imap->Reply,
- HKEY("\""), 0);
- StrBufAppendBufPlain(Imap->Reply,
- buf, Len, 0);
- StrBufAppendBufPlain(Imap->Reply,
- HKEY("\""), 0);
- }
-}
-
-
/* Output a string to the IMAP client, either as a literal or quoted.
* (We do a literal if it has any double-quotes or backslashes.) */
void imap_strout(ConstStr *args);
void imap_strbuffer(StrBuf *Reply, ConstStr *args);
void plain_imap_strbuffer(StrBuf *Reply, char *buf);
-void plain_imap_strout(char *buf);
int imap_parameterize(citimap_command *Cmd);
-void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf);
-void imap_ial_out(struct internet_address_list *ialist);
+long imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf);
int imap_roomname(char *buf, int bufsize, const char *foldername);
int imap_is_message_set(const char *);
int imap_mailbox_matches_pattern(const char *pattern, char *mailboxname);
void IPutStr(const char *Msg, long Len);
#define IPutCStr(_ConstStr) IPutStr(CKEY(_ConstStr))
#define IPutCParamStr(n) IPutStr(CKEY(Params[n]))
-
+#define IPutMsgField(Which) IPutStr(CM_KEY(msg, Which))
void IUnbuffer (void);
*/
void imap_namespace(int num_parms, ConstStr *Params)
{
+ long len;
int i;
struct floor *fl;
int floors = 0;
if (fl->f_flags & F_INUSE) {
/* if (floors > 0) IAPuts(" "); samjam says this confuses javamail */
IAPuts("(");
- snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name);
- plain_imap_strout(Namespace);
+ len = snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name);
+ IPutStr(Namespace, len);
IAPuts(" \"/\")");
++floors;
}
*/
void imap_status(int num_parms, ConstStr *Params)
{
+ long len;
int ret;
char roomname[ROOMNAMELEN];
char imaproomname[SIZ];
* names and simply spew all possible data items. It's far easier to
* code and probably saves us some processing time too.
*/
- imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room);
+ len = imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room);
IAPuts("* STATUS ");
- plain_imap_strout(imaproomname);
+ IPutStr(imaproomname, len);
IAPrintf(" (MESSAGES %d ", msgs);
IAPrintf("RECENT %d ", new); /* Initially, new==recent */
IAPrintf("UIDNEXT %ld ", CitControl.MMhighest + 1);
void CM_FreeContents (struct CtdlMessage *msg);
int CM_IsValidMsg (struct CtdlMessage *msg);
+#define CM_KEY(Message, Which) Message->cm_fields[Which], Message->cm_lengths[Which]
+
void CtdlSerializeMessage(struct ser_ret *, struct CtdlMessage *);
void ReplicationChecks(struct CtdlMessage *);
int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs,