git-svn-id: file:///raid/svn-personal/keine/trunk@4 a3977ea8-0dc0-2842-9144-a1a46b47fd40
This commit is contained in:
Nishi 2024-09-11 10:22:22 +00:00
parent c34e7fc8fd
commit 0f3f8bdcd2
11 changed files with 249 additions and 33 deletions

15
.clang-format Normal file
View File

@ -0,0 +1,15 @@
---
# $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

View File

@ -2,7 +2,7 @@
include $(PWD)/Platform/$(PLATFORM).mk 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 .PHONY: all clean
.SUFFIXES: .c .o .SUFFIXES: .c .o

View File

@ -11,6 +11,7 @@
#include "kn_version.h" #include "kn_version.h"
#include "kn_util.h" #include "kn_util.h"
#include "kn_man.h"
struct q_entry { struct q_entry {
char* key; char* key;
@ -20,39 +21,38 @@ struct q_entry {
bool no = false; bool no = false;
bool showmain = false; bool showmain = false;
struct q_entry** entries = NULL; 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; if(entries == NULL) return NULL;
int i; int i;
for(i = 0; entries[i] != NULL; i++){ for(i = 0; entries[i] != NULL; i++) {
if(strcmp(entries[i]->key, key) == 0 ) return entries[i]->value; if(strcmp(entries[i]->key, key) == 0) return entries[i]->value;
} }
return NULL; return NULL;
} }
char* kn_null(const char* a){ char* kn_null(const char* a) { return a == NULL ? "" : (char*)a; }
return a == NULL ? "" : (char*)a;
}
void kn_parse_query(void){ void kn_parse_query(void) {
char* query = getenv("QUERY_STRING"); char* query = getenv("QUERY_STRING");
if(query != NULL){ if(query != NULL) {
entries = malloc(sizeof(*entries)); entries = malloc(sizeof(*entries));
entries[0] = NULL; entries[0] = NULL;
int i; int i;
int incr = 0; int incr = 0;
for(i = 0;; i++){ for(i = 0;; i++) {
if(query[i] == 0 || query[i] == '&'){ if(query[i] == 0 || query[i] == '&') {
char* a = malloc(i - incr + 1); char* a = malloc(i - incr + 1);
memcpy(a, query + incr , i - incr); memcpy(a, query + incr, i - incr);
a[i - incr] = 0; a[i - incr] = 0;
char* key = a; char* key = a;
char* value = ""; char* value = "";
int j; int j;
for(j = 0; key[j] != 0; j++){ for(j = 0; key[j] != 0; j++) {
if(key[j] == '='){ if(key[j] == '=') {
key[j] = 0; key[j] = 0;
value = key + j + 1; value = key + j + 1;
break; break;
@ -64,7 +64,8 @@ void kn_parse_query(void){
e->value = kn_strdup(value); e->value = kn_strdup(value);
struct q_entry** old = entries; 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)); entries = malloc(sizeof(*entries) * (j + 2));
for(j = 0; old[j] != NULL; j++) entries[j] = old[j]; for(j = 0; old[j] != NULL; j++) entries[j] = old[j];
entries[j] = e; entries[j] = e;
@ -78,24 +79,30 @@ void kn_parse_query(void){
} }
} }
} }
if(kn_get_query("page") == NULL){ if(kn_get_query("page") == NULL) {
printf("Status: 200 OK\n\n"); printf("Status: 200 OK\n\n");
showmain = true; showmain = true;
}else{ } else {
printf("Status: 404 Not Found\n\n"); if((path = kn_find(MANPAGE_DIR, kn_get_query("page"))) != NULL) {
no = true; 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("<html>\n");
printf(" <head>\n"); printf(" <head>\n");
printf(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"); printf(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
printf(" <title>Keine - "); printf(" <title>Keine - ");
if(no){ if(no) {
printf("Not found"); printf("Not found");
}else if(showmain){ } else if(showmain) {
printf("Main"); printf("Main");
} else {
printf("%s", kn_get_query("page"));
} }
printf("</title>\n"); printf("</title>\n");
printf(" <style>\n"); printf(" <style>\n");
@ -124,12 +131,22 @@ void kn_cgi(void){
printf(" </form>\n"); printf(" </form>\n");
printf(" </div>\n"); printf(" </div>\n");
printf(" <hr>\n"); printf(" <hr>\n");
if(no){ if(no) {
printf(" Not found.\n"); 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(" <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(" </body>\n");
printf("</html>\n"); printf("</html>\n");
if(path != NULL) free(path);
} }

12
CGI/kn_man.h Normal file
View File

@ -0,0 +1,12 @@
/* $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

View File

@ -4,6 +4,7 @@
#define __KN_UTIL_H__ #define __KN_UTIL_H__
char* kn_strcat(const char* a, const char* b); 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); char* kn_strdup(const char* a);
#endif #endif

View File

@ -4,7 +4,7 @@
#include "kn_cgi.h" #include "kn_cgi.h"
int main(){ int main() {
printf("Content-Type: text/html\n"); printf("Content-Type: text/html\n");
kn_parse_query(); kn_parse_query();
kn_cgi(); kn_cgi();

157
CGI/man.c Normal file
View File

@ -0,0 +1,157 @@
/* $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;
}

View File

@ -5,7 +5,7 @@
#include <string.h> #include <string.h>
#include <stdlib.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); char* str = malloc(strlen(a) + strlen(b) + 1);
memcpy(str, a, strlen(a)); memcpy(str, a, strlen(a));
memcpy(str + strlen(a), b, strlen(b)); memcpy(str + strlen(a), b, strlen(b));
@ -13,6 +13,11 @@ char* kn_strcat(const char* a, const char* b){
return str; return str;
} }
char* kn_strdup(const char* a){ char* kn_strcat3(const char* a, const char* b, const char* c) {
return kn_strcat(a, ""); 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, ""); }

View File

@ -4,6 +4,4 @@
const char* kn_version = "1.00"; const char* kn_version = "1.00";
const char* kn_get_version(void){ const char* kn_get_version(void) { return kn_version; }
return kn_version;
}

View File

@ -5,10 +5,13 @@ PLATFORM = generic
FLAGS = PWD=$(PWD) PLATFORM=$(PLATFORM) FLAGS = PWD=$(PWD) PLATFORM=$(PLATFORM)
.PHONY: all clean ./CGI .PHONY: all format clean ./CGI
./CGI:: ./CGI::
$(MAKE) -C $@ $(FLAGS) $(MAKE) -C $@ $(FLAGS)
format:
clang-format -i --verbose `find . -name "*.c" -or -name "*.h"`
clean: clean:
$(MAKE) -C ./CGI $(FLAGS) clean $(MAKE) -C ./CGI $(FLAGS) clean

View File

@ -3,6 +3,14 @@
#ifndef __CONFIG_H__ #ifndef __CONFIG_H__
#define __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 #endif
/*
vim: syntax=c
*/