#include #include #include #include #include #include #include #include #include "../src/blog.h" #include "../src/wbtum.h" /**********************************************************************/ static int cgi_error(int level,char const *msg, ...) { va_list args; char *file = NULL; char *errmsg = NULL; char *doc = NULL; int len; assert(level >= 100); assert(level <= 599); assert(msg != NULL); va_start(args,msg); vasprintf(&errmsg,msg,args); va_end(args); asprintf(&file,"%s/errors/%d.html",getenv("DOCUMENT_ROOT"),level); len = asprintf( &doc, "" "" "Error %d" "" "" "

Error %d

" "

%s

" "" "" "", level, level, errmsg ); fprintf( stdout, "Status: %d\r\n" "X-Error: %s\r\n" "Content-Type: text/html\r\n" "Content-Length: %d\r\n" "\r\n" "%s", level, errmsg, len, doc ); free(doc); free(file); free(errmsg); return 0; } /**********************************************************************/ static int main_cgi_bad(Cgi cgi) { (void)cgi; return cgi_error(HTTP_METHODNOTALLOWED,"Nope, not allowed."); } /**********************************************************************/ static char *safetext(char *s) { char *r = s; assert(s != NULL); for ( ; *s ; s++) if ((*s < ' ') || (*s > '~')) *s = ' '; return r; } /**********************************************************************/ static int main_cgi_POST(Cgi cgi) { Blog *blog; char *source; char *target; url__t *burl; url__t *surl; url__t *turl; tumbler__s tumbler; assert(cgi != NULL); source = CgiGetValue(cgi,"source"); target = CgiGetValue(cgi,"target"); if ((source == NULL) || (target == NULL)) return cgi_error(HTTP_BADREQ,"no cookie for you!"); surl = UrlNew(source); turl = UrlNew(target); if ((surl == NULL) || (turl == NULL)) return cgi_error(HTTP_BADREQ,"That ain't a URL"); if ((surl->scheme != URL_HTTP) && (surl->scheme != URL_HTTPS)) return cgi_error(HTTP_BADREQ,"I only support the web"); blog = BlogNew(NULL); if (blog == NULL) return cgi_error(HTTP_ISERVERERR,"Internal Error, ribs bleeding"); burl = UrlNew(blog->config.url); if (burl == NULL) return cgi_error(HTTP_ISERVERERR,"Must use BatMedKit"); if ( (burl->scheme != turl->scheme) || (strcmp(burl->http.host,turl->http.host) != 0) || (burl->http.port != turl->http.port) ) return cgi_error(HTTP_BADREQ,"This is not the site you are looking for"); /*---------------------------------------------------------------------- ; For some inexplicable reason, sometimes we get a double slash at the ; start of the path, so let's just check '/blah' and '//blah' ;-----------------------------------------------------------------------*/ if (!tumbler_new(&tumbler,&turl->http.path[1],&blog->first,&blog->last)) if (!tumbler_new(&tumbler,&turl->http.path[2],&blog->first,&blog->last)) return cgi_error(HTTP_BADREQ,"This is not the entry you are looking for"); if (tumbler.file || tumbler.range) /* can't use redirect here, sigh */ return cgi_error(HTTP_BADREQ,"You can only mention an entry"); Email email = EmailNew(); email->from = strdup(blog->config.author.email); email->to = strdup(blog->config.author.email); email->subject = strdup("Webmention, sir!"); fprintf( email->body, "\n" "From: %s\n" "User-Agent: %s\n" "Expected values:\n" "\tsource: %s\n" "\ttarget: %s\n" "\n" "All values:\n" "", getenv("REMOTE_ADDR"), getenv("HTTP_USER_AGENT"), safetext(source), safetext(target) ); for ( struct pair *pair = (struct pair *)ListGetHead(&cgi->pvars); NodeValid(&pair->node); pair = (struct pair *)NodeNext(&pair->node) ) { fprintf(email->body,"%s: %s\n",safetext(pair->name),safetext(pair->value)); } EmailSend(email); EmailFree(email); fprintf( stdout, "Status: 202 Created\r\n" "Content-Length: 0\r\n" "\r\n" ); return 0; } /**********************************************************************/ int main(int argc,char *argv[]) { Cgi cgi; int rc; crashreport_args(argc,argv,true); crashreport_core(); cgi = CgiNew(); if (cgi == NULL) return main_cgi_bad(NULL); switch(CgiMethod(cgi)) { case POST: rc = main_cgi_POST(cgi); break; case GET: case HEAD: default: rc = main_cgi_bad(cgi); break; } CgiFree(cgi); return rc; } .