Mercurial > blahgd
changeset 13:76cee581f48b
story: work in progress
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Wed, 04 Feb 2009 01:14:15 -0500 |
parents | b5ea996aa617 |
children | 06b2d0a67c4d |
files | Makefile html.c html.h post.c post.h sar.c sar.h story.c xattr.c xattr.h |
diffstat | 10 files changed, 454 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,9 @@ +CC=gcc +CFLAGS=-Wall -g -O2 + +FILES=sar.c post.c xattr.c html.c + +all: story + +story: story.c $(FILES) + $(CC) $(CFLAGS) -o $@ story.c $(FILES)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/html.c Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,75 @@ +#include <stdio.h> + +#include "sar.h" +#include "html.h" + +/************************************************************************/ +/* POST */ +/************************************************************************/ +void html_story(struct post *post) +{ + cat(post, "templates/story-top.html", repltab_html); + +#if 0 + for_each_category(post) + cat(stdout, "templates/story-cat-item.html", repltab_html); +#endif + + cat(post, "templates/story-middle.html", repltab_html); + + cat_post(post); + + cat(post, "templates/story-bottom.html", NULL); +} + +/************************************************************************/ +/* POST COMMENTS */ +/************************************************************************/ +void html_comments(struct post *post) +{ + cat(post, "templates/story-comment-head.html", repltab_html); + +#if 0 + for_each_comment(post) { + cat(post, "templates/story-comment-item-head.html", repltab_html); + cat_post_comment(post, commentid); + cat(post, "templates/story-comment-item-tail.html", repltab_html); + } +#endif + + cat(post, "templates/story-comment-tail.html", repltab_html); +} + +/************************************************************************/ +/* SIDEBAR */ +/************************************************************************/ +void html_sidebar(struct post *post) +{ + cat(post, "templates/sidebar-top.html", repltab_html); +#if 0 + for_each_category() + cat(post, "templates/sidebar-cat-item.html", repltab_html); +#endif + cat(post, "templates/sidebar-middle.html", repltab_html); +#if 0 + for_each_month() + cat(post, "templates/sidebar-archive-item.html", repltab_html); +#endif + cat(post, "templates/sidebar-bottom.html", repltab_html); +} + +/************************************************************************/ +/* PAGE HEADER */ +/************************************************************************/ +void html_header(struct post *post) +{ + cat(post, "templates/header.html", repltab_html); +} + +/************************************************************************/ +/* PAGE FOOTER */ +/************************************************************************/ +void html_footer(struct post *post) +{ + cat(post, "templates/footer.html", repltab_html); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/html.h Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,12 @@ +#ifndef __HTML_H +#define __HTML_H + +#include "post.h" + +extern void html_story(struct post *post); +extern void html_comments(struct post *post); +extern void html_sidebar(struct post *post); +extern void html_header(struct post *post); +extern void html_footer(struct post *post); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/post.c Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,119 @@ +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <errno.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +#include "post.h" +#include "xattr.h" +#include "sar.h" + +void cat(struct post *post, char *tmpl, struct repltab_entry *repltab) +{ + struct stat statbuf; + char *ibuf; + int ret; + int fd; + + fd = open(tmpl, O_RDONLY); + if (fd == -1) { + fprintf(post->out, "template open error\n"); + return; + } + + ret = fstat(fd, &statbuf); + if (ret == -1) { + fprintf(post->out, "fstat failed\n"); + goto out_close; + } + + ibuf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (ibuf == MAP_FAILED) { + fprintf(post->out, "mmap failed\n"); + goto out_close; + } + + sar(post, ibuf, statbuf.st_size, repltab); + + munmap(ibuf, statbuf.st_size); + +out_close: + close(fd); +} + +void cat_post(struct post *post) +{ + char path[FILENAME_MAX]; + struct stat statbuf; + char *ibuf; + int ret; + int fd; + + snprintf(path, FILENAME_MAX, "data/posts/%d/post.txt", post->id); + + fd = open(path, O_RDONLY); + if (fd == -1) { + fprintf(post->out, "post.txt open error\n"); + return; + } + + ret = fstat(fd, &statbuf); + if (ret == -1) { + fprintf(post->out, "fstat failed\n"); + goto out_close; + } + + ibuf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (ibuf == MAP_FAILED) { + fprintf(post->out, "mmap failed\n"); + goto out_close; + } + + /* FIXME: do <p> insertion, etc. */ + fwrite(ibuf, 1, statbuf.st_size, post->out); + + munmap(ibuf, statbuf.st_size); + +out_close: + close(fd); +} + +int load_post(int postid, struct post *post) +{ + char path[FILENAME_MAX]; + + snprintf(path, FILENAME_MAX, "data/posts/%d", postid); + + post->id = postid; + post->title = safe_getxattr(path, XATTR_TITLE); + post->cats = safe_getxattr(path, XATTR_CATS); + post->time = safe_getxattr(path, XATTR_TIME); + + if (post->title && post->time) + return 0; + + destroy_post(post); + return ENOMEM; +} + +void destroy_post(struct post *post) +{ + free(post->title); + free(post->cats); + free(post->time); +} + +void dump_post(struct post *post) +{ + if (!post) + fprintf(stdout, "p=NULL\n"); + else + fprintf(post->out, "p=%p { %d, '%s', '%s', '%s' }\n\n", + post, post->id, post->title, post->cats, + post->time); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/post.h Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,25 @@ +#ifndef __POST_H +#define __POST_H + +struct post { + FILE *out; + int id; + char *title; + char *cats; + char *time; +}; + +#define XATTR_TITLE "user.post_title" +#define XATTR_CATS "user.post_cats" +#define XATTR_TIME "user.post_time" + +extern int load_post(int postid, struct post *post); +extern void dump_post(struct post *post); +extern void destroy_post(struct post *post); + +struct repltab_entry; + +extern void cat_post(struct post *post); +extern void cat(struct post *post, char *tmpl, struct repltab_entry *repltab); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sar.c Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,133 @@ +#include <stdio.h> +#include <string.h> + +#include "post.h" +#include "sar.h" + +static void echo_postid(struct post *post) +{ + fprintf(post->out, "%d", post->id); +} + +static void echo_title(struct post *post) +{ + fprintf(post->out, "%s", post->title); +} + +static void echo_posttime(struct post *post) +{ + fprintf(post->out, "||posttime||"); +} + +static void echo_postdate(struct post *post) +{ + fprintf(post->out, "||postdate||"); +} + +static struct repltab_entry __repltab_html[] = { + {"POSTID", echo_postid}, + {"POSTDATE", echo_postdate}, + {"POSTTIME", echo_posttime}, + {"TITLE", echo_title}, + {"", NULL}, +}; + +struct repltab_entry *repltab_html = __repltab_html; + +static int invoke_repl(struct post *post, char *cmd, + struct repltab_entry *repltab) +{ + int i; + + if (!repltab) + return 1; + + for(i=0; repltab[i].f; i++) { + if (strcmp(cmd, repltab[i].what)) + continue; + + repltab[i].f(post); + return 0; + } + + return 1; +} + +#define SAR_NORMAL 0 +#define SAR_WAIT1 1 +#define SAR_WAIT2 2 +#define SAR_SPECIAL 3 +#define SAR_ERROR 4 + +#define COPYCHAR(ob, oi, c) do { \ + ob[oi] = c; \ + oi++; \ + } while(0) + +void sar(struct post *post, char *ibuf, int size, + struct repltab_entry *repltab) +{ + char obuf[size]; + char cmd[16]; + int iidx, oidx, cidx; + int state = SAR_NORMAL; + char tmp; + + for(iidx = oidx = cidx = 0; (iidx < size) && (state != SAR_ERROR); iidx++) { + tmp = ibuf[iidx]; +#if 0 + fprintf(post->out, "\n| cur '%c', state %d| ", tmp, state); +#endif + + switch(state) { + case SAR_NORMAL: + if (tmp == '@') + state = SAR_WAIT1; + else + COPYCHAR(obuf, oidx, tmp); + break; + + case SAR_WAIT1: + if (tmp == '@') { + state = SAR_SPECIAL; + COPYCHAR(obuf, oidx, '\0'); + fprintf(post->out, obuf); + oidx = 0; + } else { + state = SAR_NORMAL; + COPYCHAR(obuf, oidx, '@'); + COPYCHAR(obuf, oidx, tmp); + } + break; + + case SAR_SPECIAL: + if (tmp != '@' && cidx < 16) + COPYCHAR(cmd, cidx, tmp); + else if (tmp != '@' && cidx >= 16) + state = SAR_ERROR; + else + state = SAR_WAIT2; + break; + + case SAR_WAIT2: + if (tmp != '@') + state = SAR_ERROR; + else { + COPYCHAR(cmd, cidx, '\0'); + if (invoke_repl(post, cmd, repltab)) + fprintf(post->out, "@@%s@@", cmd); + cidx = 0; + state = SAR_NORMAL; + } + break; + } + } + + if (state == SAR_ERROR) + fprintf(post->out, "\n====================\nSAR error!\n"); + + if (oidx) { + COPYCHAR(obuf, oidx, '\0'); + fprintf(post->out, obuf); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sar.h Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,16 @@ +#ifndef __SAR_H +#define __SAR_H + +#include "post.h" + +struct repltab_entry { + char what[16]; + void (*f)(struct post*); +}; + +extern void sar(struct post *post, char *ibuf, int size, + struct repltab_entry *repltab); + +struct repltab_entry *repltab_html; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/story.c Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "post.h" +#include "sar.h" +#include "html.h" + +int main(int argc, char **argv) +{ + struct post post; + int ret; + + post.out = stdout; + + fprintf(post.out, "Content-Type: text/html\n\n"); + + ret = load_post(30, &post); + if (ret) { + fprintf(post.out, "Gah! %d\n", ret); + return 0; + } + + html_header(&post); + html_story(&post); + html_comments(&post); + html_sidebar(&post); + html_footer(&post); + + destroy_post(&post); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xattr.c Wed Feb 04 01:14:15 2009 -0500 @@ -0,0 +1,26 @@ +#include <stdlib.h> + +#include <sys/types.h> +#include <attr/xattr.h> + +char *safe_getxattr(char *path, char *attr_name) +{ + ssize_t size; + char *buf; + + size = getxattr(path, attr_name, NULL, 0); + if (size == -1) + return NULL; + + buf = malloc(size+1); + if (!buf) + return NULL; + + size = getxattr(path, attr_name, buf, size+1); + if (size == -1) { + free(buf); + return NULL; + } + + return buf; +}