Subject: ln -i
To: None <tech-userlevel@netbsd.org>
From: None <hiramatu@boreas.dti.ne.jp>
List: tech-userlevel
Date: 09/03/2003 16:26:09
Hello,
How about adding -i(interactive) option to /bin/ln, to be more
consistent with mv, cp and rm?
This code is actually copied from FreeBSD.
diff -bur ln.orig/ln.1 ln/ln.1
--- ln.orig/ln.1 2003-08-24 04:53:37.000000000 +0900
+++ ln/ln.1 2003-08-24 04:50:57.000000000 +0900
@@ -75,6 +75,21 @@
This is most useful with the
.Fl f
option, to replace a symlink which may point to a directory.
+.It Fl i
+Cause
+.Nm
+to write a prompt to standard error if the target file exists.
+If the response from the standard input begins with the character
+.Sq Li y
+or
+.Sq Li Y ,
+then unlink the target file so that the link may occur.
+Otherwise, do not attempt the link.
+(The
+.Fl i
+option overrides any previous
+.Fl f
+options.)
.It Fl n
Same as
.Fl h ,
diff -bur ln.orig/ln.c ln/ln.c
--- ln.orig/ln.c 2003-08-24 04:53:37.000000000 +0900
+++ ln/ln.c 2003-08-24 04:50:57.000000000 +0900
@@ -56,6 +56,7 @@
int fflag; /* Unlink existing files. */
int hflag; /* Check new name for symlink first. */
+int iflag; /* Interactive mode. */
int sflag; /* Symbolic, not hard, link. */
int vflag; /* Verbose output */
int stdout_ok; /* stdout connected to a terminal */
@@ -77,15 +78,20 @@
char *sourcedir;
setprogname(argv[0]);
- while ((ch = getopt(argc, argv, "fhnsv")) != -1)
+ while ((ch = getopt(argc, argv, "fhnisv")) != -1)
switch (ch) {
case 'f':
fflag = 1;
+ iflag = 0;
break;
case 'h':
case 'n':
hflag = 1;
break;
+ case 'i':
+ iflag = 1;
+ fflag = 0;
+ break;
case 's':
sflag = 1;
break;
@@ -150,6 +156,7 @@
linkit(char *target, char *source, int isdir)
{
struct stat sb;
+ int ch, exists, first;
char *p, path[MAXPATHLEN];
char *sn, *tn;
@@ -181,12 +188,36 @@
source = path;
}
+ exists = !lstat(source, &sb);
/*
- * If the file exists, and -f was specified, unlink it.
- * Attempt the link.
+ * If the file exists, then unlink it forcibly if -f was specified
+ * and interactively if -i was specified.
*/
- if ((fflag && unlink(source) < 0 && errno != ENOENT) ||
- (*linkf)(target, source)) {
+ if (fflag & exists) {
+ if (unlink(source)) {
+ warn("%s", source);
+ return (1);
+ }
+ } else if (iflag && exists) {
+ fflush(stdout);
+ fprintf(stderr, "replace %s? ", source);
+
+ first = ch = getchar();
+ while(ch != '\n' && ch != EOF)
+ ch = getchar();
+ if (first != 'y' && first != 'Y') {
+ fprintf(stderr, "not replaced\n");
+ return (1);
+ }
+
+ if (unlink(source)) {
+ warn("%s", source);
+ return (1);
+ }
+ }
+
+ /* Attempt the link. */
+ if ((*linkf)(target, source)) {
warn("%s", source);
free(sn);
free(tn);