#include "config.h" #include #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); } struct passwd *user; char *bbspath = ""; char *bbsroot = ""; int fillin = 0; int printenv = 0; int preview = 0; int help = 0; char *text = 0; char *script = 0; char *siteowner = 0; char *name = 0; char *email = 0; char *website = 0; char *url = 0; static void putbody(FILE *f) { int rows; char *p; fputs("
\n", f); if (fillin) { fprintf(f, "

Please enter your name, email or website,\n"); fprintf(f, "and some text.

\n"); } fprintf(f, "\n", preview, text ? strlen(text) : 0); if ( preview && text && (strlen(text) > 1) ) { fputs("
\n", f); format(f, text, FM_BLOCKED); fputs("
\n" "
\n", f); rows=10; } else { rows=24; } fprintf(f, "
\n", script); fprintf(f, "\n", url); fprintf(f, "
Name" "\n", name ? name : ""); if (fillin && !name) fprintf(f, " Please enter your name\n"); fprintf(f, "
Email" "\n", email ? email : ""); if (fillin && !email) fprintf(f, " Please enter your email address\n"); fprintf(f, "
Website " "\n", website ? website : ""); if (fillin && !email) fprintf(f, " Please enter your website\n"); if (fillin && !text) fprintf(f, "

Please enter a message

\n"); fprintf(f, "
\n" "\n" "
\n", f); fputs("
\n", f); if (preview) fprintf(f, "\n"); fprintf(f, "\n" "\n" "\n"); if (help) fprintf(f, "\n"); fprintf(f, "\n", help ? "Hide Help" : "Show Help"); fputs("
\n" "\n", f); if (help) fputs("

\n" " *text* boldfaces text; \n" " _text_ italicizes text; \n" " a blank line starts a new paragraph\n" "
", f); } int comment(char *from, char *email, char *website, char *text, char *article) { struct article *art; int len = strlen(article); char *base = strrchr(article, '/'); FILE *out; time_t now; struct tm *tm, *today; int buildflags = PG_ARCHIVE; if ( (art = openart(article)) == 0) { syslog(LOG_ERR, "openart(%s): %m", article); return 0; } else if (art->comments_ok == 0) { syslog(LOG_INFO, "comment_ok is FALSE"); freeart(art); return 0; } if ( (out = fopen(art->cmtfile, "a")) == 0) { syslog(LOG_ERR, "cannot open [%s]: %m", art->cmtfile); return 0; } flock(fileno(out), LOCK_EX); fprintf(out, "
\n"); if (art->comments > 0) fputs(fmt.commentsep, out); format(out, text, FM_BLOCKED); fprintf(out, "
\n"); fprintf(out, "
\n"); if (email || website) { if (website) { if (strncasecmp(website, "http://", 7) == 0) fprintf(out, "%s\n", website, from); else fprintf(out, "%s\n", website, from); } else fprintf(out, "%s\n", email, from); } else fprintf(out, "%s ", from); time(&now); fputs(ctime(&now), out); fprintf(out, "
\n"); fflush(out); art->comments++; tm = localtime( &(art->timeofday) ); today = localtime( &now ); if ( (tm->tm_year == today->tm_year) && (tm->tm_mon == today->tm_mon) ) buildflags |= (PG_HOME|PG_POST); writectl(art); writehtml(art); generate(tm,bbspath,0,buildflags); flock(fileno(out), LOCK_UN); fclose(out); return 1; } static char * xgetenv(char *e) { char *p = getenv(e); if (p && strlen(p)) { while (isspace(*p) && *p) ++p; return (*p) ? p : 0; } return 0; } main(int argc, char **argv, char **envp) { FILE *theme; char *themfile; char *bbsdir = "/"; register c; char *p; static char *item[] = { "WWW_text", "WWW_name", "WWW_email", "WWW_website", "WWW_preview", "WWW_url", "WWW_help", 0 }; openlog("comment", LOG_PID, LOG_NEWS); fillin = 0; opterr = 0; while ( (c = getopt(argc, argv, "d:eu:A:S:")) != EOF) { switch (c) { case 'S': script = optarg; break; case 'A': siteowner = optarg; break; case 'd': bbsdir = optarg; break; case 'u': siteowner = 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, '/'); siteowner = bbsdir+2; if (r) { *r++ = 0; bbsdir = r; } else bbsdir = ""; } if ( siteowner) { if ( (user = getpwnam(siteowner)) == 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); if (!script) script = getenv("SCRIPT_NAME"); if (!script) script = "/bin/false"; if ( siteowner == 0 && (siteowner = getenv("REMOTE_USER")) == 0) html_error(500, "I don't know who you are!"); uncgi(); text = xgetenv("WWW_text"); name = xgetenv("WWW_name"); email = xgetenv("WWW_email"); website = xgetenv("WWW_website"); preview = getenv("WWW_preview") != 0; url = getenv("WWW_url"); if ( (p = getenv("WWW_help")) != 0 && strncasecmp(p, "Show", 4) == 0) help = 1; if (url == 0) html_error(500, "Nothing to comment to?"); if (getenv("WWW_post")) { if (text && name && (email||website) ) { if ( comment(name,email,website,text,url) ) { printf("HTTP/1.0 307 Ok\r\n" "Location: %s%s\n" "\n", bbsroot, url); exit(0); } syslog(LOG_ERR, "Oops#1"); } else fillin = 1; /* complain about missing items */ } else if (getenv("WWW_cancel")) { printf("HTTP/1.0 307 Ok\n" "Location: %s\n" "\n", bbsroot); exit(0); } 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", siteowner); sprintf(themfile, "%s/post.theme", bbspath); process(themfile, putbody, 1, stdout); if (printenv) { int i; puts(""); puts(""); } exit(0); }