* MIME parser declarations
*/
-void extract_key(char *target, char *source, char *key);
+void extract_key(char *target, char *source, long sourcelen, char *key, long keylen);
void mime_parser(char *content_start, char *content_end,
void (*CallBack)
int CtdlDecodeBase64(char *dest, const char *source, size_t length);
unsigned int decode_hex(char *Source);
int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
-void striplt(char *);
+long striplt(char *);
int haschar(const char *st, int ch);
void remove_token(char *source, int parmnum, char separator);
void fmt_date(char *buf, size_t n, time_t thetime, int seconds);
FILE *CtdlTempFile(void);
void generate_uuid(char *buf);
char *bmstrcasestr(char *text, char *pattern);
+char *bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen);
void CtdlMakeTempFileName(char *name, int len);
char *rfc2047encode(char *line, long length);
int is_msg_in_mset(const char *mset, long msgnum);
#include "libcitadel.h"
#include "libcitadellocal.h"
-void extract_key(char *target, char *source, char *key)
+void extract_key(char *target, char *source, long sourcelen, char *key, long keylen)
{
+ char *lookat;
char *ptr;
- char looking_for[256];
+ //char looking_for[256];
int double_quotes = 0;
- snprintf(looking_for, sizeof looking_for, "%s=", key);
+ lookat = source;
+ //snprintf(looking_for, sizeof looking_for, "%s=", key);
- ptr = bmstrcasestr(source, looking_for);
+ while ((lookat != NULL)) {
+ ptr = bmstrcasestr_len(lookat, sourcelen, key, keylen);
+ lookat = ptr;
+ if ((ptr != NULL) &&
+ (*(ptr + keylen) == '='))
+ lookat = NULL;
+
+
+ }
+ //ptr = bmstrcasestr(source, looking_for);
if (ptr == NULL) {
strcpy(target, "");
return;
}
- strcpy(target, (ptr + strlen(looking_for)));
+ strcpy(target, (ptr + keylen + 1));
for (ptr=target; (*ptr != 0); ++ptr) {
}
}
}
+ *ptr = '\0';
}
char *next_boundary;
char *content_type;
char *charset;
+ size_t content_type_len;
size_t content_length;
char *encoding;
char *disposition;
+ size_t disposition_len;
char *id;
char *name = NULL;
char *content_type_name;
ptr = content_start;
content_length = 0;
- boundary = malloc(SIZ);
- memset(boundary, 0, SIZ);
+ boundary = malloc(SIZ * 12);
+ *boundary = '\0';
- startary = malloc(SIZ);
- memset(startary, 0, SIZ);
+ startary = boundary + SIZ * 1;
+ *startary = '\0';
- endary = malloc(SIZ);
- memset(endary, 0, SIZ);
+ endary = boundary + SIZ * 2;
+ *endary = '\0';
- header = malloc(SIZ);
- memset(header, 0, SIZ);
+ header = boundary + SIZ * 3;
+ *header = '\0';
- content_type = malloc(SIZ);
- memset(content_type, 0, SIZ);
+ content_type = boundary + SIZ * 4;
+ *content_type = '\0';
- charset = malloc(SIZ);
- memset(charset, 0, SIZ);
+ charset = boundary + SIZ * 5;
+ *charset = '\0';
- encoding = malloc(SIZ);
- memset(encoding, 0, SIZ);
+ encoding = boundary + SIZ * 6;
+ *encoding = '\0';
- content_type_name = malloc(SIZ);
- memset(content_type_name, 0, SIZ);
+ content_type_name = boundary + SIZ * 7;
+ *content_type_name = '\0';
- content_disposition_name = malloc(SIZ);
- memset(content_disposition_name, 0, SIZ);
+ content_disposition_name = boundary + SIZ * 8;
+ *content_disposition_name = '\0';
- filename = malloc(SIZ);
- memset(filename, 0, SIZ);
+ filename = boundary + SIZ * 9;
+ *filename = '\0';
- disposition = malloc(SIZ);
- memset(disposition, 0, SIZ);
+ disposition = boundary + SIZ * 10;
+ *disposition = '\0';
- id = malloc(SIZ);
- memset(id, 0, SIZ);
+ id = boundary + SIZ * 11;
+ *id = '\0';
/* If the caller didn't supply an endpointer, generate one by measure */
if (content_end == NULL) {
if (!isspace(buf[0])) {
if (!strncasecmp(header, "Content-type:", 13)) {
- strcpy(content_type, &header[13]);
- striplt(content_type);
- extract_key(content_type_name, content_type, "name");
- extract_key(charset, content_type, "charset");
- extract_key(boundary, header, "boundary");
+ memcpy (content_type, &header[13], headerlen - 12);
+ content_type_len = striplt (content_type);
+
+ extract_key(content_type_name, content_type, content_type_len, HKEY("name"));
+ extract_key(charset, content_type, content_type_len, HKEY("charset"));
+ extract_key(boundary, header, headerlen, HKEY("boundary"));
+
/* Deal with weird headers */
if (strchr(content_type, ' '))
*(strchr(content_type, ' ')) = '\0';
*(strchr(content_type, ';')) = '\0';
}
if (!strncasecmp(header, "Content-Disposition:", 20)) {
- strcpy(disposition, &header[20]);
- striplt(disposition);
- extract_key(content_disposition_name, disposition, "name");
- extract_key(filename, disposition, "filename");
+ memcpy (disposition, &header[20], headerlen - 19);
+ disposition_len = striplt(disposition);
+ extract_key(content_disposition_name, disposition, disposition_len, HKEY("name"));
+ extract_key(filename, disposition, disposition_len, HKEY("filename"));
}
if (!strncasecmp(header, "Content-ID:", 11)) {
strcpy(id, &header[11]);
}
/* Figure out where the boundaries are */
- snprintf(startary, SIZ, "--%s", boundary);
+ startary_len = snprintf(startary, SIZ, "--%s", boundary);
snprintf(endary, SIZ, "--%s--", boundary);
- startary_len = strlen(startary);
part_start = NULL;
do {
end_parser: /* free the buffers! end the oppression!! */
free(boundary);
- free(startary);
- free(endary);
- free(header);
- free(content_type);
- free(charset);
- free(encoding);
- free(content_type_name);
- free(content_disposition_name);
- free(filename);
- free(disposition);
- free(id);
}
/*
* Strip leading and trailing spaces from a string
*/
-void striplt(char *buf)
+long striplt(char *buf)
{
- size_t len;
- int a;
+ int CountTrail = 0;
+ int FromStart = 1;
+ char *aptr, *bptr;
+
+ if ((buf==NULL) || (IsEmptyStr(buf)))
+ return 0;
+
+ bptr = aptr = buf;
+
+ while (!IsEmptyStr(aptr)) {
+ if (isspace(*aptr)) {
+ if (FromStart)
+ aptr ++;
+ else {
+ CountTrail ++;
+ *bptr = *aptr;
+ aptr++; bptr++;
+ }
+ }
+ else {
+ CountTrail = 0;
+ *bptr = *aptr;
+ aptr++; bptr++;
+ }
+ }
- if (buf==NULL) return;
- if (IsEmptyStr(buf)) return;
- len = strlen(buf);
- while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
- buf[--len] = 0;
- if (IsEmptyStr(buf)) return;
- a = 0;
- while ((!IsEmptyStr(buf)) && (isspace(buf[a])))
- a++;
- if (a > 0)
- memmove(buf, &buf[a], len - a + 1);
+ if (CountTrail > 0) {
+ bptr -= CountTrail;
+ }
+
+ *bptr = '\0';
+ return bptr - buf;
}
* The code is roughly based on the strstr() replacement from 'tin' written
* by Urs Jannsen.
*/
-char *bmstrcasestr(char *text, char *pattern) {
+inline char *_bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen) {
register unsigned char *p, *t;
register int i, j, *delta;
register size_t p1;
int deltaspace[256];
- size_t textlen;
- size_t patlen;
if (!text) return(NULL);
if (!pattern) return(NULL);
- textlen = strlen (text);
- patlen = strlen (pattern);
-
/* algorithm fails if pattern is empty */
if ((p1 = patlen) == 0)
return (text);
return (NULL);
}
+/*
+ * bmstrcasestr() -- case-insensitive substring search
+ *
+ * This uses the Boyer-Moore search algorithm and is therefore quite fast.
+ * The code is roughly based on the strstr() replacement from 'tin' written
+ * by Urs Jannsen.
+ */
+char *bmstrcasestr(char *text, char *pattern) {
+ size_t textlen;
+ size_t patlen;
+ if (!text) return(NULL);
+ if (!pattern) return(NULL);
+
+ textlen = strlen (text);
+ patlen = strlen (pattern);
+
+ return _bmstrcasestr_len(text, textlen, pattern, patlen);
+}
+
+char *bmstrcasestr_len(char *text, size_t textlen, char *pattern, size_t patlen) {
+ return _bmstrcasestr_len(text, textlen, pattern, patlen);
+}
/*
* Local replacement for controversial C library function that generates