Пример #1
0
void
fset_ftime(char *fnm, int fd, time_t mtime, time_t atime, int frc)
{
	struct timespec tv[2];

	tv[0].tv_sec = atime;
	tv[0].tv_nsec = 0L;
	tv[1].tv_sec = mtime;
	tv[1].tv_nsec = 0L;
	if (!frc) {
		/*
		 * if we are not forcing, only set those times the user wants
		 * set.
		 */
		if (!patime)
			tv[0].tv_nsec = UTIME_OMIT;
		if (!pmtime)
			tv[1].tv_nsec = UTIME_OMIT;
	}
	/*
	 * set the times
	 */
	if (futimens(fd, tv) < 0)
		syswarn(1, errno, "Access/modification time set failed on: %s",
		    fnm);
}
Пример #2
0
int
main(int argc, char *argv[])
{
    int i, fd;
    struct stat statbuf;
    struct timespec times[2];

    for (int i = 0; i < argc; ++i)
    {
        if (stat(argv[i], &statbuf) < 0) {
            err_ret("%s: stat error", argv[i]);
            continue;
        }

        if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) {
            err_ret("%s :open error", argv[i]);
            continue;
        }
        times[0] = statbuf.st_atim;
        times[1] = statbuf.st_mtim;
        if (futimens(fd, times) < 0)
            err_ret("%s: futimens error", argv[i]);
        close(fd);
    }
    exit(0);
}
Пример #3
0
void default_touch(const char *str)
{
#ifdef _MSC_VER
	int mode_file;
#endif
#ifdef __GNUC__
	mode_t mode_file;
#endif
	int handle;

	mode_file = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

	if (access(str, F_OK) == ERROR)
	{

		if ((handle = creat(str, mode_file)) == ERROR)
		{
			warn(" creat - default_touch\n");
			return;
		}

		if (futimens(handle, NULL) == ERROR)
		{
			warn(" fudimens - default_touch.\n");
			return;
		}
		close(handle);
	}
}
Пример #4
0
static void
restore_timestamps(struct file_stream *out, const tchar *newpath,
		   const struct stat *stbuf)
{
	int ret;
#if defined(HAVE_FUTIMENS)
	struct timespec times[2] = {
		stbuf->st_atim, stbuf->st_mtim,
	};
	ret = futimens(out->fd, times);
#elif defined(HAVE_FUTIMES)
	struct timeval times[2] = {
		{ stbuf->st_atim.tv_sec, stbuf->st_atim.tv_nsec / 1000, },
		{ stbuf->st_mtim.tv_sec, stbuf->st_mtim.tv_nsec / 1000, },
	};
	ret = futimes(out->fd, times);
#else /* HAVE_FUTIMES */
	struct tutimbuf times = {
		stbuf->st_atime, stbuf->st_mtime,
	};
	ret = tutime(newpath, &times);
#endif /* !HAVE_FUTIMES */
	if (ret != 0)
		msg_errno("%"TS": unable to preserve timestamps", out->name);
}
Пример #5
0
/* Closes the file belonging to a flow.
 * Does not take tcpip out of flow database.
 * Does not change pos. 
 */
void tcpip::close_file()
{
    if (fd>=0){
	struct timeval times[2];
	times[0] = myflow.tstart;
	times[1] = myflow.tstart;

	DEBUG(5) ("%s: closing file in tcpip::close_file", flow_pathname.c_str());
	/* close the file and remember that it's closed */
#if defined(HAVE_FUTIMES)
	if(futimes(fd,times)){
	    fprintf(stderr,"%s: futimes(fd=%d)\n",strerror(errno),fd);
            abort();
	}
#elif defined(HAVE_FUTIMENS) 
	struct timespec tstimes[2];
	for(int i=0;i<2;i++){
	    tstimes[i].tv_sec = times[i].tv_sec;
	    tstimes[i].tv_nsec = times[i].tv_usec * 1000;
	}
	if(futimens(fd,tstimes)){
	    perror("futimens(fd=%d)",fd);
	}
#endif
	close(fd);
	fd = -1;
    }
    demux.open_flows.erase(this);           // we are no longer open
}
Пример #6
0
void
fset_ftime(char *fnm, int fd, time_t mtime, time_t atime, int frc)
{
	static struct timespec tv[2] = {{0L, 0L}, {0L, 0L}};
	struct stat sb;

	tv[0].tv_sec = (long)atime;
	tv[1].tv_sec = (long)mtime;
	if (!frc && (!patime || !pmtime)) {
		/*
		 * if we are not forcing, only set those times the user wants
		 * set. We get the current values of the times if we need them.
		 */
		if (fstat(fd, &sb) == 0) {
			if (!patime)
				tv[0].tv_sec = (long)sb.st_atime;
			if (!pmtime)
				tv[1].tv_sec = (long)sb.st_mtime;
		} else
			syswarn(0,errno,"Unable to obtain file stats %s", fnm);
	}
	/*
	 * set the times
	 */
	if (futimens(fd, tv) < 0)
		syswarn(1, errno, "Access/modification time set failed on: %s",
		    fnm);
	return;
}
Пример #7
0
int main(int argc, char *argv[]) {
	if (argc < 2) {
		fprintf(stderr, "Usage: %s file1 file2 file3 ... fileN\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	int i;
	for (i = 1; i < argc; i++) {

		struct stat statbuf;
		if (stat(argv[i], &statbuf) < 0) {
			fprintf(stderr, "Error collecting file data for %s: %s\n", argv[i], strerror(errno));
			continue;
		}

		int fd;
		if ((fd = open(argv[i], O_RDWR | O_CREAT | O_TRUNC)) < 0) {
			fprintf(stderr, "Couldn't open %s: %s\n", argv[i], strerror(errno));
			continue;
		}

		struct timespec times[2];
		times[0] = statbuf.st_atim;
		times[1] = statbuf.st_mtim;

		if (futimens(fd, times) < 0) {
			fprintf(stderr, "Error changing file access and modification times for %s: %s\n", argv[i], strerror(errno));
		}

		close(fd);
	}

	return 0;
}
Пример #8
0
void sys_stat_check_functions()
{
    (void)chmod((const char *)1234, (mode_t)0);
    (void)fchmod(0, (mode_t)0);
#if HAVE_XXXAT
    (void)fchmodat(0, (const char *)1234, (mode_t)0, 0);
#endif
    (void)fstat(0, (struct stat *)1234);
#if HAVE_XXXAT
    (void)fstatat(0, (const char *)1234, (struct stat *)1234, 0);
#endif
    (void)futimens(0, (const struct timespec *)1234);
    (void)lstat((const char *)1234, (struct stat *)1234);
    (void)mkdir((const char *)1234, (mode_t)0);
#if HAVE_XXXAT
    (void)mkdirat(0, (const char *)1234, (mode_t)0);
#endif
    (void)mkfifo((const char *)1234, (mode_t)0);
    (void)mkfifoat(0, (const char *)1234, (mode_t)0);
    (void)mknod((const char *)1234, (mode_t)0, (dev_t)0);
    (void)mknodat(0, (const char *)1234, (mode_t)0, (dev_t)0);
    (void)stat((const char *)1234, (struct stat *)1234);
    (void)umask((mode_t)0);
    (void)utimensat(0, (const char *)1234, (const struct timespec *)1234, 0);
}
Пример #9
0
/* Closes the file belonging to a flow.
 * Does not take tcpip out of flow database.
 * Does not change pos. 
 */
void tcpip::close_file()
{
    if (fd>=0){
	struct timeval times[2];
	times[0] = myflow.tstart;
	times[1] = myflow.tstart;

	DEBUG(5) ("%s: closing file in tcpip::close_file", flow_pathname.c_str());
	/* close the file and remember that it's closed */
#if defined(HAVE_FUTIMES)
	if(futimes(fd,times)){
	    fprintf(stderr,"%s: futimes(fd=%d)\n",strerror(errno),fd);
            abort();
	}
#elif defined(HAVE_FUTIMENS) 
	struct timespec tstimes[2];
	for(int i=0;i<2;i++){
	    tstimes[i].tv_sec = times[i].tv_sec;
	    tstimes[i].tv_nsec = times[i].tv_usec * 1000;
	}
	if(futimens(fd,tstimes)){
	    perror("futimens(fd=%d)",fd);
	}
#endif
	close(fd);
	fd = -1;
	demux.open_flows.erase(this);           // we are no longer open
    }
    // Also close the flow_index file, if flow indexing is in use --GDD
    if(demux.opt.output_packet_index && idx_file.is_open()){
    	idx_file.close();
    }
    //std::cerr << "close_file1 " << *this << "\n";
}
Пример #10
0
static int apply_timestamp(const char *path, struct timespec *ts) {
        struct timespec twice[2] = {
                *ts,
                *ts
        };
        struct stat st;

        assert(path);
        assert(ts);

        if (stat(path, &st) >= 0) {
                /* Is the timestamp file already newer than the OS? If
                 * so, there's nothing to do. We ignore the nanosecond
                 * component of the timestamp, since some file systems
                 * do not support any better accuracy than 1s and we
                 * have no way to identify the accuracy
                 * available. Most notably ext4 on small disks (where
                 * 128 byte inodes are used) does not support better
                 * accuracy than 1s. */
                if (st.st_mtim.tv_sec > ts->tv_sec)
                        return 0;

                /* It is older? Then let's update it */
                if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {

                        if (errno == EROFS)
                                return log_debug("Can't update timestamp file %s, file system is read-only.", path);

                        return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
                }

        } else if (errno == ENOENT) {
                _cleanup_close_ int fd = -1;
                int r;

                /* The timestamp file doesn't exist yet? Then let's create it. */

                r = mac_selinux_create_file_prepare(path, S_IFREG);
                if (r < 0)
                        return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);

                fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
                mac_selinux_create_file_clear();

                if (fd < 0) {
                        if (errno == EROFS)
                                return log_debug("Can't create timestamp file %s, file system is read-only.", path);

                        return log_error_errno(errno, "Failed to create timestamp file %s: %m", path);
                }

                (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false);

                if (futimens(fd, twice) < 0)
                        return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
        } else
                log_error_errno(errno, "Failed to stat() timestamp file %s: %m", path);

        return 0;
}
Пример #11
0
TEST(sys_stat, futimens) {
  FILE* fp = tmpfile();
  ASSERT_TRUE(fp != NULL);

  int fd = fileno(fp);
  ASSERT_NE(fd, -1);

  // ARC MOD BEGIN
  // NaCl IRT does not have futimens.
#if !defined(__native_client__) && !defined(BARE_METAL_BIONIC)
  // ARC MOD END
  timespec times[2];
  times[0].tv_sec = 123;
  times[0].tv_nsec = 0;
  times[1].tv_sec = 456;
  times[1].tv_nsec = 0;
  ASSERT_EQ(0, futimens(fd, times)) << strerror(errno);

  struct stat sb;
  ASSERT_EQ(0, fstat(fd, &sb));
  ASSERT_EQ(times[0].tv_sec, static_cast<long>(sb.st_atime));
  ASSERT_EQ(times[1].tv_sec, static_cast<long>(sb.st_mtime));
// ARC MOD BEGIN
#endif
// ARC MOD END

  fclose(fp);
}
Пример #12
0
int write_string_stream_ts(
                FILE *f,
                const char *line,
                WriteStringFileFlags flags,
                struct timespec *ts) {

        assert(f);
        assert(line);

        fputs(line, f);
        if (!(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"))
                fputc('\n', f);

        if (ts) {
                struct timespec twice[2] = {*ts, *ts};

                if (futimens(fileno(f), twice) < 0)
                        return -errno;
        }

        if (flags & WRITE_STRING_FILE_SYNC)
                return fflush_sync_and_check(f);
        else
                return fflush_and_check(f);
}
Пример #13
0
int main(int argc, char *argv[])
{
  int i, fd;
  struct stat statbuf;
  struct timespec times[2];

  for (i = 1; i < argc; i ++) {
    if (stat(argv[i], &statbuf) < 0) {
      fprintf(stderr, "%s: stat error\n", argv[i]);
      continue;
    }

    if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) {
      fprintf(stderr, "%s: open error\n", argv[i]);
      continue;
    }

    times[0] = statbuf.st_atim;
    times[1] = statbuf.st_mtim;

    if (futimens(fd, times) < 0) {
      fprintf(stderr, "%s: futimens error\n", argv[i]);
    }

    close(fd);
  }

  return 0;
}
Пример #14
0
// ARC MOD END
TEST(sys_stat, futimens_EBADF) {
  timespec times[2];
  times[0].tv_sec = 123;
  times[0].tv_nsec = 0;
  times[1].tv_sec = 456;
  times[1].tv_nsec = 0;
  ASSERT_EQ(-1, futimens(-1, times));
  ASSERT_EQ(EBADF, errno);
}
static int apply_timestamp(const char *path, struct timespec *ts) {
        struct timespec twice[2];
        struct stat st;

        assert(path);
        assert(ts);

        if (stat(path, &st) >= 0) {
                /* Is the timestamp file already newer than the OS? If so, there's nothing to do. */
                if (st.st_mtim.tv_sec > ts->tv_sec ||
                    (st.st_mtim.tv_sec == ts->tv_sec && st.st_mtim.tv_nsec >= ts->tv_nsec))
                        return 0;

                /* It is older? Then let's update it */
                twice[0] = *ts;
                twice[1] = *ts;

                if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {

                        if (errno == EROFS)
                                return log_debug("Can't update timestamp file %s, file system is read-only.", path);

                        return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
                }

        } else if (errno == ENOENT) {
                _cleanup_close_ int fd = -1;
                int r;

                /* The timestamp file doesn't exist yet? Then let's create it. */

                r = mac_selinux_create_file_prepare(path, S_IFREG);
                if (r < 0)
                        return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);

                fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
                mac_selinux_create_file_clear();

                if (fd < 0) {
                        if (errno == EROFS)
                                return log_debug("Can't create timestamp file %s, file system is read-only.", path);

                        return log_error_errno(errno, "Failed to create timestamp file %s: %m", path);
                }

                (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false);

                twice[0] = *ts;
                twice[1] = *ts;

                if (futimens(fd, twice) < 0)
                        return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
        } else
                log_error_errno(errno, "Failed to stat() timestamp file %s: %m", path);

        return 0;
}
Пример #16
0
static int copy_metadata(struct btrfs_root *root, int fd,
		struct btrfs_key *key)
{
	struct btrfs_path *path;
	struct btrfs_inode_item *inode_item;
	int ret;

	path = btrfs_alloc_path();
	if (!path) {
		fprintf(stderr, "ERROR: Ran out of memory\n");
		return -ENOMEM;
	}

	ret = btrfs_lookup_inode(NULL, root, path, key, 0);
	if (ret == 0) {
		struct btrfs_timespec *bts;
		struct timespec times[2];

		inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
				struct btrfs_inode_item);

		ret = fchown(fd, btrfs_inode_uid(path->nodes[0], inode_item),
				btrfs_inode_gid(path->nodes[0], inode_item));
		if (ret) {
			fprintf(stderr, "ERROR: Failed to change owner: %s\n",
					strerror(errno));
			goto out;
		}

		ret = fchmod(fd, btrfs_inode_mode(path->nodes[0], inode_item));
		if (ret) {
			fprintf(stderr, "ERROR: Failed to change mode: %s\n",
					strerror(errno));
			goto out;
		}

		bts = btrfs_inode_atime(inode_item);
		times[0].tv_sec = btrfs_timespec_sec(path->nodes[0], bts);
		times[0].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts);

		bts = btrfs_inode_mtime(inode_item);
		times[1].tv_sec = btrfs_timespec_sec(path->nodes[0], bts);
		times[1].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts);

		ret = futimens(fd, times);
		if (ret) {
			fprintf(stderr, "ERROR: Failed to set times: %s\n",
					strerror(errno));
			goto out;
		}
	}
out:
	btrfs_free_path(path);
	return ret;
}
Пример #17
0
int
do_touch (const char *path)
{
    int fd;
    int r;
    struct stat buf;

    /* RHBZ#582484: Restrict touch to regular files.  It's also OK
     * here if the file does not exist, since we will create it.
     *
     * XXX Coverity flags this as a time-of-check to time-of-use race
     * condition, particularly in the libguestfs live case.  Not clear
     * how to fix this yet, since unconditionally opening the file can
     * cause a hang, so you have to somehow check it first before you
     * open it.
     */
    CHROOT_IN;
    r = lstat (path, &buf);
    CHROOT_OUT;

    if (r == -1) {
        if (errno != ENOENT) {
            reply_with_perror ("lstat: %s", path);
            return -1;
        }
    } else {
        if (! S_ISREG (buf.st_mode)) {
            reply_with_error ("%s: touch can only be used on a regular files", path);
            return -1;
        }
    }

    CHROOT_IN;
    fd = open (path, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0666);
    CHROOT_OUT;

    if (fd == -1) {
        reply_with_perror ("open: %s", path);
        return -1;
    }

    r = futimens (fd, NULL);
    if (r == -1) {
        reply_with_perror ("futimens: %s", path);
        close (fd);
        return -1;
    }

    if (close (fd) == -1) {
        reply_with_perror ("close: %s", path);
        return -1;
    }

    return 0;
}
Пример #18
0
int
setfile(struct stat *fs, int fd)
{
	struct timespec ts[2];
	int rval;

	rval = 0;
	fs->st_mode &= S_ISTXT | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;

	ts[0] = fs->st_atim;
	ts[1] = fs->st_mtim;
	if (fd >= 0 ? futimens(fd, ts) :
	    utimensat(AT_FDCWD, to.p_path, ts, AT_SYMLINK_NOFOLLOW)) {
		warn("update times: %s", to.p_path);
		rval = 1;
	}
	/*
	 * Changing the ownership probably won't succeed, unless we're root
	 * or POSIX_CHOWN_RESTRICTED is not set.  Set uid/gid before setting
	 * the mode; current BSD behavior is to remove all setuid bits on
	 * chown.  If chown fails, lose setuid/setgid bits.
	 */
	if (fd >= 0 ? fchown(fd, fs->st_uid, fs->st_gid) :
	    lchown(to.p_path, fs->st_uid, fs->st_gid)) {
		if (errno != EPERM) {
			warn("chown: %s", to.p_path);
			rval = 1;
		}
		fs->st_mode &= ~(S_ISTXT | S_ISUID | S_ISGID);
	}
	if (fd >= 0 ? fchmod(fd, fs->st_mode) :
	    fchmodat(AT_FDCWD, to.p_path, fs->st_mode, AT_SYMLINK_NOFOLLOW)) {
		warn("chmod: %s", to.p_path);
		rval = 1;
	}

	/*
	 * XXX
	 * NFS doesn't support chflags; ignore errors unless there's reason
	 * to believe we're losing bits.  (Note, this still won't be right
	 * if the server supports flags and we were trying to *remove* flags
	 * on a file that we copied, i.e., that we didn't create.)
	 */
	errno = 0;
	if (fd >= 0 ? fchflags(fd, fs->st_flags) :
	    chflagsat(AT_FDCWD, to.p_path, fs->st_flags, AT_SYMLINK_NOFOLLOW))
		if (errno != EOPNOTSUPP || fs->st_flags != 0) {
			warn("chflags: %s", to.p_path);
			rval = 1;
		}
	return (rval);
}
Пример #19
0
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
        _cleanup_close_ int fd;
        int r;

        assert(path);

        if (parents)
                mkdir_parents(path, 0755);

        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
                        (mode == 0 || mode == MODE_INVALID) ? 0644 : mode);
        if (fd < 0)
                return -errno;

        if (mode != MODE_INVALID) {
                r = fchmod(fd, mode);
                if (r < 0)
                        return -errno;
        }

        if (uid != UID_INVALID || gid != GID_INVALID) {
                r = fchown(fd, uid, gid);
                if (r < 0)
                        return -errno;
        }

        if (stamp != USEC_INFINITY) {
                struct timespec ts[2];

                timespec_store(&ts[0], stamp);
                ts[1] = ts[0];
                r = futimens(fd, ts);
        } else
                r = futimens(fd, NULL);
        if (r < 0)
                return -errno;

        return 0;
}
Пример #20
0
static int apply_timestamp(const char *path, struct timespec *ts) {
        struct timespec twice[2] = {
                *ts,
                *ts
        };
        int fd = -1;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(path);
        assert(ts);

        /*
         * We store the timestamp both as mtime of the file and in the file itself,
         * to support filesystems which cannot store nanosecond-precision timestamps.
         * Hence, don't bother updating the file, let's just rewrite it.
         */

        r = mac_selinux_create_file_prepare(path, S_IFREG);
        if (r < 0)
                return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);

        fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
        mac_selinux_create_file_clear();

        if (fd < 0) {
                if (errno == EROFS)
                        return log_debug("Can't create timestamp file %s, file system is read-only.", path);

                return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path);
        }

        f = fdopen(fd, "w");
        if (!f) {
                safe_close(fd);
                return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path);
        }

        (void) fprintf(f,
                       "%s"
                       "TimestampNSec=" NSEC_FMT "\n",
                       MESSAGE, timespec_load_nsec(ts));

        fflush(f);

        if (futimens(fd, twice) < 0)
                return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);

        return 0;
}
Пример #21
0
int
utimesys(int code,
    uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)
{
	switch (code) {
	case 0:
		return (futimens((int)arg1, (timespec_t *)arg2));
	case 1:
		return (utimensat((int)arg1, (char *)arg2,
		    (timespec_t *)arg3, (int)arg4));
	default:
		return (set_errno(EINVAL));
	}
}
Пример #22
0
int
do_touch (const char *path)
{
  int fd;
  int r;
  struct stat buf;

  /* RHBZ#582484: Restrict touch to regular files.  It's also OK
   * here if the file does not exist, since we will create it.
   */
  CHROOT_IN;
  r = lstat (path, &buf);
  CHROOT_OUT;

  if (r == -1) {
    if (errno != ENOENT) {
      reply_with_perror ("lstat: %s", path);
      return -1;
    }
  } else {
    if (! S_ISREG (buf.st_mode)) {
      reply_with_error ("%s: touch can only be used on a regular files", path);
      return -1;
    }
  }

  CHROOT_IN;
  fd = open (path, O_WRONLY | O_CREAT | O_NOCTTY, 0666);
  CHROOT_OUT;

  if (fd == -1) {
    reply_with_perror ("open: %s", path);
    return -1;
  }

  r = futimens (fd, NULL);
  if (r == -1) {
    reply_with_perror ("futimens: %s", path);
    close (fd);
    return -1;
  }

  if (close (fd) == -1) {
    reply_with_perror ("close: %s", path);
    return -1;
  }

  return 0;
}
Пример #23
0
void fallback(int f, struct stat* st)
{
#if HAVE_FUTIMENS
	struct timespec tv[2];
#else
	struct timeval tv[2];
#endif
	int ret;

#if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
	tv[0].tv_sec = st->st_mtime;
	if (STAT_NSEC(st) != STAT_NSEC_INVALID)
		tv[0].tv_nsec = STAT_NSEC(st);
	else
		tv[0].tv_nsec = 0;
	tv[1].tv_sec = tv[0].tv_sec;
	tv[1].tv_nsec = tv[0].tv_nsec;

	ret = futimens(f, tv);
#elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
	tv[0].tv_sec = st->st_mtime;
	if (STAT_NSEC(st) != STAT_NSEC_INVALID)
		tv[0].tv_usec = STAT_NSEC(st) / 1000;
	else
		tv[0].tv_usec = 0;
	tv[1].tv_sec = tv[0].tv_sec;
	tv[1].tv_usec = tv[0].tv_usec;

	ret = futimes(f, tv);
#elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
	tv[0].tv_sec = st->st_mtime;
	if (STAT_NSEC(st) != STAT_NSEC_INVALID)
		tv[0].tv_usec = STAT_NSEC(st) / 1000;
	else
		tv[0].tv_usec = 0;
	tv[1].tv_sec = tv[0].tv_sec;
	tv[1].tv_usec = tv[0].tv_usec;

	ret = futimesat(f, 0, tv);
#else
#error No function available to set file timestamps
#endif
	if (ret != 0) {
		/* LCOV_EXCL_START */
		fprintf(stderr, "Error restoring time\n");
		exit(EXIT_FAILURE);
		/* LCOV_EXCL_STOP */
	}
}
Пример #24
0
int write_string_stream_ts(
                FILE *f,
                const char *line,
                WriteStringFileFlags flags,
                struct timespec *ts) {

        bool needs_nl;
        int r;

        assert(f);
        assert(line);

        if (ferror(f))
                return -EIO;

        needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");

        if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
                /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
                 * that the write goes out in one go, instead of two */

                line = strjoina(line, "\n");
                needs_nl = false;
        }

        if (fputs(line, f) == EOF)
                return -errno;

        if (needs_nl)
                if (fputc('\n', f) == EOF)
                        return -errno;

        if (flags & WRITE_STRING_FILE_SYNC)
                r = fflush_sync_and_check(f);
        else
                r = fflush_and_check(f);
        if (r < 0)
                return r;

        if (ts) {
                struct timespec twice[2] = {*ts, *ts};

                if (futimens(fileno(f), twice) < 0)
                        return -errno;
        }

        return 0;
}
Пример #25
0
int
main(int argc, char **argv)
{
	int fd = creat ("file", 0600);
	struct stat st1, st2;
	struct timespec t[2] = { { 1000000000, 0 }, { 0, UTIME_OMIT } };

	fstat(fd, &st1);
	sleep(1);
	futimens(fd, t);
	fstat(fd, &st2);

	if (st1.st_ctime == st2.st_ctime)
		printf("failed to update ctime!\n");
	return 0;
}
Пример #26
0
int
fdutimensat (int fd, int dir, char const *file, struct timespec const ts[2],
             int atflag)
{
  int result = 1;
  if (0 <= fd)
    result = futimens (fd, ts);
  if (file && (fd < 0 || (result == -1 && errno == ENOSYS)))
    result = utimensat (dir, file, ts, atflag);
  if (result == 1)
    {
      errno = EBADF;
      result = -1;
    }
  return result;
}
Пример #27
0
static int copy_metadata(struct btrfs_root *root, int fd,
		struct btrfs_key *key)
{
	struct btrfs_path path;
	struct btrfs_inode_item *inode_item;
	int ret;

	btrfs_init_path(&path);
	ret = btrfs_lookup_inode(NULL, root, &path, key, 0);
	if (ret == 0) {
		struct btrfs_timespec *bts;
		struct timespec times[2];

		inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0],
				struct btrfs_inode_item);

		ret = fchown(fd, btrfs_inode_uid(path.nodes[0], inode_item),
				btrfs_inode_gid(path.nodes[0], inode_item));
		if (ret) {
			error("failed to change owner: %m");
			goto out;
		}

		ret = fchmod(fd, btrfs_inode_mode(path.nodes[0], inode_item));
		if (ret) {
			error("failed to change mode: %m");
			goto out;
		}

		bts = btrfs_inode_atime(inode_item);
		times[0].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
		times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);

		bts = btrfs_inode_mtime(inode_item);
		times[1].tv_sec = btrfs_timespec_sec(path.nodes[0], bts);
		times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts);

		ret = futimens(fd, times);
		if (ret) {
			error("failed to set times: %m");
			goto out;
		}
	}
out:
	btrfs_release_path(&path);
	return ret;
}
int ask_the_user(const char *domain) {
	struct stat stat_buf;
	char stat_file_path[100];
	int stat_file_fd;
	char ask_cmd[512];
	time_t now;
	int autoaccept_time;
	const char *env;
	struct timespec times[2];

	autoaccept_time = DEFAULT_AUTOACCEPT_TIME;
	env = getenv("QUBES_GPG_AUTOACCEPT");
	if (env)
		autoaccept_time = atoi(env);

	snprintf(stat_file_path, sizeof(stat_file_path), "%s/stat.%s", RUNDIR, domain);
	now = time(NULL);
	// if user accepts at most "autoaccept_time" seconds ago
	if (stat(stat_file_path, &stat_buf) == 0 && stat_buf.st_mtime > now-autoaccept_time )
		return 1;

	snprintf(ask_cmd, sizeof(ask_cmd), "zenity --question --text \"Do you allow"
			" VM '%s' to access your GPG keys (now and for the following %d"
				" seconds)?\" 2>/dev/null", domain, autoaccept_time);
	switch (system(ask_cmd)) {
		case -1:
			perror("system");
			exit(1);
		case 0:
			// "YES"
			stat_file_fd = open(stat_file_path, O_WRONLY | O_CREAT, 0600);
			if (stat_file_fd < 0) {
				perror("Cannot touch stat-file");
				// continue on this error
			} else {
				times[0].tv_nsec = UTIME_OMIT;
				times[1].tv_nsec = UTIME_NOW;
				futimens(stat_file_fd, times);
				close(stat_file_fd);
			}
			return 1;
		default:
			// "NO" or any other case
			return 0;
	}
}
Пример #29
0
/*
 * set the owner, mode, flags & utimes using the given file descriptor.
 * file is only used in possible warning messages.
 */
static void
copymodes(int fd, const struct stat *sbp, const char *file)
{
	struct timespec times[2];
	struct stat sb;

	/*
	 * If we have no info on the input, give this file some
	 * default values and return..
	 */
	if (sbp == NULL) {
		mode_t mask = umask(022);

		(void)fchmod(fd, DEFFILEMODE & ~mask);
		(void)umask(mask);
		return; 
	}
	sb = *sbp;

	/* if the chown fails, remove set-id bits as-per compress(1) */
	if (fchown(fd, sb.st_uid, sb.st_gid) < 0) {
		if (errno != EPERM)
			maybe_warn("couldn't fchown: %s", file);
		sb.st_mode &= ~(S_ISUID|S_ISGID);
	}

	/* we only allow set-id and the 9 normal permission bits */
	sb.st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
	if (fchmod(fd, sb.st_mode) < 0)
		maybe_warn("couldn't fchmod: %s", file);

#ifdef __APPLE__
	times[0] = sb.st_atimespec;
	times[1] = sb.st_mtimespec;
#else
	times[0] = sb.st_atim;
	times[1] = sb.st_mtim;
#endif
	if (futimens(fd, times) < 0)
		maybe_warn("couldn't futimens: %s", file);

	/* only try flags if they exist already */
        if (sb.st_flags != 0 && fchflags(fd, sb.st_flags) < 0)
		maybe_warn("couldn't fchflags: %s", file);
}
Пример #30
0
int insecure_utimens (const char *path, const struct timespec tv[2]) {
    insecure_flush_tables ();

    gchar *backname = insecure_get_backname (path);
    gchar *full_backname = g_build_path ("/", FS_DATA->backend_point, backname, NULL);

    int fd = open (full_backname, O_RDONLY);
    if (fd < 0) return -errno;
    int ret = futimens (fd, tv);
    close (fd);

    g_free (backname);
    g_free (full_backname);

    if (ret < 0) return -errno;

    return 0;
}