git-svn: trunk@3213
Nigel Horne authored on 2007/09/12 22:25:13... | ... |
@@ -69,53 +69,6 @@ static char const rcsid[] = "$Id: line.c,v 1.11 2007/02/12 20:46:08 njh Exp $"; |
69 | 69 |
#include "line.h" |
70 | 70 |
#include "others.h" |
71 | 71 |
|
72 |
-#ifdef OLD |
|
73 |
-line_t * |
|
74 |
-lineCreate(const char *data) |
|
75 |
-{ |
|
76 |
- line_t *ret = (line_t *)cli_malloc(sizeof(struct line)); |
|
77 |
- |
|
78 |
- if(ret == NULL) |
|
79 |
- return NULL; |
|
80 |
- |
|
81 |
- ret->l_str = strdup(data); |
|
82 |
- if(ret->l_str == NULL) { |
|
83 |
- free(ret); |
|
84 |
- return NULL; |
|
85 |
- } |
|
86 |
- ret->l_refs = 1; |
|
87 |
- |
|
88 |
- return ret; |
|
89 |
-} |
|
90 |
- |
|
91 |
-line_t * |
|
92 |
-lineLink(line_t *line) |
|
93 |
-{ |
|
94 |
- line->l_refs++; |
|
95 |
- return line; |
|
96 |
-} |
|
97 |
- |
|
98 |
-line_t * |
|
99 |
-lineUnlink(line_t *line) |
|
100 |
-{ |
|
101 |
- /*printf("%d:\n\t'%s'\n", line->l_refs, line->l_str);*/ |
|
102 |
- |
|
103 |
- if(--line->l_refs == 0) { |
|
104 |
- free(line->l_str); |
|
105 |
- free(line); |
|
106 |
- return NULL; |
|
107 |
- } |
|
108 |
- return line; |
|
109 |
-} |
|
110 |
- |
|
111 |
-const char * |
|
112 |
-lineGetData(const line_t *line) |
|
113 |
-{ |
|
114 |
- return line ? line->l_str : NULL; |
|
115 |
-} |
|
116 |
- |
|
117 |
-#else |
|
118 |
- |
|
119 | 72 |
line_t * |
120 | 73 |
lineCreate(const char *data) |
121 | 74 |
{ |
... | ... |
@@ -163,10 +116,3 @@ lineGetData(const line_t *line) |
163 | 163 |
{ |
164 | 164 |
return line ? &line[1] : NULL; |
165 | 165 |
} |
166 |
- |
|
167 |
-unsigned char |
|
168 |
-lineGetRefCount(const line_t *line) |
|
169 |
-{ |
|
170 |
- return (unsigned char)line[0]; |
|
171 |
-} |
|
172 |
-#endif |
... | ... |
@@ -37,21 +37,13 @@ |
37 | 37 |
#ifndef __LINE_H |
38 | 38 |
#define __LINE_H |
39 | 39 |
|
40 |
-#ifdef OLD |
|
41 |
-/* easier to read, but slower */ |
|
42 |
- |
|
43 |
-typedef struct line { |
|
44 |
- char *l_str; /* the line's contents */ |
|
45 |
- unsigned int l_refs; /* the number of references to the data */ |
|
46 |
-} line_t; |
|
47 |
-#else |
|
48 | 40 |
typedef char line_t; /* first byte is the ref count */ |
49 |
-#endif |
|
50 | 41 |
|
51 | 42 |
line_t *lineCreate(const char *data); |
52 | 43 |
line_t *lineLink(line_t *line); |
53 | 44 |
line_t *lineUnlink(line_t *line); |
54 | 45 |
const char *lineGetData(const line_t *line); |
55 |
-unsigned char lineGetRefCount(const line_t *line); |
|
46 |
+ |
|
47 |
+#define lineGetRefCount(line) ((unsigned char)line[0]) |
|
56 | 48 |
|
57 | 49 |
#endif |
... | ... |
@@ -1705,8 +1705,6 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1705 | 1705 |
return NULL; |
1706 | 1706 |
} |
1707 | 1707 |
|
1708 |
- messageClean(ret); |
|
1709 |
- |
|
1710 | 1708 |
cli_dbgmsg("parseEmailFile: return\n"); |
1711 | 1709 |
|
1712 | 1710 |
return ret; |
... | ... |
@@ -1715,12 +1713,8 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1715 | 1715 |
/* |
1716 | 1716 |
* The given message contains a raw e-mail. |
1717 | 1717 |
* |
1718 |
- * Returns the message's body with the correct arguments set |
|
1719 |
- * |
|
1720 |
- * The downside of this approach is that for a short time we have two copies |
|
1721 |
- * of the message in memory, the upside is that it makes for easier parsing |
|
1722 |
- * of encapsulated messages, and in the long run uses less memory in those |
|
1723 |
- * scenarios |
|
1718 |
+ * Returns the message's body with the correct arguments set, empties the |
|
1719 |
+ * given message's contents (note that it isn't destroyed) |
|
1724 | 1720 |
* |
1725 | 1721 |
* TODO: remove the duplication with parseEmailFile |
1726 | 1722 |
*/ |
... | ... |
@@ -1729,7 +1723,7 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1729 | 1729 |
{ |
1730 | 1730 |
bool inHeader = TRUE; |
1731 | 1731 |
bool bodyIsEmpty = TRUE; |
1732 |
- const text *t; |
|
1732 |
+ text *t; |
|
1733 | 1733 |
message *ret; |
1734 | 1734 |
bool anyHeadersFound = FALSE; |
1735 | 1735 |
int commandNumber = -1; |
... | ... |
@@ -1814,13 +1808,15 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1814 | 1814 |
fullline = ptr; |
1815 | 1815 |
strcat(fullline, line); |
1816 | 1816 |
} |
1817 |
- |
|
1818 | 1817 |
assert(fullline != NULL); |
1819 | 1818 |
|
1820 | 1819 |
if(next_is_folded_header(t)) |
1821 | 1820 |
/* Add arguments to this line */ |
1822 | 1821 |
continue; |
1823 | 1822 |
|
1823 |
+ lineUnlink(t->t_line); |
|
1824 |
+ t->t_line = NULL; |
|
1825 |
+ |
|
1824 | 1826 |
if(count_quotes(fullline) & 1) |
1825 | 1827 |
continue; |
1826 | 1828 |
|
... | ... |
@@ -1853,9 +1849,9 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1853 | 1853 |
} |
1854 | 1854 |
/*if(t->t_line && isuuencodebegin(t->t_line)) |
1855 | 1855 |
puts("FIXME: add fast visa here");*/ |
1856 |
- /*cli_dbgmsg("Add line to body '%s'\n", line);*/ |
|
1857 |
- if(messageAddLine(ret, t->t_line) < 0) |
|
1858 |
- break; |
|
1856 |
+ cli_dbgmsg("parseEmailHeaders: inished with headers, moving body\n"); |
|
1857 |
+ messageMoveText(ret, t, m); |
|
1858 |
+ break; |
|
1859 | 1859 |
} |
1860 | 1860 |
} |
1861 | 1861 |
|
... | ... |
@@ -1878,8 +1874,6 @@ parseEmailHeaders(message *m, const table_t *rfc821) |
1878 | 1878 |
return NULL; |
1879 | 1879 |
} |
1880 | 1880 |
|
1881 |
- messageClean(ret); |
|
1882 |
- |
|
1883 | 1881 |
cli_dbgmsg("parseEmailHeaders: return\n"); |
1884 | 1882 |
|
1885 | 1883 |
return ret; |
... | ... |
@@ -2444,8 +2438,6 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re |
2444 | 2444 |
if(rc == VIRUS) |
2445 | 2445 |
infected = TRUE; |
2446 | 2446 |
break; |
2447 |
- default: |
|
2448 |
- messageClean(aMessage); |
|
2449 | 2447 |
} |
2450 | 2448 |
} |
2451 | 2449 |
|
... | ... |
@@ -2543,8 +2535,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re |
2543 | 2543 |
assert(aMessage == messages[htmltextPart]); |
2544 | 2544 |
messageDestroy(aMessage); |
2545 | 2545 |
messages[htmltextPart] = NULL; |
2546 |
- } |
|
2547 |
- else if(rc == VIRUS) { |
|
2546 |
+ } else if(rc == VIRUS) { |
|
2548 | 2547 |
infected = TRUE; |
2549 | 2548 |
break; |
2550 | 2549 |
} |
... | ... |
@@ -3312,7 +3303,6 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c |
3312 | 3312 |
cli_dbgmsg("Invalid content-type '%s' received, no subtype specified, assuming text/plain; charset=us-ascii\n", ptr); |
3313 | 3313 |
else { |
3314 | 3314 |
int i; |
3315 |
- char *mimeArgs; /* RHS of the ; */ |
|
3316 | 3315 |
|
3317 | 3316 |
buf = cli_malloc(strlen(ptr) + 1); |
3318 | 3317 |
if(buf == NULL) { |
... | ... |
@@ -3406,10 +3396,10 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c |
3406 | 3406 |
* we find the boundary argument set it |
3407 | 3407 |
*/ |
3408 | 3408 |
i = 1; |
3409 |
- while((mimeArgs = cli_strtokbuf(ptr, i++, ";", buf)) != NULL) { |
|
3410 |
- cli_dbgmsg("mimeArgs = '%s'\n", mimeArgs); |
|
3409 |
+ while(cli_strtokbuf(ptr, i++, ";", buf) != NULL) { |
|
3410 |
+ cli_dbgmsg("mimeArgs = '%s'\n", buf); |
|
3411 | 3411 |
|
3412 |
- messageAddArguments(m, mimeArgs); |
|
3412 |
+ messageAddArguments(m, buf); |
|
3413 | 3413 |
} |
3414 | 3414 |
} |
3415 | 3415 |
break; |
... | ... |
@@ -682,7 +682,7 @@ messageGetFilename(const message *m) |
682 | 682 |
if(filename) |
683 | 683 |
return filename; |
684 | 684 |
|
685 |
- return (char *)messageFindArgument(m, "name"); |
|
685 |
+ return (char *)messageFindArgument(m, "name"); |
|
686 | 686 |
} |
687 | 687 |
|
688 | 688 |
void |
... | ... |
@@ -964,6 +964,83 @@ messageAddStrAtTop(message *m, const char *data) |
964 | 964 |
} |
965 | 965 |
|
966 | 966 |
/* |
967 |
+ * Put the contents of the given text at the end of the current object. |
|
968 |
+ * Can be used either to move a text object into a message, or to move a |
|
969 |
+ * message's text into another message only moving from a given offset. |
|
970 |
+ * The given text emptied; it can be used again if needed, though be warned that |
|
971 |
+ * it will have an empty line at the start. |
|
972 |
+ * Returns 0 for failure, 1 for success |
|
973 |
+ */ |
|
974 |
+int |
|
975 |
+messageMoveText(message *m, text *t, message *old_message) |
|
976 |
+{ |
|
977 |
+ int rc; |
|
978 |
+ |
|
979 |
+ if(m->body_first == NULL) { |
|
980 |
+ if(old_message) { |
|
981 |
+ text *u; |
|
982 |
+ /* |
|
983 |
+ * t is within old_message which is about to be |
|
984 |
+ * destroyed |
|
985 |
+ */ |
|
986 |
+ assert(old_message->body_first != NULL); |
|
987 |
+ |
|
988 |
+ m->body_first = t; |
|
989 |
+ for(u = old_message->body_first; u != t;) { |
|
990 |
+ text *next; |
|
991 |
+ |
|
992 |
+ if(u->t_line) |
|
993 |
+ lineUnlink(u->t_line); |
|
994 |
+ next = u->t_next; |
|
995 |
+ |
|
996 |
+ free(u); |
|
997 |
+ u = next; |
|
998 |
+ |
|
999 |
+ if(u == NULL) { |
|
1000 |
+ cli_errmsg("messageMoveText sanity check: t not within old_message\n"); |
|
1001 |
+ return -1; |
|
1002 |
+ } |
|
1003 |
+ } |
|
1004 |
+ assert(m->body_last->t_next == NULL); |
|
1005 |
+ |
|
1006 |
+ m->body_last = old_message->body_last; |
|
1007 |
+ old_message->body_first = old_message->body_last = NULL; |
|
1008 |
+ |
|
1009 |
+ /* Do any pointers need to be reset? */ |
|
1010 |
+ if((old_message->bounce == NULL) && |
|
1011 |
+ (old_message->encoding == NULL) && |
|
1012 |
+ (old_message->binhex == NULL) && |
|
1013 |
+ (old_message->yenc == NULL)) |
|
1014 |
+ return 0; |
|
1015 |
+ |
|
1016 |
+ m->body_last = m->body_first; |
|
1017 |
+ rc = 0; |
|
1018 |
+ } else { |
|
1019 |
+ m->body_last = m->body_first = textMove(NULL, t); |
|
1020 |
+ if(m->body_first == NULL) |
|
1021 |
+ rc = -1; |
|
1022 |
+ else |
|
1023 |
+ rc = 0; |
|
1024 |
+ } |
|
1025 |
+ } else { |
|
1026 |
+ m->body_last = textMove(m->body_last, t); |
|
1027 |
+ if(m->body_last == NULL) { |
|
1028 |
+ rc = -1; |
|
1029 |
+ m->body_last = m->body_first; |
|
1030 |
+ } else |
|
1031 |
+ rc = 0; |
|
1032 |
+ } |
|
1033 |
+ |
|
1034 |
+ while(m->body_last->t_next) { |
|
1035 |
+ m->body_last = m->body_last->t_next; |
|
1036 |
+ if(m->body_last->t_line) |
|
1037 |
+ messageIsEncoding(m); |
|
1038 |
+ } |
|
1039 |
+ |
|
1040 |
+ return rc; |
|
1041 |
+} |
|
1042 |
+ |
|
1043 |
+/* |
|
967 | 1044 |
* See if the last line marks the start of a non MIME inclusion that |
968 | 1045 |
* will need to be scanned |
969 | 1046 |
*/ |
... | ... |
@@ -974,11 +1051,6 @@ messageIsEncoding(message *m) |
974 | 974 |
static const char binhex[] = "(This file must be converted with BinHex 4.0)"; |
975 | 975 |
const char *line = lineGetData(m->body_last->t_line); |
976 | 976 |
|
977 |
- /* not enough matches to warrant this test */ |
|
978 |
- /*if(lineGetRefCount(m->body_last->t_line) > 1) { |
|
979 |
- return; |
|
980 |
- }*/ |
|
981 |
- |
|
982 | 977 |
if((m->encoding == NULL) && |
983 | 978 |
(strncasecmp(line, encoding, sizeof(encoding) - 1) == 0) && |
984 | 979 |
(strstr(line, "7bit") == NULL)) |
... | ... |
@@ -1015,18 +1087,6 @@ messageGetBody(message *m) |
1015 | 1015 |
} |
1016 | 1016 |
|
1017 | 1017 |
/* |
1018 |
- * Clean up the message by removing trailing spaces and blank lines |
|
1019 |
- */ |
|
1020 |
-void |
|
1021 |
-messageClean(message *m) |
|
1022 |
-{ |
|
1023 |
- text *newEnd = textClean(m->body_first); |
|
1024 |
- |
|
1025 |
- if(newEnd) |
|
1026 |
- m->body_last = newEnd; |
|
1027 |
-} |
|
1028 |
- |
|
1029 |
-/* |
|
1030 | 1018 |
* Export a message using the given export routines |
1031 | 1019 |
* |
1032 | 1020 |
* TODO: It really should export into an array, one |
... | ... |
@@ -65,8 +65,8 @@ encoding_type messageGetEncoding(const message *m); |
65 | 65 |
int messageAddLine(message *m, line_t *line); |
66 | 66 |
int messageAddStr(message *m, const char *data); |
67 | 67 |
int messageAddStrAtTop(message *m, const char *data); |
68 |
+int messageMoveText(message *m, text *t, message *old_message); |
|
68 | 69 |
text *messageGetBody(message *m); |
69 |
-void messageClean(message *m); |
|
70 | 70 |
unsigned char *base64Flush(message *m, unsigned char *buf); |
71 | 71 |
fileblob *messageToFileblob(message *m, const char *dir, int destroy); |
72 | 72 |
blob *messageToBlob(message *m, int destroy); |
... | ... |
@@ -134,18 +134,6 @@ textDestroy(text *t_head) |
134 | 134 |
} |
135 | 135 |
} |
136 | 136 |
|
137 |
-/* |
|
138 |
- * Remove trailing spaces from the lines and trailing blank lines |
|
139 |
- * This could be used to remove trailing blank lines, empty lines etc., |
|
140 |
- * but it probably isn't worth the time taken given that it won't reclaim |
|
141 |
- * much memory |
|
142 |
- */ |
|
143 |
-text * |
|
144 |
-textClean(text *t_head) |
|
145 |
-{ |
|
146 |
- return t_head; |
|
147 |
-} |
|
148 |
- |
|
149 | 137 |
/* Clone the current object */ |
150 | 138 |
static text * |
151 | 139 |
textCopy(const text *t_head) |
... | ... |
@@ -424,8 +412,7 @@ addToFileblob(const line_t *line, void *arg) |
424 | 424 |
if(line) { |
425 | 425 |
const char *l = lineGetData(line); |
426 | 426 |
|
427 |
- if(l) |
|
428 |
- fileblobAddData(fb, (const unsigned char *)l, strlen(l)); |
|
427 |
+ fileblobAddData(fb, (const unsigned char *)l, strlen(l)); |
|
429 | 428 |
} |
430 | 429 |
fileblobAddData(fb, (const unsigned char *)"\n", 1); |
431 | 430 |
} |
... | ... |
@@ -49,7 +49,6 @@ typedef struct text { |
49 | 49 |
#include "message.h" |
50 | 50 |
|
51 | 51 |
void textDestroy(text *t_head); |
52 |
-text *textClean(text *t_head); |
|
53 | 52 |
text *textAddMessage(text *aText, message *aMessage); |
54 | 53 |
text *textMove(text *t_head, text *t); |
55 | 54 |
blob *textToBlob(text *t, blob *b, int destroy); |