Last active
September 5, 2022 02:58
-
-
Save michaelfm1211/99b754eaafb494dbceb9928ac67491ba to your computer and use it in GitHub Desktop.
cowsay CGI in C (tested with fastcgi+nginx)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ISC License | |
Copyright 2022 Michael M. | |
Permission to use, copy, modify, and/or distribute this software for any purpose | |
with or without fee is hereby granted, provided that the above copyright notice | |
and this permission notice appear in all copies. | |
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | |
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | |
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | |
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
THIS SOFTWARE. | |
*/ | |
#include <ctype.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#define BUF_SIZ 1024 | |
#define COWSAY_CMD "cowsay" | |
#define HTTP_400 "400 Bad Request" | |
#define HTTP_411 "411 Length Required" | |
// Returns an environment variable if it exists. Otherwise, panic with err. | |
const char *assert_env(const char *name, const char *err) { | |
const char *var = getenv(name); | |
if (!var) { | |
printf("Status: %s\n\n", err); | |
exit(1); | |
} | |
return var; | |
} | |
// Remove all non-alphabetic characters from NULL-terminated string str. | |
void sanitize(char *str) { | |
int x = 0; | |
for (int i = 0; str[i]; i++) { | |
if (isalpha(str[i])) | |
str[x++] = str[i]; | |
} | |
str[x] = '\0'; | |
} | |
int main() { | |
const char *req_method = assert_env("REQUEST_METHOD", HTTP_400); | |
if (strcmp(req_method, "POST")) { | |
puts("Status: 501 Not Implemented\n"); | |
return 1; | |
} | |
int len = atoi(assert_env("CONTENT_LENGTH", HTTP_411)) + 1; | |
char req_buf[len]; | |
fgets(req_buf, len, stdin); | |
char *name = "", *line = strtok(req_buf, "\n"); | |
for (; line != NULL; line = strtok(NULL, "\n")) { | |
char *value; | |
char *key = strtok_r(line, "=", &value); | |
if (!strcmp(key, "name")) { | |
name = value; | |
break; | |
} | |
} | |
sanitize(name); | |
char cmd[strlen(name) + sizeof(COWSAY_CMD) + 1]; | |
sprintf(cmd, COWSAY_CMD" Aloha, %s!", name); | |
FILE *cowsayfd = popen(cmd, "r"); | |
puts("Content-Type: text/html\n"); | |
puts("<link rel=\"stylesheet\" href=\"style.css\">"); | |
puts("<main><h1 style=\"white-space: pre; padding: 20px;" | |
"overflow: auto; font-family: monospace;\">"); | |
char cowsay_buf[BUF_SIZ]; | |
while (fgets(cowsay_buf, sizeof(cowsay_buf), cowsayfd)) | |
fputs(cowsay_buf, stdout); | |
puts("\n</h1></main>"); | |
pclose(cowsayfd); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="style.css"> | |
<title>Cowsay Aloha</title> | |
</head> | |
<body> | |
<main> | |
<h1 class="jumo">Aloha, world!</h1> | |
<p> | |
Let me say aloha to you too: | |
</p> | |
<!-- adjust the path of cowsay.cgi to whatever you need --> | |
<form action="/cowsay.cgi" method="POST"> | |
<label for="name">Name: </label> | |
<input type="text" name="name" required> | |
<input type="submit" value="Aloha!"> | |
</form> | |
</main> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Michael's General Purpose CSS Styles. | |
This is neither sepcific to nor required by the CGI script, but it's makes | |
everything look prettier and is nice to have. | |
*/ | |
/* | |
ISC License | |
Copyright 2022 Michael M. | |
Permission to use, copy, modify, and/or distribute this software for any purpose | |
with or without fee is hereby granted, provided that the above copyright notice | |
and this permission notice appear in all copies. | |
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | |
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | |
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | |
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
THIS SOFTWARE. | |
*/ | |
body { | |
line-height :1.6; | |
font-family: sans-serif; | |
color: #444; | |
} | |
main { | |
margin: 40px auto; | |
max-width: 650px; | |
font-size: 18px; | |
padding: 0 10px; | |
} | |
h1,h2,h3 { | |
font-family: monospace; | |
line-height: 1.2; | |
background-color: #EEEEEE; | |
} | |
.jumbo { | |
padding: 1em; | |
overflow: auto; | |
} | |
nav { | |
font-size: 16px; | |
font-family: monospace; | |
padding: 5px; | |
} | |
nav a { | |
color: blue; | |
} | |
.footnote { | |
font-size: 15px; | |
font-style: italic; | |
} | |
input[type="text"] { | |
background: transparent; | |
border-top: none; | |
border-left: none; | |
border-right: none; | |
outline: none; | |
color: #111; | |
padding-left: 3px; | |
padding-right: 3px; | |
} | |
input[type="text"]:hover { | |
border-color: #333; | |
} | |
main input[type="text"] { | |
font-size: 18px; | |
} | |
@media (prefers-color-scheme: dark) { | |
body { | |
color: #cfcfcf; | |
background-color: #1f1f1f; | |
} | |
h1,h2,h3 { | |
background-color: #414141; | |
} | |
a,nav a { | |
color: #56c8ff; | |
} | |
input[type="text"] { | |
color: #EEE; | |
} | |
input[type="text"]:hover { | |
border-color: #CCC; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment