Created
April 30, 2020 18:58
-
-
Save levaidaniel/dfc71d782a6e023459c04a3f30ff5a6e to your computer and use it in GitHub Desktop.
Preserve ownership of files when RCSing!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/usr.bin/rcs/ci.c b/usr.bin/rcs/ci.c | |
index 765b03a9388..d7212ad8365 100644 | |
--- a/usr.bin/rcs/ci.c | |
+++ b/usr.bin/rcs/ci.c | |
@@ -565,6 +565,10 @@ checkin_update(struct checkin_params *pb) | |
/* Strip all the write bits */ | |
pb->file->rf_mode = st.st_mode & ~(S_IWUSR|S_IWGRP|S_IWOTH); | |
+ /* Preserve the owner and group */ | |
+ pb->file->rf_uid = st.st_uid; | |
+ pb->file->rf_gid = st.st_gid; | |
+ | |
(void)close(workfile_fd); | |
(void)unlink(pb->filename); | |
@@ -685,6 +689,10 @@ skipdesc: | |
/* Strip all the write bits */ | |
pb->file->rf_mode = st.st_mode & ~(S_IWUSR|S_IWGRP|S_IWOTH); | |
+ /* Preserve the owner and group */ | |
+ pb->file->rf_uid = st.st_uid; | |
+ pb->file->rf_gid = st.st_gid; | |
+ | |
(void)close(workfile_fd); | |
(void)unlink(pb->filename); | |
diff --git a/usr.bin/rcs/co.c b/usr.bin/rcs/co.c | |
index 97baae78c44..4f5b0f41800 100644 | |
--- a/usr.bin/rcs/co.c | |
+++ b/usr.bin/rcs/co.c | |
@@ -364,6 +364,9 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags, | |
if (fstat(fileno(file->rf_file), &st) == -1) | |
err(1, "%s", file->rf_path); | |
file->rf_mode = mode = st.st_mode; | |
+ /* Preserve the owner and group */ | |
+ file->rf_uid = st.st_uid; | |
+ file->rf_gid = st.st_gid; | |
} else { | |
mode = file->rf_mode; | |
} | |
@@ -479,8 +482,13 @@ checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags, | |
return (-1); | |
} | |
- if (fchmod(fd, mode) == -1) | |
- warn("%s", dst); | |
+ if (fchmod(fd, mode) == -1) { | |
+ warn("chmod() %s", dst); | |
+ } else { | |
+ if (fchown(fd, file->rf_uid, file->rf_gid) == -1) { | |
+ warn("chown() %s", dst); | |
+ } | |
+ } | |
if (flags & CO_REVDATE) { | |
struct timeval tv[2]; | |
diff --git a/usr.bin/rcs/rcs.c b/usr.bin/rcs/rcs.c | |
index 30415b9de17..13d41a526bd 100644 | |
--- a/usr.bin/rcs/rcs.c | |
+++ b/usr.bin/rcs/rcs.c | |
@@ -72,7 +72,7 @@ int rcs_errno = RCS_ERR_NOERR; | |
char *timezone_flag = NULL; | |
int rcs_patch_lines(struct rcs_lines *, struct rcs_lines *); | |
-static int rcs_movefile(char *, char *, mode_t, u_int); | |
+static int rcs_movefile(char *, char *, mode_t, uid_t, gid_t, u_int); | |
static void rcs_freedelta(struct rcs_delta *); | |
static void rcs_strprint(const u_char *, size_t, FILE *); | |
@@ -338,9 +338,12 @@ rcs_write(RCSFILE *rfp) | |
} | |
(void)fclose(fp); | |
- if (rcs_movefile(fn, rfp->rf_path, rfp->rf_mode, rfp->rf_flags) == -1) { | |
+ if (rcs_movefile(fn, rfp->rf_path, rfp->rf_mode, rfp->rf_uid, rfp->rf_gid, rfp->rf_flags) == -1) { | |
+ if (rcs_movefile(fn, rfp->rf_path, rfp->rf_mode, -1, -1, rfp->rf_flags) == -1) { | |
+ (void)unlink(fn); | |
+ errx(1, "rcs_movefile failed"); | |
+ } | |
(void)unlink(fn); | |
- errx(1, "rcs_movefile failed"); | |
} | |
rfp->rf_flags |= RCS_SYNCED; | |
@@ -355,7 +358,7 @@ rcs_write(RCSFILE *rfp) | |
* Returns 0 on success, -1 on failure. | |
*/ | |
static int | |
-rcs_movefile(char *from, char *to, mode_t perm, u_int to_flags) | |
+rcs_movefile(char *from, char *to, mode_t perm, uid_t owner, gid_t group, u_int to_flags) | |
{ | |
FILE *src, *dst; | |
size_t nread, nwritten; | |
@@ -366,6 +369,10 @@ rcs_movefile(char *from, char *to, mode_t perm, u_int to_flags) | |
warn("%s", to); | |
return (-1); | |
} | |
+ if (chown(to, owner, group) == -1) { | |
+ warn("%s", to); | |
+ return (-1); | |
+ } | |
return (0); | |
} else if (errno != EXDEV) { | |
warn("failed to access temp RCS output file"); | |
@@ -393,6 +400,12 @@ rcs_movefile(char *from, char *to, mode_t perm, u_int to_flags) | |
(void)fclose(src); | |
(void)fclose(dst); | |
return (-1); | |
+ } else { | |
+ if (fchown(fileno(dst), owner, group) == -1) { | |
+ warn("%s", to); | |
+ (void)unlink(to); | |
+ return (-1); | |
+ } | |
} | |
buf = xmalloc(MAXBSIZE); | |
diff --git a/usr.bin/rcs/rcs.h b/usr.bin/rcs/rcs.h | |
index ec672a1306f..8a94d476dbd 100644 | |
--- a/usr.bin/rcs/rcs.h | |
+++ b/usr.bin/rcs/rcs.h | |
@@ -198,6 +198,8 @@ typedef struct rcs_file { | |
FILE *rf_file; | |
char *rf_path; | |
mode_t rf_mode; | |
+ uid_t rf_uid; | |
+ gid_t rf_gid; | |
u_int rf_flags; | |
RCSNUM *rf_head; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment