#include "config.h" #include #include #include #include #include #include #include #include #include "indexer.h" #include "formatting.h" void html_error(int code, char *why) { int err = errno; syslog(LOG_ERR, "%m"); printf("HTTP/1.0 %03d %s\r\n", code, why); puts("content-type: text/html\r\n" "\r\n" "\n" "Aaaaiieee!\n" "\n" "
OH, NO!
"); if (code == 503) puts(strerror(err)); else puts(why); puts("
\n" ""); exit(1); } char *text, *title; static struct article *art; int help; char *p, *q; int rows; int complain = 0; struct passwd *user; int didpara = 0; int printenv = 0; char *author = 0; char *bbspath = ""; char *bbsroot = ""; char *username = 0; char *script = 0; char *filename = 0; int editing = 0; int preview = 0; int comments_ok = 0; static int boolenv(char *s) { return getenv(s) != 0; } static char * xgetenv(char *s) { char *val = getenv(s); if (val && val[0]) return val; return 0; } static void putbody(FILE *f) { fputs("
\n", f); if ( (editing||preview) && (art->size > 1)) { fputs("
\n", f); article(f, art, editing ? FM_COOKED : (FM_PREVIEW|FM_IMAGES)); fputs("
\n" "
\n", f); rows=10; } else { rows=24; } fprintf(f, "
\n", script); fputs("
Subject title) fprintf(f, " VALUE=\"%s\"", art->title); fputs(">\n", f); if (complain && !art->title) fputs("Please enter a subject\n", f); fputs("
\n", f); fprintf(f, "
\n" "\n", f); if (complain && !art->body) fputs("
Please enter a message\n", f); fputs("
\n", f); fputs("
\n" "Allow comments" "
\n",f); fputs("
\n", f); fprintf(f, "\n", art->comments); if (preview || editing) fprintf(f,"\n"); if (editing) { fprintf(f, "\n"); fprintf(f, "url); } fprintf(f, "\n"); fprintf(f, "\n" "\n" "\n", editing ? "Save" : "Post"); fputs("
", f); if (editing) help = 0; else fprintf(f, "\n", help ? "nohelp" : "needhelp", help ? "Hide Help" : "Show Help"); fputs("
\n", f); if (help) fputs("

\n" " *text* boldfaces text; \n" " _text_ italicizes text; \n" " blank line starts a new paragraph; \n" " {pic:url} displays the picture at url
\n" " {url}{title} makes title a" " link to url
\n" "
", f); } main(int argc, char **argv) { FILE *theme; char *themfile; char *bbsdir = "/"; char *filetoedit = 0; register c; struct article scratch; char *p; openlog("bbs_post", LOG_PID, LOG_NEWS); opterr = 0; while ( (c = getopt(argc, argv, "d:eu:A:S:")) != EOF) { switch (c) { case 'S': script = optarg; break; case 'A': author = optarg; break; case 'd': bbsdir = optarg; break; case 'u': username = optarg; break; case 'e': printenv=1; break; } } bbsroot = malloc(strlen(bbsdir)+2); strcpy(bbsroot, bbsdir); if (bbsroot[0] && bbsroot[strlen(bbsroot)-1] != '/') strcat(bbsroot, "/"); stash("weblog",bbsroot); stash("_ROOT", bbsroot); if ( (bbsdir[0] == '/') && (bbsdir[1] == '~') ) { char *r = strchr(bbsdir+2, '/'); username = bbsdir+2; if (r) { *r++ = 0; bbsdir = r; } else bbsdir = ""; } if ( username) { if ( (user = getpwnam(username)) == 0 ) html_error(500, "User does not exist"); if (user->pw_uid == 0 || user->pw_gid == 0) html_error(500, "User cannot be root"); bbspath = malloc(strlen(user->pw_dir) + strlen(PATH_USERDIR) + strlen(bbsdir) + 4); if (bbspath == 0) html_error(503, "Out of memory!"); if (setgid(user->pw_gid) || setuid(user->pw_uid)) html_error(503, "Privilege confusion"); sprintf(bbspath, "%s/%s/%s", user->pw_dir, PATH_USERDIR, bbsdir); } else { bbspath = malloc(strlen(PATH_WWWDIR) + strlen(bbsdir) + 3); if (bbspath == 0) html_error(503, "Out of memory!"); sprintf(bbspath, "%s/%s", PATH_WWWDIR, bbsdir); } if (chdir(bbspath) != 0) html_error(503, bbspath); readconfig(bbspath); uncgi(); if (!script) script = xgetenv("SCRIPT_NAME"); if ( author == 0 && (author = xgetenv("REMOTE_USER")) == 0) html_error(500, "I don't know who you are!"); if ( (text = xgetenv("WWW_text")) && (*text == 0) ) text = 0; preview = boolenv("WWW_previewing") | boolenv("WWW_preview"); title = xgetenv("WWW_title"); comments_ok = 0; if ( editing = boolenv("WWW_edit") ) { char *filetoedit; if ( filetoedit = xgetenv("WWW_url")) { if ( (art = openart(filetoedit)) == 0) html_error(404, filetoedit); else if (text) { freeartbody(art); art->body = text; art->size = strlen(text); } comments_ok = art->comments_ok; } else editing = 0; } if (boolenv("WWW_more")) comments_ok = boolenv("WWW_commentsok"); if (!art) { char *p; memset(&scratch, 0, sizeof scratch); art = &scratch; art->body = text; art->size = text ? strlen(text) : 0; art->author = author; art->title = title; art->url = xgetenv("WWW_url"); time(&art->timeofday); } art->comments_ok = comments_ok; if (p = xgetenv("WWW_post")) { if (art->author && art->title && art->body) { int res ; if (editing) res = edit(art, bbspath); else res = post(art, bbspath); syslog(LOG_INFO, "res (%s) is %d", editing?"edit":"post", res); if (res) { printf("HTTP/1.0 307 Ok\r\n" "Location: %s/post\n" "\n", bbsroot); exit(0); } } complain = (strcmp(p, "New Message") != 0); } else if (xgetenv("WWW_cancel")) { printf("HTTP/1.0 307 Ok\n" "Location: %s/post\n" "\n", bbsroot); exit(0); } help = boolenv("WWW_needhelp"); if ( (themfile = alloca(strlen(bbspath) + 20)) == 0 ) html_error(503, "Out of memory!"); printf("Content-Type: text/html; charset=iso-8859-1\r\n" "Connection: close\r\n" "Server: %s\r\n" "Cache-Control: no-cache\r\n" "\r\n", script); stash("_DOCUMENT", script); stash("_USER", author); stash("title", editing ? "Edit Article" : "New Article"); sprintf(themfile, "%s/post.theme", bbspath); process(themfile, putbody, 1, stdout); if (printenv) { printf("\n"); } exit(0); }