aboutsummaryrefslogtreecommitdiff
path: root/auth.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-25 09:57:19 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-25 09:57:19 +0100
commitee6809eac527e101a077bc1d10e2acce96754ca8 (patch)
tree01c24a000496fefac37d06c79d67bc4e06f8f7a6 /auth.c
parent09a157d307f3dd766912a203347069b11fed1aa1 (diff)
auth.c: Ensure absolute path for a->dir
Otherwise, slcl would create broken symbolic links if the user passes a relative path as command line argument.
Diffstat (limited to 'auth.c')
-rw-r--r--auth.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/auth.c b/auth.c
index 5ea6a3b..e6f86fe 100644
--- a/auth.c
+++ b/auth.c
@@ -510,14 +510,51 @@ static int init_db(struct auth *const a)
return 0;
}
+static char *resolve_cwd(void)
+{
+ size_t len = 1;
+ char *p = NULL;
+
+ for (;;)
+ {
+ char *const pp = realloc(p, len);
+
+ if (!pp)
+ {
+ fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno));
+ break;
+ }
+
+ p = pp;
+
+ if (!getcwd(pp, len))
+ {
+ if (errno != ERANGE)
+ {
+ fprintf(stderr, "%s: getcwd(3): %s\n",
+ __func__, strerror(errno));
+ break;
+ }
+ else
+ len++;
+ }
+ else
+ return p;
+ }
+
+ free(p);
+ return NULL;
+}
+
struct auth *auth_alloc(const char *const dir)
{
- struct auth *const a = malloc(sizeof *a);
+ struct auth *const a = malloc(sizeof *a), *ret = NULL;
+ char *abspath = NULL;
if (!a)
{
fprintf(stderr, "%s: malloc(3) auth: %s\n", __func__, strerror(errno));
- goto failure;
+ goto end;
}
*a = (const struct auth){0};
@@ -525,25 +562,39 @@ struct auth *auth_alloc(const char *const dir)
dynstr_init(&a->db);
dynstr_init(&a->dir);
- if (dynstr_append(&a->dir, "%s", dir))
+ if (*dir != '/' && !(abspath = resolve_cwd()))
{
- fprintf(stderr, "%s: dynstr_append failed\n", __func__);
- goto failure;
+ fprintf(stderr, "%s: resolve_cwd failed\n", __func__);
+ goto end;
}
- else if (dynstr_append(&a->db, "%s/db.json", dir))
+ else if (abspath && dynstr_append(&a->dir, "%s", abspath))
{
- fprintf(stderr, "%s: dynstr_append failed\n", __func__);
- goto failure;
+ fprintf(stderr, "%s: dynstr_append abspath failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_append(&a->dir, "%s%s", abspath ? "/" : "", dir))
+ {
+ fprintf(stderr, "%s: dynstr_append dir failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_append(&a->db, "%s/db.json", a->dir.str))
+ {
+ fprintf(stderr, "%s: dynstr_append db failed\n", __func__);
+ goto end;
}
else if (init_db(a))
{
fprintf(stderr, "%s: init_db failed\n", __func__);
- goto failure;
+ goto end;
}
- return a;
+ ret = a;
-failure:
- auth_free(a);
- return NULL;
+end:
+ free(abspath);
+
+ if (!ret)
+ auth_free(a);
+
+ return ret;
}