along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
-
-#include <microhttpd.h>
-
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
#endif
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
-#include "sd-journal.h"
-#include "sd-daemon.h"
#include "sd-bus.h"
-#include "log.h"
-#include "util.h"
+#include "sd-daemon.h"
+#include "sd-journal.h"
+
#include "bus-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "hostname-util.h"
+#include "log.h"
#include "logs-show.h"
#include "microhttpd-util.h"
-#include "build.h"
-#include "fileio.h"
+#include "parse-util.h"
#include "sigbus.h"
+#include "util.h"
static char *arg_key_pem = NULL;
static char *arg_cert_pem = NULL;
if (!m)
return;
- if (m->journal)
- sd_journal_close(m->journal);
+ sd_journal_close(m->journal);
- if (m->tmp)
- fclose(m->tmp);
+ safe_fclose(m->tmp);
free(m->cursor);
free(m);
return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM);
}
+static int request_meta_ensure_tmp(RequestMeta *m) {
+ if (m->tmp)
+ rewind(m->tmp);
+ else {
+ int fd;
+
+ fd = open_tmpfile("/tmp", O_RDWR|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ m->tmp = fdopen(fd, "w+");
+ if (!m->tmp) {
+ safe_close(fd);
+ return -errno;
+ }
+ }
+
+ return 0;
+}
+
static ssize_t request_reader_entries(
void *cls,
uint64_t pos,
m->n_skip = 0;
- if (m->tmp)
- rewind(m->tmp);
- else {
- m->tmp = tmpfile();
- if (!m->tmp) {
- log_error_errno(errno, "Failed to create temporary file: %m");
- return MHD_CONTENT_READER_END_WITH_ERROR;
- }
+ r = request_meta_ensure_tmp(m);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create temporary file: %m");
+ return MHD_CONTENT_READER_END_WITH_ERROR;
}
r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH, NULL);
return -ENOMEM;
m->cursor[strcspn(m->cursor, WHITESPACE)] = 0;
- if (isempty(m->cursor)) {
- free(m->cursor);
- m->cursor = NULL;
- }
+ if (isempty(m->cursor))
+ m->cursor = mfree(m->cursor);
return 0;
}
if (m->n_fields_set)
m->n_fields -= 1;
- if (m->tmp)
- rewind(m->tmp);
- else {
- m->tmp = tmpfile();
- if (!m->tmp) {
- log_error_errno(errno, "Failed to create temporary file: %m");
- return MHD_CONTENT_READER_END_WITH_ERROR;
- }
+ r = request_meta_ensure_tmp(m);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create temporary file: %m");
+ return MHD_CONTENT_READER_END_WITH_ERROR;
}
r = output_field(m->tmp, m->mode, d, l);
RequestMeta *m = connection_cls;
int r;
_cleanup_free_ char* hostname = NULL, *os_name = NULL;
- uint64_t cutoff_from = 0, cutoff_to = 0, usage;
+ uint64_t cutoff_from = 0, cutoff_to = 0, usage = 0;
char *json;
sd_id128_t mid, bid;
_cleanup_free_ char *v = NULL;
return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL) == -ENOENT)
- parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
+ (void) parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
get_virtualization(&v);
"\"cutoff_to_realtime\" : \"%"PRIu64"\" }\n",
SD_ID128_FORMAT_VAL(mid),
SD_ID128_FORMAT_VAL(bid),
- hostname_cleanup(hostname, false),
+ hostname_cleanup(hostname),
os_name ? os_name : "Linux",
v ? v : "bare",
usage,
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_KEY:
if (arg_key_pem) {
{ MHD_OPTION_END, 0, NULL },
{ MHD_OPTION_END, 0, NULL }};
int opts_pos = 2;
- int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG;
+
+ /* We force MHD_USE_PIPE_FOR_SHUTDOWN here, in order
+ * to make sure libmicrohttpd doesn't use shutdown()
+ * on our listening socket, which would break socket
+ * re-activation. See
+ *
+ * https://lists.gnu.org/archive/html/libmicrohttpd/2015-09/msg00014.html
+ * https://github.com/systemd/systemd/pull/1286
+ */
+
+ int flags =
+ MHD_USE_DEBUG |
+ MHD_USE_DUAL_STACK |
+ MHD_USE_PIPE_FOR_SHUTDOWN |
+ MHD_USE_POLL |
+ MHD_USE_THREAD_PER_CONNECTION;
if (n > 0)
opts[opts_pos++] = (struct MHD_OptionItem)