diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-05 12:59:29 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-05 12:59:29 +0200 |
commit | e5a927883ea8f85e2258d5e15ac6ede8f44aeaab (patch) | |
tree | 1798a5dc8008c29d688093783e6bece1094cedbc /commands | |
parent | 62b665b6442c493eb2537d1c5f6c8925a2ce73bf (diff) | |
parent | 42d3d24c7152462f7bb40056255ebcfffa8dbd9f (diff) | |
download | barebox-e5a927883ea8f85e2258d5e15ac6ede8f44aeaab.tar.gz barebox-e5a927883ea8f85e2258d5e15ac6ede8f44aeaab.tar.xz |
Merge branch 'for-next/link'
Diffstat (limited to 'commands')
-rw-r--r-- | commands/Kconfig | 10 | ||||
-rw-r--r-- | commands/Makefile | 2 | ||||
-rw-r--r-- | commands/dirname.c | 24 | ||||
-rw-r--r-- | commands/ln.c | 51 | ||||
-rw-r--r-- | commands/ls.c | 31 | ||||
-rw-r--r-- | commands/readlink.c | 80 | ||||
-rw-r--r-- | commands/test.c | 11 |
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"; |