From Matt Kraai <kraai@alumni.carnegiemellon.edu>:
authorEric Andersen <andersen@codepoet.org>
Mon, 10 Jul 2000 16:44:03 +0000 (16:44 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 10 Jul 2000 16:44:03 +0000 (16:44 -0000)
Howdy,

Bug #1006 reports that

ln -s /tmp/foo .

does not work correctly.  In fact, it appears that any instantiation of

ln -s FILE... DIRECTORY

does not work.  The following patch adds support for this form, which
then fixes the particular instance noted in the bug report.

In the process, I needed the basename function.  This appears in the
string.h provided by glibc, but not uC-libc.  So I wrote my own to go in
utility.c, called get_last_path_component.  I also modified the basename
utility to use this function.

At some point it might be desirous to use the basename from the library
if it exists, and otherwise compile our own.  But I don't know how to do
this.

Matt

basename.c
coreutils/basename.c
coreutils/ln.c
internal.h
ln.c
utility.c

index ac371d274490844fcbc6363137c3480c2104a8cd..fa15aa9799e24b715ecce5b4c942c4d4d757d18a 100644 (file)
@@ -43,14 +43,7 @@ extern int basename_main(int argc, char **argv)
 
        argv++;
 
-       s1=*argv+strlen(*argv)-1;
-       while (s1 && *s1 == '/') {
-               *s1 = '\0';
-               s1--;
-       }
-       s = strrchr(*argv, '/');
-       if (s==NULL) s=*argv;
-       else s++;
+       s = get_last_path_component(*argv);
 
        if (argc>2) {
                argv++;
@@ -62,4 +55,3 @@ extern int basename_main(int argc, char **argv)
        printf("%s\n", s);
        return(TRUE);
 }
-
index ac371d274490844fcbc6363137c3480c2104a8cd..fa15aa9799e24b715ecce5b4c942c4d4d757d18a 100644 (file)
@@ -43,14 +43,7 @@ extern int basename_main(int argc, char **argv)
 
        argv++;
 
-       s1=*argv+strlen(*argv)-1;
-       while (s1 && *s1 == '/') {
-               *s1 = '\0';
-               s1--;
-       }
-       s = strrchr(*argv, '/');
-       if (s==NULL) s=*argv;
-       else s++;
+       s = get_last_path_component(*argv);
 
        if (argc>2) {
                argv++;
@@ -62,4 +55,3 @@ extern int basename_main(int argc, char **argv)
        printf("%s\n", s);
        return(TRUE);
 }
-
index 57e412dc8fe23ac6163183c9f9637300af50ac96..beaa58fac52c5f010bc8e4b080c47c1c78101951 100644 (file)
@@ -52,7 +52,7 @@ static int followLinks = TRUE;
 
 extern int ln_main(int argc, char **argv)
 {
-       char *linkName;
+       char *linkName, *dirName;
        int linkIntoDirFlag;
        int stopIt = FALSE;
 
@@ -104,6 +104,9 @@ extern int ln_main(int argc, char **argv)
                exit FALSE;
        }
 
+       if (linkIntoDirFlag == TRUE)
+               dirName = linkName;
+
        while (argc-- >= 2) {
 #if 0
                char srcName[BUFSIZ + 1];
@@ -126,6 +129,14 @@ extern int ln_main(int argc, char **argv)
                        srcName[nChars] = '\0';
                }
 #endif
+               if (linkIntoDirFlag == TRUE) {
+                       char *baseName = get_last_path_component(*argv);
+                       linkName = (char *)malloc(strlen(dirName)+strlen(baseName)+2);
+                       strcpy(linkName, dirName);
+                       if(dirName[strlen(dirName)-1] != '/')
+                               strcat(linkName, "/");
+                       strcat(linkName,baseName);
+               }
 
                if (removeoldFlag == TRUE) {
                        status = (unlink(linkName) && errno != ENOENT);
@@ -143,6 +154,11 @@ extern int ln_main(int argc, char **argv)
                        perror(linkName);
                        exit FALSE;
                }
+
+               if (linkIntoDirFlag)
+                       free(linkName);
+
+               argv++;
        }
        return( TRUE);
 }
index 362df327093f0618be49bbb6dee839d8d938ee3a..a4772b82055632323ed05d6163051e0aa6d323ed 100644 (file)
@@ -259,6 +259,7 @@ extern void *xmalloc (size_t size);
 extern int find_real_root_device_name(char* name);
 extern char *get_line_from_file(FILE *file);
 extern char process_escape_sequence(char **ptr);
+extern char *get_last_path_component(char *path);
 
 /* These parse entries in /etc/passwd and /etc/group.  This is desirable
  * for BusyBox since we want to avoid using the glibc NSS stuff, which
diff --git a/ln.c b/ln.c
index 57e412dc8fe23ac6163183c9f9637300af50ac96..beaa58fac52c5f010bc8e4b080c47c1c78101951 100644 (file)
--- a/ln.c
+++ b/ln.c
@@ -52,7 +52,7 @@ static int followLinks = TRUE;
 
 extern int ln_main(int argc, char **argv)
 {
-       char *linkName;
+       char *linkName, *dirName;
        int linkIntoDirFlag;
        int stopIt = FALSE;
 
@@ -104,6 +104,9 @@ extern int ln_main(int argc, char **argv)
                exit FALSE;
        }
 
+       if (linkIntoDirFlag == TRUE)
+               dirName = linkName;
+
        while (argc-- >= 2) {
 #if 0
                char srcName[BUFSIZ + 1];
@@ -126,6 +129,14 @@ extern int ln_main(int argc, char **argv)
                        srcName[nChars] = '\0';
                }
 #endif
+               if (linkIntoDirFlag == TRUE) {
+                       char *baseName = get_last_path_component(*argv);
+                       linkName = (char *)malloc(strlen(dirName)+strlen(baseName)+2);
+                       strcpy(linkName, dirName);
+                       if(dirName[strlen(dirName)-1] != '/')
+                               strcat(linkName, "/");
+                       strcat(linkName,baseName);
+               }
 
                if (removeoldFlag == TRUE) {
                        status = (unlink(linkName) && errno != ENOENT);
@@ -143,6 +154,11 @@ extern int ln_main(int argc, char **argv)
                        perror(linkName);
                        exit FALSE;
                }
+
+               if (linkIntoDirFlag)
+                       free(linkName);
+
+               argv++;
        }
        return( TRUE);
 }
index a15ae68dafd56e7789916783f369f4a6ac38bcfa..a313078cfd49c1cbdb22809060012d072291677e 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -1675,6 +1675,23 @@ char process_escape_sequence(char **ptr)
 }
 #endif
 
+#if defined BB_BASENAME || defined BB_LN
+char *get_last_path_component(char *path)
+{
+       char *s=path+strlen(path)-1;
+
+       /* strip trailing slashes */
+       while (s && *s == '/') {
+               *s-- = '\0';
+       }
+
+       /* find last component */
+       s = strrchr(path, '/');
+       if (s==NULL) return path;
+       else return s+1;
+}
+#endif
+
 /* END CODE */
 /*
 Local Variables: