/* * readlink.c - read value of a symbolic link * * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD * * 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. * */ #include #include #include #include #include #include #include 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 (canonicalize) { char *buf = canonicalize_path(argv[optind]); struct stat s; if (!buf) goto err; if (stat(dirname(argv[optind]), &s) || !S_ISDIR(s.st_mode)) { free(buf); goto err; } setenv(argv[optind + 1], buf); free(buf); } else { if (readlink(argv[optind], realname, PATH_MAX - 1) < 0) goto err; setenv(argv[optind + 1], realname); } return 0; err: setenv(argv[optind + 1], ""); return 1; } BAREBOX_CMD_HELP_START(readlink) BAREBOX_CMD_HELP_TEXT("Read value of a symbolic link or canonical file name and store it into VARIABLE.") BAREBOX_CMD_HELP_TEXT("") BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_OPT("-f", "canonicalize by following symlinks;") BAREBOX_CMD_HELP_OPT("", "final component need not exist"); BAREBOX_CMD_HELP_END BAREBOX_CMD_START(readlink) .cmd = do_readlink, BAREBOX_CMD_DESC("read value of a symbolic link or canonical file name") BAREBOX_CMD_OPTS("[-f] FILE VARIABLE") BAREBOX_CMD_GROUP(CMD_GRP_FILE) BAREBOX_CMD_HELP(cmd_readlink_help) BAREBOX_CMD_END