diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libudev/Makefile.am | 2 | ||||
-rw-r--r-- | src/libudev/conf-files.c | 17 | ||||
-rw-r--r-- | src/libudev/conf-files.h | 1 | ||||
-rw-r--r-- | src/libudev/env-util.c | 49 | ||||
-rw-r--r-- | src/libudev/env-util.h | 25 | ||||
-rw-r--r-- | src/libudev/hashmap.c | 60 | ||||
-rw-r--r-- | src/libudev/hashmap.h | 2 | ||||
-rw-r--r-- | src/libudev/log.h | 11 | ||||
-rw-r--r-- | src/libudev/util.c | 1282 | ||||
-rw-r--r-- | src/libudev/util.h | 70 |
10 files changed, 0 insertions, 1519 deletions
diff --git a/src/libudev/Makefile.am b/src/libudev/Makefile.am index 521eea8253..683944a671 100644 --- a/src/libudev/Makefile.am +++ b/src/libudev/Makefile.am @@ -36,7 +36,6 @@ libudev_la_SOURCES =\ cgroup-util.c \ conf-files.c \ exit-status.c \ - env-util.c \ hashmap.c \ log.c \ path-util.c \ @@ -51,7 +50,6 @@ noinst_HEADERS = \ cgroup-util.h \ conf-files.h \ def.h \ - env-util.h \ exit-status.h \ hashmap.h \ ioprio.h \ diff --git a/src/libudev/conf-files.c b/src/libudev/conf-files.c index 5938481f6b..2baefffad5 100644 --- a/src/libudev/conf-files.c +++ b/src/libudev/conf-files.c @@ -146,20 +146,3 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con return conf_files_list_strv_internal(strv, suffix, root, copy); } - -int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) { - _cleanup_strv_free_ char **dirs = NULL; - va_list ap; - - assert(strv); - assert(suffix); - - va_start(ap, dir); - dirs = strv_new_ap(dir, ap); - va_end(ap); - - if (!dirs) - return -ENOMEM; - - return conf_files_list_strv_internal(strv, suffix, root, dirs); -} diff --git a/src/libudev/conf-files.h b/src/libudev/conf-files.h index 73afe19b97..8fdf9a4632 100644 --- a/src/libudev/conf-files.h +++ b/src/libudev/conf-files.h @@ -25,7 +25,6 @@ #include "macro.h" -int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...); int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs); #endif diff --git a/src/libudev/env-util.c b/src/libudev/env-util.c deleted file mode 100644 index c2381ec6a3..0000000000 --- a/src/libudev/env-util.c +++ /dev/null @@ -1,49 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2012 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 <assert.h> -#include <string.h> -#include <util.h> -#include <unistd.h> - -#include "strv.h" - -char *strv_env_get_n(char **l, const char *name, size_t k) { - char **i; - - assert(name); - - if (k <= 0) - return NULL; - - STRV_FOREACH(i, l) - if (strneq(*i, name, k) && - (*i)[k] == '=') - return *i + k + 1; - - return NULL; -} - -char *strv_env_get(char **l, const char *name) { - assert(name); - - return strv_env_get_n(l, name, strlen(name)); -} diff --git a/src/libudev/env-util.h b/src/libudev/env-util.h deleted file mode 100644 index 2aa30aeda3..0000000000 --- a/src/libudev/env-util.h +++ /dev/null @@ -1,25 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2013 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/>. -***/ - -char *strv_env_get_n(char **l, const char *name, size_t k) _pure_; -char *strv_env_get(char **x, const char *n) _pure_; diff --git a/src/libudev/hashmap.c b/src/libudev/hashmap.c index 6626288cdc..58702d7d59 100644 --- a/src/libudev/hashmap.c +++ b/src/libudev/hashmap.c @@ -103,19 +103,6 @@ static void deallocate_tile(void **first_tile, void *p) { *first_tile = p; } -#ifdef VALGRIND - -static void drop_pool(struct pool *p) { - while (p) { - struct pool *n; - n = p->next; - free(p); - p = n; - } -} - -#endif - unsigned string_hash_func(const void *p) { unsigned hash = 5381; const signed char *c; @@ -363,25 +350,6 @@ bool hashmap_contains(Hashmap *h, const void *key) { return true; } -void* hashmap_remove(Hashmap *h, const void *key) { - struct hashmap_entry *e; - unsigned hash; - void *data; - - if (!h) - return NULL; - - hash = h->hash_func(key) % NBUCKETS; - - if (!(e = hash_scan(h, hash, key))) - return NULL; - - data = e->value; - remove_entry(h, e); - - return data; -} - void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) { struct hashmap_entry *e; @@ -494,34 +462,6 @@ int hashmap_merge(Hashmap *h, Hashmap *other) { return 0; } -void hashmap_move(Hashmap *h, Hashmap *other) { - struct hashmap_entry *e, *n; - - assert(h); - - /* The same as hashmap_merge(), but every new item from other - * is moved to h. This function is guaranteed to succeed. */ - - if (!other) - return; - - for (e = other->iterate_list_head; e; e = n) { - unsigned h_hash, other_hash; - - n = e->iterate_next; - - h_hash = h->hash_func(e->key) % NBUCKETS; - - if (hash_scan(h, h_hash, e->key)) - continue; - - other_hash = other->hash_func(e->key) % NBUCKETS; - - unlink_entry(other, e, other_hash); - link_entry(h, e, h_hash); - } -} - char **hashmap_get_strv(Hashmap *h) { char **sv; Iterator it; diff --git a/src/libudev/hashmap.h b/src/libudev/hashmap.h index a889fc7c18..4c17fe4d33 100644 --- a/src/libudev/hashmap.h +++ b/src/libudev/hashmap.h @@ -56,10 +56,8 @@ void hashmap_free_free(Hashmap *h); int hashmap_put(Hashmap *h, const void *key, void *value); void *hashmap_get(Hashmap *h, const void *key); bool hashmap_contains(Hashmap *h, const void *key); -void *hashmap_remove(Hashmap *h, const void *key); int hashmap_merge(Hashmap *h, Hashmap *other); -void hashmap_move(Hashmap *h, Hashmap *other); unsigned hashmap_size(Hashmap *h) _pure_; diff --git a/src/libudev/log.h b/src/libudev/log.h index fab0100b6a..0a15adb41c 100644 --- a/src/libudev/log.h +++ b/src/libudev/log.h @@ -73,14 +73,6 @@ int log_oom_internal( int line, const char *func); -/* This modifies the buffer passed! */ -int log_dump_internal( - int level, - const char*file, - int line, - const char *func, - char *buffer); - _noreturn_ void log_assert_failed( const char *text, const char *file, @@ -103,9 +95,6 @@ _noreturn_ void log_assert_failed_unreachable( #define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) -/* This modifies the buffer passed! */ -#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) - const char *log_target_to_string(LogTarget target) _const_; LogTarget log_target_from_string(const char *s) _pure_; diff --git a/src/libudev/util.c b/src/libudev/util.c index 48469e6e34..dc1641c3bc 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -70,7 +70,6 @@ #include "path-util.h" #include "exit-status.h" #include "hashmap.h" -#include "env-util.h" int saved_argc = 0; char **saved_argv = NULL; @@ -197,27 +196,6 @@ void close_nointr_nofail(int fd) { assert_se(close_nointr(fd) == 0); } -int parse_uid(const char *s, uid_t* ret_uid) { - unsigned long ul = 0; - uid_t uid; - int r; - - assert(s); - assert(ret_uid); - - r = safe_atolu(s, &ul); - if (r < 0) - return r; - - uid = (uid_t) ul; - - if ((unsigned long) uid != ul) - return -ERANGE; - - *ret_uid = uid; - return 0; -} - int safe_atou(const char *s, unsigned *ret_u) { char *x = NULL; unsigned long l; @@ -418,62 +396,6 @@ int read_one_line_file(const char *fn, char **line) { return 0; } -int read_full_file(const char *fn, char **contents, size_t *size) { - _cleanup_fclose_ FILE *f = NULL; - size_t n, l; - _cleanup_free_ char *buf = NULL; - struct stat st; - - f = fopen(fn, "re"); - if (!f) - return -errno; - - if (fstat(fileno(f), &st) < 0) - return -errno; - - /* Safety check */ - if (st.st_size > 4*1024*1024) - return -E2BIG; - - n = st.st_size > 0 ? st.st_size : LINE_MAX; - l = 0; - - for (;;) { - char *t; - size_t k; - - t = realloc(buf, n+1); - if (!t) - return -ENOMEM; - - buf = t; - k = fread(buf + l, 1, n - l, f); - - if (k <= 0) { - if (ferror(f)) - return -errno; - - break; - } - - l += k; - n *= 2; - - /* Safety check */ - if (n > 4*1024*1024) - return -E2BIG; - } - - buf[l] = 0; - *contents = buf; - buf = NULL; - - if (size) - *size = l; - - return 0; -} - char *truncate_nl(char *s) { assert(s); @@ -546,50 +468,6 @@ int readlink_malloc(const char *p, char **r) { } } -char *strstrip(char *s) { - char *e; - - /* Drops trailing whitespace. Modifies the string in - * place. Returns pointer to first non-space character */ - - s += strspn(s, WHITESPACE); - - for (e = strchr(s, 0); e > s; e --) - if (!strchr(WHITESPACE, e[-1])) - break; - - *e = 0; - - return s; -} - -char *file_in_same_dir(const char *path, const char *filename) { - char *e, *r; - size_t k; - - assert(path); - assert(filename); - - /* This removes the last component of path and appends - * filename, unless the latter is absolute anyway or the - * former isn't */ - - if (path_is_absolute(filename)) - return strdup(filename); - - if (!(e = strrchr(path, '/'))) - return strdup(filename); - - k = strlen(filename); - if (!(r = new(char, e-path+1+k+1))) - return NULL; - - memcpy(r, path, e-path+1); - memcpy(r+(e-path)+1, filename, k+1); - - return r; -} - char hexchar(int x) { static const char table[16] = "0123456789abcdef"; @@ -622,174 +500,6 @@ int unoctchar(char c) { return -1; } -char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) { - char *r, *t; - const char *f; - size_t pl; - - assert(s); - - /* Undoes C style string escaping, and optionally prefixes it. */ - - pl = prefix ? strlen(prefix) : 0; - - r = new(char, pl+length+1); - if (!r) - return r; - - if (prefix) - memcpy(r, prefix, pl); - - for (f = s, t = r + pl; f < s + length; f++) { - - if (*f != '\\') { - *(t++) = *f; - continue; - } - - f++; - - switch (*f) { - - case 'a': - *(t++) = '\a'; - break; - case 'b': - *(t++) = '\b'; - break; - case 'f': - *(t++) = '\f'; - break; - case 'n': - *(t++) = '\n'; - break; - case 'r': - *(t++) = '\r'; - break; - case 't': - *(t++) = '\t'; - break; - case 'v': - *(t++) = '\v'; - break; - case '\\': - *(t++) = '\\'; - break; - case '"': - *(t++) = '"'; - break; - case '\'': - *(t++) = '\''; - break; - - case 's': - /* This is an extension of the XDG syntax files */ - *(t++) = ' '; - break; - - case 'x': { - /* hexadecimal encoding */ - int a, b; - - a = unhexchar(f[1]); - b = unhexchar(f[2]); - - if (a < 0 || b < 0) { - /* Invalid escape code, let's take it literal then */ - *(t++) = '\\'; - *(t++) = 'x'; - } else { - *(t++) = (char) ((a << 4) | b); - f += 2; - } - - break; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': { - /* octal encoding */ - int a, b, c; - - a = unoctchar(f[0]); - b = unoctchar(f[1]); - c = unoctchar(f[2]); - - if (a < 0 || b < 0 || c < 0) { - /* Invalid escape code, let's take it literal then */ - *(t++) = '\\'; - *(t++) = f[0]; - } else { - *(t++) = (char) ((a << 6) | (b << 3) | c); - f += 2; - } - - break; - } - - case 0: - /* premature end of string.*/ - *(t++) = '\\'; - goto finish; - - default: - /* Invalid escape code, let's take it literal then */ - *(t++) = '\\'; - *(t++) = *f; - break; - } - } - -finish: - *t = 0; - return r; -} - -char *cunescape_length(const char *s, size_t length) { - return cunescape_length_with_prefix(s, length, NULL); -} - -char *cunescape(const char *s) { - assert(s); - - return cunescape_length(s, strlen(s)); -} - -char *xescape(const char *s, const char *bad) { - char *r, *t; - const char *f; - - /* Escapes all chars in bad, in addition to \ and all special - * chars, in \xFF style escaping. May be reversed with - * cunescape. */ - - r = new(char, strlen(s) * 4 + 1); - if (!r) - return NULL; - - for (f = s, t = r; *f; f++) { - - if ((*f < ' ') || (*f >= 127) || - (*f == '\\') || strchr(bad, *f)) { - *(t++) = '\\'; - *(t++) = 'x'; - *(t++) = hexchar(*f >> 4); - *(t++) = hexchar(*f); - } else - *(t++) = *f; - } - - *t = 0; - - return r; -} - _pure_ static bool ignore_file_allow_backup(const char *filename) { assert(filename); @@ -827,66 +537,6 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { return false; } -int close_all_fds(const int except[], unsigned n_except) { - DIR *d; - struct dirent *de; - int r = 0; - - assert(n_except == 0 || except); - - d = opendir("/proc/self/fd"); - if (!d) { - int fd; - struct rlimit rl; - - /* When /proc isn't available (for example in chroots) - * the fallback is brute forcing through the fd - * table */ - - assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0); - for (fd = 3; fd < (int) rl.rlim_max; fd ++) { - - if (fd_in_set(fd, except, n_except)) - continue; - - if (close_nointr(fd) < 0) - if (errno != EBADF && r == 0) - r = -errno; - } - - return r; - } - - while ((de = readdir(d))) { - int fd = -1; - - if (ignore_file(de->d_name)) - continue; - - if (safe_atoi(de->d_name, &fd) < 0) - /* Let's better ignore this, just in case */ - continue; - - if (fd < 3) - continue; - - if (fd == dirfd(d)) - continue; - - if (fd_in_set(fd, except, n_except)) - continue; - - if (close_nointr(fd) < 0) { - /* Valgrind has its own FD and doesn't want to have it closed */ - if (errno != EBADF && r == 0) - r = -errno; - } - } - - closedir(d); - return r; -} - char *format_timespan(char *buf, size_t l, usec_t t) { static const struct { const char *suffix; @@ -942,190 +592,6 @@ char *format_timespan(char *buf, size_t l, usec_t t) { return buf; } -int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { - struct termios old_termios, new_termios; - char c; - char line[LINE_MAX]; - - assert(f); - assert(ret); - - if (tcgetattr(fileno(f), &old_termios) >= 0) { - new_termios = old_termios; - - new_termios.c_lflag &= ~ICANON; - new_termios.c_cc[VMIN] = 1; - new_termios.c_cc[VTIME] = 0; - - if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) { - size_t k; - - if (t != (usec_t) -1) { - if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) { - tcsetattr(fileno(f), TCSADRAIN, &old_termios); - return -ETIMEDOUT; - } - } - - k = fread(&c, 1, 1, f); - - tcsetattr(fileno(f), TCSADRAIN, &old_termios); - - if (k <= 0) - return -EIO; - - if (need_nl) - *need_nl = c != '\n'; - - *ret = c; - return 0; - } - } - - if (t != (usec_t) -1) - if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) - return -ETIMEDOUT; - - if (!fgets(line, sizeof(line), f)) - return -EIO; - - truncate_nl(line); - - if (strlen(line) != 1) - return -EBADMSG; - - if (need_nl) - *need_nl = false; - - *ret = line[0]; - return 0; -} - -int ask(char *ret, const char *replies, const char *text, ...) { - - assert(ret); - assert(replies); - assert(text); - - for (;;) { - va_list ap; - char c; - int r; - bool need_nl = true; - - if (on_tty()) - fputs(ANSI_HIGHLIGHT_ON, stdout); - - va_start(ap, text); - vprintf(text, ap); - va_end(ap); - - if (on_tty()) - fputs(ANSI_HIGHLIGHT_OFF, stdout); - - fflush(stdout); - - r = read_one_char(stdin, &c, (usec_t) -1, &need_nl); - if (r < 0) { - - if (r == -EBADMSG) { - puts("Bad input, please try again."); - continue; - } - - putchar('\n'); - return r; - } - - if (need_nl) - putchar('\n'); - - if (strchr(replies, c)) { - *ret = c; - return 0; - } - - puts("Read unexpected character, please try again."); - } -} - -int reset_terminal_fd(int fd, bool switch_to_text) { - struct termios termios; - int r = 0; - - /* Set terminal to some sane defaults */ - - assert(fd >= 0); - - /* We leave locked terminal attributes untouched, so that - * Plymouth may set whatever it wants to set, and we don't - * interfere with that. */ - - /* Disable exclusive mode, just in case */ - ioctl(fd, TIOCNXCL); - - /* Switch to text mode */ - if (switch_to_text) - ioctl(fd, KDSETMODE, KD_TEXT); - - /* Enable console unicode mode */ - ioctl(fd, KDSKBMODE, K_UNICODE); - - if (tcgetattr(fd, &termios) < 0) { - r = -errno; - goto finish; - } - - /* We only reset the stuff that matters to the software. How - * hardware is set up we don't touch assuming that somebody - * else will do that for us */ - - termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC); - termios.c_iflag |= ICRNL | IMAXBEL | IUTF8; - termios.c_oflag |= ONLCR; - termios.c_cflag |= CREAD; - termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE; - - termios.c_cc[VINTR] = 03; /* ^C */ - termios.c_cc[VQUIT] = 034; /* ^\ */ - termios.c_cc[VERASE] = 0177; - termios.c_cc[VKILL] = 025; /* ^X */ - termios.c_cc[VEOF] = 04; /* ^D */ - termios.c_cc[VSTART] = 021; /* ^Q */ - termios.c_cc[VSTOP] = 023; /* ^S */ - termios.c_cc[VSUSP] = 032; /* ^Z */ - termios.c_cc[VLNEXT] = 026; /* ^V */ - termios.c_cc[VWERASE] = 027; /* ^W */ - termios.c_cc[VREPRINT] = 022; /* ^R */ - termios.c_cc[VEOL] = 0; - termios.c_cc[VEOL2] = 0; - - termios.c_cc[VTIME] = 0; - termios.c_cc[VMIN] = 1; - - if (tcsetattr(fd, TCSANOW, &termios) < 0) - r = -errno; - -finish: - /* Just in case, flush all crap out */ - tcflush(fd, TCIOFLUSH); - - return r; -} - -int reset_terminal(const char *name) { - int fd, r; - - fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); - if (fd < 0) - return fd; - - r = reset_terminal_fd(fd, true); - close_nointr_nofail(fd); - - return r; -} - int open_terminal(const char *name, int mode) { int fd, r; unsigned c = 0; @@ -1172,294 +638,6 @@ int open_terminal(const char *name, int mode) { return fd; } -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; - ssize_t n = 0; - - assert(fd >= 0); - assert(buf); - - p = buf; - - while (nbytes > 0) { - ssize_t k; - - if ((k = read(fd, p, nbytes)) <= 0) { - - if (k < 0 && errno == EINTR) - continue; - - if (k < 0 && errno == EAGAIN && do_poll) { - struct pollfd pollfd = { - .fd = fd, - .events = POLLIN, - }; - - if (poll(&pollfd, 1, -1) < 0) { - if (errno == EINTR) - continue; - - return n > 0 ? n : -errno; - } - - if (pollfd.revents != POLLIN) - return n > 0 ? n : -EIO; - - continue; - } - - return n > 0 ? n : (k < 0 ? -errno : 0); - } - - p += k; - nbytes -= k; - n += k; - } - - return n; -} - -int get_ctty_devnr(pid_t pid, dev_t *d) { - _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX], *p; - unsigned long ttynr; - const char *fn; - int k; - - assert(pid >= 0); - assert(d); - - if (pid == 0) - fn = "/proc/self/stat"; - else - fn = procfs_file_alloca(pid, "stat"); - - f = fopen(fn, "re"); - if (!f) - return -errno; - - if (!fgets(line, sizeof(line), f)) { - k = feof(f) ? -EIO : -errno; - return k; - } - - p = strrchr(line, ')'); - if (!p) - return -EIO; - - p++; - - if (sscanf(p, " " - "%*c " /* state */ - "%*d " /* ppid */ - "%*d " /* pgrp */ - "%*d " /* session */ - "%lu ", /* ttynr */ - &ttynr) != 1) - return -EIO; - - if (major(ttynr) == 0 && minor(ttynr) == 0) - return -ENOENT; - - *d = (dev_t) ttynr; - return 0; -} - -int get_ctty(pid_t pid, dev_t *_devnr, char **r) { - int k; - char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *s, *b, *p; - dev_t devnr; - - assert(r); - - k = get_ctty_devnr(pid, &devnr); - if (k < 0) - return k; - - snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr)); - - k = readlink_malloc(fn, &s); - if (k < 0) { - - if (k != -ENOENT) - return k; - - /* This is an ugly hack */ - if (major(devnr) == 136) { - if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0) - return -ENOMEM; - - *r = b; - if (_devnr) - *_devnr = devnr; - - return 0; - } - - /* Probably something like the ptys which have no - * symlink in /dev/char. Let's return something - * vaguely useful. */ - - b = strdup(fn + 5); - if (!b) - return -ENOMEM; - - *r = b; - if (_devnr) - *_devnr = devnr; - - return 0; - } - - if (startswith(s, "/dev/")) - p = s + 5; - else if (startswith(s, "../")) - p = s + 3; - else - p = s; - - b = strdup(p); - free(s); - - if (!b) - return -ENOMEM; - - *r = b; - if (_devnr) - *_devnr = devnr; - - return 0; -} - -int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { - DIR *d; - int ret = 0; - - assert(fd >= 0); - - /* This returns the first error we run into, but nevertheless - * tries to go on. This closes the passed fd. */ - - d = fdopendir(fd); - if (!d) { - close_nointr_nofail(fd); - - return errno == ENOENT ? 0 : -errno; - } - - for (;;) { - struct dirent *de; - union dirent_storage buf; - bool is_dir, keep_around; - struct stat st; - int r; - - r = readdir_r(d, &buf.de, &de); - if (r != 0 && ret == 0) { - ret = -r; - break; - } - - if (!de) - break; - - if (streq(de->d_name, ".") || streq(de->d_name, "..")) - continue; - - if (de->d_type == DT_UNKNOWN || - honour_sticky || - (de->d_type == DT_DIR && root_dev)) { - if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { - if (ret == 0 && errno != ENOENT) - ret = -errno; - continue; - } - - is_dir = S_ISDIR(st.st_mode); - keep_around = - honour_sticky && - (st.st_uid == 0 || st.st_uid == getuid()) && - (st.st_mode & S_ISVTX); - } else { - is_dir = de->d_type == DT_DIR; - keep_around = false; - } - - if (is_dir) { - int subdir_fd; - - /* if root_dev is set, remove subdirectories only, if device is same as dir */ - if (root_dev && st.st_dev != root_dev->st_dev) - continue; - - subdir_fd = openat(fd, de->d_name, - O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); - if (subdir_fd < 0) { - if (ret == 0 && errno != ENOENT) - ret = -errno; - continue; - } - - r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev); - if (r < 0 && ret == 0) - ret = r; - - if (!keep_around) - if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) { - if (ret == 0 && errno != ENOENT) - ret = -errno; - } - - } else if (!only_dirs && !keep_around) { - - if (unlinkat(fd, de->d_name, 0) < 0) { - if (ret == 0 && errno != ENOENT) - ret = -errno; - } - } - } - - closedir(d); - - return ret; -} - _pure_ static int is_temporary_fs(struct statfs *s) { assert(s); return @@ -1467,97 +645,6 @@ _pure_ static int is_temporary_fs(struct statfs *s) { F_TYPE_CMP(s->f_type, RAMFS_MAGIC); } -int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { - struct statfs s; - - assert(fd >= 0); - - if (fstatfs(fd, &s) < 0) { - close_nointr_nofail(fd); - return -errno; - } - - /* We refuse to clean disk file systems with this call. This - * is extra paranoia just to be sure we never ever remove - * non-state data */ - if (!is_temporary_fs(&s)) { - log_error("Attempted to remove disk file system, and we can't allow that."); - close_nointr_nofail(fd); - return -EPERM; - } - - return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev); -} - -static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) { - int fd, r; - struct statfs s; - - assert(path); - - /* We refuse to clean the root file system with this - * call. This is extra paranoia to never cause a really - * seriously broken system. */ - if (path_equal(path, "/")) { - log_error("Attempted to remove entire root file system, and we can't allow that."); - return -EPERM; - } - - fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); - if (fd < 0) { - - if (errno != ENOTDIR) - return -errno; - - if (!dangerous) { - if (statfs(path, &s) < 0) - return -errno; - - if (!is_temporary_fs(&s)) { - log_error("Attempted to remove disk file system, and we can't allow that."); - return -EPERM; - } - } - - if (delete_root && !only_dirs) - if (unlink(path) < 0 && errno != ENOENT) - return -errno; - - return 0; - } - - if (!dangerous) { - if (fstatfs(fd, &s) < 0) { - close_nointr_nofail(fd); - return -errno; - } - - if (!is_temporary_fs(&s)) { - log_error("Attempted to remove disk file system, and we can't allow that."); - close_nointr_nofail(fd); - return -EPERM; - } - } - - r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL); - if (delete_root) { - - if (honour_sticky && file_is_priv_sticky(path) > 0) - return r; - - if (rmdir(path) < 0 && errno != ENOENT) { - if (r == 0) - r = -errno; - } - } - - return r; -} - -int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { - return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false); -} - int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { assert(path); @@ -1576,219 +663,6 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { return 0; } -int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) { - static const char status_indent[] = " "; /* "[" STATUS "] " */ - _cleanup_free_ char *s = NULL; - _cleanup_close_ int fd = -1; - struct iovec iovec[6] = {}; - int n = 0; - static bool prev_ephemeral; - - assert(format); - - /* This is independent of logging, as status messages are - * optional and go exclusively to the console. */ - - if (vasprintf(&s, format, ap) < 0) - return log_oom(); - - fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); - if (fd < 0) - return fd; - - if (ellipse) { - char *e; - size_t emax, sl; - int c; - - c = fd_columns(fd); - if (c <= 0) - c = 80; - - sl = status ? sizeof(status_indent)-1 : 0; - - emax = c - sl - 1; - if (emax < 3) - emax = 3; - - e = ellipsize(s, emax, 75); - if (e) { - free(s); - s = e; - } - } - - if (prev_ephemeral) - IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE); - prev_ephemeral = ephemeral; - - if (status) { - if (!isempty(status)) { - IOVEC_SET_STRING(iovec[n++], "["); - IOVEC_SET_STRING(iovec[n++], status); - IOVEC_SET_STRING(iovec[n++], "] "); - } else - IOVEC_SET_STRING(iovec[n++], status_indent); - } - - IOVEC_SET_STRING(iovec[n++], s); - if (!ephemeral) - IOVEC_SET_STRING(iovec[n++], "\n"); - - if (writev(fd, iovec, n) < 0) - return -errno; - - return 0; -} - -int fd_columns(int fd) { - struct winsize ws = {}; - - if (ioctl(fd, TIOCGWINSZ, &ws) < 0) - return -errno; - - if (ws.ws_col <= 0) - return -EIO; - - return ws.ws_col; -} - -unsigned columns(void) { - const char *e; - int c; - - if (_likely_(cached_columns > 0)) - return cached_columns; - - c = 0; - e = getenv("COLUMNS"); - if (e) - safe_atoi(e, &c); - - if (c <= 0) - c = fd_columns(STDOUT_FILENO); - - if (c <= 0) - c = 80; - - cached_columns = c; - return c; -} - -int fd_lines(int fd) { - struct winsize ws = {}; - - if (ioctl(fd, TIOCGWINSZ, &ws) < 0) - return -errno; - - if (ws.ws_row <= 0) - return -EIO; - - return ws.ws_row; -} - -unsigned lines(void) { - const char *e; - unsigned l; - - if (_likely_(cached_lines > 0)) - return cached_lines; - - l = 0; - e = getenv("LINES"); - if (e) - safe_atou(e, &l); - - if (l <= 0) - l = fd_lines(STDOUT_FILENO); - - if (l <= 0) - l = 24; - - cached_lines = l; - return cached_lines; -} - -bool on_tty(void) { - static int cached_on_tty = -1; - - if (_unlikely_(cached_on_tty < 0)) - cached_on_tty = isatty(STDOUT_FILENO) > 0; - - return cached_on_tty; -} - -char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { - size_t x; - char *r; - - assert(s); - assert(percent <= 100); - assert(new_length >= 3); - - if (old_length <= 3 || old_length <= new_length) - return strndup(s, old_length); - - r = new0(char, new_length+1); - if (!r) - return r; - - x = (new_length * percent) / 100; - - if (x > new_length - 3) - x = new_length - 3; - - memcpy(r, s, x); - r[x] = '.'; - r[x+1] = '.'; - r[x+2] = '.'; - memcpy(r + x + 3, - s + old_length - (new_length - x - 3), - new_length - x - 3); - - return r; -} - -char *ellipsize(const char *s, size_t length, unsigned percent) { - return ellipsize_mem(s, strlen(s), length, percent); -} - -int touch(const char *path) { - int fd; - - assert(path); - - /* This just opens the file for writing, ensuring it - * exists. It doesn't call utimensat() the way /usr/bin/touch - * does it. */ - - fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644); - if (fd < 0) - return -errno; - - close_nointr_nofail(fd); - return 0; -} - -char *unquote(const char *s, const char* quotes) { - size_t l; - assert(s); - - /* This is rather stupid, simply removes the heading and - * trailing quotes if there is one. Doesn't care about - * escaping or anything. We should make this smarter one - * day...*/ - - l = strlen(s); - if (l < 2) - return strdup(s); - - if (strchr(quotes, s[0]) && s[l-1] == s[0]) - return strndup(s+1, l-2); - - return strdup(s); -} - bool null_or_empty(struct stat *st) { assert(st); @@ -1812,76 +686,6 @@ int null_or_empty_path(const char *fn) { return null_or_empty(&st); } -bool tty_is_vc(const char *tty) { - assert(tty); - - if (startswith(tty, "/dev/")) - tty += 5; - - return vtnr_from_tty(tty) >= 0; -} - -int vtnr_from_tty(const char *tty) { - int i, r; - - assert(tty); - - if (startswith(tty, "/dev/")) - tty += 5; - - if (!startswith(tty, "tty") ) - return -EINVAL; - - if (tty[3] < '0' || tty[3] > '9') - return -EINVAL; - - r = safe_atoi(tty+3, &i); - if (r < 0) - return r; - - if (i < 0 || i > 63) - return -EINVAL; - - return i; -} - -char *resolve_dev_console(char **active) { - char *tty; - - /* Resolve where /dev/console is pointing to, if /sys is actually ours - * (i.e. not read-only-mounted which is a sign for container setups) */ - - if (path_is_read_only_fs("/sys") > 0) - return NULL; - - if (read_one_line_file("/sys/class/tty/console/active", active) < 0) - return NULL; - - /* If multiple log outputs are configured the last one is what - * /dev/console points to */ - tty = strrchr(*active, ' '); - if (tty) - tty++; - else - tty = *active; - - return tty; -} - -bool dirent_is_file(const struct dirent *de) { - assert(de); - - if (ignore_file(de->d_name)) - return false; - - if (de->d_type != DT_REG && - de->d_type != DT_LNK && - de->d_type != DT_UNKNOWN) - return false; - - return true; -} - bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { assert(de); @@ -1936,23 +740,6 @@ int execute_command(const char *command, char *const argv[]) } } -int fd_wait_for_event(int fd, int event, usec_t t) { - int r; - struct pollfd pollfd = { - .fd = fd, - .events = event, - }; - - r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC)); - 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; @@ -1998,28 +785,6 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { return 0; } -int terminal_vhangup_fd(int fd) { - assert(fd >= 0); - - if (ioctl(fd, TIOCVHANGUP) < 0) - return -errno; - - return 0; -} - -int terminal_vhangup(const char *name) { - int fd, r; - - fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); - if (fd < 0) - return fd; - - r = terminal_vhangup_fd(fd); - close_nointr_nofail(fd); - - return r; -} - char *strjoin(const char *x, ...) { va_list ap; size_t l; @@ -2086,19 +851,6 @@ bool is_main_thread(void) { return cached > 0; } -int file_is_priv_sticky(const char *p) { - struct stat st; - - assert(p); - - if (lstat(p, &st) < 0) - return -errno; - - return - (st.st_uid == 0 || st.st_uid == getuid()) && - (st.st_mode & S_ISVTX); -} - static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", @@ -2251,40 +1003,6 @@ const char *signal_to_string(int signo) { return buf; } -int signal_from_string(const char *s) { - int signo; - int offset = 0; - unsigned u; - - signo = __signal_from_string(s); - if (signo > 0) - return signo; - - if (startswith(s, "RTMIN+")) { - s += 6; - offset = SIGRTMIN; - } - if (safe_atou(s, &u) >= 0) { - signo = (int) u + offset; - if (signo > 0 && signo < _NSIG) - return signo; - } - return -1; -} - -void* memdup(const void *p, size_t l) { - void *r; - - assert(p); - - r = malloc(l); - if (!r) - return NULL; - - memcpy(r, p, l); - return r; -} - int fd_inc_sndbuf(int fd, size_t n) { int r, value; socklen_t l = sizeof(value); diff --git a/src/libudev/util.h b/src/libudev/util.h index 0920082613..80a0c436ad 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -145,9 +145,6 @@ char *startswith(const char *s, const char *prefix) _pure_; int close_nointr(int fd); void close_nointr_nofail(int fd); -int parse_uid(const char *s, uid_t* ret_uid); -#define parse_gid(s, ret_uid) parse_uid(s, ret_uid) - int safe_atou(const char *s, unsigned *ret_u); int safe_atoi(const char *s, int *ret_i); @@ -208,30 +205,19 @@ char *split_quoted(const char *c, size_t *l, char **state); int write_one_line_file(const char *fn, const char *line); int read_one_line_file(const char *fn, char **line); -int read_full_file(const char *fn, char **contents, size_t *size); char *strappend(const char *s, const char *suffix); char *strnappend(const char *s, const char *suffix, size_t length); int readlink_malloc(const char *p, char **r); -char *strstrip(char *s); char *truncate_nl(char *s); -char *file_in_same_dir(const char *path, const char *filename); - char hexchar(int x) _const_; int unhexchar(char c) _const_; char octchar(int x) _const_; int unoctchar(char c) _const_; -char *cunescape(const char *s); -char *cunescape_length(const char *s, size_t length); -char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix); - -char *xescape(const char *s, const char *bad); - -bool dirent_is_file(const struct dirent *de) _pure_; bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; bool ignore_file(const char *filename) _pure_; @@ -292,65 +278,21 @@ char *format_timespan(char *buf, size_t l, usec_t t); } \ struct __useless_struct_to_allow_trailing_semicolon__ -int close_all_fds(const int except[], unsigned n_except); - -int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl); -int ask(char *ret, const char *replies, const char *text, ...) _printf_attr_(3, 4); - -int reset_terminal_fd(int fd, bool switch_to_text); -int reset_terminal(const char *name); - int open_terminal(const char *name, int mode); -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 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 rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); -int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); -int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); - -int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_attr_(4,0); - -int fd_columns(int fd); -unsigned columns(void); -int fd_lines(int fd); -unsigned lines(void); - -bool on_tty(void); - -char *ellipsize(const char *s, size_t length, unsigned percent); -char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent); - -int touch(const char *path); - -char *unquote(const char *s, const char *quotes); - bool null_or_empty(struct stat *st) _pure_; int null_or_empty_path(const char *fn); -char *resolve_dev_console(char **active); -bool tty_is_vc(const char *tty); -int vtnr_from_tty(const char *tty); - int execute_command(const char *command, char *const argv[]); -int terminal_vhangup_fd(int fd); -int terminal_vhangup(const char *name); - char *strjoin(const char *x, ...) _sentinel_; bool is_main_thread(void); -int file_is_priv_sticky(const char *p); - #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) @@ -379,15 +321,10 @@ int ip_tos_to_string_alloc(int i, char **s); int ip_tos_from_string(const char *s); const char *signal_to_string(int i) _const_; -int signal_from_string(const char *s) _pure_; extern int saved_argc; extern char **saved_argv; -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); bool in_initrd(void); @@ -435,13 +372,6 @@ _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) return malloc(a * b); } -_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) { - if (_unlikely_(b == 0 || a > ((size_t) -1) / b)) - return NULL; - - return memdup(p, a * b); -} - void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), void *arg); |