aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c41
-rw-r--r--page.c2
-rw-r--r--page.h1
3 files changed, 31 insertions, 13 deletions
diff --git a/main.c b/main.c
index 3959295..aa57c5e 100644
--- a/main.c
+++ b/main.c
@@ -487,15 +487,13 @@ end:
return ret;
}
-static char *create_symlink(const char *const username, const char *const dir,
- const char *const path)
+static char *create_symlink(const char *const dir, const char *user)
{
char *ret = NULL;
unsigned char buf[16];
char dbuf[1 + 2 * sizeof buf];
- struct dynstr user, abs, rel;
+ struct dynstr abs, rel;
- dynstr_init(&user);
dynstr_init(&abs);
dynstr_init(&rel);
@@ -510,11 +508,6 @@ static char *create_symlink(const char *const username, const char *const dir,
fprintf(stderr, "%s: hex_encode failed\n", __func__);
goto end;
}
- else if (dynstr_append(&user, "%s/user/%s%s", dir, username, path))
- {
- fprintf(stderr, "%s: dynstr_append user failed\n", __func__);
- goto end;
- }
else if (dynstr_append(&rel, "/public/%s", dbuf))
{
fprintf(stderr, "%s: dynstr_append rel failed\n", __func__);
@@ -525,7 +518,7 @@ static char *create_symlink(const char *const username, const char *const dir,
fprintf(stderr, "%s: dynstr_append abs failed\n", __func__);
goto end;
}
- else if (symlink(user.str, abs.str))
+ else if (symlink(user, abs.str))
{
fprintf(stderr, "%s: symlink(2): %s\n", __func__, strerror(errno));
goto end;
@@ -534,7 +527,6 @@ static char *create_symlink(const char *const username, const char *const dir,
ret = rel.str;
end:
- dynstr_free(&user);
dynstr_free(&abs);
if (!ret)
@@ -806,6 +798,9 @@ static int share(const struct http_payload *const p,
struct form *forms = NULL;
size_t n = 0;
char *sympath = NULL;
+ struct dynstr userpath;
+
+ dynstr_init(&userpath);
if ((ret = get_forms(p, &forms, &n)))
{
@@ -824,6 +819,7 @@ static int share(const struct http_payload *const p,
}
const char *const path = forms->value, *const username = p->cookie.field;
+ struct stat sb;
if (path_invalid(path))
{
@@ -831,7 +827,27 @@ static int share(const struct http_payload *const p,
ret = page_bad_request(r);
goto end;
}
- else if (!(sympath = create_symlink(username, adir, path)))
+ else if (dynstr_append(&userpath, "%s/user/%s%s", adir, username, path))
+ {
+ fprintf(stderr, "%s: dynstr_append user failed\n", __func__);
+ goto end;
+ }
+ else if (stat(userpath.str, &sb))
+ {
+ fprintf(stderr, "%s: stat(2) %s: %s\n", __func__, userpath.str,
+ strerror(errno));
+
+ if (errno == ENOENT || errno == ENOTDIR)
+ ret = page_not_found(r);
+
+ goto end;
+ }
+ else if (!S_ISREG(sb.st_mode))
+ {
+ ret = page_bad_request(r);
+ goto end;
+ }
+ else if (!(sympath = create_symlink(adir, userpath.str)))
{
fprintf(stderr, "%s: create_symlink failed\n", __func__);
goto end;
@@ -847,6 +863,7 @@ static int share(const struct http_payload *const p,
end:
forms_free(forms, n);
free(sympath);
+ dynstr_free(&userpath);
return ret;
}
diff --git a/page.c b/page.c
index 0d15473..c103f4a 100644
--- a/page.c
+++ b/page.c
@@ -1626,7 +1626,7 @@ end:
return ret;
}
-static int page_not_found(struct http_response *const r)
+int page_not_found(struct http_response *const r)
{
static const char body[] =
DOCTYPE_TAG
diff --git a/page.h b/page.h
index 22658fd..ca7f3cc 100644
--- a/page.h
+++ b/page.h
@@ -42,6 +42,7 @@ int page_style(struct http_response *r, const char *path);
int page_failed_login(struct http_response *r);
int page_forbidden(struct http_response *r);
int page_bad_request(struct http_response *r);
+int page_not_found(struct http_response *r);
int page_resource(const struct page_resource *r);
int page_head_resource(struct http_response *r, const char *res);
int page_public(struct http_response *r, const char *res);