diff options
author | Vincent Labrecque <vincent@cvs.openbsd.org> | 2002-04-22 05:27:40 +0000 |
---|---|---|
committer | Vincent Labrecque <vincent@cvs.openbsd.org> | 2002-04-22 05:27:40 +0000 |
commit | 120329df858051aaef7b6b39295d669b40dbdb88 (patch) | |
tree | 8327c0304aa92f4c5d6c3610a98902baf202286d /usr.bin/mg/fileio.c | |
parent | ad8216c86df40cf509b7bc811f480a7f07d5dfe3 (diff) |
don't use /bin/cp to copy files.
ok deraadt@
Diffstat (limited to 'usr.bin/mg/fileio.c')
-rw-r--r-- | usr.bin/mg/fileio.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/usr.bin/mg/fileio.c b/usr.bin/mg/fileio.c index cfe1eddea57..ab57e4db708 100644 --- a/usr.bin/mg/fileio.c +++ b/usr.bin/mg/fileio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fileio.c,v 1.29 2002/04/22 04:27:37 vincent Exp $ */ +/* $OpenBSD: fileio.c,v 1.30 2002/04/22 05:27:39 vincent Exp $ */ /* * POSIX fileio.c @@ -174,7 +174,6 @@ fbackupfile(const char *fn) } if (stat(fn, &sb) == -1) { ewprintf("Can't stat %s : %s", fn, strerror(errno)); - free(nname); return (FALSE); } @@ -192,8 +191,8 @@ fbackupfile(const char *fn) } while ((nread = read(from, buf, sizeof(buf))) > 0) { if (write(to, buf, nread) != nread) { - nread = -1; - break; + nread = -1; + break; } } serrno = errno; @@ -397,19 +396,49 @@ nohome: int copy(char *frname, char *toname) { - pid_t pid; - int status; - - switch ((pid = vfork())) { - case -1: - return -1; - case 0: - execl("/bin/cp", "cp", frname, toname, (char *)NULL); - _exit(1); /* shouldn't happen */ - default: - waitpid(pid, &status, 0); - return (WIFEXITED(status) && WEXITSTATUS(status) == 0); + int ifd, ofd, n; + char buf[BUFSIZ]; + mode_t mode = DEFFILEMODE; /* XXX?? */ + struct stat orig; + + if ((ifd = open(frname, O_RDONLY)) == -1) + return (FALSE); + if (fstat(ifd, &orig) == -1) { + ewprintf("fstat: %s", strerror(errno)); + close(ifd); + return (FALSE); } + + if ((ofd = open(toname, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) { + close(ifd); + return (FALSE); + } + while ((n = read(ifd, buf, sizeof buf)) > 0) { + if (write(ofd, buf, n) != n) { + ewprintf("write error : %s", strerror(errno)); + break; + } + } + if (fchmod(ofd, orig.st_mode) == -1) + ewprintf("Cannot set original mode : %s", strerror(errno)); + + if (n == -1) { + ewprintf("Read error : %s", strerror(errno)); + close(ifd); + close(ofd); + return (FALSE); + } + /* + * It is "normal" for this to fail since we can't garantee that + * we will be running as root + */ + if (fchown(ofd, orig.st_uid, orig.st_gid) && errno != EPERM) + ewprintf("Cannot set owner : %s", strerror(errno)); + + (void) close(ifd); + (void) close(ofd); + + return (TRUE); } /* |