Patch from Matthew S. Wood:

> The following patch adds support for the -S and -b flags to `ln'.  These
> flags [especially -b] are used extensively in Debian pre and post
> installation scripts.

Comments from Vladimir Oleynik influenced the final patch, and I also ripped
out the in-file changelog since it belongs here.  At the time, it said:

/* Apr 15, 2004      Matthew S. Wood    (mwood@realmsys.com)
 *
 * Implement '-b' (backup) flag.
 * Implement '-S' (backup suffix) flag.
 *
 *
 * Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
 *
 * Fixed bug involving -n option.  Essentially, -n was always in effect.
 */
This commit is contained in:
Rob Landley 2005-04-29 22:13:04 +00:00
parent fdc4c203e5
commit 3071e2fda3

View File

@ -21,21 +21,20 @@
*/ */
/* BB_AUDIT SUSv3 compliant */ /* BB_AUDIT SUSv3 compliant */
/* BB_AUDIT GNU options missing: -b, -d, -F, -i, -S, and -v. */ /* BB_AUDIT GNU options missing: -d, -F, -i, and -v. */
/* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) #include <stdio.h>
*
* Fixed bug involving -n option. Essentially, -n was always in effect.
*/
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include "busybox.h" #include "busybox.h"
#define LN_SYMLINK 1 #define LN_SYMLINK 1
#define LN_FORCE 2 #define LN_FORCE 2
#define LN_NODEREFERENCE 4 #define LN_NODEREFERENCE 4
#define LN_BACKUP 8
#define LN_SUFFIX 16
extern int ln_main(int argc, char **argv) extern int ln_main(int argc, char **argv)
{ {
@ -44,10 +43,11 @@ extern int ln_main(int argc, char **argv)
char *last; char *last;
char *src_name; char *src_name;
char *src; char *src;
char *suffix = "~";
struct stat statbuf; struct stat statbuf;
int (*link_func)(const char *, const char *); int (*link_func)(const char *, const char *);
flag = bb_getopt_ulflags(argc, argv, "sfn"); flag = bb_getopt_ulflags(argc, argv, "sfnbS:", &suffix);
if (argc == optind) { if (argc == optind) {
bb_show_usage(); bb_show_usage();
@ -80,7 +80,23 @@ extern int ln_main(int argc, char **argv)
continue; continue;
} }
if (flag & LN_FORCE) { if (flag & LN_BACKUP) {
char *backup = NULL;
bb_xasprintf(&backup, "%s%s", src, suffix);
if (rename(src, backup) < 0 && errno != ENOENT) {
bb_perror_msg(src);
status = EXIT_FAILURE;
free(backup);
continue;
}
free(backup);
/*
* When the source and dest are both hard links to the same
* inode, a rename may succeed even though nothing happened.
* Therefore, always unlink().
*/
unlink(src);
} else if (flag & LN_FORCE) {
unlink(src); unlink(src);
} }