summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-09-05 12:59:29 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-09-05 12:59:29 +0200
commite5a927883ea8f85e2258d5e15ac6ede8f44aeaab (patch)
tree1798a5dc8008c29d688093783e6bece1094cedbc /commands
parent62b665b6442c493eb2537d1c5f6c8925a2ce73bf (diff)
parent42d3d24c7152462f7bb40056255ebcfffa8dbd9f (diff)
downloadbarebox-e5a927883ea8f85e2258d5e15ac6ede8f44aeaab.tar.gz
barebox-e5a927883ea8f85e2258d5e15ac6ede8f44aeaab.tar.xz
Merge branch 'for-next/link'
Diffstat (limited to 'commands')
-rw-r--r--commands/Kconfig10
-rw-r--r--commands/Makefile2
-rw-r--r--commands/dirname.c24
-rw-r--r--commands/ln.c51
-rw-r--r--commands/ls.c31
-rw-r--r--commands/readlink.c80
-rw-r--r--commands/test.c11
7 files changed, 194 insertions, 15 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index 92a8152905..337f545058 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -57,6 +57,10 @@ config CMD_READLINE
tristate
prompt "readline"
+config CMD_LN
+ tristate
+ prompt "ln"
+
config CMD_TRUE
tristate
default y
@@ -220,6 +224,12 @@ config CMD_DIRNAME
Strip last component of file name and store the result in a
environment variable
+config CMD_READLINK
+ tristate
+ prompt "readlink"
+ help
+ read value of a symbolic link
+
endmenu
menu "console "
diff --git a/commands/Makefile b/commands/Makefile
index e9157bfcc7..ccebd7f559 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -72,3 +72,5 @@ obj-$(CONFIG_CMD_AUTOMOUNT) += automount.o
obj-$(CONFIG_CMD_GLOBAL) += global.o
obj-$(CONFIG_CMD_BASENAME) += basename.o
obj-$(CONFIG_CMD_DIRNAME) += dirname.o
+obj-$(CONFIG_CMD_READLINK) += readlink.o
+obj-$(CONFIG_CMD_LN) += ln.o
diff --git a/commands/dirname.c b/commands/dirname.c
index cf1d0a022d..f34d88d0fc 100644
--- a/commands/dirname.c
+++ b/commands/dirname.c
@@ -24,20 +24,38 @@
#include <command.h>
#include <libgen.h>
#include <environment.h>
+#include <fs.h>
+#include <getopt.h>
static int do_dirname(int argc, char *argv[])
{
- if (argc != 3)
+ int opt;
+ int path_fs = 0;
+ int len = 0;
+
+ while ((opt = getopt(argc, argv, "V")) > 0) {
+ switch (opt) {
+ case 'V':
+ path_fs = 1;
+ break;
+ }
+ }
+
+ if (argc < optind + 2)
return COMMAND_ERROR_USAGE;
- setenv(argv[2], dirname(argv[1]));
+ if (path_fs)
+ len = strlen(get_mounted_path(argv[optind]));
+
+ setenv(argv[optind + 1], dirname(argv[optind]) + len);
return 0;
}
BAREBOX_CMD_HELP_START(dirname)
-BAREBOX_CMD_HELP_USAGE("dirname NAME DIRNAME\n")
+BAREBOX_CMD_HELP_USAGE("dirname [-V] NAME DIRNAME\n")
BAREBOX_CMD_HELP_SHORT("strip last componext of NAME and store into $DIRNAME\n")
+BAREBOX_CMD_HELP_SHORT("-V return the path relative to the mountpoint.\n")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(dirname)
diff --git a/commands/ln.c b/commands/ln.c
new file mode 100644
index 0000000000..0237447ae4
--- /dev/null
+++ b/commands/ln.c
@@ -0,0 +1,51 @@
+/*
+ * ln.c - make links between files
+ *
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <libgen.h>
+#include <environment.h>
+#include <fs.h>
+#include <errno.h>
+
+static int do_ln(int argc, char *argv[])
+{
+ if (argc != 3)
+ return COMMAND_ERROR_USAGE;
+
+ if (symlink(argv[1], argv[2]) < 0) {
+ perror("ln");
+ return 1;
+ }
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(ln)
+BAREBOX_CMD_HELP_USAGE("ln SRC DEST\n")
+BAREBOX_CMD_HELP_SHORT("symlink - make a new name for a file\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(ln)
+ .cmd = do_ln,
+ .usage = "symlink - make a new name for a file",
+ BAREBOX_CMD_HELP(cmd_ln_help)
+BAREBOX_CMD_END
diff --git a/commands/ls.c b/commands/ls.c
index fbcbadcd08..d36ef578c9 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -29,13 +29,24 @@
#include <getopt.h>
#include <stringlist.h>
-static void ls_one(const char *path, struct stat *s)
+static void ls_one(const char *path, const char* fullname, struct stat *s)
{
char modestr[11];
unsigned int namelen = strlen(path);
mkmodestr(s->st_mode, modestr);
- printf("%s %10llu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
+ printf("%s %10llu %*.*s", modestr, s->st_size, namelen, namelen, path);
+
+ if (S_ISLNK(s->st_mode)) {
+ char realname[PATH_MAX];
+
+ memset(realname, 0, PATH_MAX);
+
+ if (readlink(fullname, realname, PATH_MAX - 1) >= 0)
+ printf(" -> %s", realname);
+ }
+
+ puts("\n");
}
int ls(const char *path, ulong flags)
@@ -48,14 +59,14 @@ int ls(const char *path, ulong flags)
string_list_init(&sl);
- if (stat(path, &s))
+ if (lstat(path, &s))
return -errno;
if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
printf("%s:\n", path);
if (!(s.st_mode & S_IFDIR)) {
- ls_one(path, &s);
+ ls_one(path, path, &s);
return 0;
}
@@ -65,12 +76,12 @@ int ls(const char *path, ulong flags)
while ((d = readdir(dir))) {
sprintf(tmp, "%s/%s", path, d->d_name);
- if (stat(tmp, &s))
+ if (lstat(tmp, &s))
goto out;
if (flags & LS_COLUMN)
string_list_add_sorted(&sl, d->d_name);
else
- ls_one(d->d_name, &s);
+ ls_one(d->d_name, tmp, &s);
}
closedir(dir);
@@ -97,7 +108,7 @@ int ls(const char *path, ulong flags)
continue;
sprintf(tmp, "%s/%s", path, d->d_name);
- if (stat(tmp, &s))
+ if (lstat(tmp, &s))
goto out;
if (s.st_mode & S_IFDIR) {
char *norm = normalise_path(tmp);
@@ -146,7 +157,7 @@ static int do_ls(int argc, char *argv[])
/* first pass: all files */
while (o < argc) {
- ret = stat(argv[o], &s);
+ ret = lstat(argv[o], &s);
if (ret) {
printf("%s: %s: %s\n", argv[0],
argv[o], errno_str());
@@ -158,7 +169,7 @@ static int do_ls(int argc, char *argv[])
if (flags & LS_COLUMN)
string_list_add_sorted(&sl, argv[o]);
else
- ls_one(argv[o], &s);
+ ls_one(argv[o], argv[o], &s);
}
o++;
@@ -173,7 +184,7 @@ static int do_ls(int argc, char *argv[])
/* second pass: directories */
while (o < argc) {
- ret = stat(argv[o], &s);
+ ret = lstat(argv[o], &s);
if (ret) {
o++;
continue;
diff --git a/commands/readlink.c b/commands/readlink.c
new file mode 100644
index 0000000000..d2671e0f2e
--- /dev/null
+++ b/commands/readlink.c
@@ -0,0 +1,80 @@
+/*
+ * readlink.c - read value of a symbolic link
+ *
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <libgen.h>
+#include <environment.h>
+#include <fs.h>
+#include <malloc.h>
+#include <getopt.h>
+
+static int do_readlink(int argc, char *argv[])
+{
+ char realname[PATH_MAX];
+ int canonicalize = 0;
+ int opt;
+
+ memset(realname, 0, PATH_MAX);
+
+ while ((opt = getopt(argc, argv, "f")) > 0) {
+ switch (opt) {
+ case 'f':
+ canonicalize = 1;
+ break;
+ }
+ }
+
+ if (argc < optind + 2)
+ return COMMAND_ERROR_USAGE;
+
+ if (readlink(argv[optind], realname, PATH_MAX - 1) < 0)
+ goto err;
+
+ if (canonicalize) {
+ char *buf = normalise_link(argv[optind], realname);
+
+ if (!buf)
+ goto err;
+ setenv(argv[optind + 1], buf);
+ free(buf);
+ } else {
+ setenv(argv[optind + 1], realname);
+ }
+
+ return 0;
+err:
+ setenv(argv[optind + 1], "");
+ return 1;
+}
+
+BAREBOX_CMD_HELP_START(readlink)
+BAREBOX_CMD_HELP_USAGE("readlink [-f] FILE REALNAME\n")
+BAREBOX_CMD_HELP_SHORT("read value of a symbolic link and store into $REALNAME\n")
+BAREBOX_CMD_HELP_SHORT("-f canonicalize by following first symlink");
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(readlink)
+ .cmd = do_readlink,
+ .usage = "read value of a symbolic link",
+ BAREBOX_CMD_HELP(cmd_readlink_help)
+BAREBOX_CMD_END
diff --git a/commands/test.c b/commands/test.c
index 9ffa892524..18eeaab8c1 100644
--- a/commands/test.c
+++ b/commands/test.c
@@ -43,6 +43,7 @@ typedef enum {
OPT_DIRECTORY,
OPT_FILE,
OPT_EXISTS,
+ OPT_SYMBOLIC_LINK,
OPT_MAX,
} test_opts;
@@ -62,6 +63,7 @@ static char *test_options[] = {
[OPT_FILE] = "-f",
[OPT_DIRECTORY] = "-d",
[OPT_EXISTS] = "-e",
+ [OPT_SYMBOLIC_LINK] = "-L",
};
static int parse_opt(const char *opt)
@@ -140,9 +142,10 @@ static int do_test(int argc, char *argv[])
case OPT_FILE:
case OPT_DIRECTORY:
case OPT_EXISTS:
+ case OPT_SYMBOLIC_LINK:
adv = 2;
if (ap[1] && *ap[1] != ']' && strlen(ap[1])) {
- expr = stat(ap[1], &statbuf);
+ expr = (opt == OPT_SYMBOLIC_LINK ? lstat : stat)(ap[1], &statbuf);
if (expr < 0) {
expr = 0;
break;
@@ -160,6 +163,10 @@ static int do_test(int argc, char *argv[])
expr = 1;
break;
}
+ if (opt == OPT_SYMBOLIC_LINK && S_ISLNK(statbuf.st_mode)) {
+ expr = 1;
+ break;
+ }
}
break;
@@ -224,7 +231,7 @@ static const char *test_aliases[] = { "[", NULL};
static const __maybe_unused char cmd_test_help[] =
"Usage: test [OPTIONS]\n"
-"options: !, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n, -d, -e, -f\n"
+"options: !, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n, -d, -e, -f, -L\n"
"see 'man test' on your PC for more information.\n";
static const __maybe_unused char cmd_test_usage[] = "minimal test like /bin/sh";