diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2005-01-31 15:48:01 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2005-01-31 15:48:01 +0000 |
commit | e297acea233b1c5e3d25f5f4bfd45c9c3147b990 (patch) | |
tree | eabd8f716bca9dd3426a0b1f671024d4557b9834 /usr.bin/mg/fileio.c | |
parent | 436c3962fea1bd45748743ca72d11c5b5d29baca (diff) |
Safer backup file generation using mkstemp(); henning@ OK
Diffstat (limited to 'usr.bin/mg/fileio.c')
-rw-r--r-- | usr.bin/mg/fileio.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/usr.bin/mg/fileio.c b/usr.bin/mg/fileio.c index 627df0de0b6..850cbc8a2f1 100644 --- a/usr.bin/mg/fileio.c +++ b/usr.bin/mg/fileio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fileio.c,v 1.43 2005/01/11 17:19:16 henning Exp $ */ +/* $OpenBSD: fileio.c,v 1.44 2005/01/31 15:48:00 millert Exp $ */ /* * POSIX fileio.c @@ -160,7 +160,7 @@ fbackupfile(const char *fn) int from, to, serrno; ssize_t nread; char buf[BUFSIZ]; - char *nname; + char *nname, *tname; if (stat(fn, &sb) == -1) { ewprintf("Can't stat %s : %s", fn, strerror(errno)); @@ -168,20 +168,27 @@ fbackupfile(const char *fn) } if (asprintf(&nname, "%s~", fn) == -1) { - ewprintf("Can't allocate temp file name : %s", - strerror(errno)); + ewprintf("Can't allocate temp file name : %s", strerror(errno)); + return (ABORT); + } + + if (asprintf(&tname, "%s.XXXXXXXXXX", fn) == -1) { + ewprintf("Can't allocate temp file name : %s", strerror(errno)); + free(nname); return (ABORT); } if ((from = open(fn, O_RDONLY)) == -1) { free(nname); + free(tname); return (FALSE); } - to = open(nname, O_WRONLY|O_CREAT|O_TRUNC, (sb.st_mode & 0777)); + to = mkstemp(tname); if (to == -1) { serrno = errno; close(from); free(nname); + free(tname); errno = serrno; return (FALSE); } @@ -192,13 +199,20 @@ fbackupfile(const char *fn) } } serrno = errno; + (void) fchmod(to, (sb.st_mode & 0777)); close(from); close(to); if (nread == -1) { - if (unlink(nname) == -1) + if (unlink(tname) == -1) ewprintf("Can't unlink temp : %s", strerror(errno)); + } else { + if (rename(tname, nname) == -1) { + ewprintf("Can't rename temp : %s", strerror(errno)); + (void) unlink(tname); + } } free(nname); + free(tname); errno = serrno; return (nread == -1 ? FALSE : TRUE); |