switch (session->state) {
case STATE_COMMAND:
- s = evbuffer_readline (EVBUFFER_INPUT (bev));
+ s = buffer_readline (session->session_pool, EVBUFFER_INPUT (bev));
msg_debug ("read_socket: got '%s' string from user", s);
if (s != NULL && *s != 0) {
len = strlen (s);
else {
bufferevent_enable (bev, EV_WRITE);
}
- if (s != NULL) {
- free (s);
- }
break;
case STATE_LEARN:
i = bufferevent_read (bev, session->learn_buf->pos, session->learn_buf->free);
return new;
}
+/*
+ * These functions are from libevent where they are static and not exported anywhere
+ * XXX: think how to avoid this
+ */
+
+char *
+buffer_readline (memory_pool_t *pool, struct evbuffer *buf)
+{
+ u_char *data = EVBUFFER_DATA (buf);
+ size_t len = EVBUFFER_LENGTH (buf);
+ char *line, fch, sch;
+ unsigned int i;
+
+ for (i = 0; i < len; i++) {
+ if (data[i] == '\r' || data[i] == '\n') {
+ break;
+ }
+ }
+
+ if (i == len) {
+ return (NULL);
+ }
+
+ line = memory_pool_alloc (pool, i + 1);
+
+ memcpy (line, data, i);
+ line[i] = '\0';
+
+ /*
+ * Some protocols terminate a line with '\r\n', so check for
+ * that, too.
+ */
+ if ( i < len - 1 ) {
+ fch = data[i], sch = data[i+1];
+
+ /* Drain one more character if needed */
+ if ( (sch == '\r' || sch == '\n') && sch != fch )
+ i += 1;
+ }
+
+ evbuffer_drain (buf, i + 1);
+
+ return (line);
+}
+
/*
* vi:ts=4
*/
/* Replace %r with rcpt value and %f with from value, new string is allocated in pool */
char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from);
+/* Replace libevent evbuffer_readline with memory_pool variant */
+char* buffer_readline (memory_pool_t *pool, struct evbuffer *buf);
+
#endif
switch (task->state) {
case READ_COMMAND:
case READ_HEADER:
- s = evbuffer_readline (EVBUFFER_INPUT (bev));
+ s = buffer_readline (task->task_pool, EVBUFFER_INPUT (bev));
+ if (s == NULL) {
+ msg_debug ("read_socket: got incomplete line from user");
+ return;
+ }
if (read_rspamd_input_line (task, s) != 0) {
task->last_error = "Read error";
task->error_code = RSPAMD_NETWORK_ERROR;
bufferevent_enable (bev, EV_WRITE);
bufferevent_disable (bev, EV_READ);
}
- free (s);
break;
case READ_MESSAGE:
r = bufferevent_read (bev, task->msg->pos, task->msg->free);