Exemplo n.º 1
0
static int ghost_apply_metadata(const char *path, GhostFileEntry *gfe)
{
	struct timeval tv[2];
	int ret = -1;

	if (chown(path, gfe->uid, gfe->gid) < 0) {
		pr_perror("Can't reset user/group on ghost %s", path);
		goto err;
	}

	if (chmod(path, gfe->mode)) {
		pr_perror("Can't set perms %o on ghost %s", gfe->mode, path);
		goto err;
	}

	if (gfe->atim) {
		tv[0].tv_sec = gfe->atim->tv_sec;
		tv[0].tv_usec = gfe->atim->tv_usec;
		tv[1].tv_sec = gfe->mtim->tv_sec;
		tv[1].tv_usec = gfe->mtim->tv_usec;
		if (lutimes(path, tv)) {
			pr_perror("Can't set access and modufication times on ghost %s", path);
			goto err;
		}
	}

	ret = 0;
err:
	return ret;
}
Exemplo n.º 2
0
void
set_ftime(char *fnm, time_t mtime, time_t atime, int frc)
{
	static struct timeval tv[2] = {{0L, 0L}, {0L, 0L}};
	struct stat sb;

	tv[0].tv_sec = atime;
	tv[1].tv_sec = 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 (lstat(fnm, &sb) == 0) {
			if (!patime)
				tv[0].tv_sec = sb.st_atime;
			if (!pmtime)
				tv[1].tv_sec = sb.st_mtime;
		} else
			syswarn(0,errno,"Unable to obtain file stats %s", fnm);
	}

	/*
	 * set the times
	 */
	if (lutimes(fnm, tv) < 0)
		syswarn(1, errno, "Access/modification time set failed on: %s",
		    fnm);
	return;
}
Exemplo n.º 3
0
void DCOPY_copy_timestamps(
    bayer_flist flist,
    uint64_t idx,
    const char* dest_path)
{
    /* get atime seconds and nsecs */
    uint64_t atime      = bayer_flist_file_get_atime(flist, idx);
    uint64_t atime_nsec = bayer_flist_file_get_atime_nsec(flist, idx);

    /* get mtime seconds and nsecs */
    uint64_t mtime      = bayer_flist_file_get_mtime(flist, idx);
    uint64_t mtime_nsec = bayer_flist_file_get_mtime_nsec(flist, idx);

    /* fill in time structures */
    struct timespec times[2];
    times[0].tv_sec  = (time_t) atime;
    times[0].tv_nsec = (long)   atime_nsec;
    times[1].tv_sec  = (time_t) mtime;
    times[1].tv_nsec = (long)   mtime_nsec;

    /* set times with nanosecond precision using utimensat,
     * assume path is relative to current working directory,
     * if it's not absolute, and set times on link (not target file)
     * if dest_path refers to a link */
    if(utimensat(AT_FDCWD, dest_path, times, AT_SYMLINK_NOFOLLOW) != 0) {
        BAYER_LOG(BAYER_LOG_ERR, "Failed to change timestamps on %s utime() errno=%d %s",
                  dest_path, errno, strerror(errno)
                 );
    }

#if 0
    /* TODO: see stat-time.h and get_stat_atime/mtime/ctime to read sub-second times,
     * and use utimensat to set sub-second times */
    /* as last step, change timestamps */
    if(! S_ISLNK(statbuf->st_mode)) {
        struct utimbuf times;
        times.actime  = statbuf->st_atime;
        times.modtime = statbuf->st_mtime;
        if(utime(dest_path, &times) != 0) {
            BAYER_LOG(BAYER_LOG_ERR, "Failed to change timestamps on %s utime() errno=%d %s",
                      dest_path, errno, strerror(errno)
                     );
        }
    }
    else {
        struct timeval tv[2];
        tv[0].tv_sec  = statbuf->st_atime;
        tv[0].tv_usec = 0;
        tv[1].tv_sec  = statbuf->st_mtime;
        tv[1].tv_usec = 0;
        if(lutimes(dest_path, tv) != 0) {
            BAYER_LOG(BAYER_LOG_ERR, "Failed to change timestamps on %s utime() errno=%d %s",
                      dest_path, errno, strerror(errno)
                     );
        }
    }
#endif

    return;
}
Exemplo n.º 4
0
static bool copy_entry(const char *source,
                       const char *destination,
                       uid_t uid,
                       gid_t gid) {
  struct stat sb;
  if (lstat(source, &sb) != 0)
    return false;

  struct timeval tv[2];
  tv[0].tv_sec = sb.st_atime;
  tv[0].tv_usec = 0;
  tv[1].tv_sec = sb.st_mtime;
  tv[1].tv_usec = 0;

  if (S_ISDIR(sb.st_mode)) {
    if (!copy_dir(source, destination, uid, gid, &sb))
      return false;
  } else if (S_ISLNK(sb.st_mode)) {
    if (!copy_symlink(source, destination, uid, gid, &sb))
      return false;
  } else if (S_ISREG(sb.st_mode)) {
    if (!copy_file(source, destination, uid, gid, &sb))
      return false;
  } else {
    if (!copy_special(source, destination, uid, gid, &sb))
      return false;
  }

  if (lutimes(destination, tv) != 0)
    return false;

  return true;
}
Exemplo n.º 5
0
Arquivo: null.c Projeto: glk/puffs
/*
 * set attributes to what is specified.  XXX: no rollback in case of failure
 */
static int
processvattr(const char *path, const struct vattr *va, int regular)
{
	struct timeval tv[2];

	/* XXX: -1 == PUFFS_VNOVAL, but shouldn't trust that */
	if (va->va_uid != (unsigned)-1 || va->va_gid != (unsigned)-1)
		if (lchown(path, va->va_uid, va->va_gid) == -1)
			return errno;

	if (va->va_mode != (u_short)PUFFS_VNOVAL)
		if (lchmod(path, va->va_mode) == -1)
			return errno;

	/* sloppy */
	if (va->va_atime.tv_sec != (time_t)PUFFS_VNOVAL
	    || va->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) {
		TIMESPEC_TO_TIMEVAL(&tv[0], &va->va_atime);
		TIMESPEC_TO_TIMEVAL(&tv[1], &va->va_mtime);

		if (lutimes(path, tv) == -1)
			return errno;
	}

	if (regular && va->va_size != (u_quad_t)PUFFS_VNOVAL)
		if (truncate(path, (off_t)va->va_size) == -1)
			return errno;

	return 0;
}
Exemplo n.º 6
0
// .utimens
static int mhdd_utimens(const char *path, const struct timespec ts[2])
{
	mhdd_debug(MHDD_MSG, "mhdd_utimens: %s\n", path);
	int i, res, flag_found;

	for (i = flag_found = 0; i<mhdd.cdirs; i++) {
		char *object = create_path(mhdd.dirs[i], path);
		struct stat st;
		if (lstat(object, &st) != 0) {
			free(object);
			continue;
		}

		flag_found = 1;
		struct timeval tv[2];

		tv[0].tv_sec = ts[0].tv_sec;
		tv[0].tv_usec = ts[0].tv_nsec / 1000;
		tv[1].tv_sec = ts[1].tv_sec;
		tv[1].tv_usec = ts[1].tv_nsec / 1000;

		res = lutimes(object, tv);
		free(object);
		if (res == -1)
			return -errno;
	}
	if (flag_found)
		return 0;
	errno = ENOENT;
	return -errno;
}
Exemplo n.º 7
0
void
psync_utimes(const char *fn, const struct pfl_timespec *pts, int flags)
{
#ifdef HAVE_FUTIMENS
	struct timespec ts[2];

	ts[0].tv_sec = pts[0].tv_sec;
	ts[0].tv_nsec = pts[0].tv_nsec;

	ts[1].tv_sec = pts[1].tv_sec;
	ts[1].tv_nsec = pts[1].tv_nsec;

	if (utimensat(AT_FDCWD, fn, ts, flags) == -1)
		psynclog_warn("utimes %s", fn);
#else
	struct timeval tv[2];

	(void)flags;

	tv[0].tv_sec = pts[0].tv_sec;
	tv[0].tv_usec = pts[0].tv_nsec / 1000;

	tv[1].tv_sec = pts[1].tv_sec;
	tv[1].tv_usec = pts[1].tv_nsec / 1000;

	if (lutimes(fn, tv) == -1)
		psynclog_warn("utimes %s", fn);
#endif
}
Exemplo n.º 8
0
int
set_utimes(const char *file, struct stat *fs)
{
    static struct timeval tv[2];

#ifndef BSD
    tv[0].tv_sec = fs->st_atime;
    tv[0].tv_usec = 0;
    tv[1].tv_sec = fs->st_mtime;
    tv[1].tv_usec = 0;

    if (utimes(file, tv)) {
        warn("utimes: %s", file);
        return 1;
    }
#else
    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);

    if (lutimes(file, tv)) {
    warn("lutimes: %s", file);
    return (1);
    }
#endif
    return (0);
}
Exemplo n.º 9
0
bool CFile::SetTimestamp(long timestamp)
{
#ifdef WIN32
	FILETIME ftime;
	HANDLE h;
	bool close = false;
	if (handle==NULL) {
		h = CreateFile(s2ws(filename).c_str() , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
		close = true;
	} else {
		h = (HANDLE)_get_osfhandle(fileno(handle));
	}
	if (h == NULL) {
		return false;
	}
	fileSystem->TimestampToFiletime(timestamp, ftime);
	bool ret = SetFileTime(h, NULL, NULL, &ftime);
	if (close) { //close opened file
		CloseHandle(h);
	}
	return ret;
#else
	struct timeval tv = {0, 0};
	tv.tv_sec = timestamp;
	if (handle==NULL) {
		return lutimes(filename.c_str(), &tv) == 0;
	} else {
		return futimes(fileno(handle), &tv) == 0;
	}
#endif
}
Exemplo n.º 10
0
static int do_lutimes(const char *path, struct stat *statp)
{
    struct timeval t[2];
    t[0].tv_sec = statp->st_atime;
    t[0].tv_usec = 0;
    t[1].tv_sec = statp->st_mtime;
    t[1].tv_usec = 0;
    return lutimes(path, t);
}
Exemplo n.º 11
0
gint32
Mono_Posix_Syscall_lutimes(const char *filename, struct Mono_Posix_Timeval *tv)
{
	struct timeval _tv[2];
	struct timeval *ptv;

	ptv = copy_utimes (_tv, tv);

	return lutimes (filename, ptv);
}
Exemplo n.º 12
0
static int
restore_time(struct cpio *cpio, struct archive_entry *entry,
    const char *name, int fd)
{
#ifndef HAVE_UTIMES
	static int warned = 0;

	(void)cpio; /* UNUSED */
	(void)entry; /* UNUSED */
	(void)name; /* UNUSED */

	if (!warned)
		lafe_warnc(0, "Can't restore access times on this platform");
	warned = 1;
	return (fd);
#else
#if defined(_WIN32) && !defined(__CYGWIN__)
	struct __timeval times[2];
#else
	struct timeval times[2];
#endif

	if (!cpio->option_atime_restore)
		return (fd);

        times[1].tv_sec = archive_entry_mtime(entry);
        times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000;

        times[0].tv_sec = archive_entry_atime(entry);
        times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000;

#if defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
        if (fd >= 0 && futimes(fd, times) == 0)
		return (fd);
#endif
	/*
	 * Some platform cannot restore access times if the file descriptor
	 * is still opened.
	 */
	if (fd >= 0) {
		close(fd);
		fd = -1;
	}

#ifdef HAVE_LUTIMES
        if (lutimes(name, times) != 0)
#else
        if ((AE_IFLNK != archive_entry_filetype(entry))
			&& utimes(name, times) != 0)
#endif
                lafe_warnc(errno, "Can't update time for %s", name);
#endif
	return (fd);
}
Exemplo n.º 13
0
void MyDirEntry::setMetadata(const QString& path) const{
    QFile file(path);
    file.setPermissions(permissions);
    
    struct timeval tv[2];
    tv[0].tv_sec=lastModified.toTime_t();
    tv[0].tv_usec=0;
    tv[1].tv_sec=lastModified.toTime_t();
    tv[1].tv_usec=0;
    lutimes(QFile::encodeName(file.fileName()), tv);
    lchown(QFile::encodeName(file.fileName()), uid(), gid());
}
Exemplo n.º 14
0
void hh_lutimes(value filename_v) {
  CAMLparam1(filename_v);
#ifdef _WIN32
  /* Not implemented */
  CAMLreturn0;
#else
  char* filename = String_val(filename_v);
  int success = lutimes(filename, NULL);
  if (success != 0) {
    caml_failwith("lutimes failed");
  }
#endif
  CAMLreturn0;
}
Exemplo n.º 15
0
int
set_utimes(const char *file, struct stat *fs)
{
    static struct timeval tv[2];

    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);

    if (lutimes(file, tv)) {
	warn("lutimes: %s", file);
	return (1);
    }
    return (0);
}
Exemplo n.º 16
0
int _do_utimens(EncFS_Context *, const string &cyName,
                const struct timespec ts[2]) {
#ifdef HAVE_UTIMENSAT
  int res = utimensat(AT_FDCWD, cyName.c_str(), ts, AT_SYMLINK_NOFOLLOW);
#else
  struct timeval tv[2];
  tv[0].tv_sec = ts[0].tv_sec;
  tv[0].tv_usec = ts[0].tv_nsec / 1000;
  tv[1].tv_sec = ts[1].tv_sec;
  tv[1].tv_usec = ts[1].tv_nsec / 1000;

  int res = lutimes(cyName.c_str(), tv);
#endif
  return (res == -1) ? -errno : ESUCCESS;
}
Exemplo n.º 17
0
void
set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk)
{
	struct timeval tv[2];
	struct stat sb;

	tv[0].tv_sec = atime;
	tv[0].tv_usec = 0;
	tv[1].tv_sec = mtime;
	tv[1].tv_usec = 0;
	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 (lstat(fnm, &sb) == 0) {
#if BSD4_4 && !HAVE_NBTOOL_CONFIG_H
			if (!patime)
				TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
			if (!pmtime)
				TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
#else
			if (!patime)
				tv[0].tv_sec = sb.st_atime;
			if (!pmtime)
				tv[1].tv_sec = sb.st_mtime;
#endif
		} else
			syswarn(0, errno, "Cannot obtain file stats %s", fnm);
	}

	/*
	 * set the times
	 */
#if HAVE_LUTIMES
	if (lutimes(fnm, tv) == 0)
		return;
	if (errno != ENOSYS)	/* XXX linux: lutimes is per-FS */
		goto bad;
#endif
	if (slk)
		return;
	if (utimes(fnm, tv) == -1)
		goto bad;
	return;
bad:
	syswarn(1, errno, "Access/modification time set failed on: %s", fnm);
}
Exemplo n.º 18
0
int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags)
{
	int rc;
	struct timeval tv[2];
	tv[0].tv_sec = times[0].tv_sec;
	tv[0].tv_usec = times[0].tv_nsec / 1000;
	tv[1].tv_sec = times[1].tv_sec;
	tv[1].tv_usec = times[1].tv_nsec / 1000;

	dir_mutex_lock(dirfd);
	if(flags & AT_SYMLINK_NOFOLLOW) {
		rc = lutimes(pathname, tv);
	} else {
		rc = utimes(pathname, tv);
	}
	dir_mutex_unlock();
	return rc;
}
Exemplo n.º 19
0
Arquivo: utils.c Projeto: jhbsz/OSI-OS
int setfile(struct stat *fs, int fd) {
	static struct timeval tv[2];
	struct stat ts;
	int rval, gotstat, islink, fdval;

	rval = 0;
	fdval = fd != -1;
	islink = !fdval && S_ISLNK(fs->st_mode);
	fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO;
	TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim);
	TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim);
	if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
		warn("%sutimes: %s", islink ? "l" : "", to.p_path);
		rval = 1;
	}
	if (fdval ? fstat(fd, &ts) : (islink ? lstat(to.p_path, &ts) : stat(to.p_path, &ts)))
		gotstat = 0;
	else {
		gotstat = 1;
		ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO;
	}
	if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
		if (fdval ? fchown(fd, fs->st_uid, fs->st_gid) : (islink ? lchown(to.p_path, fs->st_uid, fs->st_gid) :
chown(to.p_path, fs->st_uid, fs->st_gid))) {
			if (errno != EPERM) {
				warn("chown: %s", to.p_path);
				rval = 1;
			}
			fs->st_mode &= ~(S_ISUID | S_ISGID);
		}
	if (!gotstat || fs->st_mode != ts.st_mode)
		if (fdval ? fchmod(fd, fs->st_mode) : (islink ? lchmod(to.p_path, fs->st_mode) :
chmod(to.p_path, fs->st_mode))) {
			warn("chmod: %s", to.p_path);
			rval = 1;
		}
	if (!gotstat || fs->st_flags != ts.st_flags)
		if (fdval ? fchflags(fd, fs->st_flags) : (islink ? lchflags(to.p_path, fs->st_flags) :
chflags(to.p_path, fs->st_flags))) {
			warn("chflags: %s", to.p_path);
			rval = 1;
		}
	return (rval);
}
Exemplo n.º 20
0
int set_utime(const char *filename, __u32 yst_atime, __u32 yst_mtime) {
#ifdef HAS_LUTIMES
	struct timeval ftime[2];

	ftime[0].tv_sec  = yst_atime;
	ftime[0].tv_usec = 0;
	ftime[1].tv_sec  = yst_mtime;
	ftime[1].tv_usec = 0;

	return lutimes(filename, ftime);
#else
	struct utimbuf ftime;

	ftime.actime  = yst_atime;
	ftime.modtime = yst_mtime;

	return utime(filename, &ftime);
#endif
}
Exemplo n.º 21
0
static int _single_p(Copy * copy, char const * dst, struct stat const * st)
{
	struct timeval tv[2];

	if(lchown(dst, st->st_uid, st->st_gid) != 0)
	{
		_copy_filename_error(copy, dst, 0);
		if(lchmod(dst, st->st_mode & ~(S_ISUID | S_ISGID)) != 0)
			_copy_filename_error(copy, dst, 0);
	}
	else if(lchmod(dst, st->st_mode) != 0)
		_copy_filename_error(copy, dst, 0);
	tv[0].tv_sec = st->st_atime;
	tv[0].tv_usec = 0;
	tv[1].tv_sec = st->st_mtime;
	tv[1].tv_usec = 0;
	if(lutimes(dst, tv) != 0)
		_copy_filename_error(copy, dst, 0);
	return 0;
}
Exemplo n.º 22
0
int
set_utimes(const char *file, struct stat *fs)
{
    static struct timeval tv[2];

#ifndef HAVE_STRUCT_STAT_ST_ATIMESPEC
    tv[0].tv_sec = fs->st_atime;
    tv[0].tv_usec = 0;
    tv[1].tv_sec = fs->st_mtime;
    tv[1].tv_usec = 0;
#else
    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
#endif

    if (lutimes(file, tv)) {
	warn("lutimes: %s", file);
	return (1);
    }
    return (0);
}
Exemplo n.º 23
0
Arquivo: os_ext.c Projeto: mk-fg/fgc
static PyObject *
oe_lutimes(PyObject *self, PyObject *args) { // (str) filename, (tuple) (atime, mtime)
	char *path; PyObject *ftimes;
	if (!PyArg_ParseTuple( args, "etO:utime",
		Py_FileSystemDefaultEncoding, &path, &ftimes )) return NULL;

	struct timeval tv[2];

	if (PyTuple_Check(ftimes) && PyTuple_Size(ftimes) == 2) {
		int i;
		for (i=0; i<2; i++) {
			if ( extract_time(PyTuple_GET_ITEM(ftimes, i),
					&tv[i].tv_sec, &tv[i].tv_usec) == -1 ) {
				PyMem_Free(path);
				return NULL; } }

		Py_BEGIN_ALLOW_THREADS
		i = lutimes(path, tv);
		Py_END_ALLOW_THREADS

		if (i < 0) return posix_error_with_allocated_filename(path); }
Exemplo n.º 24
0
int cow_utimens(const char *path, const struct timespec ts[2])
{
    int res;
    LOG("%s",path);

    char *fqpath = create_path(cow_getConfig()->srcdir, path);
    if(fqpath==NULL){ return -errno; }
    
    struct timeval tv[2];

    tv[0].tv_sec = ts[0].tv_sec;
    tv[0].tv_usec = ts[0].tv_nsec / 1000;
    tv[1].tv_sec = ts[1].tv_sec;
    tv[1].tv_usec = ts[1].tv_nsec / 1000;

    res = lutimes(fqpath, tv);
    free(fqpath);
    if (res == -1)
        return -errno;

    return 0;
}
Exemplo n.º 25
0
static PyObject *
utimensat_wrapper(PyObject *self, PyObject *args)
{
    int ret;
    const char *filename;
    long atime_sec, atime_nsec;
    long mtime_sec, mtime_nsec;
#if NO_NANOSECONDS
    struct timeval tv[2];
#else
    struct timespec tv[2];
#endif
    if (!PyArg_ParseTuple(args, "sllll",
                          &filename,
                          &atime_sec,
                          &atime_nsec,
                          &mtime_sec,
                          &mtime_nsec))
        return NULL;

#if NO_NANOSECONDS
    tv[0].tv_sec = atime_sec;
    tv[0].tv_usec = atime_nsec / 1000;
    tv[1].tv_sec = mtime_sec;
    tv[1].tv_usec = mtime_nsec / 1000;
    ret = lutimes(filename, tv);
#else
    tv[0].tv_sec = atime_sec;
    tv[0].tv_nsec = atime_nsec;
    tv[1].tv_sec = mtime_sec;
    tv[1].tv_nsec = mtime_nsec;
    ret = utimensat(AT_FDCWD, filename, tv, AT_SYMLINK_NOFOLLOW);
#endif
    if (ret == -1)
        ret = errno;
    return Py_BuildValue("i", ret);
}
Exemplo n.º 26
0
int
extractfile(char *name)
{
	int flags;
	uid_t uid;
	gid_t gid;
	mode_t mode;
	int extsize;
	struct timeval mtimep[2], ctimep[2];
	struct entry *ep;
	char *buf;

	curfile.name = name;
	curfile.action = USING;
	mtimep[0].tv_sec = curfile.atime_sec;
	mtimep[0].tv_usec = curfile.atime_nsec / 1000;
	mtimep[1].tv_sec = curfile.mtime_sec;
	mtimep[1].tv_usec = curfile.mtime_nsec / 1000;
	ctimep[0].tv_sec = curfile.atime_sec;
	ctimep[0].tv_usec = curfile.atime_nsec / 1000;
	ctimep[1].tv_sec = curfile.birthtime_sec;
	ctimep[1].tv_usec = curfile.birthtime_nsec / 1000;
	extsize = curfile.extsize;
	uid = getuid();
	if (uid == 0)
		uid = curfile.uid;
	gid = curfile.gid;
	mode = curfile.mode;
	flags = curfile.file_flags;
	switch (mode & IFMT) {

	default:
		fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode);
		skipfile();
		return (FAIL);

	case IFSOCK:
		vprintf(stdout, "skipped socket %s\n", name);
		skipfile();
		return (GOOD);

	case IFDIR:
		if (mflag) {
			ep = lookupname(name);
			if (ep == NULL || ep->e_flags & EXTRACT)
				panic("unextracted directory %s\n", name);
			skipfile();
			return (GOOD);
		}
		vprintf(stdout, "extract file %s\n", name);
		return (genliteraldir(name, curfile.ino));

	case IFLNK:
		lnkbuf[0] = '\0';
		pathlen = 0;
		buf = setupextattr(extsize);
		getfile(xtrlnkfile, xtrattr, xtrlnkskip);
		if (pathlen == 0) {
			vprintf(stdout,
			    "%s: zero length symbolic link (ignored)\n", name);
			return (GOOD);
		}
		if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
			if (extsize > 0)
				set_extattr_link(name, buf, extsize);
			(void) lchown(name, uid, gid);
			(void) lchmod(name, mode);
			(void) lutimes(name, ctimep);
			(void) lutimes(name, mtimep);
			(void) lchflags(name, flags);
			return (GOOD);
		}
		return (FAIL);

	case IFIFO:
		vprintf(stdout, "extract fifo %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if (mkfifo(name, 0600) < 0) {
			fprintf(stderr, "%s: cannot create fifo: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		if (extsize == 0) {
			skipfile();
		} else {
			buf = setupextattr(extsize);
			getfile(xtrnull, xtrattr, xtrnull);
			set_extattr_file(name, buf, extsize);
		}
		(void) chown(name, uid, gid);
		(void) chmod(name, mode);
		(void) utimes(name, ctimep);
		(void) utimes(name, mtimep);
		(void) chflags(name, flags);
		return (GOOD);

	case IFCHR:
	case IFBLK:
		vprintf(stdout, "extract special file %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600,
		    (int)curfile.rdev) < 0) {
			fprintf(stderr, "%s: cannot create special file: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		if (extsize == 0) {
			skipfile();
		} else {
			buf = setupextattr(extsize);
			getfile(xtrnull, xtrattr, xtrnull);
			set_extattr_file(name, buf, extsize);
		}
		(void) chown(name, uid, gid);
		(void) chmod(name, mode);
		(void) utimes(name, ctimep);
		(void) utimes(name, mtimep);
		(void) chflags(name, flags);
		return (GOOD);

	case IFREG:
		vprintf(stdout, "extract file %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
		    0600)) < 0) {
			fprintf(stderr, "%s: cannot create file: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		buf = setupextattr(extsize);
		getfile(xtrfile, xtrattr, xtrskip);
		if (extsize > 0)
			set_extattr_fd(ofile, name, buf, extsize);
		(void) fchown(ofile, uid, gid);
		(void) fchmod(ofile, mode);
		(void) futimes(ofile, ctimep);
		(void) futimes(ofile, mtimep);
		(void) fchflags(ofile, flags);
		(void) close(ofile);
		return (GOOD);
	}
	/* NOTREACHED */
}
Exemplo n.º 27
0
/* Set the access and modification time stamps of FILE to be
   TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
   symlinks.  Fail with ENOSYS if the platform does not support
   changing symlink timestamps, but FILE was a symlink.  */
int
lutimens (char const *file, struct timespec const timespec[2])
{
    struct timespec adjusted_timespec[2];
    struct timespec *ts = timespec ? adjusted_timespec : NULL;
    int adjustment_needed = 0;
    struct stat st;

    if (ts)
    {
        adjusted_timespec[0] = timespec[0];
        adjusted_timespec[1] = timespec[1];
        adjustment_needed = validate_timespec (ts);
    }
    if (adjustment_needed < 0)
        return -1;

    /* The Linux kernel did not support symlink timestamps until
       utimensat, in version 2.6.22, so we don't need to mimic
       fdutimens' worry about buggy NFS clients.  But we do have to
       worry about bogus return values.  */

#if HAVE_UTIMENSAT
    if (0 <= lutimensat_works_really)
    {
        int result;
# if __linux__
        /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
           systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
           but work if both times are either explicitly specified or
           UTIME_NOW.  Work around it with a preparatory lstat prior to
           calling utimensat; fortunately, there is not much timing
           impact due to the extra syscall even on file systems where
           UTIME_OMIT would have worked.  FIXME: Simplify this in 2012,
           when file system bugs are no longer common.  */
        if (adjustment_needed == 2)
        {
            if (lstat (file, &st))
                return -1;
            if (ts[0].tv_nsec == UTIME_OMIT)
                ts[0] = get_stat_atime (&st);
            else if (ts[1].tv_nsec == UTIME_OMIT)
                ts[1] = get_stat_mtime (&st);
            /* Note that st is good, in case utimensat gives ENOSYS.  */
            adjustment_needed++;
        }
# endif /* __linux__ */
        result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
# ifdef __linux__
        /* Work around a kernel bug:
           http://bugzilla.redhat.com/442352
           http://bugzilla.redhat.com/449910
           It appears that utimensat can mistakenly return 280 rather
           than -1 upon ENOSYS failure.
           FIXME: remove in 2010 or whenever the offending kernels
           are no longer in common use.  */
        if (0 < result)
            errno = ENOSYS;
# endif
        if (result == 0 || errno != ENOSYS)
        {
            utimensat_works_really = 1;
            lutimensat_works_really = 1;
            return result;
        }
    }
    lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT */

    /* The platform lacks an interface to set file timestamps with
       nanosecond resolution, so do the best we can, discarding any
       fractional part of the timestamp.  */

    if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
    {
        if (adjustment_needed != 3 && lstat (file, &st))
            return -1;
        if (ts && update_timespec (&st, &ts))
            return 0;
    }

    /* On Linux, lutimes is a thin wrapper around utimensat, so there is
       no point trying lutimes if utimensat failed with ENOSYS.  */
#if HAVE_LUTIMES && !HAVE_UTIMENSAT
    {
        struct timeval timeval[2];
        struct timeval *t;
        int result;
        if (ts)
        {
            timeval[0].tv_sec = ts[0].tv_sec;
            timeval[0].tv_usec = ts[0].tv_nsec / 1000;
            timeval[1].tv_sec = ts[1].tv_sec;
            timeval[1].tv_usec = ts[1].tv_nsec / 1000;
            t = timeval;
        }
        else
            t = NULL;

        result = lutimes (file, t);
        if (result == 0 || errno != ENOSYS)
            return result;
    }
#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */

    /* Out of luck for symlinks, but we still handle regular files.  */
    if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
        return -1;
    if (!S_ISLNK (st.st_mode))
        return fdutimens (-1, file, ts);
    errno = ENOSYS;
    return -1;
}
Exemplo n.º 28
0
int
setfile(struct stat *fs, int fd)
{
    static struct timeval tv[2];
    struct stat ts;
    int rval, gotstat, islink, fdval;

    rval = 0;
    fdval = fd != -1;
    islink = !fdval && S_ISLNK(fs->st_mode);
    fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX |
                   S_IRWXU | S_IRWXG | S_IRWXO;

    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
    if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
        warn("%sutimes: %s", islink ? "l" : "", to.p_path);
        rval = 1;
    }
    if (fdval ? fstat(fd, &ts) :
            (islink ? lstat(to.p_path, &ts) : stat(to.p_path, &ts)))
        gotstat = 0;
    else {
        gotstat = 1;
        ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX |
                      S_IRWXU | S_IRWXG | S_IRWXO;
    }
    /*
     * 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 (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
        if (fdval ? fchown(fd, fs->st_uid, fs->st_gid) :
                (islink ? lchown(to.p_path, fs->st_uid, fs->st_gid) :
                 chown(to.p_path, fs->st_uid, fs->st_gid))) {
            if (errno != EPERM) {
                warn("chown: %s", to.p_path);
                rval = 1;
            }
            fs->st_mode &= ~(S_ISUID | S_ISGID);
        }

    if (!gotstat || fs->st_mode != ts.st_mode)
        if (fdval ? fchmod(fd, fs->st_mode) :
                (islink ? lchmod(to.p_path, fs->st_mode) :
                 chmod(to.p_path, fs->st_mode))) {
            warn("chmod: %s", to.p_path);
            rval = 1;
        }

    if (!gotstat || fs->st_flags != ts.st_flags)
        if (fdval ?
                fchflags(fd, fs->st_flags) :
                (islink ? lchflags(to.p_path, fs->st_flags) :
                 chflags(to.p_path, fs->st_flags))) {
            warn("chflags: %s", to.p_path);
            rval = 1;
        }

    return (rval);
}
Exemplo n.º 29
0
RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
                               PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags)
{
    /*
     * Validate input.
     */
    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER);
    AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);

    /*
     * Convert the paths.
     */
    char const *pszNativePath;
    int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
    if (RT_SUCCESS(rc))
    {
        RTFSOBJINFO ObjInfo;

        /*
         * If it's a no-op, we'll only verify the existance of the file.
         */
        if (!pAccessTime && !pModificationTime)
            rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, fFlags);
        else
        {
            /*
             * Convert the input to timeval, getting the missing one if necessary,
             * and call the API which does the change.
             */
            struct timeval aTimevals[2];
            if (pAccessTime && pModificationTime)
            {
                RTTimeSpecGetTimeval(pAccessTime,       &aTimevals[0]);
                RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]);
            }
            else
            {
                rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
                if (RT_SUCCESS(rc))
                {
                    RTTimeSpecGetTimeval(pAccessTime        ? pAccessTime       : &ObjInfo.AccessTime,       &aTimevals[0]);
                    RTTimeSpecGetTimeval(pModificationTime  ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]);
                }
                else
                    Log(("RTPathSetTimes('%s',%p,%p,,): RTPathQueryInfo failed with %Rrc\n",
                         pszPath, pAccessTime, pModificationTime, rc));
            }
            if (RT_SUCCESS(rc))
            {
                if (fFlags & RTPATH_F_FOLLOW_LINK)
                {
                    if (utimes(pszNativePath, aTimevals))
                        rc = RTErrConvertFromErrno(errno);
                }
#if (defined(RT_OS_DARWIN) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) \
 || defined(RT_OS_FREEBSD) \
 || defined(RT_OS_LINUX) \
 || defined(RT_OS_OS2) /** @todo who really has lutimes? */
                else
                {
                    if (lutimes(pszNativePath, aTimevals))
                        rc = RTErrConvertFromErrno(errno);
                }
#else
                else
                {
                    if (pAccessTime && pModificationTime)
                        rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
                    if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
                        rc = VERR_NS_SYMLINK_SET_TIME;
                    else if (RT_SUCCESS(rc))
                    {
                        if (utimes(pszNativePath, aTimevals))
                            rc = RTErrConvertFromErrno(errno);
                    }
                }
#endif
                if (RT_FAILURE(rc))
                    Log(("RTPathSetTimes('%s',%p,%p,,): failed with %Rrc and errno=%d\n",
                         pszPath, pAccessTime, pModificationTime, rc, errno));
            }
        }
        rtPathFreeNative(pszNativePath, pszPath);
    }
Exemplo n.º 30
0
/*
 * copy_symlink - copy a symlink
 *
 *	Copy a symlink from src to dst.
 *
 *	statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set
 *	the access and modification and the access rights.
 *
 *	Return 0 on success, -1 on error.
 */
static int copy_symlink (const char *src, const char *dst,
                         unused bool reset_selinux,
                         const struct stat *statp, const struct timeval mt[],
                         uid_t old_uid, uid_t new_uid,
                         gid_t old_gid, gid_t new_gid)
{
    char *oldlink;

    /* copy_tree () must be the entry point */
    assert (NULL != src_orig);
    assert (NULL != dst_orig);

    /*
     * Get the name of the file which the link points
     * to.  If that name begins with the original
     * source directory name, that part of the link
     * name will be replaced with the original
     * destination directory name.
     */

    oldlink = readlink_malloc (src);
    if (NULL == oldlink) {
        return -1;
    }

    /* If src was a link to an entry of the src_orig directory itself,
     * create a link to the corresponding entry in the dst_orig
     * directory.
     */
    if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
        size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
        char *dummy = (char *) xmalloc (len);
        (void) snprintf (dummy, len, "%s%s",
                         dst_orig,
                         oldlink + strlen (src_orig));
        free (oldlink);
        oldlink = dummy;
    }

#ifdef WITH_SELINUX
    if (set_selinux_file_context (dst) != 0) {
        free (oldlink);
        return -1;
    }
#endif				/* WITH_SELINUX */
    if (   (symlink (oldlink, dst) != 0)
            || (lchown_if_needed (dst, statp,
                                  old_uid, new_uid, old_gid, new_gid) != 0)) {
        /* FIXME: there are no modes on symlinks, right?
         *        ACL could be copied, but this would be much more
         *        complex than calling perm_copy_file.
         *        Ditto for Extended Attributes.
         *        We currently only document that ACL and Extended
         *        Attributes are not copied.
         */
        free (oldlink);
        return -1;
    }
    free (oldlink);

#ifdef HAVE_LUTIMES
    /* 2007-10-18: We don't care about
     *  exit status of lutimes because
     *  it returns ENOSYS on many system
     *  - not implemented
     */
    (void) lutimes (dst, mt);
#endif				/* HAVE_LUTIMES */

    return 0;
}