X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=2241b79859ff16233f4a33e7f66aea13efb11464;hp=594f8de755c7a767b698187b50b67fe68e0d7185;hb=844ec79b3c2f246114ea316ebe1f36044bdb688e;hpb=a740c14c59907f370a6b3a3ba5a86fada88cb07e diff --git a/src/shared/util.c b/src/shared/util.c index 594f8de75..2241b7985 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; @@ -1029,7 +1032,6 @@ int rmdir_parents(const char *path, const char *stop) { return 0; } - char hexchar(int x) { static const char table[16] = "0123456789abcdef"; @@ -1050,6 +1052,23 @@ int unhexchar(char c) { return -1; } +char *hexmem(const void *p, size_t l) { + char *r, *z; + const uint8_t *x; + + z = r = malloc(l * 2 + 1); + if (!r) + return NULL; + + for (x = p; x < (const uint8_t*) p + l; x++) { + *(z++) = hexchar(*x >> 4); + *(z++) = hexchar(*x & 15); + } + + *z = 0; + return r; +} + char octchar(int x) { return '0' + (x & 7); } @@ -2338,6 +2357,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; @@ -2963,7 +3000,7 @@ int status_welcome(void) { if (r < 0 && r != -ENOENT) log_warning("Failed to read /etc/os-release: %s", strerror(-r)); - return status_printf(NULL, false, + return status_printf(NULL, false, false, "\nWelcome to \x1B[%sm%s\x1B[0m!\n", isempty(ansi_color) ? "1" : ansi_color, isempty(pretty_name) ? "Linux" : pretty_name); @@ -3757,13 +3794,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; @@ -4174,6 +4225,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; @@ -4212,14 +4280,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; @@ -4242,6 +4306,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; @@ -5190,53 +5265,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); @@ -5537,7 +5565,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; @@ -5682,3 +5709,123 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear return search_and_fopen_internal(path, mode, s, _f); } + +int create_tmp_dir(char template[], char** dir_name) { + int r = 0; + char *d, *dt; + mode_t _cleanup_umask_ u; + + assert(dir_name); + + u = umask(0077); + d = mkdtemp(template); + if (!d) { + log_error("Can't create directory %s: %m", template); + return -errno; + } + + dt = strjoin(d, "/tmp", NULL); + if (!dt) { + r = log_oom(); + goto fail3; + } + + umask(0000); + r = mkdir(dt, 0777); + if (r) { + log_error("Can't create directory %s: %m", dt); + r = -errno; + goto fail2; + } + log_debug("Created temporary directory %s", dt); + + r = chmod(dt, 0777 | S_ISVTX); + if (r < 0) { + log_error("Failed to chmod %s: %m", dt); + r = -errno; + goto fail1; + } + log_debug("Set sticky bit on %s", dt); + + *dir_name = dt; + + return 0; +fail1: + rmdir(dt); +fail2: + free(dt); +fail3: + rmdir(template); + return r; +} + +char *strextend(char **x, ...) { + va_list ap; + size_t f, l; + char *r, *p; + + assert(x); + + l = f = *x ? strlen(*x) : 0; + + va_start(ap, x); + for (;;) { + const char *t; + size_t n; + + t = va_arg(ap, const char *); + if (!t) + break; + + n = strlen(t); + if (n > ((size_t) -1) - l) { + va_end(ap); + return NULL; + } + + l += n; + } + va_end(ap); + + r = realloc(*x, l+1); + if (!r) + return NULL; + + p = r + f; + + va_start(ap, x); + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + p = stpcpy(p, t); + } + va_end(ap); + + *p = 0; + *x = r; + + return r + l; +} + +char *strrep(const char *s, unsigned n) { + size_t l; + char *r, *p; + unsigned i; + + assert(s); + + l = strlen(s); + p = r = malloc(l * n + 1); + if (!r) + return NULL; + + for (i = 0; i < n; i++) + p = stpcpy(p, s); + + *p = 0; + return r; +}