--- /dev/null
+---
+# $Id$
+Language: Cpp
+UseTab: Always
+TabWidth: 8
+IndentWidth: 8
+PointerAlignment: Left
+ColumnLimit: 1024
+AllowShortIfStatementsOnASingleLine: Always
+AllowShortBlocksOnASingleLine: Never
+AllowShortLoopsOnASingleLine: true
+SpaceBeforeParens: Never
+AlignEscapedNewlines: DontAlign
+SortIncludes: false
+AllowShortEnumsOnASingleLine: false
include $(PWD)/Platform/$(PLATFORM).mk
-OBJS = main.o cgi.o util.o version.o
+OBJS = main.o cgi.o util.o version.o man.o
.PHONY: all clean
.SUFFIXES: .c .o
#include "kn_version.h"
#include "kn_util.h"
+#include "kn_man.h"
struct q_entry {
char* key;
bool no = false;
bool showmain = false;
struct q_entry** entries = NULL;
+char* path;
-char* kn_get_query(const char* key){
+char* kn_get_query(const char* key) {
if(entries == NULL) return NULL;
int i;
- for(i = 0; entries[i] != NULL; i++){
- if(strcmp(entries[i]->key, key) == 0 ) return entries[i]->value;
+ for(i = 0; entries[i] != NULL; i++) {
+ if(strcmp(entries[i]->key, key) == 0) return entries[i]->value;
}
return NULL;
}
-char* kn_null(const char* a){
- return a == NULL ? "" : (char*)a;
-}
+char* kn_null(const char* a) { return a == NULL ? "" : (char*)a; }
-void kn_parse_query(void){
+void kn_parse_query(void) {
char* query = getenv("QUERY_STRING");
- if(query != NULL){
+ if(query != NULL) {
entries = malloc(sizeof(*entries));
entries[0] = NULL;
int i;
int incr = 0;
- for(i = 0;; i++){
- if(query[i] == 0 || query[i] == '&'){
+ for(i = 0;; i++) {
+ if(query[i] == 0 || query[i] == '&') {
char* a = malloc(i - incr + 1);
- memcpy(a, query + incr , i - incr);
+ memcpy(a, query + incr, i - incr);
a[i - incr] = 0;
char* key = a;
char* value = "";
int j;
- for(j = 0; key[j] != 0; j++){
- if(key[j] == '='){
+ for(j = 0; key[j] != 0; j++) {
+ if(key[j] == '=') {
key[j] = 0;
value = key + j + 1;
break;
e->value = kn_strdup(value);
struct q_entry** old = entries;
- for(j = 0; old[j] != NULL; j++);
+ for(j = 0; old[j] != NULL; j++)
+ ;
entries = malloc(sizeof(*entries) * (j + 2));
for(j = 0; old[j] != NULL; j++) entries[j] = old[j];
entries[j] = e;
}
}
}
- if(kn_get_query("page") == NULL){
+ if(kn_get_query("page") == NULL) {
printf("Status: 200 OK\n\n");
showmain = true;
- }else{
- printf("Status: 404 Not Found\n\n");
- no = true;
+ } else {
+ if((path = kn_find(MANPAGE_DIR, kn_get_query("page"))) != NULL) {
+ printf("Status: 200 OK\n\n");
+ } else {
+ printf("Status: 404 Not Found\n\n");
+ no = true;
+ }
}
}
-void kn_cgi(void){
+void kn_cgi(void) {
printf("<html>\n");
printf(" <head>\n");
printf(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
printf(" <title>Keine - ");
- if(no){
+ if(no) {
printf("Not found");
- }else if(showmain){
+ } else if(showmain) {
printf("Main");
+ } else {
+ printf("%s", kn_get_query("page"));
}
printf("</title>\n");
printf(" <style>\n");
printf(" </form>\n");
printf(" </div>\n");
printf(" <hr>\n");
- if(no){
+ if(no) {
printf(" Not found.\n");
- }else if(showmain){
+ } else if(showmain) {
+ printf("%s", MAIN_HTML);
+ } else {
+ printf("<pre>");
+ char* c = kn_manpage_process(path);
+ if(c != NULL) {
+ printf("%s", c);
+ free(c);
+ }
+ printf("</pre>\n");
}
printf(" <hr>\n");
- printf(" <i>Generated by Keine <a href=\"http://nishi.boats/keine\">%s</a></i>\n", kn_get_version());
+ printf(" <i>Generated by <a href=\"http://nishi.boats/keine\">Keine</a> %s</i>\n", kn_get_version());
printf(" </body>\n");
printf("</html>\n");
+ if(path != NULL) free(path);
}
--- /dev/null
+/* $Id$ */
+
+#ifndef __KN_MAN_H__
+#define __KN_MAN_H__
+
+#include <stdbool.h>
+
+char* kn_find(const char* root, const char* name);
+char* kn_manpage_process(const char* path);
+bool kn_has_manpage(const char* str);
+
+#endif
#define __KN_UTIL_H__
char* kn_strcat(const char* a, const char* b);
+char* kn_strcat3(const char* a, const char* b, const char* c);
char* kn_strdup(const char* a);
#endif
#include "kn_cgi.h"
-int main(){
+int main() {
printf("Content-Type: text/html\n");
kn_parse_query();
kn_cgi();
--- /dev/null
+/* $Id$ */
+
+#include "../config.h"
+
+#include "kn_man.h"
+
+#include "kn_util.h"
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+char* kn_find(const char* root, const char* name) {
+ DIR* dir = opendir(root);
+ if(dir != NULL) {
+ struct dirent* d;
+ while((d = readdir(dir)) != NULL) {
+ if(strcmp(d->d_name, "..") != 0 && strcmp(d->d_name, ".") != 0) {
+ char* path = kn_strcat3(root, "/", d->d_name);
+ struct stat s;
+ if(stat(path, &s) == 0) {
+ if(S_ISDIR(s.st_mode)) {
+ char* v;
+ if((v = kn_find(path, name)) != NULL) {
+ closedir(dir);
+ return v;
+ }
+ } else if(strcmp(d->d_name, name) == 0) {
+ closedir(dir);
+ return path;
+ }
+ }
+ free(path);
+ }
+ }
+ closedir(dir);
+ }
+ return NULL;
+}
+
+bool kn_has_manpage(const char* str) {
+ char* pth = kn_find(MANPAGE_DIR, str);
+ if(pth == NULL) return false;
+ free(pth);
+ return true;
+}
+
+char* kn_manpage_process(const char* path) {
+ char* b = malloc(1);
+ b[0] = 0;
+ int pipes[2];
+ char cbuf[2];
+ cbuf[1] = 0;
+ pipe(pipes);
+ pid_t pid = fork();
+ if(pid == 0) {
+ close(pipes[0]);
+ dup2(pipes[1], STDOUT_FILENO);
+ execlp("man", "man", path, NULL);
+ _exit(1);
+ } else {
+ close(pipes[1]);
+ char c;
+ bool sta = false;
+ char s = 0;
+ char old = 0;
+ char m = 0;
+ while(1) {
+ if(read(pipes[0], &c, 1) <= 0) break;
+ if(c == 8) {
+ sta = true;
+ } else {
+ if(s != 0) {
+ if(sta) {
+ sta = false;
+ old = s;
+ } else {
+ if(old == 0) {
+ char* tmp;
+ if(m == 'B') {
+ tmp = b;
+ b = kn_strcat(b, "</b>");
+ free(tmp);
+ } else if(m == 'U') {
+ tmp = b;
+ b = kn_strcat(b, "</u>");
+ free(tmp);
+ }
+ m = 0;
+ cbuf[0] = s;
+ tmp = b;
+ b = kn_strcat(b, cbuf);
+ free(tmp);
+ } else {
+ if(old == s) {
+ cbuf[0] = s;
+ char* tmp;
+ if(m == 'U') {
+ tmp = b;
+ b = kn_strcat(b, "</u>");
+ free(tmp);
+ }
+ if(m != 'B') {
+ tmp = b;
+ b = kn_strcat(b, "<b>");
+ free(tmp);
+ }
+ m = 'B';
+ tmp = b;
+ b = kn_strcat(b, cbuf);
+ free(tmp);
+ } else if(old == '_') {
+ cbuf[0] = s;
+ char* tmp;
+ if(m == 'B') {
+ tmp = b;
+ b = kn_strcat(b, "</b>");
+ free(tmp);
+ }
+ if(m != 'U') {
+ tmp = b;
+ b = kn_strcat(b, "<u>");
+ free(tmp);
+ }
+ tmp = b;
+ b = kn_strcat(b, cbuf);
+ free(tmp);
+ tmp = b;
+ b = kn_strcat(b, "</u>");
+ free(tmp);
+ }
+ old = 0;
+ }
+ }
+ }
+ s = c;
+ }
+ }
+ waitpid(pid, 0, 0);
+ char* tmp;
+ if(m == 'B') {
+ tmp = b;
+ b = kn_strcat(b, "</b>");
+ free(tmp);
+ } else if(m == 'U') {
+ tmp = b;
+ b = kn_strcat(b, "</u>");
+ free(tmp);
+ }
+ }
+ return b;
+}
#include <string.h>
#include <stdlib.h>
-char* kn_strcat(const char* a, const char* b){
+char* kn_strcat(const char* a, const char* b) {
char* str = malloc(strlen(a) + strlen(b) + 1);
memcpy(str, a, strlen(a));
memcpy(str + strlen(a), b, strlen(b));
return str;
}
-char* kn_strdup(const char* a){
- return kn_strcat(a, "");
+char* kn_strcat3(const char* a, const char* b, const char* c) {
+ char* tmp = kn_strcat(a, b);
+ char* str = kn_strcat(tmp, c);
+ free(tmp);
+ return str;
}
+
+char* kn_strdup(const char* a) { return kn_strcat(a, ""); }
const char* kn_version = "1.00";
-const char* kn_get_version(void){
- return kn_version;
-}
+const char* kn_get_version(void) { return kn_version; }
FLAGS = PWD=$(PWD) PLATFORM=$(PLATFORM)
-.PHONY: all clean ./CGI
+.PHONY: all format clean ./CGI
./CGI::
$(MAKE) -C $@ $(FLAGS)
+format:
+ clang-format -i --verbose `find . -name "*.c" -or -name "*.h"`
+
clean:
$(MAKE) -C ./CGI $(FLAGS) clean
#ifndef __CONFIG_H__
#define __CONFIG_H__
+/* HTML which gets shown on the main. */
+#define MAIN_HTML "<h1>Index</h1>"
+/* Manual page root */
+#define MANPAGE_DIR "/usr/share/man"
#endif
+
+/*
+vim: syntax=c
+*/