diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-06-13 12:37:59 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-06-13 12:37:59 +0200 |
commit | 4f7d9bf759bc38fc363155643e9b7bb8fcdf0724 (patch) | |
tree | 2032a3aacd3a8d57fd2d0b85c3a449bbfb74bf69 /src/options.c | |
parent | 436983fe412b9e764f6bec422317b8588d175a86 (diff) |
POTD skeleton #104.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/options.c')
-rw-r--r-- | src/options.c | 37 |
1 files changed, 36 insertions, 1 deletions
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 <string.h> #include <assert.h> #include <getopt.h> +#include <linux/limits.h> +#include <libgen.h> +#include <errno.h> #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: |