aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-24 02:39:23 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-03-28 03:15:27 +0200
commitfa97b1904c72c184b09c627c7ccab0d0db4a060c (patch)
tree917ec45c58dd1c55caa96aef6133a19ba68ab453 /main.c
parent30d31e8c9d98b5641954207a909b531d9fc922c5 (diff)
downloadslcl-imagemagick.tar.gz
WIP thumbnail stuffimagemagick
Diffstat (limited to 'main.c')
-rw-r--r--main.c214
1 files changed, 157 insertions, 57 deletions
diff --git a/main.c b/main.c
index 66328a8..b411a0f 100644
--- a/main.c
+++ b/main.c
@@ -5,7 +5,9 @@
#include "handler.h"
#include "hex.h"
#include "http.h"
+#include "mkdir_r.h"
#include "page.h"
+#include "thumbnail.h"
#include <openssl/err.h>
#include <openssl/rand.h>
#include <dynstr.h>
@@ -643,58 +645,54 @@ static int check_length(const unsigned long long len,
static int getnode(const struct http_payload *const p,
struct http_response *const r, void *const user)
{
+ int ret = -1;
struct auth *const a = user;
+ const char *adir, *const username = p->cookie.field;
+ struct dynstr d;
+
+ dynstr_init(&d);
if (auth_cookie(a, &p->cookie))
{
fprintf(stderr, "%s: auth_cookie failed\n", __func__);
- return page_forbidden(r);
- }
-
- const char *const username = p->cookie.field,
- *const resource = p->resource + strlen("/user/");
-
- if (path_isrel(resource))
- {
- fprintf(stderr, "%s: illegal relative path %s\n", __func__, resource);
- return page_forbidden(r);
+ ret = page_forbidden(r);
+ goto end;
}
-
- int ret = -1;
- struct dynstr dir, root, d;
- const char *const adir = auth_dir(a),
- *const sep = p->resource[strlen(p->resource) - 1] != '/' ? "/" : "";
-
- dynstr_init(&dir);
- dynstr_init(&d);
- dynstr_init(&root);
-
- if (!adir)
+ else if (path_isrel(p->resource))
{
- fprintf(stderr, "%s: auth_dir failed\n", __func__);
+ fprintf(stderr, "%s: illegal relative path %s\n",
+ __func__, p->resource);
+ ret = page_forbidden(r);
goto end;
}
- else if (dynstr_append(&dir, "%s%s", p->resource, sep))
+ else if (!(adir = auth_dir(a)))
{
- fprintf(stderr, "%s: dynstr_append dird failed\n", __func__);
+ fprintf(stderr, "%s: auth_dir failed\n", __func__);
goto end;
}
- else if (dynstr_append(&root, "%s/user/%s/", adir, username)
- || dynstr_append(&d, "%s%s", root.str, resource))
+ else if (dynstr_append(&d, "%s/user/%s/", adir, username))
{
fprintf(stderr, "%s: dynstr_append failed\n", __func__);
goto end;
}
+ const struct page_resource res =
+ {
+ .root = adir,
+ .username = username,
+ .user_root = d.str,
+ .res = p->resource + strlen("/user")
+ };
+
bool available;
unsigned long long cur, max;
- if (auth_quota(a, username, &available, &max))
+ if (auth_quota(a, res.username, &available, &max))
{
fprintf(stderr, "%s: quota_available failed\n", __func__);
goto end;
}
- else if (available && quota_current(a, username, &cur))
+ else if (available && quota_current(a, res.username, &cur))
{
fprintf(stderr, "%s: quota_current failed\n", __func__);
goto end;
@@ -707,12 +705,10 @@ static int getnode(const struct http_payload *const p,
.max = max
} : NULL;
- ret = page_resource(r, dir.str, root.str, d.str, ppq);
+ ret = page_resource(r, &res, ppq);
end:
- dynstr_free(&dir);
dynstr_free(&d);
- dynstr_free(&root);
return ret;
}
@@ -797,25 +793,84 @@ static int rename_or_move(const char *const old, const char *const new)
return res;
}
+static int ensure_dir(const char *const dir)
+{
+ struct stat sb;
+
+ if (stat(dir, &sb))
+ {
+ switch (errno)
+ {
+ case ENOENT:
+ if (mkdir(dir, S_IRWXU))
+ {
+ fprintf(stderr, "%s: mkdir(2) %s: %s\n",
+ __func__, dir, strerror(errno));
+ return -1;
+ }
+
+ printf("Created empty directory at %s\n", dir);
+ break;
+
+ default:
+ fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno));
+ return -1;
+ }
+ }
+ else if (!S_ISDIR(sb.st_mode))
+ {
+ fprintf(stderr, "%s: %s not a directory\n", __func__, dir);
+ return -1;
+ }
+
+ return 0;
+}
+
static int upload_file(const struct http_post_file *const f,
const char *const user, const char *const root, const char *const dir)
{
int ret = -1;
- struct dynstr d;
+ struct dynstr d, dird, th;
dynstr_init(&d);
+ dynstr_init(&dird);
+ dynstr_init(&th);
if (!root)
{
fprintf(stderr, "%s: auth_dir failed\n", __func__);
goto end;
}
- else if (dynstr_append(&d, "%s/user/%s/%s%s", root, user, dir, f->filename))
+ else if (dynstr_append(&d, "%s/user/%s%s%s", root, user, dir, f->filename))
{
fprintf(stderr, "%s: dynstr_append failed\n", __func__);
goto end;
}
- else if (rename_or_move(f->tmpname, d.str))
+ else if (thumbnail_configured())
+ {
+ if (dynstr_append(&dird, "%s/thumbnails/%s%s", root, user, dir))
+ {
+ fprintf(stderr, "%s: dynstr_append dird failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_append(&th, "%s%s", dird.str, f->filename))
+ {
+ fprintf(stderr, "%s: dynstr_append th failed\n", __func__);
+ goto end;
+ }
+ else if (mkdir_r(dird.str, S_IRWXU))
+ {
+ fprintf(stderr, "%s: ensure_dir failed\n", __func__);
+ goto end;
+ }
+ else if (thumbnail_create(f->tmpname, th.str) < 0)
+ {
+ fprintf(stderr, "%s: thumbnail_create failed\n", __func__);
+ goto end;
+ }
+ }
+
+ if (rename_or_move(f->tmpname, d.str))
{
fprintf(stderr, "%s: rename_or_move failed\n", __func__);
goto end;
@@ -825,6 +880,8 @@ static int upload_file(const struct http_post_file *const f,
end:
dynstr_free(&d);
+ dynstr_free(&dird);
+ dynstr_free(&th);
return ret;
}
@@ -1129,47 +1186,74 @@ static int parse_args(const int argc, char *const argv[],
return 0;
}
-static int ensure_dir(const char *const dir)
+static int getthumbnail(const struct http_payload *const p,
+ struct http_response *const r, void *const user)
{
- struct stat sb;
+ int ret = -1;
+ struct auth *const a = user;
+ struct dynstr d, dir;
+ char *name;
- if (stat(dir, &sb))
+ dynstr_init(&d);
+ dynstr_init(&dir);
+
+ if (auth_cookie(a, &p->cookie))
{
- switch (errno)
- {
- case ENOENT:
- if (mkdir(dir, S_IRWXU))
- {
- fprintf(stderr, "%s: mkdir(2) %s: %s\n",
- __func__, dir, strerror(errno));
- return -1;
- }
+ fprintf(stderr, "%s: auth_cookie failed\n", __func__);
+ ret = page_forbidden(r);
+ goto end;
+ }
- printf("Created empty directory at %s\n", dir);
- break;
+ const char *const adir = auth_dir(a);
- default:
- fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno));
- return -1;
- }
+ if (!adir)
+ {
+ fprintf(stderr, "%s: auth_dir failed\n", __func__);
+ goto end;
}
- else if (!S_ISDIR(sb.st_mode))
+ else if (dynstr_append(&d, "%s%s", adir, p->resource))
{
- fprintf(stderr, "%s: %s not a directory\n", __func__, dir);
- return -1;
+ fprintf(stderr, "%s: dynstr_append failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_dup(&dir, &d))
+ {
+ fprintf(stderr, "%s: dynstr_dup failed\n", __func__);
+ goto end;
+ }
+ else if (!(name = dirname(dir.str)))
+ {
+ fprintf(stderr, "%s: dirname(3) failed\n", __func__);
+ goto end;
+ }
+ else if (ensure_dir(name))
+ {
+ fprintf(stderr, "%s: ensure_dir failed\n", __func__);
+ goto end;
+ }
+ else if (page_thumbnail(r, d.str))
+ {
+ fprintf(stderr, "%s: page_public failed\n", __func__);
+ goto end;
}
- return 0;
+ ret = 0;
+
+end:
+ dynstr_free(&d);
+ dynstr_free(&dir);
+ return ret;
}
static int init_dirs(const char *const dir)
{
int ret = -1;
- struct dynstr user, public;
+ struct dynstr user, public, thumbnails;
struct sb;
dynstr_init(&user);
dynstr_init(&public);
+ dynstr_init(&thumbnails);
if (dynstr_append(&user, "%s/user", dir))
{
@@ -1196,12 +1280,26 @@ static int init_dirs(const char *const dir)
fprintf(stderr, "%s: ensure_dir public failed\n", __func__);
goto end;
}
+ if (thumbnail_configured())
+ {
+ if (dynstr_append(&thumbnails, "%s/thumbnails", dir))
+ {
+ fprintf(stderr, "%s: dynstr_append thumbnails failed\n", __func__);
+ goto end;
+ }
+ else if (ensure_dir(thumbnails.str))
+ {
+ fprintf(stderr, "%s: ensure_dir thumbnails failed\n", __func__);
+ goto end;
+ }
+ }
ret = 0;
end:
dynstr_free(&user);
dynstr_free(&public);
+ dynstr_free(&thumbnails);
return ret;
}
@@ -1237,6 +1335,8 @@ int main(const int argc, char *const argv[])
|| handler_add(h, "/share", HTTP_OP_POST, share, a)
|| handler_add(h, "/upload", HTTP_OP_POST, upload, a)
|| handler_add(h, "/mkdir", HTTP_OP_POST, createdir, a)
+ || (thumbnail_configured()
+ && handler_add(h, "/thumbnails/*", HTTP_OP_GET, getthumbnail, a))
|| handler_listen(h, port))
goto end;