NLFound = NLFoundLastTime = 0;
do {
size_t i;
+
LineStart = LastBlank = mptr;
Found = 'x';
-
- for (i = 0; Found == 'x'; i++)
+ i = 0;
+ while (Found == 'x')
{
if (LineStart[i] == '\n')
Found = '\n';
else if (LineStart[i] == '\r')
Found = '\r';
- else if (LineStart[i] == ' ')
+ else if (LineStart[i] == ' ')
+ {
LastBlank = &LineStart[i];
+ i++;
+ }
else if ((i > 80) && (LineStart != LastBlank))
Found = ' ';
else if (LineStart[i] == '\0')
Found = '\0';
+ else i++;
}
switch (Found)
{
case '\n':
if (LineStart[i + 1] == '\r')
- mptr = &LineStart[i + 1];
+ mptr = &LineStart[i + 2];
else
- mptr = &LineStart[i];
+ mptr = &LineStart[i + 1];
i--;
NLFound = 1;
break;
case '\r':
if (LineStart[i + 1] == '\n')
- mptr = &LineStart[i + 1];
+ mptr = &LineStart[i + 2];
else
- mptr = &LineStart[i];
+ mptr = &LineStart[i + 1];
i--;
NLFound = 1;
break;
case '\0':
- mptr = &LineStart[i];
+ mptr = &LineStart[i + 1];
i--;
NLFound = 0;
break;
break;
case 'x':
/* WHUT? */
+ while (*mptr != '\0') mptr++;
break;
}
if (NLFoundLastTime)
ma = (struct ma_info *)cbuserdata;
if (ma->is_ma == 0) {
- cprintf("part=%s|%s|%s|%s|%s|%ld|%s\n",
- name, filename, partnum, disp, cbtype, (long)length, cbid);
+ cprintf("part=%s|%s|%s|%s|%s|%ld|%s|%s\n",
+ name,
+ filename,
+ partnum,
+ disp,
+ cbtype,
+ (long)length,
+ cbid,
+ cbcharset);
}
}
|| (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
) {
*found_it = 1;
- cprintf("%d %d|-1|%s|%s\n",
+ cprintf("%d %d|-1|%s|%s|%s\n",
BINARY_FOLLOWS,
(int)length,
filename,
- cbtype
+ cbtype,
+ cbcharset
);
client_write(content, length);
}
*/
if (TheMessage->cm_format_type == FMT_FIXED) {
int buflen;
+ int xlline = 0;
+ int nllen = strlen (nl);
if (mode == MT_MIME) {
cprintf("Content-type: text/plain\n\n");
}
*buf = '\0';
buflen = 0;
while (ch = *mptr++, ch > 0) {
- if (ch == 13)
- ch = 10;
- if ((ch == 10) || (buflen > 250)) {
+ if (ch == '\n')
+ ch = '\r';
+
+ if ((buflen > 250) && (!xlline)){
+ int tbuflen;
+ tbuflen = buflen;
+
+ while ((buflen > 0) &&
+ (!isspace(buf[buflen])))
+ buflen --;
+ if (buflen == 0) {
+ xlline = 1;
+ }
+ else {
+ mptr -= tbuflen - buflen;
+ buf[buflen] = '\0';
+ ch = '\r';
+ }
+ }
+ /* if we reach the outer bounds of our buffer,
+ abort without respect what whe purge. */
+ if (xlline &&
+ ((isspace(ch)) ||
+ (buflen > SIZ - nllen - 2)))
+ ch = '\r';
+
+ if (ch == '\r') {
+ memcpy (&buf[buflen], nl, nllen);
+ buflen += nllen;
buf[buflen] = '\0';
- cprintf("%s%s", buf, nl);
+
+ client_write(buf, buflen);
*buf = '\0';
buflen = 0;
+ xlline = 0;
} else {
buf[buflen] = ch;
buflen++;
char content_type[SIZ]; /* We have to learn this */
char recipient[SIZ];
long newmsgid;
- char *mptr = NULL;
+ const char *mptr = NULL;
struct ctdluser userbuf;
int a, i;
struct MetaData smi;
/*
* Back end function used by CtdlMakeMessage() and similar functions
*/
-char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */
- size_t maxlen, /* maximum message length */
- char *exist, /* if non-null, append to it;
- exist is ALWAYS freed */
- int crlf, /* CRLF newlines instead of LF */
- int sock /* socket handle or 0 for this session's client socket */
- ) {
- char buf[1024];
- int linelen;
- size_t message_len = 0;
- size_t buffer_len = 0;
- char *ptr;
- char *m;
+StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */
+ long tlen,
+ size_t maxlen, /* maximum message length */
+ char *exist, /* if non-null, append to it;
+ exist is ALWAYS freed */
+ int crlf, /* CRLF newlines instead of LF */
+ int *sock /* socket handle or 0 for this session's client socket */
+ )
+{
+ StrBuf *Message;
+ StrBuf *LineBuf;
int flushing = 0;
int finished = 0;
int dotdot = 0;
+ LineBuf = NewStrBufPlain(NULL, SIZ);
if (exist == NULL) {
- m = malloc(4096);
- m[0] = 0;
- buffer_len = 4096;
- message_len = 0;
+ Message = NewStrBufPlain(NULL, 4 * SIZ);
}
else {
- message_len = strlen(exist);
- buffer_len = message_len + 4096;
- m = realloc(exist, buffer_len);
- if (m == NULL) {
- free(exist);
- return m;
- }
+ Message = NewStrBufPlain(exist, -1);
+ free(exist);
}
/* Do we need to change leading ".." to "." for SMTP escaping? */
- if (!strcmp(terminator, ".")) {
+ if ((tlen == 1) && (*terminator == '.')) {
dotdot = 1;
}
- /* flush the input if we have nowhere to store it */
- if (m == NULL) {
- flushing = 1;
- }
-
/* read in the lines of message text one by one */
do {
- if (sock > 0) {
- if (sock_getln(sock, buf, (sizeof buf - 3)) < 0) finished = 1;
+ if (sock != NULL) {
+ if ((CtdlSockGetLine(sock, LineBuf) < 0) ||
+ (*sock == -1))
+ finished = 1;
}
else {
- if (client_getln(buf, (sizeof buf - 3)) < 1) finished = 1;
- }
- if (!strcmp(buf, terminator)) finished = 1;
- if (crlf) {
- strcat(buf, "\r\n");
- }
- else {
- strcat(buf, "\n");
- }
-
- /* Unescape SMTP-style input of two dots at the beginning of the line */
- if (dotdot) {
- if (!strncmp(buf, "..", 2)) {
- strcpy(buf, &buf[1]);
- }
+ if (CtdlClientGetLine(LineBuf) < 0) finished = 1;
}
+ if ((StrLength(LineBuf) == tlen) &&
+ (!strcmp(ChrPtr(LineBuf), terminator)))
+ finished = 1;
if ( (!flushing) && (!finished) ) {
- /* Measure the line */
- linelen = strlen(buf);
-
- /* augment the buffer if we have to */
- if ((message_len + linelen) >= buffer_len) {
- ptr = realloc(m, (buffer_len * 2) );
- if (ptr == NULL) { /* flush if can't allocate */
- flushing = 1;
- } else {
- buffer_len = (buffer_len * 2);
- m = ptr;
- CtdlLogPrintf(CTDL_DEBUG, "buffer_len is now %ld\n", (long)buffer_len);
- }
+ if (crlf) {
+ StrBufAppendBufPlain(LineBuf, HKEY("\r\n"), 0);
}
-
- /* Add the new line to the buffer. NOTE: this loop must avoid
- * using functions like strcat() and strlen() because they
- * traverse the entire buffer upon every call, and doing that
- * for a multi-megabyte message slows it down beyond usability.
- */
- strcpy(&m[message_len], buf);
- message_len += linelen;
+ else {
+ StrBufAppendBufPlain(LineBuf, HKEY("\n"), 0);
+ }
+
+ /* Unescape SMTP-style input of two dots at the beginning of the line */
+ if ((dotdot) &&
+ (StrLength(LineBuf) == 2) &&
+ (!strcmp(ChrPtr(LineBuf), "..")))
+ {
+ StrBufCutLeft(LineBuf, 1);
+ }
+
+ StrBufAppendBuf(Message, LineBuf, 0);
}
/* if we've hit the max msg length, flush the rest */
- if (message_len >= maxlen) flushing = 1;
+ if (StrLength(Message) >= maxlen) flushing = 1;
} while (!finished);
- return(m);
+ FreeStrBuf(&LineBuf);
+ return Message;
}
+/*
+ * Back end function used by CtdlMakeMessage() and similar functions
+ */
+char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */
+ long tlen,
+ size_t maxlen, /* maximum message length */
+ char *exist, /* if non-null, append to it;
+ exist is ALWAYS freed */
+ int crlf, /* CRLF newlines instead of LF */
+ int *sock /* socket handle or 0 for this session's client socket */
+ )
+{
+ StrBuf *Message;
+
+ Message = CtdlReadMessageBodyBuf(terminator,
+ tlen,
+ maxlen,
+ exist,
+ crlf,
+ sock);
+ if (Message == NULL)
+ return NULL;
+ else
+ return SmashStrBuf(&Message);
+}
/*
msg->cm_fields['M'] = preformatted_text;
}
else {
- msg->cm_fields['M'] = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+ msg->cm_fields['M'] = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
}
return(msg);
*
* Caller needs to free the result using free_recipients()
*/
-struct recptypes *validate_recipients(char *supplied_recipients,
+struct recptypes *validate_recipients(const char *supplied_recipients,
const char *RemoteIdentifier,
int Flags) {
struct recptypes *ret;
cdb_store(CDB_MSGLISTS, &qrbuf.QRnumber, (int)sizeof(long),
msglist, (int)(num_msgs * sizeof(long)));
- qrbuf.QRhighest = msglist[num_msgs - 1];
+ if (num_msgs > 0)
+ qrbuf.QRhighest = msglist[num_msgs - 1];
+ else
+ qrbuf.QRhighest = 0;
}
CtdlPutRoomLock(&qrbuf);