summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/rsync/downloader.c39
-rw-r--r--usr.bin/rsync/extern.h4
-rw-r--r--usr.bin/rsync/receiver.c49
-rw-r--r--usr.bin/rsync/uploader.c37
4 files changed, 80 insertions, 49 deletions
diff --git a/usr.bin/rsync/downloader.c b/usr.bin/rsync/downloader.c
index 2b545f00c3e..62914437607 100644
--- a/usr.bin/rsync/downloader.c
+++ b/usr.bin/rsync/downloader.c
@@ -1,4 +1,4 @@
-/* $Id: downloader.c,v 1.8 2019/02/13 05:41:35 tb Exp $ */
+/* $Id: downloader.c,v 1.9 2019/02/14 18:29:08 florian Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -306,7 +306,6 @@ rsync_downloader(struct download *p, struct sess *sess, int *ofd)
char *buf = NULL;
unsigned char ourmd[MD4_DIGEST_LENGTH],
md[MD4_DIGEST_LENGTH];
- struct timespec tv[2];
/*
* If we don't have a download already in session, then the next
@@ -569,39 +568,11 @@ rsync_downloader(struct download *p, struct sess *sess, int *ofd)
goto out;
}
- /*
- * Conditionally adjust group id.
- * FIXME: remember the original file's group id and don't
- * reassign it if it's the same.
- * If we have an EPERM, report it but continue on: this just
- * means that we're mapping into an unknown (or disallowed)
- * group identifier.
- */
-
- if (sess->opts->preserve_gids) {
- if (fchown(p->fd, -1, f->st.gid) == -1) {
- if (errno != EPERM) {
- ERR(sess, "%s: fchown", p->fname);
- goto out;
- }
- WARNX(sess, "%s: gid unknown or not available "
- "to user: %u", f->path, f->st.gid);
- } else
- LOG4(sess, "%s: updated gid", f->path);
- }
-
- /* Conditionally adjust file modification time. */
+ /* Adjust our file metadata (uid, mode, etc.). */
- if (sess->opts->preserve_times) {
- tv[0].tv_sec = time(NULL);
- tv[0].tv_nsec = 0;
- tv[1].tv_sec = f->st.mtime;
- tv[1].tv_nsec = 0;
- if (futimens(p->fd, tv) == -1) {
- ERR(sess, "%s: futimens", p->fname);
- goto out;
- }
- LOG4(sess, "%s: updated date", f->path);
+ if (!rsync_set_metadata(sess, 1, p->fd, f, p->fname)) {
+ ERRX1(sess, "rsync_set_metadata");
+ goto out;
}
/* Finally, rename the temporary to the real file. */
diff --git a/usr.bin/rsync/extern.h b/usr.bin/rsync/extern.h
index 25dbc6420cd..da9bbac9fda 100644
--- a/usr.bin/rsync/extern.h
+++ b/usr.bin/rsync/extern.h
@@ -1,4 +1,4 @@
-/* $Id: extern.h,v 1.9 2019/02/14 18:26:52 florian Exp $ */
+/* $Id: extern.h,v 1.10 2019/02/14 18:29:08 florian Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -264,6 +264,8 @@ int rsync_client(const struct opts *, int, const struct fargs *);
int rsync_socket(const struct opts *, const struct fargs *);
int rsync_server(const struct opts *, size_t, char *[]);
int rsync_downloader(struct download *, struct sess *, int *);
+int rsync_set_metadata(struct sess *, int, int,
+ const struct flist *, const char *);
int rsync_uploader(struct upload *,
int *, struct sess *, int *);
int rsync_uploader_tail(struct upload *, struct sess *);
diff --git a/usr.bin/rsync/receiver.c b/usr.bin/rsync/receiver.c
index 5b1446265d5..b5fb79c538a 100644
--- a/usr.bin/rsync/receiver.c
+++ b/usr.bin/rsync/receiver.c
@@ -1,4 +1,4 @@
-/* $Id: receiver.c,v 1.6 2019/02/12 17:58:35 benno Exp $ */
+/* $Id: receiver.c,v 1.7 2019/02/14 18:29:08 florian Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -40,6 +40,53 @@ enum pfdt {
PFD__MAX
};
+int
+rsync_set_metadata(struct sess *sess, int newfile,
+ int fd, const struct flist *f, const char *path)
+{
+ uid_t uid;
+ gid_t gid;
+ struct timespec tv[2];
+
+ /*
+ * Conditionally adjust identifiers.
+ * If we have an EPERM, report it but continue on: this just
+ * means that we're mapping into an unknown (or disallowed)
+ * group identifier.
+ */
+
+ if (sess->opts->preserve_gids ||
+ sess->opts->preserve_uids) {
+ uid = sess->opts->preserve_uids ? f->st.uid : -1;
+ gid = sess->opts->preserve_gids ? f->st.gid : -1;
+ if (fchown(fd, uid, gid) == -1) {
+ if (errno != EPERM) {
+ ERR(sess, "%s: fchown", path);
+ return 0;
+ }
+ WARNX(sess, "%s: identity unknown or not available "
+ "to user.group: %u.%u", f->path, uid, gid);
+ } else
+ LOG4(sess, "%s: updated uid and/or gid", f->path);
+ }
+
+ /* Conditionally adjust file modification time. */
+
+ if (sess->opts->preserve_times) {
+ tv[0].tv_sec = time(NULL);
+ tv[0].tv_nsec = 0;
+ tv[1].tv_sec = f->st.mtime;
+ tv[1].tv_nsec = 0;
+ if (futimens(fd, tv) == -1) {
+ ERR(sess, "%s: futimens", path);
+ return 0;
+ }
+ LOG4(sess, "%s: updated date", f->path);
+ }
+
+ return 1;
+}
+
/*
* Pledges: unveil, rpath, cpath, wpath, stdio, fattr.
* Pledges (dry-run): -cpath, -wpath, -fattr.
diff --git a/usr.bin/rsync/uploader.c b/usr.bin/rsync/uploader.c
index ad4320aad82..efa2439c3c9 100644
--- a/usr.bin/rsync/uploader.c
+++ b/usr.bin/rsync/uploader.c
@@ -1,4 +1,4 @@
-/* $Id: uploader.c,v 1.4 2019/02/11 21:41:22 deraadt Exp $ */
+/* $Id: uploader.c,v 1.5 2019/02/14 18:29:08 florian Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -499,12 +499,13 @@ int
rsync_uploader(struct upload *u, int *fileinfd,
struct sess *sess, int *fileoutfd)
{
- struct blkset blk;
- struct stat st;
- void *map, *bufp;
- size_t i, mapsz, pos, sz;
- off_t offs;
- int c;
+ struct blkset blk;
+ struct stat st;
+ void *map, *bufp;
+ size_t i, mapsz, pos, sz;
+ off_t offs;
+ int c;
+ const struct flist *f;
/* This should never get called. */
@@ -617,23 +618,33 @@ rsync_uploader(struct upload *u, int *fileinfd,
if (u->state == UPLOAD_READ_LOCAL) {
assert(*fileinfd != -1);
assert(*fileoutfd == -1);
+ f = &u->fl[u->idx];
if (fstat(*fileinfd, &st) == -1) {
- WARN(sess, "%s: fstat", u->fl[u->idx].path);
+ ERR(sess, "%s: fstat", f->path);
close(*fileinfd);
*fileinfd = -1;
return -1;
} else if (!S_ISREG(st.st_mode)) {
- WARNX(sess, "%s: not regular", u->fl[u->idx].path);
+ ERRX(sess, "%s: not regular", f->path);
close(*fileinfd);
*fileinfd = -1;
return -1;
}
- if (st.st_size == u->fl[u->idx].st.size &&
- st.st_mtime == u->fl[u->idx].st.mtime) {
- LOG3(sess, "%s: skipping: "
- "up to date", u->fl[u->idx].path);
+ if (st.st_size == f->st.size &&
+ st.st_mtime == f->st.mtime) {
+ LOG3(sess, "%s: skipping: up to date", f->path);
+#if 0
+ /* Not yet: investigate behaviour. */
+ if (!rsync_set_metadata
+ (sess, 0, *fileinfd, f, f->path)) {
+ ERRX1(sess, "rsync_set_metadata");
+ close(*fileinfd);
+ *fileinfd = -1;
+ return -1;
+ }
+#endif
close(*fileinfd);
*fileinfd = -1;
*fileoutfd = u->fdout;