From 4f7d9bf759bc38fc363155643e9b7bb8fcdf0724 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Wed, 13 Jun 2018 12:37:59 +0200 Subject: POTD skeleton #104. Signed-off-by: Toni Uhlig --- src/options.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/options.c') diff --git a/src/options.c b/src/options.c index 0f23f4d..a9b96f7 100644 --- a/src/options.c +++ b/src/options.c @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #include "options.h" @@ -99,6 +102,37 @@ static size_t snprint_multilined_ljust(const char *prefix, static void usage(const char *arg0, int print_copyright); +static int parse_path(opt_ptr *d, char *some_path) +{ + int rc = 1; + char path[PATH_MAX]; + char *dir, *base; + + d->str_dup = realpath(some_path, NULL); + if (!d->str_dup && errno == ENOENT) { + snprintf(path, sizeof path, "%s", some_path); + dir = dirname(path); + if (!dir) + return 1; + dir = realpath(dir, NULL); + if (!dir) + return 1; + snprintf(path, sizeof path, "%s", some_path); + base = basename(path); + if (!base) + goto error; + snprintf(path, sizeof path, "%s/%s", dir, base); + d->str_dup = strndup(path, strnlen(path, sizeof path)); +error: + free(dir); + } + + if (d->str_dup) + rc = 0; + + return rc; +} + static int opt_convert(opt_type t, opt_ptr *d) { char *endptr = NULL; @@ -114,7 +148,8 @@ static int opt_convert(opt_type t, opt_ptr *d) d->str_dup = strdup(optarg); break; case OT_PATH: - d->str_dup = realpath(optarg, NULL); + if (parse_path(d, optarg)) + return 1; break; case OT_NOARG: case OT_INVALID: -- cgit v1.2.3