-/*
+/*
* $Id$
*
* Implements the message store.
{
int i;
- for (i = 0; i < strlen(name); ++i)
+ for (i = 0; i < strlen(name); ++i) {
if (name[i] == '@') {
- if (i > 0)
- if (isspace(name[i - 1])) {
- strcpy(&name[i - 1], &name[i]);
- i = 0;
- }
+ while (isspace(name[i - 1]) && i > 0) {
+ strcpy(&name[i - 1], &name[i]);
+ --i;
+ }
while (isspace(name[i + 1])) {
strcpy(&name[i + 1], &name[i + 2]);
}
}
+ }
}
int a, b;
char aaa[300], bbb[300];
- TRACE;
remove_any_whitespace_to_the_left_or_right_of_at_symbol(name);
- TRACE;
fp = fopen("network/mail.aliases", "r");
if (fp == NULL)
fp = fopen("/dev/null", "r");
if (fp == NULL)
return (MES_ERROR);
- TRACE;
strcpy(aaa, "");
strcpy(bbb, "");
while (fgets(aaa, sizeof aaa, fp) != NULL) {
if (!strcasecmp(name, aaa))
strcpy(name, bbb);
}
- TRACE;
fclose(fp);
lprintf(7, "Mail is being forwarded to %s\n", name);
}
/* determine local or remote type, see citadel.h */
- TRACE;
for (a = 0; a < strlen(name); ++a)
if (name[a] == '!')
return (MES_INTERNET);
- TRACE;
for (a = 0; a < strlen(name); ++a)
if (name[a] == '@')
for (b = a; b < strlen(name); ++b)
if (name[b] == '.')
return (MES_INTERNET);
b = 0;
- TRACE;
for (a = 0; a < strlen(name); ++a)
if (name[a] == '@')
++b;
strcpy(bbb, &bbb[1]);
fp = fopen("network/mail.sysinfo", "r");
if (fp == NULL)
- return (MES_ERROR);
+ return (MES_ERROR);
GETSN: do {
a = getstring(fp, aaa);
} while ((a >= 0) && (strcasecmp(aaa, bbb)));
- TRACE;
a = getstring(fp, aaa);
if (!strncmp(aaa, "use ", 4)) {
strcpy(bbb, &aaa[4]);
goto GETSN;
}
fclose(fp);
- TRACE;
if (!strncmp(aaa, "uum", 3)) {
strcpy(bbb, name);
for (a = 0; a < strlen(bbb); ++a) {
}
return (MES_ERROR);
}
- TRACE;
lprintf(9, "returning MES_LOCAL\n");
return (MES_LOCAL);
}
strcpy(buffer, "");
c = 1; /* c is the current pos */
-FMTA: if (subst) {
- while (ch = *mptr, ((ch != 0) && (strlen(buffer) < 126))) {
- ch = *mptr++;
- buffer[strlen(buffer) + 1] = 0;
- buffer[strlen(buffer)] = ch;
- }
-
- if (buffer[0] == '^')
- do_help_subst(buffer);
+ do {
+ if (subst) {
+ while (ch = *mptr, ((ch != 0) && (strlen(buffer) < 126))) {
+ ch = *mptr++;
+ buffer[strlen(buffer) + 1] = 0;
+ buffer[strlen(buffer)] = ch;
+ }
- buffer[strlen(buffer) + 1] = 0;
- a = buffer[0];
- strcpy(buffer, &buffer[1]);
- } else {
- ch = *mptr++;
- }
+ if (buffer[0] == '^')
+ do_help_subst(buffer);
- old = real;
- real = ch;
- if (ch <= 0)
- goto FMTEND;
+ buffer[strlen(buffer) + 1] = 0;
+ a = buffer[0];
+ strcpy(buffer, &buffer[1]);
+ } else {
+ ch = *mptr++;
+ }
- if (((ch == 13) || (ch == 10)) && (old != 13) && (old != 10))
- ch = 32;
- if (((old == 13) || (old == 10)) && (isspace(real))) {
- cprintf("%s", nl);
- c = 1;
- }
- if (ch > 126)
- goto FMTA;
+ old = real;
+ real = ch;
- if (ch > 32) {
- if (((strlen(aaa) + c) > (width - 5)) && (strlen(aaa) > (width - 5))) {
- cprintf("%s%s", nl, aaa);
- c = strlen(aaa);
- aaa[0] = 0;
- }
- b = strlen(aaa);
- aaa[b] = ch;
- aaa[b + 1] = 0;
- }
- if (ch == 32) {
- if ((strlen(aaa) + c) > (width - 5)) {
+ if (((ch == 13) || (ch == 10)) && (old != 13) && (old != 10))
+ ch = 32;
+ if (((old == 13) || (old == 10)) && (isspace(real))) {
cprintf("%s", nl);
c = 1;
}
- cprintf("%s ", aaa);
- ++c;
- c = c + strlen(aaa);
- strcpy(aaa, "");
- goto FMTA;
- }
- if ((ch == 13) || (ch == 10)) {
- cprintf("%s%s", aaa, nl);
- c = 1;
- strcpy(aaa, "");
- goto FMTA;
- }
- goto FMTA;
+ if (ch > 126)
+ continue;
+
+ if (ch > 32) {
+ if (((strlen(aaa) + c) > (width - 5)) && (strlen(aaa) > (width - 5))) {
+ cprintf("%s%s", nl, aaa);
+ c = strlen(aaa);
+ aaa[0] = 0;
+ }
+ b = strlen(aaa);
+ aaa[b] = ch;
+ aaa[b + 1] = 0;
+ }
+ if (ch == 32) {
+ if ((strlen(aaa) + c) > (width - 5)) {
+ cprintf("%s", nl);
+ c = 1;
+ }
+ cprintf("%s ", aaa);
+ ++c;
+ c = c + strlen(aaa);
+ strcpy(aaa, "");
+ }
+ if ((ch == 13) || (ch == 10)) {
+ cprintf("%s%s", aaa, nl);
+ c = 1;
+ strcpy(aaa, "");
+ }
+
+ } while (ch > 0);
-FMTEND: cprintf("%s%s", aaa, nl);
+ cprintf("%s%s", aaa, nl);
}
* Callback function for mime parser that simply lists the part
*/
void list_this_part(char *name, char *filename, char *partnum, char *disp,
- void *content, char *cbtype, size_t length)
+ void *content, char *cbtype, size_t length, char *encoding,
+ void *cbuserdata)
{
cprintf("part=%s|%s|%s|%s|%s|%d\n",
* Callback function for mime parser that opens a section for downloading
*/
void mime_download(char *name, char *filename, char *partnum, char *disp,
- void *content, char *cbtype, size_t length)
+ void *content, char *cbtype, size_t length, char *encoding,
+ void *cbuserdata)
{
/* Silently go away if there's already a download open... */
* Callback function for mime parser that wants to display text
*/
void fixed_output(char *name, char *filename, char *partnum, char *disp,
- void *content, char *cbtype, size_t length)
+ void *content, char *cbtype, size_t length, char *encoding,
+ void *cbuserdata)
{
char *ptr;
char *wptr;
int do_proto, /* do Citadel protocol responses? */
int crlf /* Use CRLF newlines instead of LF? */
) {
- int i, k;
- char buf[1024];
- CIT_UBYTE ch;
- char allkeys[256];
- char display_name[256];
struct CtdlMessage *TheMessage;
- char *mptr;
- char *nl; /* newline string */
-
- /* buffers needed for RFC822 translation */
- char suser[256];
- char luser[256];
- char fuser[256];
- char snode[256];
- char lnode[256];
- char mid[256];
- char datestamp[256];
- /* */
+ int retcode;
lprintf(7, "CtdlOutputMsg() msgnum=%ld, mode=%d\n",
msg_num, mode);
TheMessage = NULL;
- sprintf(mid, "%ld", msg_num);
- nl = (crlf ? "\r\n" : "\n");
if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
if (do_proto) cprintf("%d Not logged in.\n",
ERROR, msg_num);
return(om_no_such_msg);
}
+
+ retcode = CtdlOutputPreLoadedMsg(
+ TheMessage, msg_num, mode,
+ headers_only, do_proto, crlf);
+
+ CtdlFreeMessage(TheMessage);
+ return(retcode);
+}
+
+
+/*
+ * Get a message off disk. (returns om_* values found in msgbase.h)
+ *
+ */
+int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage,
+ long msg_num,
+ 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 i, k;
+ char buf[1024];
+ CIT_UBYTE ch;
+ char allkeys[256];
+ char display_name[256];
+ char *mptr;
+ char *nl; /* newline string */
+
+ /* buffers needed for RFC822 translation */
+ char suser[256];
+ char luser[256];
+ char fuser[256];
+ char snode[256];
+ char lnode[256];
+ char mid[256];
+ char datestamp[256];
+ /* */
+
+ sprintf(mid, "%ld", msg_num);
+ nl = (crlf ? "\r\n" : "\n");
+
+ if (!is_valid_message(TheMessage)) {
+ lprintf(1, "ERROR: invalid preloaded message for output\n");
+ return(om_no_such_msg);
+ }
/* Are we downloading a MIME component? */
if (mode == MT_DOWNLOAD) {
} else {
/* Parse the message text component */
mptr = TheMessage->cm_fields['M'];
- mime_parser(mptr, NULL, *mime_download);
+ mime_parser(mptr, NULL, *mime_download, NULL, 0);
/* If there's no file open by this time, the requested
* section wasn't found, so print an error
*/
desired_section);
}
}
- CtdlFreeMessage(TheMessage);
return((CC->download_fp != NULL) ? om_ok : om_mime_error);
}
else if (i == 'R')
cprintf("To: %s%s", mptr, nl);
else if (i == 'T') {
- generate_rfc822_datestamp(datestamp,
- atol(mptr) );
+ datestring(datestamp, atol(mptr),
+ DATESTRING_RFC822 );
cprintf("Date: %s%s", datestamp, nl);
}
}
/* Tell the client about the MIME parts in this message */
if (TheMessage->cm_format_type == FMT_RFC822) {
if (mode == MT_CITADEL) {
- mime_parser(mptr, NULL, *list_this_part);
+ mime_parser(mptr, NULL, *list_this_part, NULL, 0);
}
else if (mode == MT_MIME) { /* list parts only */
- mime_parser(mptr, NULL, *list_this_part);
+ mime_parser(mptr, NULL, *list_this_part, NULL, 0);
if (do_proto) cprintf("000\n");
- CtdlFreeMessage(TheMessage);
return(om_ok);
}
else if (mode == MT_RFC822) { /* unparsed RFC822 dump */
else cprintf("%c", ch);
}
if (do_proto) cprintf("000\n");
- CtdlFreeMessage(TheMessage);
return(om_ok);
}
}
if (headers_only) {
if (do_proto) cprintf("000\n");
- CtdlFreeMessage(TheMessage);
return(om_ok);
}
if (TheMessage->cm_format_type == FMT_RFC822) {
CtdlAllocUserData(SYM_MA_INFO, sizeof(struct ma_info));
memset(ma, 0, sizeof(struct ma_info));
- mime_parser(mptr, NULL, *fixed_output);
+ mime_parser(mptr, NULL, *fixed_output, NULL, 0);
}
/* now we're done */
if (do_proto) cprintf("000\n");
- CtdlFreeMessage(TheMessage);
return(om_ok);
}
{
long msgid;
- CtdlAllocUserData(SYM_DESIRED_SECTION, 64);
+ CtdlAllocUserData(SYM_DESIRED_SECTION, 256);
msgid = extract_long(cmdbuf, 0);
extract(desired_section, cmdbuf, 1);
/* advance past header fields */
mptr = msg->cm_fields['M'];
a = strlen(mptr);
- while (--a) {
+ while ((--a) > 0) {
if (!strncasecmp(mptr, "Content-type: ", 14)) {
safestrncpy(content_type, mptr,
sizeof(content_type));
exist is ALWAYS freed */
) {
char buf[256];
+ int linelen;
size_t message_len = 0;
size_t buffer_len = 0;
- char *ptr, *append;
+ char *ptr;
char *m;
if (exist == NULL) {
message_len = 0;
}
/* read in the lines of message text one by one */
- append = NULL;
while ( (client_gets(buf)>0) && strcmp(buf, terminator) ) {
+ /* strip trailing newline type stuff */
+ if (buf[strlen(buf)-1]==10) buf[strlen(buf)-1]=0;
+ if (buf[strlen(buf)-1]==13) buf[strlen(buf)-1]=0;
+
+ linelen = strlen(buf);
+
/* augment the buffer if we have to */
- if ((message_len + strlen(buf) + 2) > buffer_len) {
+ if ((message_len + linelen + 2) > buffer_len) {
lprintf(9, "realloking\n");
ptr = reallok(m, (buffer_len * 2) );
if (ptr == NULL) { /* flush if can't allocate */
} else {
buffer_len = (buffer_len * 2);
m = ptr;
- append = NULL;
lprintf(9, "buffer_len is %d\n", buffer_len);
}
}
- if (append == NULL) append = m;
- while (strlen(append) > 0) ++append;
- strcpy(append, buf);
- strcat(append, "\n");
- message_len = message_len + strlen(buf) + 1;
+ /* Add the new line to the buffer. We avoid using strcat()
+ * because that would involve traversing the entire message
+ * after each line, and this function needs to run fast.
+ */
+ strcpy(&m[message_len], buf);
+ m[message_len + linelen] = '\n';
+ m[message_len + linelen + 1] = 0;
+ message_len = message_len + linelen + 1;
/* if we've hit the max msg length, flush the rest */
if (message_len >= maxlen) {
- while ( (client_gets(buf)>0) && strcmp(buf, terminator)) ;;
+ while ( (client_gets(buf)>0)
+ && strcmp(buf, terminator)) ;;
return(m);
}
}
}
if (!strcasecmp(buf, "sysop")) {
mtsflag = 1;
- goto SKFALL;
}
- if (e != MES_LOCAL)
- goto SKFALL; /* don't search local file */
- if (!strcasecmp(buf, CC->usersupp.fullname)) {
- cprintf("%d Can't send mail to yourself!\n",
- ERROR + NO_SUCH_USER);
- return;
- }
- /* Check to make sure the user exists; also get the correct
- * upper/lower casing of the name.
- */
- a = getuser(&tempUS, buf);
- if (a != 0) {
- cprintf("%d No such user.\n", ERROR + NO_SUCH_USER);
- return;
+ else if (e == MES_LOCAL) { /* don't search local file */
+ if (!strcasecmp(buf, CC->usersupp.fullname)) {
+ cprintf("%d Can't send mail to yourself!\n",
+ ERROR + NO_SUCH_USER);
+ return;
+ }
+ /* Check to make sure the user exists; also get the correct
+ * upper/lower casing of the name.
+ */
+ a = getuser(&tempUS, buf);
+ if (a != 0) {
+ cprintf("%d No such user.\n", ERROR + NO_SUCH_USER);
+ return;
+ }
+ strcpy(buf, tempUS.fullname);
}
- strcpy(buf, tempUS.fullname);
}
-SKFALL: b = MES_NORMAL;
+ b = MES_NORMAL;
if (CC->quickroom.QRflags & QR_ANONONLY)
b = MES_ANON;
if (CC->quickroom.QRflags & QR_ANONOPT) {