X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=b516b9b0532e5163593487e7fc7f6a1e41aa5029;hp=69f1b00934321ac8ae4e07fd9a2f50de33fbfd40;hb=e62d8c3944745ed276e6d4f33153009860e5cfc5;hpb=9a17484d986f6cb8828afdf911db425b574c63fd diff --git a/src/shared/util.c b/src/shared/util.c index 69f1b0093..b516b9b05 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -59,6 +59,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -219,6 +220,8 @@ void close_nointr_nofail(int fd) { void close_many(const int fds[], unsigned n_fd) { unsigned i; + assert(fds || n_fd <= 0); + for (i = 0; i < n_fd; i++) close_nointr_nofail(fds[i]); } @@ -290,7 +293,7 @@ int safe_atou(const char *s, unsigned *ret_u) { l = strtoul(s, &x, 0); if (!x || x == s || *x || errno) - return errno ? -errno : -EINVAL; + return errno > 0 ? -errno : -EINVAL; if ((unsigned long) (unsigned) l != l) return -ERANGE; @@ -310,7 +313,7 @@ int safe_atoi(const char *s, int *ret_i) { l = strtol(s, &x, 0); if (!x || x == s || *x || errno) - return errno ? -errno : -EINVAL; + return errno > 0 ? -errno : -EINVAL; if ((long) (int) l != l) return -ERANGE; @@ -1066,6 +1069,32 @@ char *hexmem(const void *p, size_t l) { return r; } +void *unhexmem(const char *p, size_t l) { + uint8_t *r, *z; + const char *x; + + assert(p); + + z = r = malloc((l + 1) / 2 + 1); + if (!r) + return NULL; + + for (x = p; x < p + l; x += 2) { + int a, b; + + a = unhexchar(x[0]); + if (x+1 < p + l) + b = unhexchar(x[1]); + else + b = 0; + + *(z++) = (uint8_t) a << 4 | (uint8_t) b; + } + + *z = 0; + return r; +} + char octchar(int x) { return '0' + (x & 7); } @@ -1844,18 +1873,18 @@ int flush_fd(int fd) { ssize_t l; int r; - if ((r = poll(&pollfd, 1, 0)) < 0) { - + r = poll(&pollfd, 1, 0); + if (r < 0) { if (errno == EINTR) continue; return -errno; - } - if (r == 0) + } else if (r == 0) return 0; - if ((l = read(fd, buf, sizeof(buf))) < 0) { + l = read(fd, buf, sizeof(buf)); + if (l < 0) { if (errno == EINTR) continue; @@ -1864,9 +1893,7 @@ int flush_fd(int fd) { return 0; return -errno; - } - - if (l <= 0) + } else if (l == 0) return 0; } } @@ -2039,10 +2066,12 @@ fail: } int release_terminal(void) { - int r = 0, fd; + int r = 0; struct sigaction sa_old, sa_new; + int _cleanup_close_ fd; - if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0) + fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC); + if (fd < 0) return -errno; /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed @@ -2058,7 +2087,6 @@ int release_terminal(void) { assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); - close_nointr_nofail(fd); return r; } @@ -2262,7 +2290,7 @@ int parse_bytes(const char *t, off_t *bytes) { errno = 0; l = strtoll(p, &e, 10); - if (errno != 0) + if (errno > 0) return -errno; if (l < 0) @@ -2354,6 +2382,24 @@ int dir_is_empty(const char *path) { } } +char* dirname_malloc(const char *path) { + char *d, *dir, *dir2; + + d = strdup(path); + if (!d) + return NULL; + dir = dirname(d); + assert(dir); + + if (dir != d) { + dir2 = strdup(dir); + free(d); + return dir2; + } + + return dir; +} + unsigned long long random_ull(void) { _cleanup_close_ int fd; uint64_t ull; @@ -3773,13 +3819,27 @@ static bool hostname_valid_char(char c) { bool hostname_is_valid(const char *s) { const char *p; + bool dot; if (isempty(s)) return false; - for (p = s; *p; p++) - if (!hostname_valid_char(*p)) - return false; + for (p = s, dot = true; *p; p++) { + if (*p == '.') { + if (dot) + return false; + + dot = true; + } else { + if (!hostname_valid_char(*p)) + return false; + + dot = false; + } + } + + if (dot) + return false; if (p-s > HOST_NAME_MAX) return false; @@ -4156,7 +4216,7 @@ int get_user_creds( } if (!p) - return errno != 0 ? -errno : -ESRCH; + return errno > 0 ? -errno : -ESRCH; if (uid) *uid = p->pw_uid; @@ -4190,6 +4250,23 @@ char* uid_to_name(uid_t uid) { 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, "%lu", (unsigned long) gid) < 0) + return NULL; + + return r; +} + int get_group_creds(const char **groupname, gid_t *gid) { struct group *g; gid_t id; @@ -4220,7 +4297,7 @@ int get_group_creds(const char **groupname, gid_t *gid) { } if (!g) - return errno != 0 ? -errno : -ESRCH; + return errno > 0 ? -errno : -ESRCH; if (gid) *gid = g->gr_gid; @@ -4228,14 +4305,10 @@ int get_group_creds(const char **groupname, gid_t *gid) { return 0; } -int in_group(const char *name) { - gid_t gid, *gids; +int in_gid(gid_t gid) { + gid_t *gids; int ngroups_max, r, i; - r = get_group_creds(&name, &gid); - if (r < 0) - return r; - if (getgid() == gid) return 1; @@ -4258,6 +4331,17 @@ int in_group(const char *name) { 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) { glob_t g; int r, k; @@ -5206,53 +5290,6 @@ int get_home_dir(char **_h) { return 0; } -int get_shell(char **_sh) { - char *sh; - const char *e; - uid_t u; - struct passwd *p; - - assert(_sh); - - /* Take the user specified one */ - e = getenv("SHELL"); - if (e) { - sh = strdup(e); - if (!sh) - return -ENOMEM; - - *_sh = sh; - return 0; - } - - /* Hardcode home directory for root to avoid NSS */ - u = getuid(); - if (u == 0) { - sh = strdup("/bin/sh"); - if (!sh) - return -ENOMEM; - - *_sh = sh; - return 0; - } - - /* Check the database... */ - errno = 0; - p = getpwuid(u); - if (!p) - return errno ? -errno : -ESRCH; - - if (!path_is_absolute(p->pw_shell)) - return -EINVAL; - - sh = strdup(p->pw_shell); - if (!sh) - return -ENOMEM; - - *_sh = sh; - return 0; -} - void fclosep(FILE **f) { if (*f) fclose(*f); @@ -5553,7 +5590,6 @@ int on_ac_power(void) { for (;;) { struct dirent *de; union dirent_storage buf; - _cleanup_free_ char *p = NULL; _cleanup_close_ int fd = -1, device = -1; char contents[6]; ssize_t n; @@ -5716,7 +5752,7 @@ int create_tmp_dir(char template[], char** dir_name) { dt = strjoin(d, "/tmp", NULL); if (!dt) { r = log_oom(); - goto fail2; + goto fail3; } umask(0000); @@ -5724,7 +5760,7 @@ int create_tmp_dir(char template[], char** dir_name) { if (r) { log_error("Can't create directory %s: %m", dt); r = -errno; - goto fail1; + goto fail2; } log_debug("Created temporary directory %s", dt); @@ -5742,6 +5778,8 @@ int create_tmp_dir(char template[], char** dir_name) { fail1: rmdir(dt); fail2: + free(dt); +fail3: rmdir(template); return r; } @@ -5816,3 +5854,20 @@ char *strrep(const char *s, unsigned n) { *p = 0; return r; } + +void* greedy_realloc(void **p, size_t *allocated, size_t need) { + size_t a; + void *q; + + if (*allocated >= need) + return *p; + + a = MAX(64, need * 2); + q = realloc(*p, a); + if (!q) + return NULL; + + *p = q; + *allocated = a; + return q; +}