chiark / gitweb /
µhttp-util: setup gnutls logs in one function
[elogind.git] / src / journal-remote / journal-remote.c
index 01cfef546997aa8edb7cdc9a2a0a8dee6ef3edda..82291a4f7f1c053f793d6aca4c2e6aaefe192e5e 100644 (file)
@@ -285,6 +285,8 @@ static int dispatch_raw_source_event(sd_event_source *event,
                                      int fd,
                                      uint32_t revents,
                                      void *userdata);
+static int dispatch_raw_source_until_block(sd_event_source *event,
+                                           void *userdata);
 static int dispatch_blocking_source_event(sd_event_source *event,
                                           void *userdata);
 static int dispatch_raw_connection_event(sd_event_source *event,
@@ -372,8 +374,15 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
 
         r = sd_event_add_io(s->events, &source->event,
                             fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI,
-                            dispatch_raw_source_event, s);
-        if (r == -EPERM) {
+                            dispatch_raw_source_event, source);
+        if (r == 0) {
+                /* Add additional source for buffer processing. It will be
+                 * enabled later. */
+                r = sd_event_add_defer(s->events, &source->buffer_event,
+                                       dispatch_raw_source_until_block, source);
+                if (r == 0)
+                        sd_event_source_set_enabled(source->buffer_event, SD_EVENT_OFF);
+        } else if (r == -EPERM) {
                 log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name);
                 r = sd_event_add_defer(s->events, &source->event,
                                        dispatch_blocking_source_event, source);
@@ -507,7 +516,7 @@ static int process_http_upload(
 
         while (true) {
                 r = process_source(source, arg_compress, arg_seal);
-                if (r == -EAGAIN || r == -EWOULDBLOCK)
+                if (r == -EAGAIN)
                         break;
                 else if (r < 0) {
                         log_warning("Failed to process data for connection %p", connection);
@@ -689,7 +698,7 @@ static int setup_microhttpd_server(RemoteServer *s,
         info = MHD_get_daemon_info(d->daemon, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY);
         if (!info) {
                 log_error("µhttp returned NULL daemon info");
-                r = -ENOTSUP;
+                r = -EOPNOTSUPP;
                 goto error;
         }
 
@@ -993,15 +1002,18 @@ static void server_destroy(RemoteServer *s) {
  **********************************************************************
  **********************************************************************/
 
-static int dispatch_raw_source_event(sd_event_source *event,
-                                     int fd,
-                                     uint32_t revents,
-                                     void *userdata) {
+static int handle_raw_source(sd_event_source *event,
+                             int fd,
+                             uint32_t revents,
+                             RemoteServer *s) {
 
-        RemoteServer *s = userdata;
         RemoteSource *source;
         int r;
 
+        /* Returns 1 if there might be more data pending,
+         * 0 if data is currently exhausted, negative on error.
+         */
+
         assert(fd >= 0 && fd < (ssize_t) s->sources_size);
         source = s->sources[fd];
         assert(source->fd == fd);
@@ -1032,11 +1044,48 @@ static int dispatch_raw_source_event(sd_event_source *event,
                 return 1;
 }
 
+static int dispatch_raw_source_until_block(sd_event_source *event,
+                                           void *userdata) {
+        RemoteSource *source = userdata;
+        int r;
+
+        /* Make sure event stays around even if source is destroyed */
+        sd_event_source_ref(event);
+
+        r = handle_raw_source(event, source->fd, EPOLLIN, server);
+        if (r != 1)
+                /* No more data for now */
+                sd_event_source_set_enabled(event, SD_EVENT_OFF);
+
+        sd_event_source_unref(event);
+
+        return r;
+}
+
+static int dispatch_raw_source_event(sd_event_source *event,
+                                     int fd,
+                                     uint32_t revents,
+                                     void *userdata) {
+        RemoteSource *source = userdata;
+        int r;
+
+        assert(source->event);
+        assert(source->buffer_event);
+
+        r = handle_raw_source(event, fd, EPOLLIN, server);
+        if (r == 1)
+                /* Might have more data. We need to rerun the handler
+                 * until we are sure the buffer is exhausted. */
+                sd_event_source_set_enabled(source->buffer_event, SD_EVENT_ON);
+
+        return r;
+}
+
 static int dispatch_blocking_source_event(sd_event_source *event,
                                           void *userdata) {
         RemoteSource *source = userdata;
 
-        return dispatch_raw_source_event(event, source->fd, EPOLLIN, server);
+        return handle_raw_source(event, source->fd, EPOLLIN, server);
 }
 
 static int accept_connection(const char* type, int fd,
@@ -1454,31 +1503,6 @@ static int load_certificates(char **key, char **cert, char **trust) {
         return 0;
 }
 
-static int setup_gnutls_logger(char **categories) {
-        if (!arg_listen_http && !arg_listen_https)
-                return 0;
-
-#ifdef HAVE_GNUTLS
-        {
-                char **cat;
-                int r;
-
-                gnutls_global_set_log_function(log_func_gnutls);
-
-                if (categories) {
-                        STRV_FOREACH(cat, categories) {
-                                r = log_enable_gnutls_category(*cat);
-                                if (r < 0)
-                                        return r;
-                        }
-                } else
-                        log_reset_gnutls_level();
-        }
-#endif
-
-        return 0;
-}
-
 int main(int argc, char **argv) {
         RemoteServer s = {};
         int r;
@@ -1495,9 +1519,12 @@ int main(int argc, char **argv) {
         if (r <= 0)
                 return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 
-        r = setup_gnutls_logger(arg_gnutls_log);
-        if (r < 0)
-                return EXIT_FAILURE;
+
+        if (arg_listen_http || arg_listen_https) {
+                r = setup_gnutls_logger(arg_gnutls_log);
+                if (r < 0)
+                        return EXIT_FAILURE;
+        }
 
         if (arg_listen_https || https_socket >= 0)
                 if (load_certificates(&key, &cert, &trust) < 0)