Have an el_job_read function.
authorPierre Habouzit <madcoder@debian.org>
Fri, 11 Jan 2008 21:40:06 +0000 (22:40 +0100)
committerPierre Habouzit <madcoder@debian.org>
Fri, 11 Jan 2008 21:40:06 +0000 (22:40 +0100)
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
lib-sys/evtloop.c
lib-sys/evtloop.h

index 2dbfc9e..76d6b33 100644 (file)
@@ -119,6 +119,34 @@ int el_job_connect(job_t *w, struct sockaddr *addr, socklen_t len,
     return el_job_release(w, EL_ERROR);
 }
 
+ssize_t el_job_read(job_t *w, buffer_t *buf)
+{
+    ssize_t nr;
+
+    buffer_ensure(buf, BUFSIZ);
+
+    if (w->session) {
+        nr = gnutls_record_recv(w->session, buf->data + buf->len, BUFSIZ);
+        if (nr < 0 && gnutls_error_is_fatal(nr))
+            return el_job_release(w, EL_RDHUP);
+        if (nr <= 0) {
+            int wr = gnutls_record_get_direction(w->session);
+            return el_job_setemode(w, wr ? EL_WRITING : EL_READING);
+        }
+        EL_JOB_CHECK(el_job_setemode(w, w->mode));
+    } else {
+        nr = read(w->fd, buf->data + buf->len, BUFSIZ);
+        if (nr < 0) {
+            if (errno == EINTR || errno == EAGAIN)
+                return 0;
+        }
+        if (nr <= 0)
+            return el_job_release(w, EL_RDHUP);
+    }
+    buffer_extend(buf, nr);
+    return nr;
+}
+
 int el_dispatch(int timeout)
 {
     struct epoll_event events[FD_SETSIZE];
index 7c46bf6..84f2eb0 100644 (file)
@@ -22,6 +22,7 @@
 #define MUTT_LIB_SYS_EVTLOOP_H
 
 #include <lib-lib/lib-lib.h>
+#include <gnutls/gnutls.h>
 
 typedef enum el_state {
     EL_LLP_INIT,
@@ -55,6 +56,8 @@ typedef enum el_event {
 typedef struct job_t {
     int fd;
 
+    gnutls_session_t session;
+
     el_state state : 2;
     el_mode  mode  : 3;
     el_mode  emode : 3;
@@ -75,10 +78,14 @@ typedef struct machine_t {
     void (*finalize)(job_t *w, el_status);
 } machine_t;
 
+#define EL_JOB_CHECK(expr) \
+    do { if ((expr) < 0) return -1; } while (0)
+
 __must_check__ int el_job_setmode(job_t *w, el_mode);
 __must_check__ int el_job_release(job_t *j, el_status);
 __must_check__ int el_job_connect(job_t *w, struct sockaddr *, socklen_t len,
                                   int type, int proto);
+__must_check__ ssize_t el_job_read(job_t *w, buffer_t *buf);
 
 static inline job_t *el_job_start(const machine_t *m, void *cfg) {
     job_t *w = job_new();