#include "genstamp.h"
#include "internet_addressing.h"
-#define desired_section ((char *)CtdlGetUserData(SYM_DESIRED_SECTION))
-#define ma ((struct ma_info *)CtdlGetUserData(SYM_MA_INFO))
-#define msg_repl ((struct repl *)CtdlGetUserData(SYM_REPL))
-
extern struct config config;
long config_msgnum;
template = (struct CtdlMessage *)
malloc(sizeof(struct CtdlMessage));
memset(template, 0, sizeof(struct CtdlMessage));
- while(client_gets(buf), strcmp(buf,"000")) {
+ while(client_getln(buf, sizeof buf), strcmp(buf,"000")) {
extract(tfield, buf, 0);
extract(tvalue, buf, 1);
for (i='A'; i<='Z'; ++i) if (msgkeys[i]!=NULL) {
return;
/* ...or if this is not the desired section */
- if (strcasecmp(desired_section, partnum))
+ if (strcasecmp(CC->download_desired_section, partnum))
return;
CC->download_fp = tmpfile();
void *content, char *cbtype, size_t length, char *encoding,
void *cbuserdata)
{
- lprintf(CTDL_DEBUG, "fixed_output_pre() type=<%s>\n", cbtype);
- if (!strcasecmp(cbtype, "multipart/alternative")) {
- ++ma->is_ma;
- ma->did_print = 0;
- return;
- }
+ struct ma_info *ma;
+
+ ma = (struct ma_info *)cbuserdata;
+ lprintf(CTDL_DEBUG, "fixed_output_pre() type=<%s>\n", cbtype);
+ if (!strcasecmp(cbtype, "multipart/alternative")) {
+ ++ma->is_ma;
+ ma->did_print = 0;
+ return;
+ }
}
/*
void *content, char *cbtype, size_t length, char *encoding,
void *cbuserdata)
{
- lprintf(CTDL_DEBUG, "fixed_output_post() type=<%s>\n", cbtype);
- if (!strcasecmp(cbtype, "multipart/alternative")) {
- --ma->is_ma;
- ma->did_print = 0;
- return;
- }
+ struct ma_info *ma;
+
+ ma = (struct ma_info *)cbuserdata;
+ lprintf(CTDL_DEBUG, "fixed_output_post() type=<%s>\n", cbtype);
+ if (!strcasecmp(cbtype, "multipart/alternative")) {
+ --ma->is_ma;
+ ma->did_print = 0;
+ return;
+ }
}
/*
char *ptr;
char *wptr;
size_t wlen;
+ struct ma_info *ma;
+
+ ma = (struct ma_info *)cbuserdata;
lprintf(CTDL_DEBUG, "fixed_output() type=<%s>\n", cbtype);
{
char buf[SIZ];
int i;
+ struct ma_info *ma;
+
+ ma = (struct ma_info *)cbuserdata;
if (ma->is_ma > 0) {
for (i=0; i<num_tokens(CC->preferred_formats, '|'); ++i) {
char buf[SIZ];
int add_newline = 0;
char *text_content;
+ struct ma_info *ma;
+
+ ma = (struct ma_info *)cbuserdata;
/* This is not the MIME part you're looking for... */
if (strcasecmp(partnum, ma->chosen_part)) return;
char *nl; /* newline string */
int suppress_f = 0;
int subject_found = 0;
+ struct ma_info *ma;
/* buffers needed for RFC822 translation */
char suser[SIZ];
} else {
/* Parse the message text component */
mptr = TheMessage->cm_fields['M'];
- mime_parser(mptr, NULL,
- *mime_download, NULL, NULL,
- NULL, 0);
+ ma = malloc(sizeof(struct ma_info));
+ memset(ma, 0, sizeof(struct ma_info));
+ mime_parser(mptr, NULL, *mime_download, NULL, NULL, (void *)ma, 0);
+ free(ma);
/* If there's no file open by this time, the requested
* section wasn't found, so print an error
*/
if (do_proto) cprintf(
"%d Section %s not found.\n",
ERROR + FILE_NOT_FOUND,
- desired_section);
+ CC->download_desired_section);
}
}
return((CC->download_fp != NULL) ? om_ok : om_mime_error);
* we use will display those parts as-is.
*/
if (TheMessage->cm_format_type == FMT_RFC822) {
- CtdlAllocUserData(SYM_MA_INFO, sizeof(struct ma_info));
- memset(ma, 0, sizeof(struct ma_info));
if (mode == MT_MIME) {
+ ma = malloc(sizeof(struct ma_info));
+ memset(ma, 0, sizeof(struct ma_info));
strcpy(ma->chosen_part, "1");
mime_parser(mptr, NULL,
*choose_preferred, *fixed_output_pre,
- *fixed_output_post, NULL, 0);
+ *fixed_output_post, (void *)ma, 0);
mime_parser(mptr, NULL,
- *output_preferred, NULL, NULL, NULL, 0);
+ *output_preferred, NULL, NULL, (void *)ma, 0);
+ free(ma);
}
else {
mime_parser(mptr, NULL,
void cmd_opna(char *cmdbuf)
{
long msgid;
-
- CtdlAllocUserData(SYM_DESIRED_SECTION, SIZ);
+ char desired_section[SIZ];
msgid = extract_long(cmdbuf, 0);
extract(desired_section, cmdbuf, 1);
+ safestrncpy(CC->download_desired_section, desired_section, sizeof CC->download_desired_section);
CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1);
}
* Back end for the ReplicationChecks() function
*/
void check_repl(long msgnum, void *userdata) {
- struct CtdlMessage *msg;
- time_t timestamp = (-1L);
-
- lprintf(CTDL_DEBUG, "check_repl() found message %ld\n", msgnum);
- msg = CtdlFetchMessage(msgnum, 1);
- if (msg == NULL) return;
- if (msg->cm_fields['T'] != NULL) {
- timestamp = atol(msg->cm_fields['T']);
- }
- CtdlFreeMessage(msg);
-
- if (timestamp > msg_repl->highest) {
- msg_repl->highest = timestamp; /* newer! */
- lprintf(CTDL_DEBUG, "newer!\n");
- return;
- }
- lprintf(CTDL_DEBUG, "older!\n");
-
- /* Existing isn't newer? Then delete the old one(s). */
+ lprintf(CTDL_DEBUG, "check_repl() replacing message %ld\n", msgnum);
CtdlDeleteMessages(CC->room.QRname, msgnum, "");
}
/*
- * Check to see if any messages already exist which carry the same Extended ID
- * as this one.
+ * Check to see if any messages already exist which carry the same Exclusive ID
+ * as this one. If any are found, delete them.
*
- * If any are found:
- * -> With older timestamps: delete them and return 0. Message will be saved.
- * -> With newer timestamps: return 1. Message save will be aborted.
*/
int ReplicationChecks(struct CtdlMessage *msg) {
struct CtdlMessage *template;
int abort_this = 0;
- lprintf(CTDL_DEBUG, "ReplicationChecks() started\n");
- /* No extended id? Don't do anything. */
+ /* No exclusive id? Don't do anything. */
if (msg->cm_fields['E'] == NULL) return 0;
if (strlen(msg->cm_fields['E']) == 0) return 0;
- lprintf(CTDL_DEBUG, "Extended ID: <%s>\n", msg->cm_fields['E']);
-
- CtdlAllocUserData(SYM_REPL, sizeof(struct repl));
- strcpy(msg_repl->extended_id, msg->cm_fields['E']);
- msg_repl->highest = atol(msg->cm_fields['T']);
+ lprintf(CTDL_DEBUG, "Exclusive ID: <%s>\n", msg->cm_fields['E']);
template = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
memset(template, 0, sizeof(struct CtdlMessage));
CtdlForEachMessage(MSGS_ALL, 0L, NULL, template, check_repl, NULL);
- /* If a newer message exists with the same Extended ID, abort
- * this save.
- */
- if (msg_repl->highest > atol(msg->cm_fields['T']) ) {
- abort_this = 1;
- }
-
CtdlFreeMessage(template);
lprintf(CTDL_DEBUG, "ReplicationChecks() returning %d\n", abort_this);
return(abort_this);
lprintf(CTDL_DEBUG, "Learning what's inside\n");
if (msg->cm_fields['M'] == NULL) {
lprintf(CTDL_ERR, "ERROR: attempt to save message with NULL body\n");
- return(-1);
+ return(-2);
}
switch (msg->cm_format_type) {
break;
case 4:
strcpy(content_type, "text/plain");
- /* advance past header fields */
- mptr = msg->cm_fields['M'];
- a = strlen(mptr);
- while ((--a) > 0) {
- if (!strncasecmp(mptr, "Content-type: ", 14)) {
- safestrncpy(content_type, mptr,
- sizeof(content_type));
- strcpy(content_type, &content_type[14]);
- for (a = 0; a < strlen(content_type); ++a)
- if ((content_type[a] == ';')
- || (content_type[a] == ' ')
- || (content_type[a] == 13)
- || (content_type[a] == 10))
- content_type[a] = 0;
- break;
+ mptr = bmstrstr(msg->cm_fields['M'],
+ "Content-type: ", strncasecmp);
+ if (mptr != NULL) {
+ safestrncpy(content_type, &mptr[14],
+ sizeof content_type);
+ for (a = 0; a < strlen(content_type); ++a) {
+ if ((content_type[a] == ';')
+ || (content_type[a] == ' ')
+ || (content_type[a] == 13)
+ || (content_type[a] == 10)) {
+ content_type[a] = 0;
+ }
}
- ++mptr;
}
}
/* Goto the correct room */
- lprintf(CTDL_DEBUG, "Selected room %s\n", (recps) ? CC->room.QRname : SENTITEMS);
+ lprintf(CTDL_DEBUG, "Selected room %s\n",
+ (recps) ? CC->room.QRname : SENTITEMS);
strcpy(hold_rm, CC->room.QRname);
strcpy(actual_rm, CC->room.QRname);
if (recps != NULL) {
/* Perform "before save" hooks (aborting if any return nonzero) */
lprintf(CTDL_DEBUG, "Performing before-save hooks\n");
- if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return(-1);
+ if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return(-3);
- /* If this message has an Extended ID, perform replication checks */
+ /* If this message has an Exclusive ID, perform replication checks */
lprintf(CTDL_DEBUG, "Performing replication checks\n");
- if (ReplicationChecks(msg) > 0) return(-1);
+ if (ReplicationChecks(msg) > 0) return(-4);
/* Save it to disk */
lprintf(CTDL_DEBUG, "Saving to disk\n");
newmsgid = send_message(msg);
- if (newmsgid <= 0L) return(-1);
+ if (newmsgid <= 0L) return(-5);
/* Write a supplemental message info record. This doesn't have to
* be a critical section because nobody else knows about this message
/* read in the lines of message text one by one */
do {
- if (client_gets(buf) < 1) finished = 1;
+ if (client_getln(buf, sizeof buf) < 1) finished = 1;
if (!strcmp(buf, terminator)) finished = 1;
if (crlf) {
strcat(buf, "\r\n");
int err = 0;
struct recptypes *valid = NULL;
char subject[SIZ];
+ int do_confirm = 0;
+ long msgnum;
unbuffer_output();
anon_flag = extract_int(entargs, 2);
format_type = extract_int(entargs, 3);
extract(subject, entargs, 4);
+ do_confirm = extract_int(entargs, 6);
/* first check to make sure the request is valid. */
}
/* Read in the message from the client. */
- cprintf("%d send message\n", SEND_LISTING);
+ if (do_confirm) {
+ cprintf("%d send message\n", START_CHAT_MODE);
+ } else {
+ cprintf("%d send message\n", SEND_LISTING);
+ }
msg = CtdlMakeMessage(&CC->user, recp,
CC->room.QRname, anonymous, format_type,
masquerade_as, subject, NULL);
if (msg != NULL) {
- CtdlSubmitMsg(msg, valid, "");
+ msgnum = CtdlSubmitMsg(msg, valid, "");
+
+ if (do_confirm) {
+ cprintf("%ld\n", msgnum);
+ if (msgnum >= 0L) {
+ cprintf("Message accepted.\n");
+ }
+ else {
+ cprintf("Internal error.\n");
+ }
+ if (msg->cm_fields['E'] != NULL) {
+ cprintf("%s\n", msg->cm_fields['E']);
+ } else {
+ cprintf("\n");
+ }
+ cprintf("000\n");
+ }
+
CtdlFreeMessage(msg);
}
CC->fake_postname[0] = '\0';
}
getuser(&CC->user, CC->curr_user);
- ra = CtdlRoomAccess(&qtemp, &CC->user);
+ CtdlRoomAccess(&qtemp, &CC->user, &ra, NULL);
/* Check for permission to perform this operation.
* Remember: "CC->room" is source, "qtemp" is target.