X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=70b159f8c314ead6fb62964ece54117d7e4bd240;hp=0b81e1c4f985ea08dfc657682576d467e060bae1;hb=ba1261bc02693ac8a7712ade14aab8e22989ba88;hpb=03ad1136ba6ddaeca626aa24362dab764c7e2398 diff --git a/src/shared/util.c b/src/shared/util.c index 0b81e1c4f..70b159f8c 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2949,12 +2949,20 @@ char* gethostname_malloc(void) { assert_se(uname(&u) >= 0); - if (u.nodename[0]) + if (!isempty(u.nodename) && !streq(u.nodename, "(none)")) return strdup(u.nodename); return strdup(u.sysname); } +bool hostname_is_set(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + return !isempty(u.nodename) && !streq(u.nodename, "(none)"); +} + char* getlogname_malloc(void) { uid_t uid; long bufsize; @@ -3131,14 +3139,14 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) { return 0; } -static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) { +int rm_rf_children(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 */ + * tries to go on. This closes the passed fd. */ d = fdopendir(fd); if (!d) { @@ -3149,7 +3157,8 @@ static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) { for (;;) { struct dirent buf, *de; - bool is_dir, keep_around = false; + bool is_dir, keep_around; + struct stat st; int r; r = readdir_r(d, &buf, &de); @@ -3164,51 +3173,41 @@ static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) { if (streq(de->d_name, ".") || streq(de->d_name, "..")) continue; - if (de->d_type == DT_UNKNOWN) { - struct stat st; - + 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; } - if (honour_sticky) - keep_around = - (st.st_uid == 0 || st.st_uid == getuid()) && - (st.st_mode & S_ISVTX); - 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 { - if (honour_sticky) { - struct stat st; - - if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { - if (ret == 0 && errno != ENOENT) - ret = -errno; - continue; - } - - keep_around = - (st.st_uid == 0 || st.st_uid == getuid()) && - (st.st_mode & S_ISVTX); - } - is_dir = de->d_type == DT_DIR; + keep_around = false; } if (is_dir) { int subdir_fd; - subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + /* 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(subdir_fd, only_dirs, honour_sticky); + r = rm_rf_children(subdir_fd, only_dirs, honour_sticky, root_dev); if (r < 0 && ret == 0) ret = r; @@ -3251,7 +3250,7 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky return 0; } - r = rm_rf_children(fd, only_dirs, honour_sticky); + r = rm_rf_children(fd, only_dirs, honour_sticky, NULL); if (delete_root) { @@ -5610,3 +5609,55 @@ int can_sleep(const char *type) { free(p); return found; } + +bool is_valid_documentation_url(const char *url) { + assert(url); + + if (startswith(url, "http://") && url[7]) + return true; + + if (startswith(url, "https://") && url[8]) + return true; + + if (startswith(url, "file:") && url[5]) + return true; + + if (startswith(url, "info:") && url[5]) + return true; + + if (startswith(url, "man:") && url[4]) + return true; + + return false; +} + +bool in_initrd(void) { + static int saved = -1; + + if (saved < 0) + saved = access("/etc/initrd-release", F_OK) >= 0; + + return saved; +} + +void warn_melody(void) { + int fd; + + fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return; + + /* Yeah, this is synchronous. Kinda sucks. Bute well... */ + + ioctl(fd, KIOCSOUND, (int)(1193180/440)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, 0); + close_nointr_nofail(fd); +}