changeset 37:a520c4e74615

category: new C implementation
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 12 Feb 2009 11:57:21 -0500
parents 4955e2383f0a
children 61090f874175
files .gitignore Makefile category.c html.c html.h
diffstat 5 files changed, 122 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.gitignore	Fri Feb 06 22:15:36 2009 -0500
+++ b/.gitignore	Thu Feb 12 11:57:21 2009 -0500
@@ -1,5 +1,8 @@
 index
 story
 archive
+category
 
 tags
+
+.*.swp
--- a/Makefile	Fri Feb 06 22:15:36 2009 -0500
+++ b/Makefile	Thu Feb 12 11:57:21 2009 -0500
@@ -3,7 +3,7 @@
 
 FILES=sar.c post.c xattr.c html.c dir.c
 
-all: story index archive
+all: story index archive category
 
 clean:
 	rm -f story index
@@ -16,3 +16,6 @@
 
 archive: archive.c $(FILES)
 	$(CC) $(CFLAGS) -o $@ archive.c $(FILES)
+
+category: category.c $(FILES)
+	$(CC) $(CFLAGS) -o $@ category.c $(FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/category.c	Thu Feb 12 11:57:21 2009 -0500
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "post.h"
+#include "sar.h"
+#include "html.h"
+
+#define HDD_START	0
+#define HDD_1DOT	1
+#define HDD_2DOT	2
+#define HDD_OK		3
+
+int hasdotdot(char *path)
+{
+	int state = HDD_START;
+	char tmp;
+
+	while(*path) {
+		tmp = *path;
+
+		switch(tmp) {
+			case '.':
+				if (state == HDD_START)
+					state = HDD_1DOT;
+				else if (state == HDD_1DOT)
+					state = HDD_2DOT;
+				else
+					state = HDD_OK;
+				break;
+			case '/':
+				if (state == HDD_2DOT)
+					return 1; /* '/../' found */
+
+				state = HDD_START;
+				break;
+			default:
+				state = HDD_OK;
+				break;
+		}
+
+		path++;
+	}
+
+	return (state == HDD_2DOT);
+}
+
+int main(int argc, char **argv)
+{
+	struct timespec s,e;
+	char *path_info;
+	struct post post;
+
+	clock_gettime(CLOCK_REALTIME, &s);
+
+	memset(&post, 0, sizeof(struct post));
+	post.out = stdout;
+
+	fprintf(post.out, "Content-Type: text/html\n\n");
+
+	path_info = getenv("PATH_INFO");
+
+	if (!path_info) {
+		fprintf(post.out, "Invalid category name\n");
+		return 0;
+	}
+
+	/*
+	 * SECURITY CHECK: make sure no one is trying to give us a '..' in
+	 * the path
+	 */
+	if (hasdotdot(path_info)) {
+		fprintf(post.out, "Go away\n");
+		return 0;
+	}
+
+	post.title = path_info+1;
+
+	html_header(&post);
+	html_category(&post, path_info+1);
+	html_sidebar(&post);
+	html_footer(&post);
+
+	post.title = NULL;
+	destroy_post(&post);
+
+	clock_gettime(CLOCK_REALTIME, &e);
+
+	fprintf(post.out, "<!-- time to render: %ld.%09ld seconds -->\n", (int)e.tv_sec-s.tv_sec,
+		e.tv_nsec-s.tv_nsec+((e.tv_sec-s.tv_sec) ? 1000000000 : 0));
+
+	return 0;
+}
--- a/html.c	Fri Feb 06 22:15:36 2009 -0500
+++ b/html.c	Thu Feb 12 11:57:21 2009 -0500
@@ -133,6 +133,26 @@
 }
 
 /************************************************************************/
+/*                          CATEGORY INDEX                              */
+/************************************************************************/
+void html_category(struct post *post, char *catname)
+{
+	char path[FILENAME_MAX];
+	DIR *dir;
+
+	snprintf(path, FILENAME_MAX, "data/by-category/%s/", catname);
+
+	dir = opendir(path);
+	if (!dir)
+		return;
+
+	sorted_readdir_loop(dir, post, __each_index_helper, NULL, SORT_DESC,
+			    HTML_INDEX_STORIES);
+
+	closedir(dir);
+}
+
+/************************************************************************/
 /*                           POST COMMENTS                              */
 /************************************************************************/
 static void __html_comment(struct post *post, struct comment *comm)
--- a/html.h	Fri Feb 06 22:15:36 2009 -0500
+++ b/html.h	Thu Feb 12 11:57:21 2009 -0500
@@ -6,6 +6,7 @@
 extern void html_story(struct post *post);
 extern void html_index(struct post *post);
 extern void html_archive(struct post *post, int archid);
+extern void html_category(struct post *post, char *catname);
 extern void html_comments(struct post *post);
 extern void html_sidebar(struct post *post);
 extern void html_header(struct post *post);