Merge pull request #1676 from poettering/util-lib-2
split up util.[ch] into more pieces, and other stuff
This commit is contained in:
@@ -266,6 +266,7 @@
|
||||
/test-unaligned
|
||||
/test-unit-file
|
||||
/test-unit-name
|
||||
/test-user-util
|
||||
/test-utf8
|
||||
/test-util
|
||||
/test-verbs
|
||||
|
||||
+12
@@ -781,10 +781,14 @@ libbasic_la_SOURCES = \
|
||||
src/basic/refcnt.h \
|
||||
src/basic/util.c \
|
||||
src/basic/util.h \
|
||||
src/basic/io-util.c \
|
||||
src/basic/io-util.h \
|
||||
src/basic/string-util.c \
|
||||
src/basic/string-util.h \
|
||||
src/basic/fd-util.c \
|
||||
src/basic/fd-util.h \
|
||||
src/basic/user-util.c \
|
||||
src/basic/user-util.h \
|
||||
src/basic/extract-word.c \
|
||||
src/basic/extract-word.h \
|
||||
src/basic/escape.c \
|
||||
@@ -846,6 +850,7 @@ libbasic_la_SOURCES = \
|
||||
src/basic/in-addr-util.c \
|
||||
src/basic/in-addr-util.h \
|
||||
src/basic/ether-addr-util.h \
|
||||
src/basic/ether-addr-util.c \
|
||||
src/basic/replace-var.c \
|
||||
src/basic/replace-var.h \
|
||||
src/basic/clock-util.c \
|
||||
@@ -1410,6 +1415,7 @@ tests += \
|
||||
test-utf8 \
|
||||
test-ellipsize \
|
||||
test-util \
|
||||
test-user-util \
|
||||
test-hostname-util \
|
||||
test-process-util \
|
||||
test-terminal-util \
|
||||
@@ -1694,6 +1700,12 @@ test_util_SOURCES = \
|
||||
test_util_LDADD = \
|
||||
libshared.la
|
||||
|
||||
test_user_util_SOURCES = \
|
||||
src/test/test-user-util.c
|
||||
|
||||
test_user_util_LDADD = \
|
||||
libshared.la
|
||||
|
||||
test_hostname_util_SOURCES = \
|
||||
src/test/test-hostname-util.c
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SmackFileSystemRoot=</varname></term>
|
||||
<term><varname>SmackFileSystemRootLabel=</varname></term>
|
||||
<listitem><para>Takes a string for the smack label.
|
||||
This option specifies the label to assign the root of the
|
||||
file system if it lacks the Smack extended attribute.
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
#include "process-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "special.h"
|
||||
#include "string-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "btrfs-util.h"
|
||||
#include "copy.h"
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Tom Gundersen
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
#include "macro.h"
|
||||
|
||||
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
|
||||
assert(addr);
|
||||
assert(buffer);
|
||||
|
||||
/* Like ether_ntoa() but uses %02x instead of %x to print
|
||||
* ethernet addresses, which makes them look less funny. Also,
|
||||
* doesn't use a static buffer. */
|
||||
|
||||
sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
addr->ether_addr_octet[0],
|
||||
addr->ether_addr_octet[1],
|
||||
addr->ether_addr_octet[2],
|
||||
addr->ether_addr_octet[3],
|
||||
addr->ether_addr_octet[4],
|
||||
addr->ether_addr_octet[5]);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -25,3 +25,7 @@
|
||||
|
||||
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
|
||||
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
|
||||
|
||||
#define ETHER_ADDR_TO_STRING_MAX (3*6)
|
||||
|
||||
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "io-util.h"
|
||||
|
||||
int flush_fd(int fd) {
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
char buf[LINE_MAX];
|
||||
ssize_t l;
|
||||
int r;
|
||||
|
||||
r = poll(&pollfd, 1, 0);
|
||||
if (r < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
|
||||
} else if (r == 0)
|
||||
return 0;
|
||||
|
||||
l = read(fd, buf, sizeof(buf));
|
||||
if (l < 0) {
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
|
||||
return -errno;
|
||||
} else if (l == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
uint8_t *p = buf;
|
||||
ssize_t n = 0;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf);
|
||||
|
||||
/* If called with nbytes == 0, let's call read() at least
|
||||
* once, to validate the operation */
|
||||
|
||||
if (nbytes > (size_t) SSIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
ssize_t k;
|
||||
|
||||
k = read(fd, p, nbytes);
|
||||
if (k < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN && do_poll) {
|
||||
|
||||
/* We knowingly ignore any return value here,
|
||||
* and expect that any error/EOF is reported
|
||||
* via read() */
|
||||
|
||||
(void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
|
||||
continue;
|
||||
}
|
||||
|
||||
return n > 0 ? n : -errno;
|
||||
}
|
||||
|
||||
if (k == 0)
|
||||
return n;
|
||||
|
||||
assert((size_t) k <= nbytes);
|
||||
|
||||
p += k;
|
||||
nbytes -= k;
|
||||
n += k;
|
||||
} while (nbytes > 0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
ssize_t n;
|
||||
|
||||
n = loop_read(fd, buf, nbytes, do_poll);
|
||||
if (n < 0)
|
||||
return (int) n;
|
||||
if ((size_t) n != nbytes)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
const uint8_t *p = buf;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf);
|
||||
|
||||
if (nbytes > (size_t) SSIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
ssize_t k;
|
||||
|
||||
k = write(fd, p, nbytes);
|
||||
if (k < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN && do_poll) {
|
||||
/* We knowingly ignore any return value here,
|
||||
* and expect that any error/EOF is reported
|
||||
* via write() */
|
||||
|
||||
(void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
|
||||
continue;
|
||||
}
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
|
||||
return -EIO;
|
||||
|
||||
assert((size_t) k <= nbytes);
|
||||
|
||||
p += k;
|
||||
nbytes -= k;
|
||||
} while (nbytes > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pipe_eof(int fd) {
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = POLLIN|POLLHUP,
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
r = poll(&pollfd, 1, 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return pollfd.revents & POLLHUP;
|
||||
}
|
||||
|
||||
int fd_wait_for_event(int fd, int event, usec_t t) {
|
||||
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = event,
|
||||
};
|
||||
|
||||
struct timespec ts;
|
||||
int r;
|
||||
|
||||
r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return pollfd.revents;
|
||||
}
|
||||
|
||||
static size_t nul_length(const uint8_t *p, size_t sz) {
|
||||
size_t n = 0;
|
||||
|
||||
while (sz > 0) {
|
||||
if (*p != 0)
|
||||
break;
|
||||
|
||||
n++;
|
||||
p++;
|
||||
sz--;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
|
||||
const uint8_t *q, *w, *e;
|
||||
ssize_t l;
|
||||
|
||||
q = w = p;
|
||||
e = q + sz;
|
||||
while (q < e) {
|
||||
size_t n;
|
||||
|
||||
n = nul_length(q, e - q);
|
||||
|
||||
/* If there are more than the specified run length of
|
||||
* NUL bytes, or if this is the beginning or the end
|
||||
* of the buffer, then seek instead of write */
|
||||
if ((n > run_length) ||
|
||||
(n > 0 && q == p) ||
|
||||
(n > 0 && q + n >= e)) {
|
||||
if (q > w) {
|
||||
l = write(fd, w, q - w);
|
||||
if (l < 0)
|
||||
return -errno;
|
||||
if (l != q -w)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
|
||||
return -errno;
|
||||
|
||||
q += n;
|
||||
w = q;
|
||||
} else if (n > 0)
|
||||
q += n;
|
||||
else
|
||||
q ++;
|
||||
}
|
||||
|
||||
if (q > w) {
|
||||
l = write(fd, w, q - w);
|
||||
if (l < 0)
|
||||
return -errno;
|
||||
if (l != q - w)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return q - (const uint8_t*) p;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "time-util.h"
|
||||
|
||||
int flush_fd(int fd);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
int pipe_eof(int fd);
|
||||
|
||||
int fd_wait_for_event(int fd, int event, usec_t timeout);
|
||||
|
||||
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
|
||||
@@ -428,7 +428,7 @@ int path_compare(const char *a, const char *b) {
|
||||
* Which one is sorted before the other does not really matter.
|
||||
* Here a relative path is ordered before an absolute path. */
|
||||
d = (a[0] == '/') - (b[0] == '/');
|
||||
if (d)
|
||||
if (d != 0)
|
||||
return d;
|
||||
|
||||
for (;;) {
|
||||
@@ -451,12 +451,12 @@ int path_compare(const char *a, const char *b) {
|
||||
|
||||
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
|
||||
d = memcmp(a, b, MIN(j, k));
|
||||
if (d)
|
||||
if (d != 0)
|
||||
return (d > 0) - (d < 0); /* sign of d */
|
||||
|
||||
/* Sort "/foo/a" before "/foo/aaa" */
|
||||
d = (j > k) - (j < k); /* sign of (j - k) */
|
||||
if (d)
|
||||
if (d != 0)
|
||||
return d;
|
||||
|
||||
a += j;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "process-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int get_process_state(pid_t pid) {
|
||||
@@ -479,6 +480,16 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_cod
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
void sigkill_wait(pid_t *pid) {
|
||||
if (!pid)
|
||||
return;
|
||||
if (*pid <= 1)
|
||||
return;
|
||||
|
||||
if (kill(*pid, SIGKILL) > 0)
|
||||
(void) wait_for_terminate(*pid, NULL);
|
||||
}
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig) {
|
||||
int r;
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ int get_process_environ(pid_t pid, char **environ);
|
||||
int wait_for_terminate(pid_t pid, siginfo_t *status);
|
||||
int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
|
||||
|
||||
void sigkill_wait(pid_t *pid);
|
||||
#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig);
|
||||
pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
|
||||
void rename_process(const char name[8]);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "missing.h"
|
||||
#include "random-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
+178
-15
@@ -23,20 +23,22 @@
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing.h"
|
||||
#include "path-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
#include "socket-util.h"
|
||||
|
||||
int socket_address_parse(SocketAddress *a, const char *s) {
|
||||
char *e, *n;
|
||||
@@ -750,21 +752,182 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b
|
||||
return false;
|
||||
}
|
||||
|
||||
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
|
||||
assert(addr);
|
||||
assert(buffer);
|
||||
int fd_inc_sndbuf(int fd, size_t n) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
/* Like ether_ntoa() but uses %02x instead of %x to print
|
||||
* ethernet addresses, which makes them look less funny. Also,
|
||||
* doesn't use a static buffer. */
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
return 0;
|
||||
|
||||
sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
addr->ether_addr_octet[0],
|
||||
addr->ether_addr_octet[1],
|
||||
addr->ether_addr_octet[2],
|
||||
addr->ether_addr_octet[3],
|
||||
addr->ether_addr_octet[4],
|
||||
addr->ether_addr_octet[5]);
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
|
||||
return buffer;
|
||||
value = (int) n;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
|
||||
return -errno;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fd_inc_rcvbuf(int fd, size_t n) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
return 0;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
|
||||
value = (int) n;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
|
||||
return -errno;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char* const ip_tos_table[] = {
|
||||
[IPTOS_LOWDELAY] = "low-delay",
|
||||
[IPTOS_THROUGHPUT] = "throughput",
|
||||
[IPTOS_RELIABILITY] = "reliability",
|
||||
[IPTOS_LOWCOST] = "low-cost",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred) {
|
||||
socklen_t n = sizeof(struct ucred);
|
||||
struct ucred u;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ucred);
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (n != sizeof(struct ucred))
|
||||
return -EIO;
|
||||
|
||||
/* Check if the data is actually useful and not suppressed due
|
||||
* to namespacing issues */
|
||||
if (u.pid <= 0)
|
||||
return -ENODATA;
|
||||
if (u.uid == UID_INVALID)
|
||||
return -ENODATA;
|
||||
if (u.gid == GID_INVALID)
|
||||
return -ENODATA;
|
||||
|
||||
*ucred = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpeersec(int fd, char **ret) {
|
||||
socklen_t n = 64;
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (isempty(s)) {
|
||||
free(s);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int send_one_fd(int transport_fd, int fd, int flags) {
|
||||
union {
|
||||
struct cmsghdr cmsghdr;
|
||||
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||
} control = {};
|
||||
struct msghdr mh = {
|
||||
.msg_control = &control,
|
||||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
assert(transport_fd >= 0);
|
||||
assert(fd >= 0);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&mh);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
|
||||
|
||||
mh.msg_controllen = CMSG_SPACE(sizeof(int));
|
||||
if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int receive_one_fd(int transport_fd, int flags) {
|
||||
union {
|
||||
struct cmsghdr cmsghdr;
|
||||
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||
} control = {};
|
||||
struct msghdr mh = {
|
||||
.msg_control = &control,
|
||||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
struct cmsghdr *cmsg, *found = NULL;
|
||||
|
||||
assert(transport_fd >= 0);
|
||||
|
||||
/*
|
||||
* Receive a single FD via @transport_fd. We don't care for
|
||||
* the transport-type. We retrieve a single FD at most, so for
|
||||
* packet-based transports, the caller must ensure to send
|
||||
* only a single FD per packet. This is best used in
|
||||
* combination with send_one_fd().
|
||||
*/
|
||||
|
||||
if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
|
||||
return -errno;
|
||||
|
||||
CMSG_FOREACH(cmsg, &mh) {
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SCM_RIGHTS &&
|
||||
cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
|
||||
assert(!found);
|
||||
found = cmsg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
cmsg_close_all(&mh);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return *(int*) CMSG_DATA(found);
|
||||
}
|
||||
|
||||
+10
-2
@@ -116,6 +116,14 @@ int netlink_family_from_string(const char *s) _pure_;
|
||||
|
||||
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
|
||||
|
||||
#define ETHER_ADDR_TO_STRING_MAX (3*6)
|
||||
int fd_inc_sndbuf(int fd, size_t n);
|
||||
int fd_inc_rcvbuf(int fd, size_t n);
|
||||
|
||||
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
|
||||
int ip_tos_to_string_alloc(int i, char **s);
|
||||
int ip_tos_from_string(const char *s);
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred);
|
||||
int getpeersec(int fd, char **ret);
|
||||
|
||||
int send_one_fd(int transport_fd, int fd, int flags);
|
||||
int receive_one_fd(int transport_fd, int flags);
|
||||
|
||||
@@ -33,8 +33,10 @@
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "user-util.h"
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
#include "string-util.h"
|
||||
#include "path-util.h"
|
||||
|
||||
bool uid_is_valid(uid_t uid) {
|
||||
|
||||
/* Some libc APIs use UID_INVALID as special placeholder */
|
||||
if (uid == (uid_t) UINT32_C(0xFFFFFFFF))
|
||||
return false;
|
||||
|
||||
/* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
|
||||
if (uid == (uid_t) UINT32_C(0xFFFF))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int parse_uid(const char *s, uid_t *ret) {
|
||||
uint32_t uid = 0;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
|
||||
r = safe_atou32(s, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!uid_is_valid(uid))
|
||||
return -ENXIO; /* we return ENXIO instead of EINVAL
|
||||
* here, to make it easy to distuingish
|
||||
* invalid numeric uids invalid
|
||||
* strings. */
|
||||
|
||||
if (ret)
|
||||
*ret = uid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* getlogname_malloc(void) {
|
||||
uid_t uid;
|
||||
struct stat st;
|
||||
|
||||
if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
|
||||
uid = st.st_uid;
|
||||
else
|
||||
uid = getuid();
|
||||
|
||||
return uid_to_name(uid);
|
||||
}
|
||||
|
||||
char *getusername_malloc(void) {
|
||||
const char *e;
|
||||
|
||||
e = getenv("USER");
|
||||
if (e)
|
||||
return strdup(e);
|
||||
|
||||
return uid_to_name(getuid());
|
||||
}
|
||||
|
||||
int get_user_creds(
|
||||
const char **username,
|
||||
uid_t *uid, gid_t *gid,
|
||||
const char **home,
|
||||
const char **shell) {
|
||||
|
||||
struct passwd *p;
|
||||
uid_t u;
|
||||
|
||||
assert(username);
|
||||
assert(*username);
|
||||
|
||||
/* We enforce some special rules for uid=0: in order to avoid
|
||||
* NSS lookups for root we hardcode its data. */
|
||||
|
||||
if (streq(*username, "root") || streq(*username, "0")) {
|
||||
*username = "root";
|
||||
|
||||
if (uid)
|
||||
*uid = 0;
|
||||
|
||||
if (gid)
|
||||
*gid = 0;
|
||||
|
||||
if (home)
|
||||
*home = "/root";
|
||||
|
||||
if (shell)
|
||||
*shell = "/bin/sh";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parse_uid(*username, &u) >= 0) {
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
|
||||
/* If there are multiple users with the same id, make
|
||||
* sure to leave $USER to the configured value instead
|
||||
* of the first occurrence in the database. However if
|
||||
* the uid was configured by a numeric uid, then let's
|
||||
* pick the real username from /etc/passwd. */
|
||||
if (p)
|
||||
*username = p->pw_name;
|
||||
} else {
|
||||
errno = 0;
|
||||
p = getpwnam(*username);
|
||||
}
|
||||
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (uid) {
|
||||
if (!uid_is_valid(p->pw_uid))
|
||||
return -EBADMSG;
|
||||
|
||||
*uid = p->pw_uid;
|
||||
}
|
||||
|
||||
if (gid) {
|
||||
if (!gid_is_valid(p->pw_gid))
|
||||
return -EBADMSG;
|
||||
|
||||
*gid = p->pw_gid;
|
||||
}
|
||||
|
||||
if (home)
|
||||
*home = p->pw_dir;
|
||||
|
||||
if (shell)
|
||||
*shell = p->pw_shell;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_group_creds(const char **groupname, gid_t *gid) {
|
||||
struct group *g;
|
||||
gid_t id;
|
||||
|
||||
assert(groupname);
|
||||
|
||||
/* We enforce some special rules for gid=0: in order to avoid
|
||||
* NSS lookups for root we hardcode its data. */
|
||||
|
||||
if (streq(*groupname, "root") || streq(*groupname, "0")) {
|
||||
*groupname = "root";
|
||||
|
||||
if (gid)
|
||||
*gid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parse_gid(*groupname, &id) >= 0) {
|
||||
errno = 0;
|
||||
g = getgrgid(id);
|
||||
|
||||
if (g)
|
||||
*groupname = g->gr_name;
|
||||
} else {
|
||||
errno = 0;
|
||||
g = getgrnam(*groupname);
|
||||
}
|
||||
|
||||
if (!g)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (gid) {
|
||||
if (!gid_is_valid(g->gr_gid))
|
||||
return -EBADMSG;
|
||||
|
||||
*gid = g->gr_gid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* uid_to_name(uid_t uid) {
|
||||
char *ret;
|
||||
int r;
|
||||
|
||||
/* Shortcut things to avoid NSS lookups */
|
||||
if (uid == 0)
|
||||
return strdup("root");
|
||||
|
||||
if (uid_is_valid(uid)) {
|
||||
long bufsize;
|
||||
|
||||
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (bufsize <= 0)
|
||||
bufsize = 4096;
|
||||
|
||||
for (;;) {
|
||||
struct passwd pwbuf, *pw = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
buf = malloc(bufsize);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
|
||||
if (r == 0 && pw)
|
||||
return strdup(pw->pw_name);
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
|
||||
bufsize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (asprintf(&ret, UID_FMT, uid) < 0)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* gid_to_name(gid_t gid) {
|
||||
char *ret;
|
||||
int r;
|
||||
|
||||
if (gid == 0)
|
||||
return strdup("root");
|
||||
|
||||
if (gid_is_valid(gid)) {
|
||||
long bufsize;
|
||||
|
||||
bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
|
||||
if (bufsize <= 0)
|
||||
bufsize = 4096;
|
||||
|
||||
for (;;) {
|
||||
struct group grbuf, *gr = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
buf = malloc(bufsize);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
|
||||
if (r == 0 && gr)
|
||||
return strdup(gr->gr_name);
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
|
||||
bufsize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (asprintf(&ret, GID_FMT, gid) < 0)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int in_gid(gid_t gid) {
|
||||
gid_t *gids;
|
||||
int ngroups_max, r, i;
|
||||
|
||||
if (getgid() == gid)
|
||||
return 1;
|
||||
|
||||
if (getegid() == gid)
|
||||
return 1;
|
||||
|
||||
if (!gid_is_valid(gid))
|
||||
return -EINVAL;
|
||||
|
||||
ngroups_max = sysconf(_SC_NGROUPS_MAX);
|
||||
assert(ngroups_max > 0);
|
||||
|
||||
gids = alloca(sizeof(gid_t) * ngroups_max);
|
||||
|
||||
r = getgroups(ngroups_max, gids);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
for (i = 0; i < r; i++)
|
||||
if (gids[i] == gid)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_group(const char *name) {
|
||||
int r;
|
||||
gid_t gid;
|
||||
|
||||
r = get_group_creds(&name, &gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return in_gid(gid);
|
||||
}
|
||||
|
||||
int get_home_dir(char **_h) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *h;
|
||||
uid_t u;
|
||||
|
||||
assert(_h);
|
||||
|
||||
/* Take the user specified one */
|
||||
e = secure_getenv("HOME");
|
||||
if (e && path_is_absolute(e)) {
|
||||
h = strdup(e);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hardcode home directory for root to avoid NSS */
|
||||
u = getuid();
|
||||
if (u == 0) {
|
||||
h = strdup("/root");
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the database... */
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (!path_is_absolute(p->pw_dir))
|
||||
return -EINVAL;
|
||||
|
||||
h = strdup(p->pw_dir);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_shell(char **_s) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *s;
|
||||
uid_t u;
|
||||
|
||||
assert(_s);
|
||||
|
||||
/* Take the user specified one */
|
||||
e = getenv("SHELL");
|
||||
if (e) {
|
||||
s = strdup(e);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hardcode home directory for root to avoid NSS */
|
||||
u = getuid();
|
||||
if (u == 0) {
|
||||
s = strdup("/bin/sh");
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the database... */
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (!path_is_absolute(p->pw_shell))
|
||||
return -EINVAL;
|
||||
|
||||
s = strdup(p->pw_shell);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reset_uid_gid(void) {
|
||||
|
||||
if (setgroups(0, NULL) < 0)
|
||||
return -errno;
|
||||
|
||||
if (setresgid(0, 0, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
if (setresuid(0, 0, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool uid_is_valid(uid_t uid);
|
||||
|
||||
static inline bool gid_is_valid(gid_t gid) {
|
||||
return uid_is_valid((uid_t) gid);
|
||||
}
|
||||
|
||||
int parse_uid(const char *s, uid_t* ret_uid);
|
||||
|
||||
static inline int parse_gid(const char *s, gid_t *ret_gid) {
|
||||
return parse_uid(s, (uid_t*) ret_gid);
|
||||
}
|
||||
|
||||
char* getlogname_malloc(void);
|
||||
char* getusername_malloc(void);
|
||||
|
||||
int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
|
||||
int get_group_creds(const char **groupname, gid_t *gid);
|
||||
|
||||
char* uid_to_name(uid_t uid);
|
||||
char* gid_to_name(gid_t gid);
|
||||
|
||||
int in_gid(gid_t gid);
|
||||
int in_group(const char *name);
|
||||
|
||||
int get_home_dir(char **ret);
|
||||
int get_shell(char **_ret);
|
||||
|
||||
int reset_uid_gid(void);
|
||||
+1
-801
@@ -32,7 +32,6 @@
|
||||
#include <linux/oom.h>
|
||||
#include <linux/sched.h>
|
||||
#include <locale.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <poll.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
@@ -98,6 +97,7 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
@@ -168,47 +168,6 @@ int parse_pid(const char *s, pid_t* ret_pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool uid_is_valid(uid_t uid) {
|
||||
|
||||
/* Some libc APIs use UID_INVALID as special placeholder */
|
||||
if (uid == (uid_t) 0xFFFFFFFF)
|
||||
return false;
|
||||
|
||||
/* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
|
||||
if (uid == (uid_t) 0xFFFF)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int parse_uid(const char *s, uid_t* ret_uid) {
|
||||
unsigned long ul = 0;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
r = safe_atolu(s, &ul);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
uid = (uid_t) ul;
|
||||
|
||||
if ((unsigned long) uid != ul)
|
||||
return -ERANGE;
|
||||
|
||||
if (!uid_is_valid(uid))
|
||||
return -ENXIO; /* we return ENXIO instead of EINVAL
|
||||
* here, to make it easy to distuingish
|
||||
* invalid numeric uids invalid
|
||||
* strings. */
|
||||
|
||||
if (ret_uid)
|
||||
*ret_uid = uid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int safe_atou(const char *s, unsigned *ret_u) {
|
||||
char *x = NULL;
|
||||
unsigned long l;
|
||||
@@ -1236,142 +1195,6 @@ bool fstype_is_network(const char *fstype) {
|
||||
return nulstr_contains(table, fstype);
|
||||
}
|
||||
|
||||
int flush_fd(int fd) {
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
char buf[LINE_MAX];
|
||||
ssize_t l;
|
||||
int r;
|
||||
|
||||
r = poll(&pollfd, 1, 0);
|
||||
if (r < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
|
||||
} else if (r == 0)
|
||||
return 0;
|
||||
|
||||
l = read(fd, buf, sizeof(buf));
|
||||
if (l < 0) {
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
|
||||
return -errno;
|
||||
} else if (l == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
uint8_t *p = buf;
|
||||
ssize_t n = 0;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf);
|
||||
|
||||
/* If called with nbytes == 0, let's call read() at least
|
||||
* once, to validate the operation */
|
||||
|
||||
if (nbytes > (size_t) SSIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
ssize_t k;
|
||||
|
||||
k = read(fd, p, nbytes);
|
||||
if (k < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN && do_poll) {
|
||||
|
||||
/* We knowingly ignore any return value here,
|
||||
* and expect that any error/EOF is reported
|
||||
* via read() */
|
||||
|
||||
(void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
|
||||
continue;
|
||||
}
|
||||
|
||||
return n > 0 ? n : -errno;
|
||||
}
|
||||
|
||||
if (k == 0)
|
||||
return n;
|
||||
|
||||
assert((size_t) k <= nbytes);
|
||||
|
||||
p += k;
|
||||
nbytes -= k;
|
||||
n += k;
|
||||
} while (nbytes > 0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
ssize_t n;
|
||||
|
||||
n = loop_read(fd, buf, nbytes, do_poll);
|
||||
if (n < 0)
|
||||
return (int) n;
|
||||
if ((size_t) n != nbytes)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
const uint8_t *p = buf;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf);
|
||||
|
||||
if (nbytes > (size_t) SSIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
ssize_t k;
|
||||
|
||||
k = write(fd, p, nbytes);
|
||||
if (k < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN && do_poll) {
|
||||
/* We knowingly ignore any return value here,
|
||||
* and expect that any error/EOF is reported
|
||||
* via write() */
|
||||
|
||||
(void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
|
||||
continue;
|
||||
}
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
|
||||
return -EIO;
|
||||
|
||||
assert((size_t) k <= nbytes);
|
||||
|
||||
p += k;
|
||||
nbytes -= k;
|
||||
} while (nbytes > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_size(const char *t, uint64_t base, uint64_t *size) {
|
||||
|
||||
/* Soo, sometimes we want to parse IEC binary suffixes, and
|
||||
@@ -1573,55 +1396,6 @@ void rename_process(const char name[8]) {
|
||||
}
|
||||
}
|
||||
|
||||
char *lookup_uid(uid_t uid) {
|
||||
long bufsize;
|
||||
char *name;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
struct passwd pwbuf, *pw = NULL;
|
||||
|
||||
/* Shortcut things to avoid NSS lookups */
|
||||
if (uid == 0)
|
||||
return strdup("root");
|
||||
|
||||
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (bufsize <= 0)
|
||||
bufsize = 4096;
|
||||
|
||||
buf = malloc(bufsize);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
|
||||
return strdup(pw->pw_name);
|
||||
|
||||
if (asprintf(&name, UID_FMT, uid) < 0)
|
||||
return NULL;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
char* getlogname_malloc(void) {
|
||||
uid_t uid;
|
||||
struct stat st;
|
||||
|
||||
if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
|
||||
uid = st.st_uid;
|
||||
else
|
||||
uid = getuid();
|
||||
|
||||
return lookup_uid(uid);
|
||||
}
|
||||
|
||||
char *getusername_malloc(void) {
|
||||
const char *e;
|
||||
|
||||
e = getenv("USER");
|
||||
if (e)
|
||||
return strdup(e);
|
||||
|
||||
return lookup_uid(getuid());
|
||||
}
|
||||
|
||||
bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
|
||||
assert(s);
|
||||
assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
|
||||
@@ -2057,44 +1831,6 @@ bool plymouth_running(void) {
|
||||
return access("/run/plymouth/pid", F_OK) >= 0;
|
||||
}
|
||||
|
||||
int pipe_eof(int fd) {
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = POLLIN|POLLHUP,
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
r = poll(&pollfd, 1, 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return pollfd.revents & POLLHUP;
|
||||
}
|
||||
|
||||
int fd_wait_for_event(int fd, int event, usec_t t) {
|
||||
|
||||
struct pollfd pollfd = {
|
||||
.fd = fd,
|
||||
.events = event,
|
||||
};
|
||||
|
||||
struct timespec ts;
|
||||
int r;
|
||||
|
||||
r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return pollfd.revents;
|
||||
}
|
||||
|
||||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
|
||||
FILE *f;
|
||||
char *t;
|
||||
@@ -2248,182 +1984,6 @@ int socket_from_display(const char *display, char **path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_user_creds(
|
||||
const char **username,
|
||||
uid_t *uid, gid_t *gid,
|
||||
const char **home,
|
||||
const char **shell) {
|
||||
|
||||
struct passwd *p;
|
||||
uid_t u;
|
||||
|
||||
assert(username);
|
||||
assert(*username);
|
||||
|
||||
/* We enforce some special rules for uid=0: in order to avoid
|
||||
* NSS lookups for root we hardcode its data. */
|
||||
|
||||
if (streq(*username, "root") || streq(*username, "0")) {
|
||||
*username = "root";
|
||||
|
||||
if (uid)
|
||||
*uid = 0;
|
||||
|
||||
if (gid)
|
||||
*gid = 0;
|
||||
|
||||
if (home)
|
||||
*home = "/root";
|
||||
|
||||
if (shell)
|
||||
*shell = "/bin/sh";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parse_uid(*username, &u) >= 0) {
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
|
||||
/* If there are multiple users with the same id, make
|
||||
* sure to leave $USER to the configured value instead
|
||||
* of the first occurrence in the database. However if
|
||||
* the uid was configured by a numeric uid, then let's
|
||||
* pick the real username from /etc/passwd. */
|
||||
if (p)
|
||||
*username = p->pw_name;
|
||||
} else {
|
||||
errno = 0;
|
||||
p = getpwnam(*username);
|
||||
}
|
||||
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (uid)
|
||||
*uid = p->pw_uid;
|
||||
|
||||
if (gid)
|
||||
*gid = p->pw_gid;
|
||||
|
||||
if (home)
|
||||
*home = p->pw_dir;
|
||||
|
||||
if (shell)
|
||||
*shell = p->pw_shell;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* uid_to_name(uid_t uid) {
|
||||
struct passwd *p;
|
||||
char *r;
|
||||
|
||||
if (uid == 0)
|
||||
return strdup("root");
|
||||
|
||||
p = getpwuid(uid);
|
||||
if (p)
|
||||
return strdup(p->pw_name);
|
||||
|
||||
if (asprintf(&r, UID_FMT, uid) < 0)
|
||||
return NULL;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char* gid_to_name(gid_t gid) {
|
||||
struct group *p;
|
||||
char *r;
|
||||
|
||||
if (gid == 0)
|
||||
return strdup("root");
|
||||
|
||||
p = getgrgid(gid);
|
||||
if (p)
|
||||
return strdup(p->gr_name);
|
||||
|
||||
if (asprintf(&r, GID_FMT, gid) < 0)
|
||||
return NULL;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int get_group_creds(const char **groupname, gid_t *gid) {
|
||||
struct group *g;
|
||||
gid_t id;
|
||||
|
||||
assert(groupname);
|
||||
|
||||
/* We enforce some special rules for gid=0: in order to avoid
|
||||
* NSS lookups for root we hardcode its data. */
|
||||
|
||||
if (streq(*groupname, "root") || streq(*groupname, "0")) {
|
||||
*groupname = "root";
|
||||
|
||||
if (gid)
|
||||
*gid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parse_gid(*groupname, &id) >= 0) {
|
||||
errno = 0;
|
||||
g = getgrgid(id);
|
||||
|
||||
if (g)
|
||||
*groupname = g->gr_name;
|
||||
} else {
|
||||
errno = 0;
|
||||
g = getgrnam(*groupname);
|
||||
}
|
||||
|
||||
if (!g)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (gid)
|
||||
*gid = g->gr_gid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_gid(gid_t gid) {
|
||||
gid_t *gids;
|
||||
int ngroups_max, r, i;
|
||||
|
||||
if (getgid() == gid)
|
||||
return 1;
|
||||
|
||||
if (getegid() == gid)
|
||||
return 1;
|
||||
|
||||
ngroups_max = sysconf(_SC_NGROUPS_MAX);
|
||||
assert(ngroups_max > 0);
|
||||
|
||||
gids = alloca(sizeof(gid_t) * ngroups_max);
|
||||
|
||||
r = getgroups(ngroups_max, gids);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
for (i = 0; i < r; i++)
|
||||
if (gids[i] == gid)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_group(const char *name) {
|
||||
int r;
|
||||
gid_t gid;
|
||||
|
||||
r = get_group_creds(&name, &gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return in_gid(gid);
|
||||
}
|
||||
|
||||
int glob_exists(const char *path) {
|
||||
_cleanup_globfree_ glob_t g = {};
|
||||
int k;
|
||||
@@ -2710,15 +2270,6 @@ static const char* const rlimit_table[_RLIMIT_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
|
||||
|
||||
static const char* const ip_tos_table[] = {
|
||||
[IPTOS_LOWDELAY] = "low-delay",
|
||||
[IPTOS_THROUGHPUT] = "throughput",
|
||||
[IPTOS_RELIABILITY] = "reliability",
|
||||
[IPTOS_LOWCOST] = "low-cost",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
|
||||
|
||||
bool kexec_loaded(void) {
|
||||
bool loaded = false;
|
||||
char *s;
|
||||
@@ -2801,41 +2352,6 @@ void* memdup(const void *p, size_t l) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int fd_inc_sndbuf(int fd, size_t n) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
return 0;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
|
||||
value = (int) n;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
|
||||
return -errno;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fd_inc_rcvbuf(int fd, size_t n) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
return 0;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
|
||||
value = (int) n;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
|
||||
return -errno;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
|
||||
bool stdout_is_tty, stderr_is_tty;
|
||||
pid_t parent_pid, agent_pid;
|
||||
@@ -3038,100 +2554,6 @@ bool in_initrd(void) {
|
||||
return saved;
|
||||
}
|
||||
|
||||
int get_home_dir(char **_h) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *h;
|
||||
uid_t u;
|
||||
|
||||
assert(_h);
|
||||
|
||||
/* Take the user specified one */
|
||||
e = secure_getenv("HOME");
|
||||
if (e && path_is_absolute(e)) {
|
||||
h = strdup(e);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hardcode home directory for root to avoid NSS */
|
||||
u = getuid();
|
||||
if (u == 0) {
|
||||
h = strdup("/root");
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the database... */
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (!path_is_absolute(p->pw_dir))
|
||||
return -EINVAL;
|
||||
|
||||
h = strdup(p->pw_dir);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_shell(char **_s) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *s;
|
||||
uid_t u;
|
||||
|
||||
assert(_s);
|
||||
|
||||
/* Take the user specified one */
|
||||
e = getenv("SHELL");
|
||||
if (e) {
|
||||
s = strdup(e);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hardcode home directory for root to avoid NSS */
|
||||
u = getuid();
|
||||
if (u == 0) {
|
||||
s = strdup("/bin/sh");
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the database... */
|
||||
errno = 0;
|
||||
p = getpwuid(u);
|
||||
if (!p)
|
||||
return errno > 0 ? -errno : -ESRCH;
|
||||
|
||||
if (!path_is_absolute(p->pw_shell))
|
||||
return -EINVAL;
|
||||
|
||||
s = strdup(p->pw_shell);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool filename_is_valid(const char *p) {
|
||||
|
||||
if (isempty(p))
|
||||
@@ -3797,73 +3219,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
|
||||
return reset_uid_gid();
|
||||
}
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred) {
|
||||
socklen_t n = sizeof(struct ucred);
|
||||
struct ucred u;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ucred);
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (n != sizeof(struct ucred))
|
||||
return -EIO;
|
||||
|
||||
/* Check if the data is actually useful and not suppressed due
|
||||
* to namespacing issues */
|
||||
if (u.pid <= 0)
|
||||
return -ENODATA;
|
||||
if (u.uid == UID_INVALID)
|
||||
return -ENODATA;
|
||||
if (u.gid == GID_INVALID)
|
||||
return -ENODATA;
|
||||
|
||||
*ucred = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpeersec(int fd, char **ret) {
|
||||
socklen_t n = 64;
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
|
||||
if (errno != ERANGE)
|
||||
return -errno;
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (isempty(s)) {
|
||||
free(s);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is much like like mkostemp() but is subject to umask(). */
|
||||
int mkostemp_safe(char *pattern, int flags) {
|
||||
_cleanup_umask_ mode_t u;
|
||||
@@ -4661,78 +4016,6 @@ int read_attr_path(const char *p, unsigned *ret) {
|
||||
return read_attr_fd(fd, ret);
|
||||
}
|
||||
|
||||
static size_t nul_length(const uint8_t *p, size_t sz) {
|
||||
size_t n = 0;
|
||||
|
||||
while (sz > 0) {
|
||||
if (*p != 0)
|
||||
break;
|
||||
|
||||
n++;
|
||||
p++;
|
||||
sz--;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
|
||||
const uint8_t *q, *w, *e;
|
||||
ssize_t l;
|
||||
|
||||
q = w = p;
|
||||
e = q + sz;
|
||||
while (q < e) {
|
||||
size_t n;
|
||||
|
||||
n = nul_length(q, e - q);
|
||||
|
||||
/* If there are more than the specified run length of
|
||||
* NUL bytes, or if this is the beginning or the end
|
||||
* of the buffer, then seek instead of write */
|
||||
if ((n > run_length) ||
|
||||
(n > 0 && q == p) ||
|
||||
(n > 0 && q + n >= e)) {
|
||||
if (q > w) {
|
||||
l = write(fd, w, q - w);
|
||||
if (l < 0)
|
||||
return -errno;
|
||||
if (l != q -w)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
|
||||
return -errno;
|
||||
|
||||
q += n;
|
||||
w = q;
|
||||
} else if (n > 0)
|
||||
q += n;
|
||||
else
|
||||
q ++;
|
||||
}
|
||||
|
||||
if (q > w) {
|
||||
l = write(fd, w, q - w);
|
||||
if (l < 0)
|
||||
return -errno;
|
||||
if (l != q - w)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return q - (const uint8_t*) p;
|
||||
}
|
||||
|
||||
void sigkill_wait(pid_t *pid) {
|
||||
if (!pid)
|
||||
return;
|
||||
if (*pid <= 1)
|
||||
return;
|
||||
|
||||
if (kill(*pid, SIGKILL) > 0)
|
||||
(void) wait_for_terminate(*pid, NULL);
|
||||
}
|
||||
|
||||
int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
|
||||
int a = 0, b = 0, c = 0;
|
||||
int k;
|
||||
@@ -4867,20 +4150,6 @@ int mount_move_root(const char *path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reset_uid_gid(void) {
|
||||
|
||||
if (setgroups(0, NULL) < 0)
|
||||
return -errno;
|
||||
|
||||
if (setresgid(0, 0, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
if (setresuid(0, 0, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
|
||||
char *v;
|
||||
size_t l;
|
||||
@@ -4951,75 +4220,6 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
|
||||
}
|
||||
}
|
||||
|
||||
int send_one_fd(int transport_fd, int fd, int flags) {
|
||||
union {
|
||||
struct cmsghdr cmsghdr;
|
||||
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||
} control = {};
|
||||
struct msghdr mh = {
|
||||
.msg_control = &control,
|
||||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
assert(transport_fd >= 0);
|
||||
assert(fd >= 0);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&mh);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
|
||||
|
||||
mh.msg_controllen = CMSG_SPACE(sizeof(int));
|
||||
if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int receive_one_fd(int transport_fd, int flags) {
|
||||
union {
|
||||
struct cmsghdr cmsghdr;
|
||||
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||
} control = {};
|
||||
struct msghdr mh = {
|
||||
.msg_control = &control,
|
||||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
struct cmsghdr *cmsg, *found = NULL;
|
||||
|
||||
assert(transport_fd >= 0);
|
||||
|
||||
/*
|
||||
* Receive a single FD via @transport_fd. We don't care for
|
||||
* the transport-type. We retrieve a single FD at most, so for
|
||||
* packet-based transports, the caller must ensure to send
|
||||
* only a single FD per packet. This is best used in
|
||||
* combination with send_one_fd().
|
||||
*/
|
||||
|
||||
if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
|
||||
return -errno;
|
||||
|
||||
CMSG_FOREACH(cmsg, &mh) {
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SCM_RIGHTS &&
|
||||
cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
|
||||
assert(!found);
|
||||
found = cmsg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
cmsg_close_all(&mh);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return *(int*) CMSG_DATA(found);
|
||||
}
|
||||
|
||||
void nop_signal_handler(int sig) {
|
||||
/* nothing here */
|
||||
}
|
||||
|
||||
@@ -91,14 +91,6 @@ int parse_size(const char *t, uint64_t base, uint64_t *size);
|
||||
|
||||
int parse_boolean(const char *v) _pure_;
|
||||
int parse_pid(const char *s, pid_t* ret_pid);
|
||||
int parse_uid(const char *s, uid_t* ret_uid);
|
||||
#define parse_gid(s, ret_gid) parse_uid(s, ret_gid)
|
||||
|
||||
bool uid_is_valid(uid_t uid);
|
||||
|
||||
static inline bool gid_is_valid(gid_t gid) {
|
||||
return uid_is_valid((uid_t) gid);
|
||||
}
|
||||
|
||||
int safe_atou(const char *s, unsigned *ret_u);
|
||||
int safe_atoi(const char *s, int *ret_i);
|
||||
@@ -237,14 +229,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
|
||||
|
||||
bool fstype_is_network(const char *fstype);
|
||||
|
||||
int flush_fd(int fd);
|
||||
|
||||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
bool is_device_path(const char *path);
|
||||
|
||||
int dir_is_empty(const char *path);
|
||||
@@ -258,10 +244,6 @@ static inline int dir_is_populated(const char *path) {
|
||||
return !r;
|
||||
}
|
||||
|
||||
char* lookup_uid(uid_t uid);
|
||||
char* getlogname_malloc(void);
|
||||
char* getusername_malloc(void);
|
||||
|
||||
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);
|
||||
|
||||
@@ -274,8 +256,6 @@ int path_check_fstype(const char *path, statfs_f_type_t magic_value);
|
||||
bool is_temporary_fs(const struct statfs *s) _pure_;
|
||||
int fd_is_temporary_fs(int fd);
|
||||
|
||||
int pipe_eof(int fd);
|
||||
|
||||
#define xsprintf(buf, fmt, ...) \
|
||||
assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), \
|
||||
"xsprintf: " #buf "[] must be big enough")
|
||||
@@ -312,15 +292,6 @@ int fchmod_umask(int fd, mode_t mode);
|
||||
bool display_is_local(const char *display) _pure_;
|
||||
int socket_from_display(const char *display, char **path);
|
||||
|
||||
int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
|
||||
int get_group_creds(const char **groupname, gid_t *gid);
|
||||
|
||||
int in_gid(gid_t gid);
|
||||
int in_group(const char *name);
|
||||
|
||||
char* uid_to_name(uid_t uid);
|
||||
char* gid_to_name(gid_t gid);
|
||||
|
||||
int glob_exists(const char *path);
|
||||
int glob_extend(char ***strv, const char *path);
|
||||
|
||||
@@ -358,9 +329,6 @@ int sched_policy_from_string(const char *s);
|
||||
const char *rlimit_to_string(int i) _const_;
|
||||
int rlimit_from_string(const char *s) _pure_;
|
||||
|
||||
int ip_tos_to_string_alloc(int i, char **s);
|
||||
int ip_tos_from_string(const char *s);
|
||||
|
||||
extern int saved_argc;
|
||||
extern char **saved_argv;
|
||||
|
||||
@@ -370,13 +338,8 @@ int prot_from_flags(int flags) _const_;
|
||||
|
||||
char *format_bytes(char *buf, size_t l, uint64_t t);
|
||||
|
||||
int fd_wait_for_event(int fd, int event, usec_t timeout);
|
||||
|
||||
void* memdup(const void *p, size_t l) _alloc_(2);
|
||||
|
||||
int fd_inc_sndbuf(int fd, size_t n);
|
||||
int fd_inc_rcvbuf(int fd, size_t n);
|
||||
|
||||
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
|
||||
|
||||
int setrlimit_closest(int resource, const struct rlimit *rlim);
|
||||
@@ -388,9 +351,6 @@ bool http_etag_is_valid(const char *etag);
|
||||
|
||||
bool in_initrd(void);
|
||||
|
||||
int get_home_dir(char **ret);
|
||||
int get_shell(char **_ret);
|
||||
|
||||
static inline void freep(void *p) {
|
||||
free(*(void**) p);
|
||||
}
|
||||
@@ -644,11 +604,6 @@ int container_get_leader(const char *machine, pid_t *pid);
|
||||
int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
|
||||
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
|
||||
|
||||
int getpeercred(int fd, struct ucred *ucred);
|
||||
int getpeersec(int fd, char **ret);
|
||||
|
||||
int writev_safe(int fd, const struct iovec *w, int j);
|
||||
|
||||
int mkostemp_safe(char *pattern, int flags);
|
||||
int open_tmpfile(const char *path, int flags);
|
||||
|
||||
@@ -721,11 +676,6 @@ int read_attr_path(const char *p, unsigned *ret);
|
||||
|
||||
#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
|
||||
|
||||
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
|
||||
|
||||
void sigkill_wait(pid_t *pid);
|
||||
#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
|
||||
|
||||
int syslog_parse_priority(const char **p, int *priority, bool with_facility);
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
|
||||
@@ -734,14 +684,9 @@ int parse_mode(const char *s, mode_t *ret);
|
||||
|
||||
int mount_move_root(const char *path);
|
||||
|
||||
int reset_uid_gid(void);
|
||||
|
||||
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
|
||||
int fgetxattr_malloc(int fd, const char *name, char **value);
|
||||
|
||||
int send_one_fd(int transport_fd, int fd, int flags);
|
||||
int receive_one_fd(int transport_fd, int flags);
|
||||
|
||||
void nop_signal_handler(int sig);
|
||||
|
||||
int version(void);
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "conf-parser.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "list.h"
|
||||
#include "macro.h"
|
||||
#include "path-util.h"
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "proxy.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static char *arg_address = NULL;
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
#include "sd-login.h"
|
||||
|
||||
#include "bus-internal.h"
|
||||
#include "bus-xml-policy.h"
|
||||
#include "conf-files.h"
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "set.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "xml.h"
|
||||
#include "bus-xml-policy.h"
|
||||
|
||||
static void policy_item_free(PolicyItem *i) {
|
||||
assert(i);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "log.h"
|
||||
#include "proxy.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static char *arg_address = NULL;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "dbus-automount.h"
|
||||
#include "fd-util.h"
|
||||
#include "formats-util.h"
|
||||
#include "io-util.h"
|
||||
#include "label.h"
|
||||
#include "mkdir.h"
|
||||
#include "mount.h"
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kdbus.h"
|
||||
#include "util.h"
|
||||
#include "bus-kernel.h"
|
||||
#include "bus-policy.h"
|
||||
#include "kdbus.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int bus_kernel_translate_access(BusPolicyAccess access) {
|
||||
assert(access >= 0);
|
||||
|
||||
@@ -118,7 +118,7 @@ const sd_bus_vtable bus_mount_vtable[] = {
|
||||
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SmackFileSystemRoot", "s", NULL, offsetof(Mount, smack_fs_root), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SmackFileSystemRootLabel", "s", NULL, offsetof(Mount, smack_fs_root_label), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||
BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "io-util.h"
|
||||
#include "ioprio.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
@@ -89,6 +90,7 @@
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "utmp-wtmp.h"
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ Mount.Type, config_parse_string, 0,
|
||||
Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
|
||||
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
|
||||
Mount.SloppyOptions, config_parse_bool, 0, offsetof(Mount, sloppy_options)
|
||||
Mount.SmackFileSystemRoot, config_parse_string, 0, offsetof(Mount, smack_fs_root)
|
||||
Mount.SmackFileSystemRootLabel, config_parse_string, 0, offsetof(Mount, smack_fs_root_label)
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
|
||||
CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
|
||||
KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "machine-id-setup.h"
|
||||
#include "macro.h"
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "strv.h"
|
||||
#include "switch-root.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "virt.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "io-util.h"
|
||||
#include "locale-setup.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
|
||||
+6
-6
@@ -206,7 +206,7 @@ static void mount_done(Unit *u) {
|
||||
assert(m);
|
||||
|
||||
m->where = mfree(m->where);
|
||||
m->smack_fs_root = mfree(m->smack_fs_root);
|
||||
m->smack_fs_root_label = mfree(m->smack_fs_root_label);
|
||||
|
||||
mount_parameters_done(&m->parameters_proc_self_mountinfo);
|
||||
mount_parameters_done(&m->parameters_fragment);
|
||||
@@ -672,7 +672,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sFrom /proc/self/mountinfo: %s\n"
|
||||
"%sFrom fragment: %s\n"
|
||||
"%sDirectoryMode: %04o\n"
|
||||
"%sSmackFileSystemRoot: %s\n",
|
||||
"%sSmackFileSystemRootLabel: %s\n",
|
||||
prefix, mount_state_to_string(m->state),
|
||||
prefix, mount_result_to_string(m->result),
|
||||
prefix, m->where,
|
||||
@@ -682,7 +682,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, yes_no(m->from_proc_self_mountinfo),
|
||||
prefix, yes_no(m->from_fragment),
|
||||
prefix, m->directory_mode,
|
||||
prefix, strna(m->smack_fs_root));
|
||||
prefix, strna(m->smack_fs_root_label));
|
||||
|
||||
if (m->control_pid > 0)
|
||||
fprintf(f,
|
||||
@@ -868,12 +868,12 @@ static int mount_get_opts(Mount *m, char **_opts) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (mac_smack_use() && m->smack_fs_root) {
|
||||
if (mac_smack_use() && m->smack_fs_root_label) {
|
||||
if (!isempty(o)) {
|
||||
opts = strjoin(o, ",", "smackfsroot=", m->smack_fs_root, NULL);
|
||||
opts = strjoin(o, ",", "smackfsroot=", m->smack_fs_root_label, NULL);
|
||||
free(o);
|
||||
} else
|
||||
opts = strjoin("smackfsroot=", m->smack_fs_root, NULL);
|
||||
opts = strjoin("smackfsroot=", m->smack_fs_root_label, NULL);
|
||||
|
||||
if (!opts)
|
||||
return -ENOMEM;
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ struct Mount {
|
||||
bool reset_cpu_usage:1;
|
||||
|
||||
bool sloppy_options;
|
||||
char *smack_fs_root;
|
||||
char *smack_fs_root_label;
|
||||
|
||||
MountResult result;
|
||||
MountResult reload_result;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "namespace.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "unit-name.h"
|
||||
#include "unit-printf.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
|
||||
[SOCKET_DEAD] = UNIT_INACTIVE,
|
||||
|
||||
+2
-1
@@ -26,9 +26,10 @@
|
||||
#include "dbus-timer.h"
|
||||
#include "special.h"
|
||||
#include "string-util.h"
|
||||
#include "timer.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit.h"
|
||||
#include "timer.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
|
||||
[TIMER_DEAD] = UNIT_INACTIVE,
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "unit.h"
|
||||
#include "unit-printf.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
|
||||
Unit *u = userdata;
|
||||
|
||||
+2
-1
@@ -51,8 +51,9 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "virt.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
#include "virt.h"
|
||||
|
||||
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_SERVICE] = &service_vtable,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "import-common.h"
|
||||
#include "import-compress.h"
|
||||
#include "import-raw.h"
|
||||
#include "io-util.h"
|
||||
#include "machine-pool.h"
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "import-common.h"
|
||||
#include "import-compress.h"
|
||||
#include "import-tar.h"
|
||||
#include "io-util.h"
|
||||
#include "machine-pool.h"
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "copy.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "process-util.h"
|
||||
#include "pull-common.h"
|
||||
#include "pull-job.h"
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "machine-pool.h"
|
||||
#include "pull-job.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "compress.h"
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "journal-def.h"
|
||||
#include "macro.h"
|
||||
#include "sparse-endian.h"
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#define DEFAULT_MAX_USE_LOWER (uint64_t) (1ULL*1024ULL*1024ULL) /* 1 MiB */
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "stacktrace.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* The maximum size up to which we process coredumps */
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static enum {
|
||||
ACTION_NONE,
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "sd-journal.h"
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "memfd-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "fileio.h"
|
||||
#include "fsprg.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "journal-def.h"
|
||||
#include "journal-internal.h"
|
||||
#include "journal-qrcode.h"
|
||||
@@ -61,6 +62,7 @@
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
|
||||
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-journal.h"
|
||||
|
||||
#include "catalog.h"
|
||||
#include "compress.h"
|
||||
#include "fd-util.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "formats-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "journal-def.h"
|
||||
#include "journal-file.h"
|
||||
#include "journal-internal.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "missing.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static bool arg_no_pager = false;
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../Makefile
|
||||
@@ -25,10 +25,11 @@
|
||||
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "macro.h"
|
||||
#include "random-util.h"
|
||||
#include "util.h"
|
||||
#include "fd-util.h"
|
||||
|
||||
_public_ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]) {
|
||||
unsigned n;
|
||||
|
||||
@@ -33,10 +33,13 @@
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "login-util.h"
|
||||
#include "macro.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Error codes:
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "missing.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int sd_netlink_new(sd_netlink **ret) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
#include "event-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int from_environment(const char *envname, const char *fallback, const char **ret) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "sd-resolve.h"
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "list.h"
|
||||
#include "missing.h"
|
||||
#include "resolve-util.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "libudev-private.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "process-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char* arg_what = "idle:sleep:shutdown";
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "sysfs-show.h"
|
||||
#include "terminal-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "verbs.h"
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "formats-util.h"
|
||||
#include "process-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int manager_handle_action(
|
||||
Manager *m,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
|
||||
Device *d;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "terminal-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "utmp-wtmp.h"
|
||||
|
||||
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
|
||||
@@ -2027,7 +2028,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
|
||||
}
|
||||
|
||||
utmp_wall("The system shutdown has been cancelled",
|
||||
lookup_uid(uid), tty, logind_wall_tty_filter, m);
|
||||
uid_to_name(uid), tty, logind_wall_tty_filter, m);
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(message, "b", cancelled);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "logind-inhibit.h"
|
||||
#include "mkdir.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
Inhibitor* inhibitor_new(Manager *m, const char* id) {
|
||||
|
||||
@@ -35,12 +35,15 @@
|
||||
#include "bus-util.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "io-util.h"
|
||||
#include "logind-session.h"
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#define RELEASE_USEC (20*USEC_PER_SEC)
|
||||
|
||||
@@ -22,11 +22,12 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strv.h"
|
||||
#include "bus-util.h"
|
||||
#include "logind.h"
|
||||
#include "logind-user.h"
|
||||
#include "formats-util.h"
|
||||
#include "logind-user.h"
|
||||
#include "logind.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static int property_get_display(
|
||||
sd_bus *bus,
|
||||
|
||||
@@ -25,15 +25,17 @@
|
||||
#include <pwd.h>
|
||||
|
||||
#include "sd-messages.h"
|
||||
#include "strv.h"
|
||||
#include "special.h"
|
||||
#include "unit-name.h"
|
||||
|
||||
#include "audit.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "logind.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "formats-util.h"
|
||||
#include "logind.h"
|
||||
#include "special.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "utmp-wtmp.h"
|
||||
|
||||
_const_ static usec_t when_wall(usec_t n, usec_t elapse) {
|
||||
@@ -94,7 +96,7 @@ static int warn_wall(Manager *m, usec_t n) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
utmp_wall(l, lookup_uid(m->scheduled_shutdown_uid),
|
||||
utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid),
|
||||
m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "process-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static int property_get_pool_path(
|
||||
sd_bus *bus,
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
#include <net/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
#include "networkd-netdev-tuntap.h"
|
||||
#include "fd-util.h"
|
||||
#include "networkd-netdev-tuntap.h"
|
||||
#include "user-util.h"
|
||||
|
||||
#define TUN_DEV "/dev/net/tun"
|
||||
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
***/
|
||||
|
||||
#include "sd-daemon.h"
|
||||
|
||||
#include "capability.h"
|
||||
#include "signal-util.h"
|
||||
#include "networkd.h"
|
||||
#include "signal-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_manager_free_ Manager *m = NULL;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "local-addresses.h"
|
||||
#include "netlink-util.h"
|
||||
#include "nspawn-expose-ports.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "process-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
|
||||
|
||||
@@ -86,10 +86,12 @@
|
||||
#include "seccomp-util.h"
|
||||
#endif
|
||||
#include "signal-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef enum ContainerStatus {
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "macro.h"
|
||||
#include "nss-util.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "mkdir.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "netlink-util.h"
|
||||
#include "network-internal.h"
|
||||
#include "ordered-set.h"
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "sd-event.h"
|
||||
#include "sd-daemon.h"
|
||||
#include "mkdir.h"
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "capability.h"
|
||||
#include "mkdir.h"
|
||||
#include "resolved-conf.h"
|
||||
#include "resolved-manager.h"
|
||||
#include "selinux-util.h"
|
||||
#include "signal-util.h"
|
||||
|
||||
#include "resolved-manager.h"
|
||||
#include "resolved-conf.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "mkdir.h"
|
||||
#include "string-util.h"
|
||||
#include "udev-util.h"
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static bool arg_ask_password = true;
|
||||
static bool arg_scope = false;
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "acl-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "acl-util.h"
|
||||
|
||||
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
|
||||
acl_entry_t i;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "ask-password-api.h"
|
||||
#include "fd-util.h"
|
||||
#include "formats-util.h"
|
||||
#include "io-util.h"
|
||||
#include "missing.h"
|
||||
#include "mkdir.h"
|
||||
#include "random-util.h"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "efivars.h"
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "formats-util.h"
|
||||
#include "install-printf.h"
|
||||
#include "specifier.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "install-printf.h"
|
||||
#include "formats-util.h"
|
||||
|
||||
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
|
||||
UnitFileInstallInfo *i = userdata;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "formats-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "journal-internal.h"
|
||||
#include "log.h"
|
||||
#include "logs-show.h"
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "process-util.h"
|
||||
#include "spawn-polkit-agent.h"
|
||||
#include "fd-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef ENABLE_POLKIT
|
||||
static pid_t agent_pid = 0;
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "util.h"
|
||||
#include "uid-range.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static bool uid_range_intersect(UidRange *range, uid_t start, uid_t nr) {
|
||||
assert(range);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "utmp-wtmp.h"
|
||||
|
||||
int utmp_get_runlevel(int *runlevel, int *previous) {
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "hostname-util.h"
|
||||
#include "initreq.h"
|
||||
#include "install.h"
|
||||
#include "io-util.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
#include "logs-show.h"
|
||||
@@ -72,6 +73,7 @@
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
#include "utmp-wtmp.h"
|
||||
#include "verbs.h"
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
#include "fd-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
typedef enum ItemType {
|
||||
ADD_USER = 'u',
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "util.h"
|
||||
#include "clean-ipc.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
uid_t uid;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2015 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static void test_uid_to_name_one(uid_t uid, const char *name) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
assert_se(t = uid_to_name(uid));
|
||||
assert_se(streq_ptr(t, name));
|
||||
}
|
||||
|
||||
static void test_gid_to_name_one(gid_t gid, const char *name) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
assert_se(t = gid_to_name(gid));
|
||||
assert_se(streq_ptr(t, name));
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[]) {
|
||||
|
||||
test_uid_to_name_one(0, "root");
|
||||
test_uid_to_name_one(0xFFFF, "65535");
|
||||
test_uid_to_name_one(0xFFFFFFFF, "4294967295");
|
||||
|
||||
test_gid_to_name_one(0, "root");
|
||||
test_gid_to_name_one(TTY_GID, "tty");
|
||||
test_gid_to_name_one(0xFFFF, "65535");
|
||||
test_gid_to_name_one(0xFFFFFFFF, "4294967295");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -35,7 +35,9 @@
|
||||
#include "cpu-set-util.h"
|
||||
#include "def.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "mkdir.h"
|
||||
#include "process-util.h"
|
||||
#include "rm-rf.h"
|
||||
@@ -44,7 +46,7 @@
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
#include "fd-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static void test_streq_ptr(void) {
|
||||
assert_se(streq_ptr(NULL, NULL));
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "signal-util.h"
|
||||
#include "timesyncd-conf.h"
|
||||
#include "timesyncd-manager.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "formats-util.h"
|
||||
#include "io-util.h"
|
||||
#include "label.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
@@ -58,6 +59,7 @@
|
||||
#include "specifier.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "conf-parser.h"
|
||||
#include "def.h"
|
||||
#include "fd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "strv.h"
|
||||
#include "sysctl-util.h"
|
||||
#include "udev.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#define PREALLOC_TOKEN 2048
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "fileio.h"
|
||||
#include "formats-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "io-util.h"
|
||||
#include "netlink-util.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-util.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user