}
if (honour_sticky)
- keep_around = st.st_uid == 0 && (st.st_mode & S_ISVTX);
+ keep_around =
+ (st.st_uid == 0 || st.st_uid == getuid()) &&
+ (st.st_mode & S_ISVTX);
is_dir = S_ISDIR(st.st_mode);
continue;
}
- keep_around = st.st_uid == 0 && (st.st_mode & S_ISVTX);
+ keep_around =
+ (st.st_uid == 0 || st.st_uid == getuid()) &&
+ (st.st_mode & S_ISVTX);
}
is_dir = de->d_type == DT_DIR;
if (delete_root) {
- if (honour_sticky && file_is_sticky(path) > 0)
+ if (honour_sticky && file_is_priv_sticky(path) > 0)
return r;
if (rmdir(path) < 0 && errno != ENOENT) {
* first change the access mode and only then hand out
* ownership to avoid a window where access is too open. */
- if (chmod(path, mode) < 0)
- return -errno;
+ if (mode != (mode_t) -1)
+ if (chmod(path, mode) < 0)
+ return -errno;
- if (chown(path, uid, gid) < 0)
- return -errno;
+ if (uid != (uid_t) -1 || gid != (gid_t) -1)
+ if (chown(path, uid, gid) < 0)
+ return -errno;
return 0;
}
size_t l;
assert(s);
- if ((l = strlen(s)) < 2)
+ l = strlen(s);
+ if (l < 2)
return strdup(s);
if (strchr(quotes, s[0]) && s[l-1] == s[0])
return 0;
}
+int rtc_open(int flags) {
+ int fd;
+ DIR *d;
+
+ /* We open the first RTC which has hctosys=1 set. If we don't
+ * find any we just take the first one */
+
+ d = opendir("/sys/class/rtc");
+ if (!d)
+ goto fallback;
+
+ for (;;) {
+ char *p, *v;
+ struct dirent buf, *de;
+ int r;
+
+ r = readdir_r(d, &buf, &de);
+ if (r != 0)
+ goto fallback;
+
+ if (!de)
+ goto fallback;
+
+ if (ignore_file(de->d_name))
+ continue;
+
+ p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL);
+ if (!p) {
+ closedir(d);
+ return -ENOMEM;
+ }
+
+ r = read_one_line_file(p, &v);
+ free(p);
+
+ if (r < 0)
+ continue;
+
+ r = parse_boolean(v);
+ free(v);
+
+ if (r <= 0)
+ continue;
+
+ p = strappend("/dev/", de->d_name);
+ fd = open(p, flags);
+ free(p);
+
+ if (fd >= 0) {
+ closedir(d);
+ return fd;
+ }
+ }
+
+fallback:
+ if (d)
+ closedir(d);
+
+ fd = open("/dev/rtc0", flags);
+ if (fd < 0)
+ return -errno;
+
+ return fd;
+}
+
int hwclock_get_time(struct tm *tm) {
int fd;
int err = 0;
assert(tm);
- fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ fd = rtc_open(O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
assert(tm);
- fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ fd = rtc_open(O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
return -ENOENT;
}
-int file_is_sticky(const char *p) {
+int file_is_priv_sticky(const char *p) {
struct stat st;
assert(p);
return -errno;
return
- st.st_uid == 0 &&
+ (st.st_uid == 0 || st.st_uid == getuid()) &&
(st.st_mode & S_ISVTX);
}