1 /**
2 * This CGI program renders the oper.io blog
3 * Copyright (C) 2019 Aaron Ball <nullspoon@oper.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "common.h"
23 #include "cgi.h"
24 #include "j2.h"
25
26 #define TITLE_MAX 512
27
28
29 int html_read_title(char* path, char* out) {
30 char buf[TITLE_MAX];
31 int i = 4;
32 FILE* fd;
33 fd = fopen(path, "r");
34 if(!fd)
35 return 2;
36 fgets(buf, TITLE_MAX, fd);
37 fclose(fd);
38
39 if(strncmp(buf, "<h1>", 4) != 0)
40 return -1;
41
42 while(buf[i] != '\0' && i < TITLE_MAX) {
43 if(strncmp(&buf[i], "</h1>", 5) == 0) {
44 strncpy(out, &buf[4], i - 4);
45 out[i-4] = '\0';
46 return 1;
47 }
48 i++;
49 }
50
51 return -1;
52 }
53
54
55 int main(int argc, char* argv[], char* envp[]) {
56 char buf[256];
57 char path[512];
58 int status = 200;
59
60 // Space for title assembly
61 char titlebuf[TITLE_MAX] = {'\0'};
62 char title[TITLE_MAX + 2] = {'\0'};
63
64 // Required environment variables
65 char* header = getenv("INDEX_HEADER");
66 char* footer = getenv("INDEX_FOOTER");
67 char* posts = getenv("INDEX_POSTS");
68
69 // List of supported query string key names
70 char* keys[] = {"q", "p", "title", "\0"};
71 // Parse the query string (if present)
72 struct querystring qs;
73 qs.qs = getenv("QUERY_STRING");
74 qs.pos = 0;
75
76 // If no title specified (return non-zero), default to "index"
77 if(cgi_qs_get_val(&qs, keys, buf) != 0)
78 strcpy(buf, "index");
79
80 // If the IP address was requested
81 if(strncmp(buf, "ip", 2) == 0) {
82 cgi_print_header("text/plain", 200);
83 printf("%s\n", cgi_remote_ip());
84 return 0;
85 }
86
87 // If the remote agent was requested
88 if(strncmp(buf, "agent", 5) == 0) {
89 cgi_print_header("text/plain", 200);
90 printf("%s\n", cgi_user_agent());
91 return 0;
92 }
93
94 // Assemble the page path
95 sprintf(path, "%s/%s.html", posts, buf);
96
97 // If the file does not exist, set status to 404 and set the page to be
98 // printed to the 404 page.
99 if(file_exists(path) == 2) {
100 status = 404;
101 sprintf(path, "%s/%s.html", posts, "404");
102 strcpy(title, ": 404");
103 }
104
105 // Anything below this gets printed. Make sure all variables are set and
106 // logic completed before here.
107 cgi_print_header("text/html", status);
108
109 // The specified page exists, attempt to read the title
110 html_read_title(path, titlebuf);
111 sprintf(title, ": %s", titlebuf);
112 setenv("PAGE_TITLE", title, 1);
113
114 j2_cat(header);
115 catfile(path);
116 j2_cat(footer);
117 fflush(stdout);
118
119 return 0;
120 }
|