"hnod",
"msgn",
"jrnl",
- NULL, NULL,
+ NULL,
+ "list",
"text",
"node",
"room",
int was_seen = 0;
long lo = (-1L);
long hi = (-1L);
- long t = (-1L);
- int trimming = 0;
struct visit vbuf;
long *msglist;
int num_msgs = 0;
char *is_set; /* actually an array of booleans */
int num_sets;
int s;
+ int w = 0;
char setstr[SIZ], lostr[SIZ], histr[SIZ];
- size_t tmp;
/* Don't bother doing *anything* if we were passed a list of zero messages */
if (num_target_msgnums < 1) {
return;
}
- CtdlLogPrintf(CTDL_DEBUG, "CtdlSetSeen(%d msgs starting with %ld, %d, %d)\n",
+ /* If no room was specified, we go with the current room. */
+ if (!which_room) {
+ which_room = &CC->room;
+ }
+
+ /* If no user was specified, we go with the current user. */
+ if (!which_user) {
+ which_user = &CC->user;
+ }
+
+ CtdlLogPrintf(CTDL_DEBUG, "CtdlSetSeen(%d msgs starting with %ld, %s, %d) in <%s>\n",
num_target_msgnums, target_msgnums[0],
- target_setting, which_set);
+ (target_setting ? "SET" : "CLEAR"),
+ which_set,
+ which_room->QRname);
/* Learn about the user and room in question */
- CtdlGetRelationship(&vbuf,
- ((which_user != NULL) ? which_user : &CC->user),
- ((which_room != NULL) ? which_room : &CC->room)
- );
+ CtdlGetRelationship(&vbuf, which_user, which_room);
/* Load the message list */
- cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &which_room->QRnumber, sizeof(long));
if (cdbfr != NULL) {
msglist = (long *) cdbfr->ptr;
cdbfr->ptr = NULL; /* CtdlSetSeen() now owns this memory */
break;
}
- /* CtdlLogPrintf(CTDL_DEBUG, "before optimize: %s\n", vset); */
+
+#if 0 /* This is a special diagnostic section. Do not allow it to run during normal operation. */
+ CtdlLogPrintf(CTDL_DEBUG, "There are %d messages in the room.\n", num_msgs);
+ for (i=0; i<num_msgs; ++i) {
+ if (i > 0) if (msglist[i] <= msglist[i-1]) abort();
+ }
+ CtdlLogPrintf(CTDL_DEBUG, "We are twiddling %d of them.\n", num_target_msgnums);
+ for (k=0; k<num_target_msgnums; ++k) {
+ if (k > 0) if (target_msgnums[k] <= target_msgnums[k-1]) abort();
+ }
+#endif
+
+ CtdlLogPrintf(CTDL_DEBUG, "before update: %s\n", vset);
/* Translate the existing sequence set into an array of booleans */
num_sets = num_tokens(vset, ',');
extract_token(lostr, setstr, 0, ':', sizeof lostr);
if (num_tokens(setstr, ':') >= 2) {
extract_token(histr, setstr, 1, ':', sizeof histr);
- if (!strcmp(histr, "*")) {
- snprintf(histr, sizeof histr, "%ld", LONG_MAX);
- }
}
else {
strcpy(histr, lostr);
}
lo = atol(lostr);
- hi = atol(histr);
+ if (!strcmp(histr, "*")) {
+ hi = LONG_MAX;
+ }
+ else {
+ hi = atol(histr);
+ }
for (i = 0; i < num_msgs; ++i) {
if ((msglist[i] >= lo) && (msglist[i] <= hi)) {
}
}
+
/* Now translate the array of booleans back into a sequence set */
strcpy(vset, "");
- lo = (-1L);
- hi = (-1L);
+ was_seen = 0;
+ lo = (-1);
+ hi = (-1);
for (i=0; i<num_msgs; ++i) {
+ is_seen = is_set[i];
- is_seen = is_set[i]; /* Default to existing setting */
-
+ /* Apply changes */
for (k=0; k<num_target_msgnums; ++k) {
if (msglist[i] == target_msgnums[k]) {
is_seen = target_setting;
}
}
- if (is_seen) {
- if (lo < 0L) lo = msglist[i];
- hi = msglist[i];
- }
+ w = 0; /* set to 1 if we write something to the string */
- if ( ((is_seen == 0) && (was_seen == 1))
- || ((is_seen == 1) && (i == num_msgs-1)) ) {
+ if ((was_seen == 0) && (is_seen == 1)) {
+ lo = msglist[i];
+ }
+ else if ((was_seen == 1) && (is_seen == 0)) {
+ hi = msglist[i-1];
+ w = 1;
- /* begin trim-o-matic code */
- j=9;
- trimming = 0;
- while ( (strlen(vset) + 20) > sizeof vset) {
- remove_token(vset, 0, ',');
- trimming = 1;
- if (j--) break; /* loop no more than 9 times */
+ if (!IsEmptyStr(vset)) {
+ strcat(vset, ",");
}
- if ( (trimming) && (which_set == ctdlsetseen_seen) ) {
- t = atol(vset);
- if (t<2) t=2;
- --t;
- snprintf(lostr, sizeof lostr,
- "1:%ld,%s", t, vset);
- safestrncpy(vset, lostr, sizeof vset);
+ if (lo == hi) {
+ sprintf(&vset[strlen(vset)], "%ld", hi);
}
- /* end trim-o-matic code */
-
- tmp = strlen(vset);
- if (tmp > 0) {
+ else {
+ sprintf(&vset[strlen(vset)], "%ld:%ld", lo, hi);
+ }
+ }
+ else if ((is_seen) && (i == num_msgs - 1)) {
+ w = 1;
+ if (!IsEmptyStr(vset)) {
strcat(vset, ",");
- ++tmp;
}
- if (lo == hi) {
- snprintf(&vset[tmp], (sizeof vset) - tmp,
- "%ld", lo);
+ if ((i==0) || (was_seen == 0)) {
+ sprintf(&vset[strlen(vset)], "%ld", msglist[i]);
}
else {
- snprintf(&vset[tmp], (sizeof vset) - tmp,
- "%ld:%ld", lo, hi);
+ sprintf(&vset[strlen(vset)], "%ld:%ld", lo, msglist[i]);
+ }
+ }
+
+ /* If the string is getting too long, truncate it at the beginning; repeat up to 9 times */
+ if (w) for (j=0; j<9; ++j) {
+ if ((strlen(vset) + 20) > sizeof vset) {
+ remove_token(vset, 0, ',');
+ if (which_set == ctdlsetseen_seen) {
+ char temp[SIZ];
+ sprintf(temp, "1:%ld,", atol(vset)-1L);
+ strcat(temp, vset);
+ strcpy(vset, temp);
+ }
}
- lo = (-1L);
- hi = (-1L);
}
+
was_seen = is_seen;
}
+ CtdlLogPrintf(CTDL_DEBUG, " after update: %s\n", vset);
+
/* Decide which message set we're manipulating */
switch (which_set) {
case ctdlsetseen_seen:
safestrncpy(vbuf.v_seen, vset, sizeof vbuf.v_seen);
break;
case ctdlsetseen_answered:
- safestrncpy(vbuf.v_answered, vset,
- sizeof vbuf.v_answered);
+ safestrncpy(vbuf.v_answered, vset, sizeof vbuf.v_answered);
break;
}
- free(is_set);
- /* CtdlLogPrintf(CTDL_DEBUG, " after optimize: %s\n", vset); */
+ free(is_set);
free(msglist);
- CtdlSetRelationship(&vbuf,
- ((which_user != NULL) ? which_user : &CC->user),
- ((which_room != NULL) ? which_room : &CC->room)
- );
+ CtdlSetRelationship(&vbuf, which_user, which_room);
}
*/
void list_this_part(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
- void *cbuserdata)
+ char *cbid, void *cbuserdata)
{
struct ma_info *ma;
ma = (struct ma_info *)cbuserdata;
if (ma->is_ma == 0) {
- cprintf("part=%s|%s|%s|%s|%s|%ld\n",
- name, filename, partnum, disp, cbtype, (long)length);
+ cprintf("part=%s|%s|%s|%s|%s|%ld|%s\n",
+ name, filename, partnum, disp, cbtype, (long)length, cbid);
}
}
*/
void list_this_pref(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
- void *cbuserdata)
+ char *cbid, void *cbuserdata)
{
struct ma_info *ma;
*/
void list_this_suff(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
- void *cbuserdata)
+ char *cbid, void *cbuserdata)
{
struct ma_info *ma;
*/
void mime_download(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
- /* Silently go away if there's already a download open... */
+ /* Silently go away if there's already a download open. */
if (CC->download_fp != NULL)
return;
- /* ...or if this is not the desired section */
- if (strcasecmp(CC->download_desired_section, partnum))
- return;
-
- CC->download_fp = tmpfile();
- if (CC->download_fp == NULL)
- return;
-
- fwrite(content, length, 1, CC->download_fp);
- fflush(CC->download_fp);
- rewind(CC->download_fp);
-
- OpenCmdResult(filename, cbtype);
+ if (
+ (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
+ || (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
+ ) {
+ CC->download_fp = tmpfile();
+ if (CC->download_fp == NULL)
+ return;
+
+ fwrite(content, length, 1, CC->download_fp);
+ fflush(CC->download_fp);
+ rewind(CC->download_fp);
+
+ OpenCmdResult(filename, cbtype);
+ }
}
/*
- * Callback function for mime parser that outputs a section all at once
+ * Callback function for mime parser that outputs a section all at once.
+ * We can specify the desired section by part number *or* content-id.
*/
void mime_spew_section(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
int *found_it = (int *)cbuserdata;
- /* ...or if this is not the desired section */
- if (strcasecmp(CC->download_desired_section, partnum))
- return;
-
- *found_it = 1;
-
- cprintf("%d %d\n", BINARY_FOLLOWS, (int)length);
- client_write(content, length);
+ if (
+ (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
+ || (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
+ ) {
+ *found_it = 1;
+ cprintf("%d %d\n", BINARY_FOLLOWS, (int)length);
+ client_write(content, length);
+ }
}
*/
void fixed_output_pre(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
- void *cbuserdata)
+ char *cbid, void *cbuserdata)
{
struct ma_info *ma;
*/
void fixed_output_post(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
struct ma_info *ma;
*/
void fixed_output(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
char *ptr;
char *wptr;
*/
void choose_preferred(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
char buf[1024];
int i;
*/
void output_preferred(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
int i;
char buf[128];
/* No translations required or possible: output as text/plain */
cprintf("Content-type: text/plain\n\n");
fixed_output(name, filename, partnum, disp, content, cbtype, cbcharset,
- length, encoding, cbuserdata);
+ length, encoding, cbid, cbuserdata);
}
*/
void extract_encapsulated_message(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
- char *encoding, void *cbuserdata)
+ char *encoding, char *cbid, void *cbuserdata)
{
struct encapmsg *encap;
*
*/
int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */
- int mode, /* how would you like that message? */
- int headers_only, /* eschew the message body? */
- int do_proto, /* do Citadel protocol responses? */
- int crlf, /* Use CRLF newlines instead of LF? */
- char *section /* NULL or a message/rfc822 section */
+ int mode, /* how would you like that message? */
+ int headers_only, /* eschew the message body? */
+ int do_proto, /* do Citadel protocol responses? */
+ int crlf, /* Use CRLF newlines instead of LF? */
+ char *section, /* NULL or a message/rfc822 section */
+ int flags /* should the bessage be exported clean? */
) {
struct CtdlMessage *TheMessage = NULL;
int retcode = om_no_such_msg;
/* FIXME: check message id against msglist for this room */
/*
- * Fetch the message from disk. If we're in any sort of headers
- * only mode, request that we don't even bother loading the body
- * into memory.
+ * Fetch the message from disk. If we're in HEADERS_FAST mode,
+ * request that we don't even bother loading the body into memory.
*/
- if ( (headers_only == HEADERS_FAST) || (headers_only == HEADERS_ONLY) ) {
+ if (headers_only == HEADERS_FAST) {
TheMessage = CtdlFetchMessage(msg_num, 0);
}
else {
}
/* Ok, output the message now */
- retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf);
+ retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags);
CtdlFreeMessage(TheMessage);
return(retcode);
}
+
char *qp_encode_email_addrs(char *source)
{
char user[256], node[256], name[256];
int InQuotes = 0;
int i, n;
-
- if (source == NULL)
- return source;
+ if (source == NULL) return source;
+ if (IsEmptyStr(source)) return source;
AddrPtr = malloc (sizeof (long) * nAddrPtrMax);
AddrUtf8 = malloc (sizeof (long) * nAddrPtrMax);
*AddrPtr = 0;
i = 0;
while (!IsEmptyStr (&source[i])) {
- if (nColons > nAddrPtrMax){
+ if (nColons >= nAddrPtrMax){
long *ptr;
ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
memcpy (ptr, AddrPtr, sizeof (long) * nAddrPtrMax);
free (AddrPtr), AddrPtr = ptr;
+
ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
- memset(ptr + sizeof (long) * nAddrPtrMax, 0, sizeof (long) * nAddrPtrMax - 1);
+ memset(&ptr[nAddrPtrMax], 0,
+ sizeof (long) * nAddrPtrMax);
+
memcpy (ptr, AddrUtf8, sizeof (long) * nAddrPtrMax);
free (AddrUtf8), AddrUtf8 = ptr;
nAddrPtrMax *= 2;
if (source[i] == '"')
InQuotes = !InQuotes;
if (!InQuotes && source[i] == ',') {
- nColons++;
AddrPtr[nColons] = i;
+ nColons++;
}
i++;
}
EncodedMaxLen = nColons * (sizeof(headerStr) + 3) + SourceLen * 3;
Encoded = (char*) malloc (EncodedMaxLen);
- for (i = 1; i <= nColons; i++)
+ for (i = 0; i < nColons; i++)
source[AddrPtr[i]++] = '\0';
nPtr = Encoded;
*nPtr = '\0';
- for (i = 0; i <= nColons && nPtr != NULL; i++) {
+ for (i = 0; i < nColons && nPtr != NULL; i++) {
nmax = EncodedMaxLen - (nPtr - Encoded);
if (AddrUtf8[i]) {
process_rfc822_addr(&source[AddrPtr[i]],
i--; /* do it once more with properly lengthened buffer */
}
}
- for (i = 1; i <= nColons; i++)
+ for (i = 0; i < nColons; i++)
source[--AddrPtr[i]] = ',';
free(AddrUtf8);
free(AddrPtr);
return Encoded;
}
+
/*
* Get a message off disk. (returns om_* values found in msgbase.h)
*/
int mode, /* how would you like that message? */
int headers_only, /* eschew the message body? */
int do_proto, /* do Citadel protocol responses? */
- int crlf /* Use CRLF newlines instead of LF? */
+ int crlf, /* Use CRLF newlines instead of LF? */
+ int flags /* should the bessage be exported clean? */
) {
int i, j, k;
char buf[SIZ];
- cit_uint8_t ch;
+ cit_uint8_t ch, prev_ch;
char allkeys[30];
char display_name[256];
char *mptr, *mpptr;
if (!is_valid_message(TheMessage)) {
CtdlLogPrintf(CTDL_ERR,
"ERROR: invalid preloaded message for output\n");
+ cit_backtrace ();
return(om_no_such_msg);
}
safestrncpy(suser, mptr, sizeof suser);
}
else if (i == 'Y') {
- mptr = qp_encode_email_addrs(mptr);
+ if ((flags & QP_EADDR) != 0)
+ mptr = qp_encode_email_addrs(mptr);
cprintf("CC: %s%s", mptr, nl);
}
else if (i == 'P') {
cprintf("Return-Path: %s%s", mptr, nl);
}
+ else if (i == 'L') {
+ cprintf("List-ID: %s%s", mptr, nl);
+ }
else if (i == 'V') {
- mptr = qp_encode_email_addrs(mptr);
+ if ((flags & QP_EADDR) != 0)
+ mptr = qp_encode_email_addrs(mptr);
cprintf("Envelope-To: %s%s", mptr, nl);
}
else if (i == 'U') {
}
else
{
- mptr = qp_encode_email_addrs(mptr);
+ if ((flags & QP_EADDR) != 0)
+ mptr = qp_encode_email_addrs(mptr);
cprintf("To: %s%s", mptr, nl);
}
}
char outbuf[1024];
int outlen = 0;
int nllen = strlen(nl);
+ prev_ch = 0;
while (ch=*mptr, ch!=0) {
if (ch==13) {
/* do nothing */
}
}
}
+ if (flags & ESC_DOT)
+ {
+ if ((prev_ch == 10) && (ch == '.') && ((*(mptr+1) == 13) || (*(mptr+1) == 10)))
+ {
+ outbuf[outlen++] = '.';
+ }
+ }
+ prev_ch = ch;
++mptr;
if (outlen > 1000) {
client_write(outbuf, outlen);
msgid = extract_long(cmdbuf, 0);
headers_only = extract_int(cmdbuf, 1);
- CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL);
+ CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL, 0);
return;
}
msgid = extract_long(cmdbuf, 0);
headers_only = extract_int(cmdbuf, 1);
- CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL);
+ CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL, 0);
}
msgid = extract_long(cmdbuf, 0);
extract_token(section, cmdbuf, 1, '|', sizeof section);
- CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) );
+ CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) , 0);
}
extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section);
safestrncpy(CC->download_desired_section, desired_section,
sizeof CC->download_desired_section);
- CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL);
+ CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL, 0);
}
extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section);
safestrncpy(CC->download_desired_section, desired_section,
sizeof CC->download_desired_section);
- CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL);
+ CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL, 0);
}
* Save a message to disk and submit it into the delivery system.
*/
long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */
- struct recptypes *recps, /* recipients (if mail) */
- char *force /* force a particular room? */
+ struct recptypes *recps, /* recipients (if mail) */
+ char *force, /* force a particular room? */
+ int flags /* should the bessage be exported clean? */
) {
char submit_filename[128];
char generated_timestamp[32];
char *saved_rfc822_version = NULL;
int qualified_for_journaling = 0;
struct CitContext *CCC = CC; /* CachedCitContext - performance boost */
+ char bounce_to[1024] = "";
CtdlLogPrintf(CTDL_DEBUG, "CtdlSubmitMsg() called\n");
if (is_valid_message(msg) == 0) return(-1); /* self check */
CCC->redirect_buffer = malloc(SIZ);
CCC->redirect_len = 0;
CCC->redirect_alloc = SIZ;
- CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1);
+ CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR);
smi.meta_rfc822_length = CCC->redirect_len;
saved_rfc822_version = CCC->redirect_buffer;
CCC->redirect_buffer = NULL;
CCC->user.posted = CCC->user.posted + 1;
lputuser(&CCC->user);
+ /* Decide where bounces need to be delivered */
+ if (CCC->logged_in) {
+ snprintf(bounce_to, sizeof bounce_to, "%s@%s", CCC->user.fullname, config.c_nodename);
+ }
+ else {
+ snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields['A'], msg->cm_fields['N']);
+ }
+
/* If this is private, local mail, make a copy in the
* recipient's mailbox and bump the reference count.
*/
instr = malloc(instr_alloc);
snprintf(instr, instr_alloc,
"Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
- "bounceto|%s@%s\n",
+ "bounceto|%s\n",
SPOOLMIME, newmsgid, (long)time(NULL),
- msg->cm_fields['A'], msg->cm_fields['N']
+ bounce_to
);
imsg = malloc(sizeof(struct CtdlMessage));
imsg->cm_fields['J'] = strdup("do not journal");
imsg->cm_fields['M'] = instr; /* imsg owns this memory now */
imsg->cm_fields['W'] = strdup(recipient);
- CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM);
+ CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM, 0);
CtdlFreeMessage(imsg);
}
}
instr = malloc(instr_alloc);
snprintf(instr, instr_alloc,
"Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
- "bounceto|%s@%s\n",
+ "bounceto|%s\n",
SPOOLMIME, newmsgid, (long)time(NULL),
- msg->cm_fields['A'], msg->cm_fields['N']
+ bounce_to
);
for (i=0; i<num_tokens(recps->recp_internet, '|'); ++i) {
imsg->cm_fields['A'] = strdup("Citadel");
imsg->cm_fields['J'] = strdup("do not journal");
imsg->cm_fields['M'] = instr; /* imsg owns this memory now */
- CtdlSubmitMsg(imsg, NULL, SMTP_SPOOLOUT_ROOM);
+ CtdlSubmitMsg(imsg, NULL, SMTP_SPOOLOUT_ROOM, QP_EADDR);
CtdlFreeMessage(imsg);
}
}
if (collected_addresses != NULL) {
- begin_critical_section(S_ATBF);
aptr = (struct addresses_to_be_filed *)
malloc(sizeof(struct addresses_to_be_filed));
- aptr->next = atbf;
MailboxName(actual_rm, sizeof actual_rm,
&CCC->user, USERCONTACTSROOM);
aptr->roomname = strdup(actual_rm);
aptr->collected_addresses = collected_addresses;
+ begin_critical_section(S_ATBF);
+ aptr->next = atbf;
atbf = aptr;
end_critical_section(S_ATBF);
}
}
msg->cm_fields['M'] = strdup(text);
- CtdlSubmitMsg(msg, recp, room);
+ CtdlSubmitMsg(msg, recp, room, 0);
CtdlFreeMessage(msg);
if (recp != NULL) free_recipients(recp);
}
free(all_recps);
if (msg != NULL) {
- msgnum = CtdlSubmitMsg(msg, valid, "");
+ msgnum = CtdlSubmitMsg(msg, valid, "", QP_EADDR);
if (do_confirm) {
cprintf("%ld\n", msgnum);
struct arcq arcq_rec;
int num_records_processed = 0;
- snprintf(file_arcq_temp, sizeof file_arcq_temp, "%s2", file_arcq);
+ snprintf(file_arcq_temp, sizeof file_arcq_temp, "%s.%04x", file_arcq, rand());
begin_critical_section(S_SUPPMSGMAIN);
if (arcfp != NULL) {
smi.meta_refcount += incr;
PutMetaData(&smi);
end_critical_section(S_SUPPMSGMAIN);
- CtdlLogPrintf(CTDL_DEBUG, "msg %ld ref count delta %d, is now %d\n",
+ CtdlLogPrintf(CTDL_DEBUG, "msg %ld ref count delta %+d, is now %d\n",
msgnum, incr, smi.meta_refcount);
/* If the reference count is now zero, delete the message
* Note: this could be much more efficient. Right now we use two temporary
* files, and still pull the message into memory as with all others.
*/
-void CtdlWriteObject(char *req_room, /* Room to stuff it in */
- char *content_type, /* MIME type of this object */
- char *tempfilename, /* Where to fetch it from */
+void CtdlWriteObject(char *req_room, /* Room to stuff it in */
+ char *content_type, /* MIME type of this object */
+ char *raw_message, /* Data to be written */
+ off_t raw_length, /* Size of raw_message */
struct ctdluser *is_mailbox, /* Mailbox room? */
- int is_binary, /* Is encoding necessary? */
- int is_unique, /* Del others of this type? */
- unsigned int flags /* Internal save flags */
+ int is_binary, /* Is encoding necessary? */
+ int is_unique, /* Del others of this type? */
+ unsigned int flags /* Internal save flags */
)
{
- FILE *fp;
struct ctdlroom qrbuf;
char roomname[ROOMNAMELEN];
struct CtdlMessage *msg;
-
- char *raw_message = NULL;
char *encoded_message = NULL;
- off_t raw_length = 0;
if (is_mailbox != NULL) {
MailboxName(roomname, sizeof roomname, is_mailbox, req_room);
safestrncpy(roomname, req_room, sizeof(roomname));
}
- fp = fopen(tempfilename, "rb");
- if (fp == NULL) {
- CtdlLogPrintf(CTDL_CRIT, "Cannot open %s: %s\n",
- tempfilename, strerror(errno));
- return;
- }
- fseek(fp, 0L, SEEK_END);
- raw_length = ftell(fp);
- rewind(fp);
CtdlLogPrintf(CTDL_DEBUG, "Raw length is %ld\n", (long)raw_length);
- raw_message = malloc((size_t)raw_length + 2);
- fread(raw_message, (size_t)raw_length, 1, fp);
- fclose(fp);
-
if (is_binary) {
- encoded_message = malloc((size_t)
- (((raw_length * 134) / 100) + 4096 ) );
+ encoded_message = malloc((size_t) (((raw_length * 134) / 100) + 4096 ) );
}
else {
encoded_message = malloc((size_t)(raw_length + 4096));
);
}
else {
- raw_message[raw_length] = 0;
memcpy(
&encoded_message[strlen(encoded_message)],
raw_message,
);
}
- free(raw_message);
-
CtdlLogPrintf(CTDL_DEBUG, "Allocating\n");
msg = malloc(sizeof(struct CtdlMessage));
memset(msg, 0, sizeof(struct CtdlMessage));
);
}
/* Now write the data */
- CtdlSubmitMsg(msg, NULL, roomname);
+ CtdlSubmitMsg(msg, NULL, roomname, 0);
CtdlFreeMessage(msg);
}
return(conf);
}
-void CtdlPutSysConfig(char *sysconfname, char *sysconfdata) {
- char temp[PATH_MAX];
- FILE *fp;
-
- CtdlMakeTempFileName(temp, sizeof temp);
- fp = fopen(temp, "w");
- if (fp == NULL) return;
- fprintf(fp, "%s", sysconfdata);
- fclose(fp);
-
- /* this handy API function does all the work for us */
- CtdlWriteObject(SYSCONFIGROOM, sysconfname, temp, NULL, 0, 1, 0);
- unlink(temp);
+void CtdlPutSysConfig(char *sysconfname, char *sysconfdata) {
+ CtdlWriteObject(SYSCONFIGROOM, sysconfname, sysconfdata, (strlen(sysconfdata)+1), NULL, 0, 1, 0);
}