/* * nanobbs, a tiny forums software. * Copyright (C) 2025-2026 Xavier Del Campo Romero * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #define _POSIX_C_SOURCE 200809L #include "endpoints.h" #include "defs.h" #include #include #include #include #include #include #include int ep_style(const struct http_payload *const p, struct http_response *const r, void *const user) { int ret = -1; FILE *f = NULL; const struct cfg *const cfg = user; const char *const dir = cfg->dir; struct dynstr d; struct stat sb; dynstr_init(&d); if (!dir) { fprintf(stderr, "%s: auth_dir failed\n", __func__); goto end; } else if (dynstr_append(&d, "%s/" STYLE_PATH, dir)) { fprintf(stderr, "%s: dynstr_append failed\n", __func__); goto end; } else if (stat(d.str, &sb)) { fprintf(stderr, "%s: stat(2) %s: %s\n", __func__, d.str, strerror(errno)); goto end; } else if (!(f = fopen(d.str, "rb"))) { fprintf(stderr, "%s: fopen(3) %s: %s\n", __func__, dir, strerror(errno)); goto end; } *r = (const struct http_response) { .status = HTTP_STATUS_OK, .f = f, .n = sb.st_size }; if (http_response_add_header(r, "Content-Type", "text/css")) { fprintf(stderr, "%s: http_response_add_header failed\n", __func__); goto end; } ret = 0; end: if (ret && f && fclose(f)) fprintf(stderr, "%s: fclose(3) %s: %s\n", __func__, dir, strerror(errno)); dynstr_free(&d); return ret; }