diff options
Diffstat (limited to 'bin/ln/ln.c')
-rw-r--r-- | bin/ln/ln.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/bin/ln/ln.c b/bin/ln/ln.c index dc2db0f..9ec1efc 100644 --- a/bin/ln/ln.c +++ b/bin/ln/ln.c @@ -56,6 +56,7 @@ static const char rcsid[] = #include <unistd.h> int fflag; /* Unlink existing files. */ +int iflag; /* Interactive mode. */ int sflag; /* Symbolic, not hard, link. */ int vflag; /* Verbose output. */ /* System link call. */ @@ -92,10 +93,17 @@ main(argc, argv) usage(); } - while ((ch = getopt(argc, argv, "fsv")) != -1) + fflag = iflag = sflag = vflag = 0; + + while ((ch = getopt(argc, argv, "fisv")) != -1) switch (ch) { case 'f': fflag = 1; + iflag = 0; /* -f overrides iflag */ + break; + case 'i': + iflag = 1; + fflag = 0; /* -i overrides fflag */ break; case 's': sflag = 1; @@ -139,7 +147,7 @@ linkit(target, source, isdir) int isdir; { struct stat sb; - int exists; + int exists, ch, first; char *p, path[MAXPATHLEN]; if (!sflag) { @@ -172,7 +180,23 @@ linkit(target, source, isdir) * If the file exists, and -f was specified, unlink it. * Attempt the link. */ - if ((fflag && exists && unlink(source)) || (*linkf)(target, source)) { + if (fflag && exists && unlink(source)) { + warn("%s", source); + return (1); + } else if (iflag && exists) { + fprintf(stderr, "replace %s? ", source); + fflush(stderr); + + first = ch = getchar(); + while(ch != '\n' && ch != EOF) + ch = getchar(); + + if ((first == 'y' || first == 'Y') && unlink(source)) { + warn("%s", source); + return (1); + } + } + if ((*linkf)(target, source)) { warn("%s", source); return (1); } @@ -185,8 +209,8 @@ void usage() { (void)fprintf(stderr, "%s\n%s\n%s\n", - "usage: ln [-fsv] file1 file2", - " ln [-fsv] file ... directory", + "usage: ln [-fisv] file1 file2", + " ln [-fisv] file ... directory", " link file1 file2"); exit(1); } |