ryantimwilson / rpms / systemd

Forked from rpms/systemd a month ago
Clone
Harald Hoyer fe20ad
From 8517d72d5e52fb99eedfe4667303d5883fd38698 Mon Sep 17 00:00:00 2001
Harald Hoyer fe20ad
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Harald Hoyer fe20ad
Date: Fri, 19 Jul 2013 04:02:50 -0400
Harald Hoyer fe20ad
Subject: [PATCH] journalctl: use _COMM= match for scripts
Harald Hoyer fe20ad
Harald Hoyer fe20ad
In case of scripts, _EXE is set to the interpreter name, and
Harald Hoyer fe20ad
_COMM is set based on the file name. Add a match for _COMM,
Harald Hoyer fe20ad
and _EXE if the interpreter is not a link (e.g. for yum,
Harald Hoyer fe20ad
the interpreter is /usr/bin/python, but it is a link to
Harald Hoyer fe20ad
/usr/bin/python2, which in turn is a link to /usr/bin/python2.7,
Harald Hoyer fe20ad
at least on Fedora, so we end up with _EXE=/usr/bin/python2.7).
Harald Hoyer fe20ad
I don't think that such link chasing makes sense, because
Harald Hoyer fe20ad
the final _EXE name is more likely to change.
Harald Hoyer fe20ad
---
Harald Hoyer fe20ad
 src/journal/journalctl.c | 30 ++++++++++++++++++++++++++----
Harald Hoyer fe20ad
 src/shared/fileio.c      | 29 +++++++++++++++++++++++++++++
Harald Hoyer fe20ad
 src/shared/fileio.h      |  2 ++
Harald Hoyer fe20ad
 src/test/test-fileio.c   | 35 +++++++++++++++++++++++++++++++++++
Harald Hoyer fe20ad
 4 files changed, 92 insertions(+), 4 deletions(-)
Harald Hoyer fe20ad
Harald Hoyer fe20ad
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
Harald Hoyer fe20ad
index 083a597..dde2ed7 100644
Harald Hoyer fe20ad
--- a/src/journal/journalctl.c
Harald Hoyer fe20ad
+++ b/src/journal/journalctl.c
Harald Hoyer fe20ad
@@ -45,6 +45,7 @@
Harald Hoyer fe20ad
 #include "logs-show.h"
Harald Hoyer fe20ad
 #include "util.h"
Harald Hoyer fe20ad
 #include "path-util.h"
Harald Hoyer fe20ad
+#include "fileio.h"
Harald Hoyer fe20ad
 #include "build.h"
Harald Hoyer fe20ad
 #include "pager.h"
Harald Hoyer fe20ad
 #include "logs-show.h"
Harald Hoyer fe20ad
@@ -627,8 +628,9 @@ static int add_matches(sd_journal *j, char **args) {
Harald Hoyer fe20ad
                 if (streq(*i, "+"))
Harald Hoyer fe20ad
                         r = sd_journal_add_disjunction(j);
Harald Hoyer fe20ad
                 else if (path_is_absolute(*i)) {
Harald Hoyer fe20ad
-                        _cleanup_free_ char *p, *t = NULL;
Harald Hoyer fe20ad
+                        _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
Harald Hoyer fe20ad
                         const char *path;
Harald Hoyer fe20ad
+                        _cleanup_free_ char *interpreter = NULL;
Harald Hoyer fe20ad
                         struct stat st;
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
                         p = canonicalize_file_name(*i);
Harald Hoyer fe20ad
@@ -639,9 +641,27 @@ static int add_matches(sd_journal *j, char **args) {
Harald Hoyer fe20ad
                                 return -errno;
Harald Hoyer fe20ad
                         }
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
-                        if (S_ISREG(st.st_mode) && (0111 & st.st_mode))
Harald Hoyer fe20ad
-                                t = strappend("_EXE=", path);
Harald Hoyer fe20ad
-                        else if (S_ISCHR(st.st_mode))
Harald Hoyer fe20ad
+                        if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
Harald Hoyer fe20ad
+                                if (executable_is_script(path, &interpreter) > 0) {
Harald Hoyer fe20ad
+                                        _cleanup_free_ char *comm;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+                                        comm = strndup(path_get_file_name(path), 15);
Harald Hoyer fe20ad
+                                        if (!comm)
Harald Hoyer fe20ad
+                                                return log_oom();
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+                                        t = strappend("_COMM=", comm);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+                                        /* Append _EXE only if the interpreter is not a link.
Harald Hoyer fe20ad
+                                           Otherwise it might be outdated often. */
Harald Hoyer fe20ad
+                                        if (lstat(interpreter, &st) == 0 &&
Harald Hoyer fe20ad
+                                            !S_ISLNK(st.st_mode)) {
Harald Hoyer fe20ad
+                                                t2 = strappend("_EXE=", interpreter);
Harald Hoyer fe20ad
+                                                if (!t2)
Harald Hoyer fe20ad
+                                                        return log_oom();
Harald Hoyer fe20ad
+                                        }
Harald Hoyer fe20ad
+                                } else
Harald Hoyer fe20ad
+                                        t = strappend("_EXE=", path);
Harald Hoyer fe20ad
+                        } else if (S_ISCHR(st.st_mode))
Harald Hoyer fe20ad
                                 asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
Harald Hoyer fe20ad
                         else if (S_ISBLK(st.st_mode))
Harald Hoyer fe20ad
                                 asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
Harald Hoyer fe20ad
@@ -654,6 +674,8 @@ static int add_matches(sd_journal *j, char **args) {
Harald Hoyer fe20ad
                                 return log_oom();
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
                         r = sd_journal_add_match(j, t, 0);
Harald Hoyer fe20ad
+                        if (t2)
Harald Hoyer fe20ad
+                                r = sd_journal_add_match(j, t2, 0);
Harald Hoyer fe20ad
                 } else
Harald Hoyer fe20ad
                         r = sd_journal_add_match(j, *i, 0);
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
Harald Hoyer fe20ad
index dc13c9e..2b1dab8 100644
Harald Hoyer fe20ad
--- a/src/shared/fileio.c
Harald Hoyer fe20ad
+++ b/src/shared/fileio.c
Harald Hoyer fe20ad
@@ -593,3 +593,32 @@ int write_env_file(const char *fname, char **l) {
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
         return r;
Harald Hoyer fe20ad
 }
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+int executable_is_script(const char *path, char **interpreter) {
Harald Hoyer fe20ad
+        int r;
Harald Hoyer fe20ad
+        char _cleanup_free_ *line = NULL;
Harald Hoyer fe20ad
+        int len;
Harald Hoyer fe20ad
+        char *ans;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        assert(path);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        r = read_one_line_file(path, &line);
Harald Hoyer fe20ad
+        if (r < 0)
Harald Hoyer fe20ad
+                return r;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        if (!startswith(line, "#!"))
Harald Hoyer fe20ad
+                return 0;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        ans = strstrip(line + 2);
Harald Hoyer fe20ad
+        len = strcspn(ans, " \t");
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        if (len == 0)
Harald Hoyer fe20ad
+                return 0;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        ans = strndup(ans, len);
Harald Hoyer fe20ad
+        if (!ans)
Harald Hoyer fe20ad
+                return -ENOMEM;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        *interpreter = ans;
Harald Hoyer fe20ad
+        return 1;
Harald Hoyer fe20ad
+}
Harald Hoyer fe20ad
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
Harald Hoyer fe20ad
index 0ca6878..a0aae28 100644
Harald Hoyer fe20ad
--- a/src/shared/fileio.h
Harald Hoyer fe20ad
+++ b/src/shared/fileio.h
Harald Hoyer fe20ad
@@ -35,3 +35,5 @@ int read_full_file(const char *fn, char **contents, size_t *size);
Harald Hoyer fe20ad
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
Harald Hoyer fe20ad
 int load_env_file(const char *fname, const char *separator, char ***l);
Harald Hoyer fe20ad
 int write_env_file(const char *fname, char **l);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+int executable_is_script(const char *path, char **interpreter);
Harald Hoyer fe20ad
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
Harald Hoyer fe20ad
index d56f7cc..b08e796 100644
Harald Hoyer fe20ad
--- a/src/test/test-fileio.c
Harald Hoyer fe20ad
+++ b/src/test/test-fileio.c
Harald Hoyer fe20ad
@@ -139,7 +139,42 @@ static void test_parse_env_file(void) {
Harald Hoyer fe20ad
         unlink("/tmp/test-fileio");
Harald Hoyer fe20ad
 }
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
+static void test_executable_is_script(void) {
Harald Hoyer fe20ad
+        char t[] = "/tmp/test-executable-XXXXXX";
Harald Hoyer fe20ad
+        int fd, r;
Harald Hoyer fe20ad
+        FILE *f;
Harald Hoyer fe20ad
+        char *command;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        fd = mkostemp(t, O_CLOEXEC);
Harald Hoyer fe20ad
+        assert_se(fd >= 0);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        f = fdopen(fd, "w");
Harald Hoyer fe20ad
+        assert_se(f);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        fputs("#! /bin/script -a -b \ngoo goo", f);
Harald Hoyer fe20ad
+        fflush(f);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        r = executable_is_script(t, &command);
Harald Hoyer fe20ad
+        assert_se(r > 0);
Harald Hoyer fe20ad
+        assert_se(streq(command, "/bin/script"));
Harald Hoyer fe20ad
+        free(command);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        r = executable_is_script("/bin/sh", &command);
Harald Hoyer fe20ad
+        assert_se(r == 0);
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        r = executable_is_script("/usr/bin/yum", &command);
Harald Hoyer fe20ad
+        assert_se(r > 0 || r == -ENOENT);
Harald Hoyer fe20ad
+        if (r > 0) {
Harald Hoyer fe20ad
+                assert_se(startswith(command, "/"));
Harald Hoyer fe20ad
+                free(command);
Harald Hoyer fe20ad
+        }
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        fclose(f);
Harald Hoyer fe20ad
+        unlink(t);
Harald Hoyer fe20ad
+}
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
 int main(int argc, char *argv[]) {
Harald Hoyer fe20ad
         test_parse_env_file();
Harald Hoyer fe20ad
+        test_executable_is_script();
Harald Hoyer fe20ad
         return 0;
Harald Hoyer fe20ad
 }