From Matt Kraai <kraai@alumni.carnegiemellon.edu>:
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
diff --git a/basename.c b/basename.c
index ac371d2..fa15aa9 100644
--- a/basename.c
+++ b/basename.c
@@ -43,14 +43,7 @@
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 @@
printf("%s\n", s);
return(TRUE);
}
-
diff --git a/coreutils/basename.c b/coreutils/basename.c
index ac371d2..fa15aa9 100644
--- a/coreutils/basename.c
+++ b/coreutils/basename.c
@@ -43,14 +43,7 @@
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 @@
printf("%s\n", s);
return(TRUE);
}
-
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 57e412d..beaa58f 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -52,7 +52,7 @@
extern int ln_main(int argc, char **argv)
{
- char *linkName;
+ char *linkName, *dirName;
int linkIntoDirFlag;
int stopIt = FALSE;
@@ -104,6 +104,9 @@
exit FALSE;
}
+ if (linkIntoDirFlag == TRUE)
+ dirName = linkName;
+
while (argc-- >= 2) {
#if 0
char srcName[BUFSIZ + 1];
@@ -126,6 +129,14 @@
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 @@
perror(linkName);
exit FALSE;
}
+
+ if (linkIntoDirFlag)
+ free(linkName);
+
+ argv++;
}
return( TRUE);
}
diff --git a/internal.h b/internal.h
index 362df32..a4772b8 100644
--- a/internal.h
+++ b/internal.h
@@ -259,6 +259,7 @@
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 57e412d..beaa58f 100644
--- a/ln.c
+++ b/ln.c
@@ -52,7 +52,7 @@
extern int ln_main(int argc, char **argv)
{
- char *linkName;
+ char *linkName, *dirName;
int linkIntoDirFlag;
int stopIt = FALSE;
@@ -104,6 +104,9 @@
exit FALSE;
}
+ if (linkIntoDirFlag == TRUE)
+ dirName = linkName;
+
while (argc-- >= 2) {
#if 0
char srcName[BUFSIZ + 1];
@@ -126,6 +129,14 @@
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 @@
perror(linkName);
exit FALSE;
}
+
+ if (linkIntoDirFlag)
+ free(linkName);
+
+ argv++;
}
return( TRUE);
}
diff --git a/utility.c b/utility.c
index a15ae68..a313078 100644
--- a/utility.c
+++ b/utility.c
@@ -1675,6 +1675,23 @@
}
#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: