diff options
author | 2003-07-25 02:12:45 +0000 | |
---|---|---|
committer | 2003-07-25 02:12:45 +0000 | |
commit | 7fe8583a2a5578563ecc776e27cc7bde80a54a23 (patch) | |
tree | 960b7e00d90075e5b235a348bb27a0720840be79 /usr.bin/patch/util.c | |
parent | various tweaks; (diff) | |
download | wireguard-openbsd-7fe8583a2a5578563ecc776e27cc7bde80a54a23.tar.xz wireguard-openbsd-7fe8583a2a5578563ecc776e27cc7bde80a54a23.zip |
Add POSIX -b option but don't change the default beahvior wrt backups
yet. The old -b option is now -z (matches GNU patch).
Diffstat (limited to 'usr.bin/patch/util.c')
-rw-r--r-- | usr.bin/patch/util.c | 153 |
1 files changed, 67 insertions, 86 deletions
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c index a958b480ac5..0874dac002f 100644 --- a/usr.bin/patch/util.c +++ b/usr.bin/patch/util.c @@ -1,7 +1,7 @@ -/* $OpenBSD: util.c,v 1.17 2003/07/22 17:52:20 deraadt Exp $ */ +/* $OpenBSD: util.c,v 1.18 2003/07/25 02:12:45 millert Exp $ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: util.c,v 1.17 2003/07/22 17:52:20 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: util.c,v 1.18 2003/07/25 02:12:45 millert Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -29,7 +29,6 @@ static const char rcsid[] = "$OpenBSD: util.c,v 1.17 2003/07/22 17:52:20 der int move_file(char *from, char *to) { - char bakname[MAXPATHLEN], *s; int i, fromfd; /* to stdout? */ @@ -48,114 +47,95 @@ move_file(char *from, char *to) close(fromfd); return 0; } + if (backup_file(to) < 0) { + say("Can't backup %s, output is in %s: %s\n", to, from, + strerror(errno)); + return -1; + } +#ifdef DEBUGGING + if (debug & 4) + say("Moving %s to %s.\n", from, to); +#endif + if (rename(from, to) < 0) { + if (errno != EXDEV || copy_file(from, to) < 0) { + say("Can't create %s, output is in %s: %s\n", + to, from, strerror(errno)); + return -1; + } + } + return 0; +} + +/* Backup the original file. */ + +int +backup_file(char *orig) +{ + char bakname[MAXPATHLEN], *s, *simplename; + dev_t orig_device; + ino_t orig_inode; + + if (backup_type == none || stat(orig, &filestat) != 0) + return 0; /* nothing to do */ + orig_device = filestat.st_dev; + orig_inode = filestat.st_ino; + if (origprae) { if (strlcpy(bakname, origprae, sizeof(bakname)) >= sizeof(bakname) || - strlcat(bakname, to, sizeof(bakname)) >= sizeof(bakname)) + strlcat(bakname, orig, sizeof(bakname)) >= sizeof(bakname)) fatal("filename %s too long for buffer\n", origprae); } else { - char *backupname = find_backup_file_name(to); - if (backupname == (char *) 0) + if ((s = find_backup_file_name(orig)) == NULL) fatal("out of memory\n"); - if (strlcpy(bakname, backupname, sizeof(bakname)) >= sizeof(bakname)) - fatal("filename %s too long for buffer\n", backupname); - free(backupname); + if (strlcpy(bakname, s, sizeof(bakname)) >= sizeof(bakname)) + fatal("filename %s too long for buffer\n", s); + free(s); } - if (stat(to, &filestat) == 0) { /* output file exists */ - dev_t to_device = filestat.st_dev; - ino_t to_inode = filestat.st_ino; - char *simplename = bakname; - - for (s = bakname; *s; s++) { - if (*s == '/') - simplename = s + 1; - } - - /* - * Find a backup name that is not the same file. Change the - * first lowercase char into uppercase; if that isn't - * sufficient, chop off the first char and try again. - */ - while (stat(bakname, &filestat) == 0 && - to_device == filestat.st_dev && to_inode == filestat.st_ino) { - /* Skip initial non-lowercase chars. */ - for (s = simplename; *s && !islower(*s); s++) - ; - if (*s) - *s = toupper(*s); - else - memmove(simplename, simplename + 1, - strlen(simplename + 1) + 1); - } - unlink(bakname); + if ((simplename = strrchr(bakname, '/')) != NULL) + simplename = simplename + 1; + else + simplename = bakname; -#ifdef DEBUGGING - if (debug & 4) - say("Moving %s to %s.\n", to, bakname); -#endif - if (link(to, bakname) < 0) { - /* - * Maybe `to' is a symlink into a different file - * system. Copying replaces the symlink with a file; - * using rename would be better. - */ - int tofd, bakfd; - - bakfd = creat(bakname, 0666); - if (bakfd < 0) { - say("Can't backup %s, output is in %s: %s\n", - to, from, strerror(errno)); - return -1; - } - tofd = open(to, O_RDONLY); - if (tofd < 0) - pfatal("internal error, can't open %s", to); - while ((i = read(tofd, buf, sizeof buf)) > 0) - if (write(bakfd, buf, i) != i) - pfatal("write failed"); - close(tofd); - close(bakfd); - } - unlink(to); + /* + * Find a backup name that is not the same file. Change the + * first lowercase char into uppercase; if that isn't + * sufficient, chop off the first char and try again. + */ + while (stat(bakname, &filestat) == 0 && + orig_device == filestat.st_dev && orig_inode == filestat.st_ino) { + /* Skip initial non-lowercase chars. */ + for (s = simplename; *s && !islower(*s); s++) + ; + if (*s) + *s = toupper(*s); + else + memmove(simplename, simplename + 1, + strlen(simplename + 1) + 1); } #ifdef DEBUGGING if (debug & 4) - say("Moving %s to %s.\n", from, to); + say("Moving %s to %s.\n", orig, bakname); #endif - if (link(from, to) < 0) { /* different file system? */ - int tofd; - - tofd = creat(to, 0666); - if (tofd < 0) { - say("Can't create %s, output is in %s: %s\n", - to, from, strerror(errno)); + if (rename(orig, bakname) < 0) { + if (errno != EXDEV || copy_file(orig, bakname) < 0) return -1; - } - fromfd = open(from, O_RDONLY); - if (fromfd < 0) - pfatal("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) - if (write(tofd, buf, i) != i) - pfatal("write failed"); - close(fromfd); - close(tofd); } - unlink(from); return 0; } /* * Copy a file. */ -void +int copy_file(char *from, char *to) { int tofd, fromfd, i; - tofd = creat(to, 0666); + tofd = open(to, O_CREAT|O_TRUNC|O_WRONLY, 0666); if (tofd < 0) - pfatal("can't create %s", to); - fromfd = open(from, O_RDONLY); + return -1; + fromfd = open(from, O_RDONLY, 0); if (fromfd < 0) pfatal("internal error, can't reopen %s", from); while ((i = read(fromfd, buf, sizeof buf)) > 0) @@ -163,6 +143,7 @@ copy_file(char *from, char *to) pfatal("write to %s failed", to); close(fromfd); close(tofd); + return 0; } /* |