diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-03-24 02:39:23 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-03-28 03:15:27 +0200 |
| commit | fa97b1904c72c184b09c627c7ccab0d0db4a060c (patch) | |
| tree | 917ec45c58dd1c55caa96aef6133a19ba68ab453 /main.c | |
| parent | 30d31e8c9d98b5641954207a909b531d9fc922c5 (diff) | |
| download | slcl-imagemagick.tar.gz | |
WIP thumbnail stuffimagemagick
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 214 |
1 files changed, 157 insertions, 57 deletions
@@ -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; |
