chiark / gitweb /
Merge branch 'master' into journal
authorLennart Poettering <lennart@poettering.net>
Wed, 12 Oct 2011 02:29:11 +0000 (04:29 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 12 Oct 2011 02:29:11 +0000 (04:29 +0200)
1  2 
Makefile.am
src/util.c
src/util.h

diff --combined Makefile.am
index 892072318fb1751436efc8e518b02ef699431a87,dabe32ac46f063605a206e73e0d0b5f99d48fa4f..b26c613d4fc8f379047bb9fbf299bace2e5d23e1
@@@ -20,7 -20,7 +20,7 @@@ ACLOCAL_AMFLAGS = -I m
  SUBDIRS = po
  
  LIBSYSTEMD_LOGIN_CURRENT=0
- LIBSYSTEMD_LOGIN_REVISION=5
+ LIBSYSTEMD_LOGIN_REVISION=6
  LIBSYSTEMD_LOGIN_AGE=0
  
  LIBSYSTEMD_DAEMON_CURRENT=0
@@@ -134,8 -134,7 +134,8 @@@ rootbin_PROGRAMS = 
        systemd-ask-password \
        systemd-tty-ask-password-agent \
        systemd-tmpfiles \
 -      systemd-machine-id-setup
 +      systemd-machine-id-setup \
 +        systemd-journalctl
  
  bin_PROGRAMS = \
        systemd-cgls \
@@@ -174,8 -173,7 +174,8 @@@ rootlibexec_PROGRAMS = 
        systemd-detect-virt \
        systemd-sysctl \
          systemd-logind \
 -        systemd-uaccess
 +        systemd-uaccess \
 +        systemd-journald
  
  if ENABLE_BINFMT
  rootlibexec_PROGRAMS += \
@@@ -227,9 -225,7 +227,9 @@@ noinst_PROGRAMS = 
        test-env-replace \
        test-strv \
          test-login \
 -        test-install
 +        test-install \
 +        test-id128 \
 +        test-journal
  
  if HAVE_PAM
  pamlib_LTLIBRARIES = \
@@@ -341,7 -337,9 +341,9 @@@ dist_systemunit_DATA = 
        units/halt.target \
        units/kexec.target \
        units/local-fs.target \
+         units/local-fs-pre.target \
        units/remote-fs.target \
+         units/remote-fs-pre.target \
        units/cryptsetup.target \
        units/network.target \
        units/nss-lookup.target \
@@@ -689,8 -687,7 +691,8 @@@ libsystemd_core_la_SOURCES = 
          src/dbus-common.c \
          src/sd-daemon.c \
          src/install.c \
 -        src/cgroup-attr.c
 +        src/cgroup-attr.c \
 +        src/sd-id128.c
  
  nodist_libsystemd_core_la_SOURCES = \
          src/load-fragment-gperf.c \
@@@ -952,59 -949,6 +954,59 @@@ test_install_CFLAGS = 
  test_install_LDADD = \
        libsystemd-basic.la
  
 +test_id128_SOURCES = \
 +      src/test-id128.c \
 +        src/sd-id128.c
 +
 +test_id128_CFLAGS = \
 +      $(AM_CFLAGS)
 +
 +test_id128_LDADD = \
 +      libsystemd-basic.la
 +
 +test_journal_SOURCES = \
 +      src/journal/test-journal.c \
 +      src/journal/sd-journal.c \
 +        src/journal/journal-file.c \
 +        src/journal/lookup3.c \
 +        src/sd-id128.c
 +
 +test_journal_CFLAGS = \
 +      $(AM_CFLAGS)
 +
 +test_journal_LDADD = \
 +      libsystemd-basic.la
 +
 +systemd_journald_SOURCES = \
 +      src/journal/journald.c \
 +      src/journal/sd-journal.c \
 +        src/journal/journal-file.c \
 +        src/journal/lookup3.c \
 +        src/sd-id128.c \
 +        src/acl-util.c
 +
 +systemd_journald_CFLAGS = \
 +      $(AM_CFLAGS) \
 +        $(ACL_CFLAGS)
 +
 +systemd_journald_LDADD = \
 +      libsystemd-basic.la \
 +        libsystemd-daemon.la \
 +        $(ACL_LIBS)
 +
 +systemd_journalctl_SOURCES = \
 +      src/journal/journalctl.c \
 +      src/journal/sd-journal.c \
 +        src/journal/journal-file.c \
 +        src/journal/lookup3.c \
 +        src/sd-id128.c
 +
 +systemd_journalctl_CFLAGS = \
 +      $(AM_CFLAGS)
 +
 +systemd_journalctl_LDADD = \
 +      libsystemd-basic.la
 +
  systemd_stdout_syslog_bridge_SOURCES = \
        src/stdout-syslog-bridge.c \
        src/tcpwrap.c
@@@ -1149,12 -1093,10 +1151,12 @@@ systemd_uaccess_SOURCES = 
  
  if HAVE_ACL
  systemd_logind_SOURCES += \
 -      src/logind-acl.c
 +      src/logind-acl.c \
 +        src/acl-util.c
  
  systemd_uaccess_SOURCES += \
 -      src/logind-acl.c
 +      src/logind-acl.c \
 +        src/acl-util.c
  endif
  
  systemd_uaccess_CFLAGS = \
@@@ -1202,8 -1144,7 +1204,8 @@@ systemd_tmpfiles_LDADD = 
  
  systemd_machine_id_setup_SOURCES = \
        src/machine-id-setup.c \
 -      src/machine-id-main.c
 +      src/machine-id-main.c \
 +        src/sd-id128.c
  
  systemd_machine_id_setup_CFLAGS = \
        $(AM_CFLAGS)
diff --combined src/util.c
index a3cfe864b6e44c5cf38e04c7c0a18386be0364e4,e93e6f6cf5c962e90ac7b8a4a29cc8cfe00a80ce..26c2f22ff0c77c5f6416fac0c51b8f41d2065743
@@@ -55,7 -55,6 +55,7 @@@
  #include <linux/rtc.h>
  #include <glob.h>
  #include <grp.h>
 +#include <sys/mman.h>
  
  #include "macro.h"
  #include "util.h"
@@@ -74,7 -73,7 +74,7 @@@ size_t page_size(void) 
          static __thread size_t pgsz = 0;
          long r;
  
 -        if (_likely_(pgsz))
 +        if (_likely_(pgsz > 0))
                  return pgsz;
  
          assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
@@@ -994,51 -993,46 +994,51 @@@ char *truncate_nl(char *s) 
          return s;
  }
  
 -int get_process_name(pid_t pid, char **name) {
 -        char *p;
 +int get_process_comm(pid_t pid, char **name) {
          int r;
  
 -        assert(pid >= 1);
          assert(name);
  
 -        if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
 -                return -ENOMEM;
 -
 -        r = read_one_line_file(p, name);
 -        free(p);
 +        if (pid == 0)
 +                r = read_one_line_file("/proc/self/comm", name);
 +        else {
 +                char *p;
 +                if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
 +                        return -ENOMEM;
  
 -        if (r < 0)
 -                return r;
 +                r = read_one_line_file(p, name);
 +                free(p);
 +        }
  
 -        return 0;
 +        return r;
  }
  
 -int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
 -        char *p, *r, *k;
 +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
 +        char *r, *k;
          int c;
          bool space = false;
          size_t left;
          FILE *f;
  
 -        assert(pid >= 1);
          assert(max_length > 0);
          assert(line);
  
 -        if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
 -                return -ENOMEM;
 +        if (pid == 0)
 +                f = fopen("/proc/self/cmdline", "re");
 +        else {
 +                char *p;
 +                if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
 +                        return -ENOMEM;
  
 -        f = fopen(p, "re");
 -        free(p);
 +                f = fopen(p, "re");
 +                free(p);
 +        }
  
          if (!f)
                  return -errno;
  
 -        if (!(r = new(char, max_length))) {
 +        r = new(char, max_length);
 +        if (!r) {
                  fclose(f);
                  return -ENOMEM;
          }
  
                  free(r);
  
 -                if ((h = get_process_name(pid, &t)) < 0)
 +                if (!comm_fallback)
 +                        return -ENOENT;
 +
 +                h = get_process_comm(pid, &t);
 +                if (h < 0)
                          return h;
  
 -                h = asprintf(&r, "[%s]", t);
 +                r = join("[", t, "]", NULL);
                  free(t);
  
 -                if (h < 0)
 +                if (!r)
                          return -ENOMEM;
          }
  
          return 0;
  }
  
 +int get_process_exe(pid_t pid, char **name) {
 +        int r;
 +
 +        assert(name);
 +
 +        if (pid == 0)
 +                r = readlink_malloc("/proc/self/exe", name);
 +        else {
 +                char *p;
 +                if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
 +                        return -ENOMEM;
 +
 +                r = readlink_malloc(p, name);
 +                free(p);
 +        }
 +
 +        return r;
 +}
 +
  char *strnappend(const char *s, const char *suffix, size_t b) {
          size_t a;
          char *r;
@@@ -2336,8 -2307,10 +2336,10 @@@ int chvt(int vt) 
                          0
                  };
  
-                 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
-                         return -errno;
+                 if (ioctl(fd, TIOCLINUX, tiocl) < 0) {
+                         r = -errno;
+                         goto fail;
+                 }
  
                  vt = tiocl[0] <= 0 ? 1 : tiocl[0];
          }
          if (ioctl(fd, VT_ACTIVATE, vt) < 0)
                  r = -errno;
  
-         close_nointr_nofail(r);
+ fail:
+         close_nointr_nofail(fd);
          return r;
  }
  
@@@ -3529,22 -3503,6 +3532,22 @@@ int chmod_and_chown(const char *path, m
          return 0;
  }
  
 +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
 +        assert(fd >= 0);
 +
 +        /* Under the assumption that we are running privileged we
 +         * first change the access mode and only then hand out
 +         * ownership to avoid a window where access is too open. */
 +
 +        if (fchmod(fd, mode) < 0)
 +                return -errno;
 +
 +        if (fchown(fd, uid, gid) < 0)
 +                return -errno;
 +
 +        return 0;
 +}
 +
  cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
          cpu_set_t *r;
          unsigned n = 1024;
@@@ -4312,7 -4270,7 +4315,7 @@@ const char *default_term_for_tty(const 
          return term;
  }
  
 -bool dirent_is_file(struct dirent *de) {
 +bool dirent_is_file(const struct dirent *de) {
          assert(de);
  
          if (ignore_file(de->d_name))
          return true;
  }
  
 +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
 +        assert(de);
 +
 +        if (!dirent_is_file(de))
 +                return false;
 +
 +        return endswith(de->d_name, suffix);
 +}
 +
  void execute_directory(const char *directory, DIR *d, char *argv[]) {
          DIR *_d = NULL;
          struct dirent *de;
@@@ -4507,98 -4456,6 +4510,98 @@@ void parse_syslog_priority(char **p, in
          *p += k;
  }
  
 +void skip_syslog_pid(char **buf) {
 +        char *p;
 +
 +        assert(buf);
 +        assert(*buf);
 +
 +        p = *buf;
 +
 +        if (*p != '[')
 +                return;
 +
 +        p++;
 +        p += strspn(p, "0123456789");
 +
 +        if (*p != ']')
 +                return;
 +
 +        p++;
 +
 +        *buf = p;
 +}
 +
 +void skip_syslog_date(char **buf) {
 +        enum {
 +                LETTER,
 +                SPACE,
 +                NUMBER,
 +                SPACE_OR_NUMBER,
 +                COLON
 +        } sequence[] = {
 +                LETTER, LETTER, LETTER,
 +                SPACE,
 +                SPACE_OR_NUMBER, NUMBER,
 +                SPACE,
 +                SPACE_OR_NUMBER, NUMBER,
 +                COLON,
 +                SPACE_OR_NUMBER, NUMBER,
 +                COLON,
 +                SPACE_OR_NUMBER, NUMBER,
 +                SPACE
 +        };
 +
 +        char *p;
 +        unsigned i;
 +
 +        assert(buf);
 +        assert(*buf);
 +
 +        p = *buf;
 +
 +        for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
 +
 +                if (!*p)
 +                        return;
 +
 +                switch (sequence[i]) {
 +
 +                case SPACE:
 +                        if (*p != ' ')
 +                                return;
 +                        break;
 +
 +                case SPACE_OR_NUMBER:
 +                        if (*p == ' ')
 +                                break;
 +
 +                        /* fall through */
 +
 +                case NUMBER:
 +                        if (*p < '0' || *p > '9')
 +                                return;
 +
 +                        break;
 +
 +                case LETTER:
 +                        if (!(*p >= 'A' && *p <= 'Z') &&
 +                            !(*p >= 'a' && *p <= 'z'))
 +                                return;
 +
 +                        break;
 +
 +                case COLON:
 +                        if (*p != ':')
 +                                return;
 +                        break;
 +
 +                }
 +        }
 +
 +        *buf = p;
 +}
 +
  int have_effective_cap(int value) {
          cap_t cap;
          cap_flag_value_t fv;
@@@ -4818,6 -4675,21 +4821,6 @@@ int vt_disallocate(const char *name) 
          return 0;
  }
  
 -
 -static int file_is_conf(const struct dirent *d, const char *suffix) {
 -        assert(d);
 -
 -        if (ignore_file(d->d_name))
 -                return 0;
 -
 -        if (d->d_type != DT_REG &&
 -            d->d_type != DT_LNK &&
 -            d->d_type != DT_UNKNOWN)
 -                return 0;
 -
 -        return endswith(d->d_name, suffix);
 -}
 -
  static int files_add(Hashmap *h, const char *path, const char *suffix) {
          DIR *dir;
          struct dirent buffer, *de;
                  if (!de)
                          break;
  
 -                if (!file_is_conf(de, suffix))
 +                if (!dirent_is_file_with_suffix(de, suffix))
                          continue;
  
                  if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
@@@ -5194,27 -5066,21 +5197,27 @@@ int symlink_or_copy_atomic(const char *
  }
  
  int audit_session_from_pid(pid_t pid, uint32_t *id) {
 -        char *p, *s;
 +        char *s;
          uint32_t u;
          int r;
  
 -        assert(pid >= 1);
          assert(id);
  
          if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
                  return -ENOENT;
  
 -        if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
 -                return -ENOMEM;
 +        if (pid == 0)
 +                r = read_one_line_file("/proc/self/sessionid", &s);
 +        else {
 +                char *p;
 +
 +                if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
 +                        return -ENOMEM;
 +
 +                r = read_one_line_file(p, &s);
 +                free(p);
 +        }
  
 -        r = read_one_line_file(p, &s);
 -        free(p);
          if (r < 0)
                  return r;
  
          return 0;
  }
  
 +int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
 +        char *s;
 +        uid_t u;
 +        int r;
 +
 +        assert(uid);
 +
 +        /* Only use audit login uid if we are executed with sufficient
 +         * capabilities so that pam_loginuid could do its job. If we
 +         * are lacking the CAP_AUDIT_CONTROL capabality we most likely
 +         * are being run in a container and /proc/self/loginuid is
 +         * useless since it probably contains a uid of the host
 +         * system. */
 +
 +        if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
 +                return -ENOENT;
 +
 +        if (pid == 0)
 +                r = read_one_line_file("/proc/self/loginuid", &s);
 +        else {
 +                char *p;
 +
 +                if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0)
 +                        return -ENOMEM;
 +
 +                r = read_one_line_file(p, &s);
 +                free(p);
 +        }
 +
 +        if (r < 0)
 +                return r;
 +
 +        r = parse_uid(s, &u);
 +        free(s);
 +
 +        if (r < 0)
 +                return r;
 +
 +        if (u == (uid_t) -1)
 +                return -ENOENT;
 +
 +        *uid = (uid_t) u;
 +        return 0;
 +}
 +
  bool display_is_local(const char *display) {
          assert(display);
  
@@@ -5883,20 -5704,35 +5886,52 @@@ int strdup_or_null(const char *a, char 
          return 0;
  }
  
 +int prot_from_flags(int flags) {
 +
 +        switch (flags & O_ACCMODE) {
 +
 +        case O_RDONLY:
 +                return PROT_READ;
 +
 +        case O_WRONLY:
 +                return PROT_WRITE;
 +
 +        case O_RDWR:
 +                return PROT_READ|PROT_WRITE;
 +
 +        default:
 +                return -EINVAL;
 +        }
++
+ unsigned long cap_last_cap(void) {
+         static __thread unsigned long saved;
+         static __thread bool valid = false;
+         unsigned long p;
+         if (valid)
+                 return saved;
+         p = (unsigned long) CAP_LAST_CAP;
+         if (prctl(PR_CAPBSET_READ, p) < 0) {
+                 /* Hmm, look downwards, until we find one that
+                  * works */
+                 for (p--; p > 0; p --)
+                         if (prctl(PR_CAPBSET_READ, p) >= 0)
+                                 break;
+         } else {
+                 /* Hmm, look upwards, until we find one that doesn't
+                  * work */
+                 for (;; p++)
+                         if (prctl(PR_CAPBSET_READ, p+1) < 0)
+                                 break;
+         }
+         saved = p;
+         valid = true;
+         return p;
  }
diff --combined src/util.h
index 89a7bec61280c89171ab9eda0a5b9e145c0190db,a71a297eab6b56740efe070d3473dd3118b183f3..1db82f83e0a4ba7d2b2588d1c996507dbc99ed83
@@@ -248,9 -248,8 +248,9 @@@ int parent_of_path(const char *path, ch
  
  int rmdir_parents(const char *path, const char *stop);
  
 -int get_process_name(pid_t pid, char **name);
 -int get_process_cmdline(pid_t pid, size_t max_length, char **line);
 +int get_process_comm(pid_t pid, char **name);
 +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
 +int get_process_exe(pid_t pid, char **name);
  
  char hexchar(int x);
  int unhexchar(char c);
@@@ -275,9 -274,7 +275,9 @@@ bool path_equal(const char *a, const ch
  
  char *ascii_strlower(char *path);
  
 -bool dirent_is_file(struct dirent *de);
 +bool dirent_is_file(const struct dirent *de);
 +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix);
 +
  bool ignore_file(const char *filename);
  
  bool chars_intersect(const char *a, const char *b);
@@@ -366,7 -363,6 +366,7 @@@ int get_ctty_devnr(pid_t pid, dev_t *d)
  int get_ctty(pid_t, dev_t *_devnr, char **r);
  
  int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
 +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
  
  int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
  
@@@ -419,8 -415,6 +419,8 @@@ bool nulstr_contains(const char*nulstr
  bool plymouth_running(void);
  
  void parse_syslog_priority(char **p, int *priority);
 +void skip_syslog_pid(char **buf);
 +void skip_syslog_date(char **buf);
  
  int have_effective_cap(int value);
  
@@@ -449,7 -443,6 +449,7 @@@ int hwclock_get_time(struct tm *tm)
  int hwclock_set_time(const struct tm *tm);
  
  int audit_session_from_pid(pid_t pid, uint32_t *id);
 +int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
  
  bool display_is_local(const char *display);
  int socket_from_display(const char *display, char **path);
@@@ -513,6 -506,6 +513,8 @@@ extern char **saved_argv
  
  bool kexec_loaded(void);
  
 +int prot_from_flags(int flags);
 +
+ unsigned long cap_last_cap(void);
  #endif