Browse code

More optimisations

git-svn: trunk@3213

Nigel Horne authored on 2007/09/12 22:25:13
Showing 8 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Sep 12 13:36:37 BST 2007 (njh)
2
+----------------------------------
3
+  * libclamav:	More optimisations
4
+
1 5
 Tue Sep 11 10:33:21 BST 2007 (njh)
2 6
 ----------------------------------
3 7
   * libclamav:	Various code clean ups and optimisations
... ...
@@ -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);