/** * This CGI program renders the oper.io blog * Copyright (C) 2024 Aaron Ball * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "common.h" #include "cgi.h" #include "j2.h" int handle_special(char* querystring) { if(strncmp(querystring, "ip", 2) == 0) { // If the IP address was requested cgi_print_header("text/plain", 200); puts(cgi_remote_ip()); return 0; } else if(strncmp(querystring, "agent", 5) == 0) { // If the remote agent was requested cgi_print_header("text/plain", 200); puts(cgi_user_agent()); return 0; } else if(strncmp(querystring, "headers", 5) == 0) { // If client headers requested cgi_print_header("text/plain", 200); cgi_print_headers(); return 0; } return -1; } int handle_page(char* querystring) { char path[512] = {0}; int status = 200; // Space for title assembly char titlebuf[TITLE_MAX] = {'\0'}; char title[TITLE_MAX + 2] = {'\0'}; // Required environment variables char* header = getenv("INDEX_HEADER"); char* footer = getenv("INDEX_FOOTER"); char* posts = getenv("INDEX_POSTS"); // Assemble the page path sprintf(path, "%s/%s.html", posts, querystring); // If the file does not exist, attempt to read the 404 page instead // Return -1 if 404 page does not exist if(access(path, F_OK) != 0) { sprintf(path, "%s/404.html", posts); if(access(path, F_OK) != 0) return -1; status = 404; strcpy(title, ": 404"); } // Anything below this gets printed. Make sure all variables are set and // logic completed before here. cgi_print_header("text/html", status); // The specified page exists, attempt to read the title html_read_title(path, titlebuf); sprintf(title, "%s", titlebuf); setenv("PAGE_TITLE", title, 1); j2_cat(header); j2_cat(path); j2_cat(footer); fflush(stdout); return 0; } int main(int argc, char* argv[], char* envp[]) { char buf[256] = {0}; char* keys[] = {"q", "p", "title", "\0"}; // Supported query string key names struct querystring qs; // Parse the query string (if present) qs.qs = getenv("QUERY_STRING"); qs.pos = 0; // If no title specified (return non-zero), default to "index" if(cgi_qs_get_val(&qs, keys, buf) != 0) strcpy(buf, "index"); if(handle_special(buf) == 0) return 0; if(handle_page(buf) == 0) return 0; // All attempts to recognize the request have failed. Return generic 404. cgi_print_header("text/html", 404); setenv("PAGE_TITLE", "404 Not Found", 1); puts("404 Not Found"); fflush(stdout); return 0; }