1 /**
2 * This CGI program renders the oper.io blog
3 * Copyright (C) 2024 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 "cgi.h"
19
20 void cgi_print_header(char* ctype, int status) {
21 printf("Content-type: %s\n", ctype);
22 printf("Status: %d\n", status);
23 printf("\n");
24 }
25
26 void cgi_print_headers() {
27 int i = 0;
28 while(environ[i] != NULL) {
29 if(strncmp(environ[i], "HTTP_", 5) == 0) {
30 puts(environ[i]);
31 }
32 i++;
33 }
34 }
35
36 char* cgi_remote_ip() {
37 if(getenv("HTTP_X_FORWARDED_FOR"))
38 return getenv("HTTP_X_FORWARDED_FOR");
39 else
40 return getenv("REMOTE_ADDR");
41 return NULL;
42 }
43
44 char* cgi_user_agent() {
45 if(getenv("HTTP_USER_AGENT"))
46 return getenv("HTTP_USER_AGENT");
47 return NULL;
48 }
49
50 int cgi_read_qs(struct querystring* q, char* buf) {
51 // If query string is null, probably env var isn't set
52 if(!q->qs)
53 return EOF;
54
55 int i = q->pos;
56 while(q->qs[i] != '\0' && i < QS_MAX) {
57 if(q->qs[i] == '=' || q->qs[i] == '&')
58 break;
59 i++;
60 }
61
62 // Copy section into buffer
63 strncpy(buf, &q->qs[q->pos], i - q->pos);
64 buf[i - q->pos] = '\0';
65
66 // Advance start position to i + 1 to skip the current delimiter
67 q->pos = i + 1;
68
69 if(q->qs[i] == '\0')
70 return EOF;
71
72 return 0;
73 }
74
75
76 /**
77 * cgi_qs_get_val:
78 * Gets the value of the first occurrence of the requested key. Supports more
79 * than one key to allow for easy backwards compatibility without re-traversing
80 * the query string.
81 *
82 * @qs Query string struct
83 * @keys Array of character arrays containing the query string keys
84 * @out Output buffer
85 *
86 * Returns 0 on success, and -1 on failure
87 */
88 int cgi_qs_get_val(struct querystring* qs, char** keys, char* out) {
89 int i = 0;
90 int res = 0;
91 char buf[256];
92
93 while((res = cgi_read_qs(qs, buf)) != EOF) {
94 while(keys[i][0] != '\0') {
95 if(strcmp(buf, keys[i]) == 0) {
96 if(res == EOF)
97 return -1;
98 cgi_read_qs(qs, out);
99 return 0;
100 }
101 i++;
102 }
103 }
104 return -1;
105 }
|