From 44057234ce6be46e9dd835b0639cea230284e85d Mon Sep 17 00:00:00 2001 From: b Date: Fri, 18 Sep 2015 12:00:00 +0000 Subject: [PATCH] Initial state as of 18.09.2015. --- bb2html.awk | 688 +++++++++++++++++++++++++++++++++++++++ bot5.c | 399 +++++++++++++++++++++++ lastpost.awk | 46 +++ makefile | 34 ++ mpost.awk | 77 +++++ mpview.c | 127 ++++++++ mview.awk | 38 +++ notice.awk | 50 +++ notice2.awk | 18 ++ notice3.awk | 17 + notice4.awk | 107 ++++++ post.awk | 311 ++++++++++++++++++ post.cpp | 612 +++++++++++++++++++++++++++++++++++ posted.awk | 70 ++++ posted.c | 187 +++++++++++ postid.awk | 31 ++ preview.awk | 204 ++++++++++++ remove.c | 115 +++++++ upload.awk | 894 +++++++++++++++++++++++++++++++++++++++++++++++++++ upload.c | 97 ++++++ verify.awk | 77 +++++ view.awk | 59 ++++ viewer.c | 246 ++++++++++++++ 23 files changed, 4504 insertions(+) create mode 100644 bb2html.awk create mode 100644 bot5.c create mode 100644 lastpost.awk create mode 100644 makefile create mode 100644 mpost.awk create mode 100644 mpview.c create mode 100644 mview.awk create mode 100644 notice.awk create mode 100755 notice2.awk create mode 100644 notice3.awk create mode 100755 notice4.awk create mode 100644 post.awk create mode 100644 post.cpp create mode 100644 posted.awk create mode 100644 posted.c create mode 100644 postid.awk create mode 100644 preview.awk create mode 100644 remove.c create mode 100644 upload.awk create mode 100644 upload.c create mode 100644 verify.awk create mode 100644 view.awk create mode 100644 viewer.c diff --git a/bb2html.awk b/bb2html.awk new file mode 100644 index 0000000..b051bcc --- /dev/null +++ b/bb2html.awk @@ -0,0 +1,688 @@ +#// bb2html.awk +#// converts bbcode to html. +#// 30.03.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="=" + debug="debug=bb2html.awk:" + automome="/eizm/pro/ong1/mome.pl" + memepath="/eizm/mem/ong1/mome.txt" + + for(i=0;i<256;++i) + { + ch=sprintf("%c",i) + hex=sprintf("%02X",i) + dec=sprintf("%u",i) + ch2hex[ch]=hex + ch2dec[ch]=dec + } +}; +{ + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +}; +END{ + if(argtab["disable_bbcode"]!="") + { + debug=debug"###nl;BBcode disabled" + print debug>>outfile + exit 0 + } + text=argtab["BB"] + html=bb2html(text) + print "HTML="html>>outfile + print debug>>outfile + + # if(tempfile!="") + # { + # text=argtab["message"] + # gsub(/%5Bbr%5D/,"\n",text) + # while(sub(/%5Bong%5D/,ong(),text)>0){print text} + # while(sub(/%5Bung%5D/,ung(),text)>0){print text} + # while(sub(/%5Bong%3Ddecree%5D/,ong("decree"),text)>0){print text} + # while(sub(/%5Bung%3Ddecree%5D/,ung("decree"),text)>0){print text} + # if(text!=argtab["message"]) + # print "message="text >> outfile + # } +}; + +function bb2html(text, depth,count,bbtree,html,tag,tagstart,taglength,elm,tagv,tagname,tagvalue,matchname) +{ + depth=0 + count[0]=1 + bbtree["0"]="" + bbtree["0.n"]=0 + bbtree["0.t"]="post" + bbtree["0.v"]=argtab["subject"] + html="" + gsub(/=/,"=",text) + debug = debug "###nl;###nl;Build BBcode tree:" + while(length(text)!=0) + { + tag=match(text, /\[\/?[a-z0-9\*]+(=(([^\[<>\"\]]*)|(\"[^\"<>]*\")))?\]/) + #"#\"" + # debug = debug "###nl;" RSTART " " RLENGTH + if (tag==0) + { + debug = debug "###nl;text: " text + bbtree[ind(count,depth)]=text + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + text="" + break; + } + tagstart=RSTART + taglength=RLENGTH + if(tagstart>1) + { + elm=substr(text,1,tagstart-1) + debug = debug "###nl;text: " elm + bbtree[ind(count,depth)]=elm + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + } + tag=substr(text,tagstart,taglength) + text=substr(text,tagstart+taglength) + debug = debug "###nl;tag: " tag + if(tag!~/^\[\//) + { + tagv=index(tag,"=") + if(tagv<2) + { + tagname=substr(tag,2,length(tag)-2) + tagvalue="" + } + else + { + tagname=substr(tag,2,tagv-2) + tagvalue=substr(tag,tagv+1,length(tag)-tagv-1) + } + if(tagname !~ /^((quote)|b|i|u|(code)|(img)|(url)|(size)|(color)|(center)|(right)|(sub)|(sup)|(s)|(spoiler)|(list)|(\*))$/) + { + debug = debug "###nl;unknown tag" + bbtree[ind(count,depth)]=tag + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + continue + } + if((bbtree[indt(count,depth)".t"] == "code" && tagname!="code")||bbtree[indt(count,depth)".t"] == "img"||(bbtree[indt(count,depth)".t"] == "spoiler" && tagname=="spoiler")||(bbtree[indt(count,depth)".t"] == "size" && tagname=="size")) + { + debug = debug "###nl;this tag forbidden here" + bbtree[ind(count,depth)]=tag + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + continue + } + if(tagname=="*") + { + if(bbtree[indt(count,depth)".t"]==tagname) + { + debug = debug "###nl;implied tag: [/"tagname"]" + debug = debug "###nl;matched" + bbtree[ind(count,depth)]="[/"tagname"]" + bbtree[ind(count,depth)".k"]="e" + bbtree[ind(count,depth)".m"]=1 + bbtree[ind(count,depth)".t"]=tagname + bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"] + bbtree[indt(count,depth)".n"]=count[depth] + bbtree[indt(count,depth)".m"]=1 + count[depth]="" + --depth + ++count[depth] + } + else if(bbtree[indt(count,depth)".t"]!="list") + { + debug = debug "###nl;this tag forbidden here" + bbtree[ind(count,depth)]=tag + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + continue + } + } + debug = debug "###nl;name: " tagname " value: " tagvalue + bbtree[ind(count,depth)]=tagname" "tagvalue + bbtree[ind(count,depth)".k"]="s" + bbtree[indt(count,depth)".n"]=count[depth] + ++depth + count[depth]=1 + bbtree[indt(count,depth)]=tag + bbtree[indt(count,depth)".n"]=0 + bbtree[indt(count,depth)".t"]=tagname + bbtree[indt(count,depth)".v"]=tagvalue + } + else + { + if(depth<=0) + { + debug = debug "###nl;""unmatched" + bbtree[ind(count,depth)]=tag + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + continue + } + tagname=substr(tag,3,length(tag)-3) + if(tagname=="list"&&bbtree[indt(count,depth)".t"]=="*") + { + debug = debug "###nl;implied tag: [/*]" + debug = debug "###nl;matched" + bbtree[ind(count,depth)]="[/*]" + bbtree[ind(count,depth)".k"]="e" + bbtree[ind(count,depth)".m"]=1 + bbtree[ind(count,depth)".t"]="*" + bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"] + bbtree[indt(count,depth)".n"]=count[depth] + bbtree[indt(count,depth)".m"]=1 + count[depth]="" + --depth + ++count[depth] + } + debug = debug "###nl;name: " tagname + matchname=bbtree[indt(count,depth)".t"] + if((bbtree[indt(count,depth)".t"] == "code" && tagname!="code")||(bbtree[indt(count,depth)".t"] == "img" && tagname != "img")) + { + debug = debug "###nl;this tag forbidden here" + bbtree[ind(count,depth)]=tag + bbtree[indt(count,depth)".n"]=count[depth] + ++count[depth] + continue + } + if(tagname!=matchname) + { + debug = debug "###nl;mismatched: " matchname + # bbtree[ind(count,depth)]=tag + # bbtree[indt(count,depth)".n"]=count[depth] + # ++count[depth] + # continue + bbtree[ind(count,depth)]=tag + bbtree[ind(count,depth)".k"]="e" + bbtree[ind(count,depth)".t"]=bbtree[indt(count,depth)".t"] + bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"] + bbtree[indt(count,depth)".n"]=count[depth] + count[depth]="" + --depth + ++count[depth] + continue + } + debug = debug "###nl;matched" + bbtree[ind(count,depth)]=tag + bbtree[ind(count,depth)".k"]="e" + bbtree[ind(count,depth)".m"]=1 + bbtree[ind(count,depth)".t"]=tagname + bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"] + bbtree[indt(count,depth)".n"]=count[depth] + bbtree[indt(count,depth)".m"]=1 + count[depth]="" + --depth + ++count[depth] + } + } + if(depth>0) + debug = debug "###nl;unclosed tags: " depth + + debug = debug "###nl;###nl;""generate HTML:" + depth=0 + count[0]=0 + while(count[0]<=bbtree["0.n"]&&depth>=0) + { + if(count[depth]==0) + { + tag=bbtree[indt(count,depth)] + tagname=bbtree[indt(count,depth)".t"] + tagvalue=bbtree[indt(count,depth)".v"] + debug = debug "###nl;name: "tagname" value: "tagvalue" elements: "bbtree[indt(count,depth)".n"] + if(tagname == "post") + { + } + else if(bbtree[indt(count,depth)".m"]=="") + { + debug = debug "###nl;unmatched" + html = html tag + } + else if(tagname == "quote") + { + if (tagvalue=="") + { + html = html "
" + } + else + { + if(tagvalue !~ /^\".*\"$/) + #"#\"" + tagvalue="You forgot about the quote marks, "tagvalue + else + tagvalue=bb2html(substr(tagvalue,2,length(tagvalue)-2)) + html = html "
"tagvalue" wrote:
" + } + } + else if (tagname == "b") + { + html = html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname == "i") + { + html = html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname == "u") + { + html = html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname == "code") + { + if(bbtree[indtu(count,depth)".t"] == "code") + { + html=html tag + debug = debug "###nl;not a tag, actually" + } + else + { + html=html"
Code: Select all
" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + } + else if (tagname == "img") + html=html"" + } + else if (tagname == "size") + { + if (tagvalue==""||(tagvalue !~ /^[0-9]+$/)||(tagvalue+0)>200) + html=html" This tag should have a correct value. " + else + html=html"" + } + else if (tagname == "color") + { + if (tagvalue==""||tagvalue !~ /^#[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]$/) #for some reason /^([0-9A-F]{6})$/ doesn't work. + html=html" This tag should have a correct value. " + else + html=html"" + } + else if (tagname ~ /^((center)|(right))$/) + { + html=html"
" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname =="s") + { + html=html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname =="sub") + { + html=html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname =="sup") + { + html=html"" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname=="spoiler") + { + html=html"
Spoiler:
" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if (tagname=="list") + { + if(tagvalue=="") + html=html"
    " + else + { + if (tagvalue=="1") + tagvalue="decimal" + else if (tagvalue=="i") + tagvalue="lower-roman" + else if (tagvalue=="I") + tagvalue="upper-roman" + else if (tagvalue=="a") + tagvalue="lower-alpha" + else if (tagvalue=="A") + tagvalue="upper-alpha" + else + { + html=html"This tag should have a correct value. " + tagvalue="decimal" + } + html=html"
      " + } + } + else if (tagname=="*") + { + html=html"
    1. " + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else + { + debug = debug "###nl;unknown tag" + html = html tag + } + ++count[depth] + } + else if(bbtree[ind(count,depth)".k"]=="s") + { + debug = debug "###nl;entering tag:" + ++depth + count[depth]=0 + } + else if(bbtree[ind(count,depth)".k"]=="e") + { + debug = debug "###nl;leaving tag:" + tag=bbtree[ind(count,depth)] + tagname=bbtree[ind(count,depth)".t"] + tagvalue=bbtree[ind(count,depth)".v"] + debug = debug "###nl;name: "tagname" value: "tagvalue + if (tagname == "post") + { + } + else if(bbtree[ind(count,depth)".m"]=="") + { + debug = debug "###nl;unmatched" + html = html tag + } + else if(tagname == "quote") + html = html "
" + else if (tagname ~/^(b|i|u|(size)|(color))$/) + html = html"" + else if (tagname == "code") + { + if(bbtree[indtu(count,depth)".t"] == "code") + { + html=html tag + debug = debug "###nl;not a tag, actually" + } + else + html = html"" + } + else if (tagname == "img") + { + html = html"\" alt=\"Image\" />" + if(tagvalue!="") + html=html"This tag shouldn't have any value. " + } + else if(tagname=="url") + html=html"" + else if (tagname ~ /^((center)|(right))$/) + html=html"
" + else if (tagname =="s") + html=html"" + else if (tagname =="sub") + html=html"" + else if (tagname =="sup") + html=html"" + else if (tagname=="spoiler") + html=html"" + else if (tagname=="list") + { + if (tagvalue=="") + html=html"" + else + html=html"" + } + else if (tagname=="*") + html=html"" + else + { + debug = debug "###nl;unknown tag" + html = html tag + } + count[depth]="" + --depth + ++count[depth] + } + else if(count[depth]>bbtree[indt(count,depth)".n"]) + { + debug = debug "###nl;run out of elements in this tag; leaving" + count[depth]="" + --depth + ++count[depth] + } + else + { + tag=bbtree[ind(count,depth)] + debug = debug "###nl;text: "tag + if(bbtree[indt(count,depth)".t"] == "code") + { + # gsub(/ ?
?/,"
",tag) + gsub(/ /,"\\ ",tag) + gsub(/\t/,"\\ \\ ",tag) + } + if(argtab["disable_magic_url"]==""&& bbtree[indt(count,depth)".t"] !~ /^((code)|(img)|(url))$/) + gsub(/https?:\/\/[^\n\r\t<> ]+/,"&",tag) + if(argtab["disable_smilies"]=="" && bbtree[indt(count,depth)".t"] !~ /^((code)|(img))$/) + { + gsub(/(^|[\n\r\t ]):D($|[\n\r\t ])/," \":D\" ",tag) + gsub(/(^|[\n\r\t ]):\)($|[\n\r\t ])/," \":)\" ",tag) + gsub(/(^|[\n\r\t ]):\(($|[\n\r\t ])/," \":(\" ",tag) + gsub(/(^|[\n\r\t ]):o($|[\n\r\t ])/," \":o\" ",tag) + gsub(/(^|[\n\r\t ]):shock:($|[\n\r\t ])/," \":shock:\" ",tag) + gsub(/(^|[\n\r\t ]):\?($|[\n\r\t ])/," \":?\" ",tag) + gsub(/(^|[\n\r\t ])8-\)($|[\n\r\t ])/," \"8-)\" ",tag) + gsub(/(^|[\n\r\t ]):lol:($|[\n\r\t ])/," \":lol:\" ",tag) + gsub(/(^|[\n\r\t ]):x($|[\n\r\t ])/," \":x\" ",tag) + gsub(/(^|[\n\r\t ]):P($|[\n\r\t ])/," \":P\" ",tag) + gsub(/(^|[\n\r\t ]):oops:($|[\n\r\t ])/," \":oops:\" ",tag) + gsub(/(^|[\n\r\t ]):cry:($|[\n\r\t ])/," \":cry:\" ",tag) + gsub(/(^|[\n\r\t ]):evil:($|[\n\r\t ])/," \":evil:\" ",tag) + gsub(/(^|[\n\r\t ]):twisted:($|[\n\r\t ])/," \":twisted:\" ",tag) + gsub(/(^|[\n\r\t ]):roll:($|[\n\r\t ])/," \":roll:\" ",tag) + gsub(/(^|[\n\r\t ]):wink:($|[\n\r\t ])/," \":wink:\" ",tag) + gsub(/(^|[\n\r\t ]);\)($|[\n\r\t ])/," \":wink:\" ",tag) + gsub(/(^|[\n\r\t ]):!:($|[\n\r\t ])/," \":!:\" ",tag) + gsub(/(^|[\n\r\t ]):\?:($|[\n\r\t ])/," \":?:\" ",tag) + gsub(/(^|[\n\r\t ]):idea:($|[\n\r\t ])/," \":idea:\" ",tag) + gsub(/(^|[\n\r\t ]):arrow:($|[\n\r\t ])/," \":arrow:\" ",tag) + gsub(/(^|[\n\r\t ]):\|($|[\n\r\t ])/," \":|\" ",tag) + gsub(/(^|[\n\r\t ]):mrgreen:($|[\n\r\t ])/," \":mrgreen:\" ",tag) + } + + html = html tag + ++count[depth] + } + } + debug = debug "###nl;done" + return html +} + +function ind(count,depth, ii,iindex) +{ + iindex = "" + for(ii=0;ii<=depth;++ii) + { + if(ii!=0) + iindex = iindex "." + iindex = iindex count[ii] + } + # debug = debug "###nl;" iindex + return iindex +} +function indt(count,depth, ii,iindex) +{ + iindex = "" + for(ii=0;ii0) + iindex=iindex"." + iindex = iindex "0" + # debug = debug "###nl;" iindex + return iindex +} +function indtu(count,depth, ii,iindex) +{ + iindex = "" + for(ii=0;ii0) + iindex=iindex"." + iindex = iindex "0" + # debug = debug "###nl;" iindex + return iindex +} +function ong(decree, line) +{ + system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile) + + while((getline line < tempfile)>0) + { + gsub(/[\r\n]/,"",line) + if(sub(/[AEIOUY]-N-G/,"#O-N-G#",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/O+N+G+/,"#&#",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/DON'T/,"D#ON'G#T",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/[AEIOUY]NG/,"#ONG#",line)>0) + { + if($0!~/TH\[b\]ONG/) + return preparebb(line) + } + if(sub(/ON /,"#ONG# ",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/O\.?$/,"#ONG# ",$0)>0) + { + close(tempfile) + return preparebb(line) + } + } + close(tempfile) + return "Ong" +} + +function ung(decree, line) +{ + system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile) + + while((getline line < tempfile)>0) + { + gsub(/[\r\n]/,"",line) + if(sub(/[AEIOUY]-N-G/,"#U-N-G#",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/U+N+G+/,"#&#",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/[AEIOUY]NG/,"#UNG#",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/UN /,"#UNG# ",line)>0) + { + close(tempfile) + return preparebb(line) + } + if(sub(/U\.?$/,"#UNG# ",$0)>0) + { + close(tempfile) + return preparebb(line) + } + } + close(tempfile) + return "Ung" +} + +function preparebb(rh) +{ + if(nobb=="") + { + gsub(/\*\*/,"¤",rh) + gsub(/\*[^\*]+\*/,"±&±",rh) + gsub(/±\*/,"[i]",rh) + gsub(/\*±/,"[/i]",rh) + gsub(/¤/,"*",rh) + + gsub(/__/,"¤",rh) + gsub(/_[^_]+_/,"±&±",rh) + gsub(/±_/,"[u]",rh) + gsub(/_±/,"[/u]",rh) + gsub(/¤/,"_",rh) + + gsub(/##/,"¤",rh) + gsub(/#[^#]+#/,"±&±",rh) + gsub(/±#/,"[b]",rh) + gsub(/#±/,"[/b]",rh) + gsub(/¤/,"#",rh) + + gsub(/\$\$/,"¤",rh) + gsub(/\$[^\$]+\$/,"±&±",rh) + gsub(/±\$/,"[size=80]",rh) + gsub(/\$±/,"[/size]",rh) + gsub(/¤/,"$",rh) + } + + return rh (nobb==""?" -- [url=http://mrob.com/time/automome]automome[/url]":" -- automome") +} +function urlencode(name,all, len,iii,escaped,ch) +{ + len=length(name) + escaped="" + for(iii=1;iii<=len;++iii) + { + ch=substr(name,iii,1); + if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all=="")) + escaped = escaped ch + else + escaped = escaped "%" ch2hex[ch] + } + return escaped +} diff --git a/bot5.c b/bot5.c new file mode 100644 index 0000000..c0cfa5d --- /dev/null +++ b/bot5.c @@ -0,0 +1,399 @@ +// bot5.c +// SilentBot +// 24.03.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include + +#define TEMP_PATH "/eizm/tmp/t1i/bot5." +#define LOG_PATH "/eizm/log/t1i/bot5.log" +#define WAIT_PATH "/eizm/mem/t1i/mpost/" +#define SENT_PATH "/eizm/mem/t1i/mpost/sent/" +#define TEMPFILE_PATH "/eizm/tmp/t1i/bot5temp" +#define POSTDATA_PATH "/eizm/tmp/t1i/bot5post" +#define COOKIE_PATH "/eizm/tmp/t1i/bot5cook" +#define STOP_PATH "/eizm/tmp/t1i/bot5stop" +#define LS_PATH "/bin/ls" +#define MV_PATH "/bin/mv" +#define RM_PATH "/bin/rm" +#define MAWK_PATH "/usr/bin/mawk" +#define WGET_PATH "/usr/bin/wget" +#define AWK_POST "/eizm/pro/t1i/post.awk" +#define AWK_MPOST "/eizm/pro/t1i/mpost.awk" +#define AWK_LASTPOST "/eizm/pro/t1i/lastpost.awk" +#define PWAIT 15 +#define LASTPOST_ADDRESS "http://forums.xkcd.com/viewtopic.php?f=7&t=101043&sd=d" +#define USERAGENT "SilentBot (http://1190.bicyclesonthemoon.info/silentbot/; the Silent Chronotransponder bot)" + +pid_t sub; +int r; + +int main(int argc, char **argv) +{ + time_t t; + struct tm *nowS; + int yarg; + unsigned char text=0; + unsigned char newlog=0; + FILE *list; + FILE *post; + FILE *stopfile; + char temppath[256]; + unsigned char logopen=0; + unsigned char i; + char line[256]; + char value[256]; + char inpath[256]; + char outpath[256]; + char argp1[256]; + char argp2[256]; + char argp3[256]; + char argp4[256]; + char argp5[256]; + unsigned char d,m,h; + unsigned short y; + unsigned char another=0; + unsigned char edit; + + t=time(NULL); + sprintf(temppath,"%s%lu",TEMP_PATH,(unsigned long)getpid()); + + while((yarg = getopt(argc,argv,"tn")) != -1) + { + switch(yarg) + { + case 't': + text=1; + break; + case 'n': + newlog=1; + break; + default: + + break; + } + } + if(!text) + { + if(freopen(LOG_PATH,newlog?"wt":"at",stdout)!=NULL) + logopen=1; + } + setvbuf(stdout, NULL, _IONBF, 0); + dup2(fileno(stdout),fileno(stderr)); + printf("\n%s",ctime(&t)); + + stopfile=fopen(STOP_PATH,"wt"); + if (stopfile==NULL) + { + printf("FULL STOPFULL STOP\n"); + return 1; + } + if (lockf(fileno(stopfile),F_TLOCK,0)!=0) + { + printf("FULL STOPFULL STOP\n"); + return 1; + } + fprintf(stopfile,"%hu.FULL STOPFULL STOP\n",0); + + + sub=fork(); + if(sub==0) + { + if(freopen(temppath,"wt",stdout)==NULL) + exit(255); + r=execl(LS_PATH,LS_PATH,"-1","--color=never",WAIT_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("ls fail.\n"); + else + { + list=fopen(temppath,"rt"); + if(list==NULL) + printf("list fail.\n"); + else + { + for(i=0; fgets(line,255,list)!=NULL; ++i) + { + sscanf(line,"%s",value); + if(value[0]>'9'||value[0]<'0') + { + --i; + continue; + } + printf("%s",value); + sprintf(inpath,"%s%s",WAIT_PATH,value); + post=fopen(inpath,"rt"); + if(post==NULL) + { + printf(" fail.\n"); + continue; + } + for(h=0xff,d=0xff,m=0xff,y=0xffff;fgets(line,31,post)!=NULL;) + { + if(line[strlen(line)-1]!='\n') + continue; + if(line[0]=='h'&&line[1]=='=') + { + sscanf(line+2,"%hhu",&h); + //printf("\n h%hhu d%hhu %s",h,d,line); + } + else if(line[0]=='d'&&line[1]=='=') + { + sscanf(line+2,"%hhu",&d); + //printf("\n d%hhu d%hhu %s",d,d,line); + } + else if(line[0]=='m'&&line[1]=='=') + { + sscanf(line+2,"%hhu",&m); + //printf("\n m%hhu d%hhu %s",m,d,line); + } + else if(line[0]=='y'&&line[1]=='=') + { + sscanf(line+2,"%hu",&y); + //printf("\n y%hu d%hhu %s",y,d,line); + } + } + fclose(post); + printf(" %02hhu.%02hhu.%04hu %02hhu:00",d,m,y,h); + nowS=gmtime(&t); + + if((1900+nowS->tm_year-y)>=2) + { + printf(" timer mustard"); + continue; + } + + if(y>1900+nowS->tm_year) + { + printf(" wait\n"); + continue; + } + else if(y==1900+nowS->tm_year) + { + if(m>1+nowS->tm_mon) + { + printf(" wait\n"); + continue; + } + else if(m==1+nowS->tm_mon) + { + if(d>nowS->tm_mday) + { + printf(" wait\n"); + continue; + } + else if(d==nowS->tm_mday) + { + if(h>nowS->tm_hour) + { + printf(" wait\n"); + continue; + } + } + + } + } + + printf(" deliver"); + + do + {//test latest post + edit=0; + sub=fork(); + if(sub==0) + { + r=execl(WGET_PATH,WGET_PATH, "-q","-t", "3","-U", USERAGENT, "-O", TEMPFILE_PATH,LASTPOST_ADDRESS, (char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + break; + + sub=fork(); + if(sub==0) + { + if(freopen(temppath,"wt",stdout)==NULL) + exit(255); + r=execl(MAWK_PATH,MAWK_PATH, "-f",AWK_LASTPOST, TEMPFILE_PATH, (char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + break; + + post=fopen(temppath,"rt"); + if(post==NULL) + break; + + if(fgets(argp1,255,post)!=NULL) + { + sscanf(argp1,"%s",argp2); + sprintf(argp4,"edit=%s",argp2); + } + else + { + fclose(post); + break; + } + if(fgets(argp1,255,post)!=NULL) + { + sscanf(argp1,"%s",argp2); + sprintf(argp5,"user=%s",argp2); + } + else + { + fclose(post); + break; + } + fclose(post); + edit=1; + }while(0); + + sprintf(argp1 ,"postfile=%s",POSTDATA_PATH); + sprintf(argp2,"cookiefile=%s",COOKIE_PATH); + sprintf(argp3,"tempfile=%s",TEMPFILE_PATH); + // sprintf(argp4,"name=%s",name); + // sprintf(argp5,"pass=%s",pass); + + //no longer necessary - bot can now edit + //ETA: not true, still have to wait but only 15s - so that phpBB doesn't + if(another) + sleep(PWAIT); + + sprintf(outpath,"%s%s",SENT_PATH,value); + + sub=fork(); + if(sub==0) + { + r=execl(MV_PATH,MV_PATH,inpath,outpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf(" mv fail.\n"); + + sub=fork(); + if(!sub) + { + if(edit) + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_POST,"-v",argp1,"-v",argp2,"-v",argp3,"-v",argp4,"-v",argp5,outpath,(char *)0); + else + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_POST,"-v",argp1,"-v",argp2,"-v",argp3,outpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + { + sub=fork(); + if(!sub) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_MPOST,"-v",argp1,"-v",argp2,"-v",argp3,outpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + { + another=0; + continue; + } + } + else + { + post=fopen(POSTDATA_PATH,"rt"); + if(post!=NULL) + { + if(fgets(line,255,post)!=NULL) + { + sscanf(line,"%s",value); + fclose(post); + + post=fopen(outpath,"at"); + if(post!=NULL) + { + fprintf(post,"ID=%s\n",value); + fclose (post); + } + } + else + fclose(post); + } + + } + printf(" ok\n"); + another=1; + + } + + if(i==0) + printf("Nothing.\n"); + fclose(list); + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("rm fail.\n"); + + + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",COOKIE_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",POSTDATA_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",TEMPFILE_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + lockf(fileno(stopfile),F_ULOCK,0); + fclose(stopfile); + + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",STOP_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + } + } + if(logopen) + fclose(stdout); + return 0; +} diff --git a/lastpost.awk b/lastpost.awk new file mode 100644 index 0000000..9b93751 --- /dev/null +++ b/lastpost.awk @@ -0,0 +1,46 @@ +#// lastpost.awk +#// what was the last post? +#// 20.03.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="" +} +{ + if ((i=match($0, /id=\"p[0-9]+\"/))!=0) #" + { + temp=substr($0, i+5) + postid=substr(temp, 1, index(temp,"\"")-1) + } + + if ($0 ~ /class=\"postprofile\"/) #" + postprofile = "1" + + else if (postprofile=="") + next + + if($0 ~ /memberlist\.php.*mode=viewprofile[^<>]*>[^<>]+<\/a/) + { + temp=substr($0, index($0, ">")+1) + username=substr(temp, 1, index(temp,"<")-1) + exit + } +} +END{ + print postid + print username +} \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..3e1f397 --- /dev/null +++ b/makefile @@ -0,0 +1,34 @@ +CC=gcc +CC2=g++ +CF=-g -Wall +# LF=-lIL +LF2=-lcgi + +all: posted mpview remove post bot5 upload viewer enable + +bot5: bot5.c post.awk mpost.awk makefile + $(CC) $(CF) -o bot5 bot5.c + +# deliver: deliver.c +# $(CC) $(CF) -o deliver deliver.c + +remove: remove.c verify.awk + $(CC) $(CF) -o remove remove.c $(LF2) + +mpview: mpview.c mview.awk verify.awk makefile + $(CC) $(CF) -o mpview mpview.c $(LF2) + +posted: posted.c posted.awk makefile + $(CC) $(CF) -o posted posted.c $(LF2) + +post: post.cpp preview.awk bb2html.awk verify.awk makefile + $(CC2) $(CF) -o post post.cpp $(LF2) + +upload: upload.c upload.awk makefile + $(CC) $(CF) -o upload upload.c $(LF2) + +viewer: viewer.c makefile + $(CC) $(CF) -o viewer viewer.c $(LF2) + +enable: posted mpview remove post upload viewer + chmod u+s posted mpview remove post upload viewer diff --git a/mpost.awk b/mpost.awk new file mode 100644 index 0000000..7f90979 --- /dev/null +++ b/mpost.awk @@ -0,0 +1,77 @@ +#// mpost.awk +#// The tool to post to the mirror +#// 23.11.2014 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="=" + fora="http://1190.bicyclesonthemoon.info/ott" + useragent="\"SilentBot (http://1190.bicyclesonthemoon.info/silentbot/; Time thread post bot)\"" +}; +{ + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +}; +END{ + printf ("username=%s",argtab["username"])>postfile + printf ("&password=%s",argtab["password"])>>postfile + printf ("&subject=%s",argtab["subject"])>>postfile + if("&addbbcode20" in argtab) + printf ("&addbbcode20=%s",argtab["addbbcode20"])>>postfile + printf ("&message=%s",argtab["message"])>>postfile + printf ("&post=%s","Submit")>>postfile + if("disable_bbcode" in argtab) + printf ("&disable_bbcode=%s",argtab["disable_bbcode"])>>postfile + if("disable_smilies" in argtab) + printf ("&disable_smilies=%s",argtab["disable_smilies"])>>postfile + if("disable_magic_url" in argtab) + printf ("&disable_magic_url=%s",argtab["disable_magic_url"])>>postfile + if("attach_sig" in argtab) + printf ("&attach_sig=%s",argtab["attach_sig"])>>postfile + if("notify" in argtab) + printf ("¬ify=%s",argtab["notify"])>>postfile + printf ("&creation_time=%s",argtab["creation_time"])>>postfile + printf ("&form_token=%s",argtab["form_token"])>>postfile + close(postfile) + + if(system("wget -q -t 3 --connect-timeout=60 --post-file=" postfile " -U " useragent " -O " tempfile " \""fora "/post\"")) + { + print "Submit fail." + exit 1 + } + + while((getline temp < tempfile)>0) + { + if (temp ~ /

information/) + { + success=1 + } + } + close(tempfile) + + if (success!=1) + { + print "Sent back to preview!" + exit INDELIVERABLE + } +} diff --git a/mpview.c b/mpview.c new file mode 100644 index 0000000..6995887 --- /dev/null +++ b/mpview.c @@ -0,0 +1,127 @@ +// mpview.c (1190.bicyclesonthemoon.info/silentbot/view) +// Display one post +// 25.04.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include + +#define RM_PATH "/bin/rm" +#define CAT_PATH "/bin/cat" +#define MAWK_PATH "/usr/bin/mawk" + +#define SENT_PATH "/eizm/mem/t1i/mpost/sent/" +#define WAIT_PATH "/eizm/mem/t1i/mpost/" + +#define AWK_MVIEW "/eizm/pro/t1i/mview.awk" +#define TEMP_PATH "/eizm/tmp/t1i/mpview." + +int main() +{ + s_cgi *cgi; + pid_t sub; + int r; + + char line[32]; + char filename[32]; + char postpath[256]; + char cat[8]; + + char *arg; + char key[64]; + + char path2[256]; + + cgi=cgiInit(); + + dup2(fileno(stdout),fileno(stderr)); + + printf("Content-type: text/html\n\n"); + + arg=cgiGetValue(cgi,"v"); + sprintf(line,"%s",arg?arg:"???"); + + arg=cgiGetValue(cgi,"key"); + sprintf(key,"key=%s",arg?arg:"???"); + + if(line[0]=='s' && line[1]=='t') + { + sprintf(filename,"%s",line+2); + sprintf(cat,"cat=%s","st"); + sprintf(postpath,"%s%s",SENT_PATH,filename); + } + else if(line[0]=='w' && line[1]=='t') + { + sprintf(filename,"%s",line+2); + sprintf(cat,"cat=%s","wt"); + sprintf(postpath,"%s%s",WAIT_PATH,filename); + } + else + { + sprintf(filename,"%s","???"); + sprintf(postpath,"%s","???"); + sprintf(cat,"cat=%s","???"); + } + + sprintf(path2,"%s%lu",TEMP_PATH,(unsigned long)getpid()); + + printf("\n"); + printf("\n"); + printf("the Silent Chronotransponder • Bicycles on the Moon\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\"1190.bicyclesonthemoon.info\"\n"); + printf("

the Silent Chronotransponder

\n"); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_MVIEW,"-v","bg=1","-v",cat,"-v","s=1","-v",key,postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + // if(r) + // { + // printf("
\n",line); + // printf("
\n"); + // printf("%s %s POST NOT FOUND.\n",AWK_MVIEW,postpath); + // printf("\n
\n"); + // printf("
\n"); + // } + + printf("
back to the Silent Chronotransponder
\n"); + printf("
1190.bicyclesonthemoon.info\n"); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",path2,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("

Ch*rpin* M*stard! file not deleted!

"); + + return 0; +} diff --git a/mview.awk b/mview.awk new file mode 100644 index 0000000..f122227 --- /dev/null +++ b/mview.awk @@ -0,0 +1,38 @@ +#// mview.awk +#// Display one post +#// 25.04.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="=" +}; +{ + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +}; +END{ + if(key!=argtab["key"]&&cat=="wt"&&argtab["key"]!="") + { + print"Invalid key.

" + exit + } + print "
" + print "
"argtab["subject_h"]"
" + print "
"argtab["username_h"]" • "argtab["y"]"-"argtab["m"]"-"argtab["d"]" "argtab["h"]":00
quote "((cat=="wt")?("edit "):"")"remove "(argtab["ID"]!=""?" OTT":"")"
" + print "
"((argtab["HTML"]!="")?argtab["HTML"]:argtab["BBHTML"])"
" + print "
" +} diff --git a/notice.awk b/notice.awk new file mode 100644 index 0000000..56e6355 --- /dev/null +++ b/notice.awk @@ -0,0 +1,50 @@ +#// notice.awk +#// Display "Did you notice..." post in viewer +#// 31.03.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + timecmd="date -u +\"%Y%m%d%H\"" +} +{ + real=1 + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +} +END{ + if(real=="") + exit 1 + + posttime=argtab["y"]argtab["m"]argtab["d"]argtab["h"] + timecmd | getline thistime + close(timecmd) + + if (thistime"argtab["subject_h"]" "(argtab["ID"]!=""?"        (OTT time travel)":"")"" + print""((argtab["HTML"]!="")?argtab["HTML"]:argtab["BBHTML"])"" + } + else if (int(argtab["round"])==int(round)+1) + { + print ""argtab["subject_h"]"" + } + +} \ No newline at end of file diff --git a/notice2.awk b/notice2.awk new file mode 100755 index 0000000..7024872 --- /dev/null +++ b/notice2.awk @@ -0,0 +1,18 @@ +#! /usr/bin/mawk -f + +#notice2.awk +#28.03.2015 +#find SilentBot's "Did you notice..." posts +#replaced by the aftertime system, notice4.awk + +BEGIN{ + mawk="/usr/bin/mawk" + wget="/usr/bin/wget" + tempfile="/eizm/tmp/t1i/notice" + postlist="\"http://forums.xkcd.com/search.php?st=0&sk=t&sd=d&sr=posts&author_id=560926\"" + useragent="\"t1i - did you notice...(http://1190.bicyclesonthemoon.info/bluet1i/viewer)\"" + noticeawk="/eizm/pro/t1i/notice3.awk" + + system(wget" -q -O "tempfile" -U "useragent" "postlist) + system(mawk" -f "noticeawk" "tempfile) +} \ No newline at end of file diff --git a/notice3.awk b/notice3.awk new file mode 100644 index 0000000..f0daea6 --- /dev/null +++ b/notice3.awk @@ -0,0 +1,17 @@ +#notice3.awk +#28.03.2015 +#used by notice2,awk + +{ + if($0 ~ /

TimeAfterTime Revisited/) + { + post=substr($0, index($0,"#p")+2) + post=substr(post, 1, index(post, "\"")-1) + + frame=substr($0, index($0, "t1i-")+4, 4) + + file="/eizm/mem/t1i/notice/"frame + printf("%s",post) > file + close(file) + } +} diff --git a/notice4.awk b/notice4.awk new file mode 100755 index 0000000..01d420d --- /dev/null +++ b/notice4.awk @@ -0,0 +1,107 @@ +#! /usr/bin/mawk -f + +#// notice4.awk +#// Add SilentBot's posts' ID to the viewer +#// 31.03.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + lasttime="/eizm/mem/t1i/notice/lasttime" + list="/eizm/mem/t1i/mpost/sent/" + list2="/eizm/mem/aftertime/mpost/" + + listcmd="/bin/ls -1 --color=never "list + + + getline lastpost < lasttime + close(lasttime) + + if(lastpost=="") + lastpost="0000000000" + + while ((listcmd | getline postid)>0) + { + if (postid !~ /^[0-9A-F]+_53696C656E7454696D6572/) + continue + + number=substr(postid,1,index(postid,"_")-1) + + if (number<=lasttime) + continue + + postfile=list postid + + split("", argtab, ":") + while((getline line < postfile)>0) + { + f=1 + gsub(/[\r\n]/,"",line) + eq=index(line,"=") + argtab[substr(line,1,eq-1)]=substr(line,eq+1) + } + close (postfile) + if(argtab["ID"]=="") + continue + + if(argtab["subject_h"]!~/t1i-[0-9][0-9][0-9][0-9]$/) + continue + + ottid=argtab["ID"] + + frame=substr(argtab["subject_h"], length(argtab["subject_h"])-3) + + y=substr(number,1,4) + m=substr(number,5,2) + d=substr(number,7,2) + h=substr(number,9,2) + + + for(i=1;i<100;++i) + { + postfile=list2 "t1i-"frame"-"sprintf("%02u",i) + + split("", argtab, ":") + while((getline line < postfile)>0) + { + f=1 + gsub(/[\r\n]/,"",line) + eq=index(line,"=") + argtab[substr(line,1,eq-1)]=substr(line,eq+1) + } + close (postfile) + + if(argtab["timenumber"]=="") + break; + + if(argtab["y"]!=y || argtab["m"]!=m || argtab["d"]!=d || argtab["h"]!=h) + continue + + if(argtab["ID"]!="") + break; + + print "ID="ottid >> postfile + close(postfile) + + #print argtab["timenumber"] + + print number > lasttime + close(lasttime) + + } + } + close(listcmd) +} \ No newline at end of file diff --git a/post.awk b/post.awk new file mode 100644 index 0000000..32542e3 --- /dev/null +++ b/post.awk @@ -0,0 +1,311 @@ +#// post.awk +#// The tool to post to the OTT +#// 25.04.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="=" + fora="http://forums.xkcd.com" + useragent="\"SilentBot (http://1190.bicyclesonthemoon.info/silentbot/; the Silent Chronotransponder bot)\"" + timecmd="date -u +\"%d %b %Y, %k:%M UTC\"" + + for(i=0;i<256;++i) + { + ch=sprintf("%c",i) + hex=sprintf("%02X",i); + ch2hex[ch]=hex + hex2ch[hex]=ch + } +}; +{ + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +}; +END{ + if(entitydecode(user)!=urldecode(argtab["username"])) + edit="" + + if(system("wget -q -t 3 --connect-timeout=60 --save-cookies=" cookiefile " -U " useragent " -O " tempfile " " fora "/ucp.php?mode=login")) + { + print "Pre-login fail." + exit 1 + } + while((getline cookie < cookiefile)>0) + { + if(cookie ~ /_sid/) + { + split(cookie,arr,"_sid[ \t]*") + SID=arr[2] + } + } + close(cookiefile) + print "username=" argtab["username"] "&password=" argtab["password"] "&sid=" SID "&login=Login" > postfile + close(postfile) + if(system("wget -q -t 3 --connect-timeout=60 --save-cookies=" cookiefile " --post-file=" postfile " -U " useragent " -O " tempfile " \"" fora "/ucp.php?mode=login\"")) + { + print "Login fail." + exit 1 + } + + while((getline temp < tempfile)>0) + { + if (temp ~ /
0) + { + if (tolower(line) ~ /

information/) + { + print "Unexpected h2: information\n" + getline line < tempfile + print line + exit 1 + } + + while (line!="") + { + i=match(line, //) + if(i!=0) + { + tag=substr(line,1,i) + line=substr(line,i+1) + } + else #oh no tag doesn't end on this line - whatever, I don't care. + { + tag=line + line="" + } + + + if(tag ~ /^postfile + if("&addbbcode20" in argtab) + printf ("&addbbcode20=%s",argtab["addbbcode20"])>>postfile + if(edit!="") + printf ("&message=%s",argtab["old_message"] "%0A%5Bsize%3D110%5D%5Bb%5D" argtab["subject"] "%5B%2Fb%5D%5B%2Fsize%5D%0A%5Bsize%3D80%5D" urlencode(posttime) "%5B%2Fsize%5D%0A" argtab["message"])>>postfile + else + printf ("&message=%s",argtab["message"])>>postfile + printf ("&post=%s","Submit")>>postfile + if("disable_bbcode" in argtab) + printf ("&disable_bbcode=%s",argtab["disable_bbcode"])>>postfile + if("disable_smilies" in argtab) + printf ("&disable_smilies=%s",argtab["disable_smilies"])>>postfile + if("disable_magic_url" in argtab) + printf ("&disable_magic_url=%s",argtab["disable_magic_url"])>>postfile + if("attach_sig" in argtab) + printf ("&attach_sig=%s",argtab["attach_sig"])>>postfile + if("notify" in argtab) + printf ("¬ify=%s",argtab["notify"])>>postfile + printf ("&creation_time=%s",argtab["creation_time"])>>postfile + printf ("&form_token=%s",argtab["form_token"])>>postfile + for(i=0; i>postfile + + close(postfile) + + system("sleep 1") + if(system("wget -q -t 3 --connect-timeout=60 --load-cookies=" cookiefile " --save-cookies=" cookiefile " --post-file=" postfile " -U " useragent " -O " tempfile " \"" fora "/posting.php?mode="((edit!="")?"edit&f=7&p="edit:"reply&f=7&t=101043")"\"")) + { + print "Submit fail." + exit 1 + } + + while((getline temp < tempfile)>0) + { + if (temp ~ /

information/) + { + success=1 + } + if ((temp ~ /]*p=/) && (postid=="")) + { + postid = substr (temp , index(temp, "#p")+2) + postid = substr (postid, 1, index(postid, "\"") - 1) + } + } + close(tempfile) + + print postid > postfile + close(postfile) + + if (success!=1) + { + print "Sent back to preview!" + exit INDELIVERABLE + } + + while((getline cookie < cookiefile)>0) + { + if(cookie ~ /_sid/) + { + split(cookie,arr,"_sid[ \t]*") + SID=arr[2] + break + } + } + close(cookiefile) + if(system("wget -q -t 3 --connect-timeout=60 -U " useragent " -O " tempfile " \"" fora "/ucp.php?mode=logout&sid=" SID"\"")) + { + print "Logout fail." + } + + +} +function urlencode(name,all, len,iii,escaped,ch) +{ + len=length(name) + escaped="" + for(iii=1;iii<=len;++iii) + { + ch=substr(name,iii,1); + if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all=="")) + escaped = escaped ch + else + escaped = escaped "%" ch2hex[ch] + } + return escaped +} +function entitydecode(ht ,i,j,un,num) +# quot, amp, lt, gt, nbsp, and decimal numbered. +{ + while ((i=match(ht, /&((#[0-9]+)|([a-zA-Z]+));/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + j=index(ht, ";") + + if(ht~/^&#/) + { + num=int(substr(ht, 3, j-3)) + un=un sprintf("%c",num) + } + else + { + num=tolower(substr(ht, 2, j-2)) + if(num == "quot") + un=un "\"" + else if(num == "amp") + un=un "&" + else if(num == "lt") + un=un "<" + else if(num == "gt") + un=un ">" + else if(num == "nbsp") + un=un "\xA0" + else + un = un ht + } + ht=substr(ht, j+1) + } + un=un ht + return un +} +function urldecode(ht ,i,j,un,num) +{ + while ((i=match(ht, /%[0-9a-fA-F][0-9a-fA-F]/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + num=toupper(substr(ht, 2, 2)) + un=un hex2ch[num] + ht=substr(ht, 4) + } + un=un ht + return un +} diff --git a/post.cpp b/post.cpp new file mode 100644 index 0000000..89fb04a --- /dev/null +++ b/post.cpp @@ -0,0 +1,612 @@ +// post.cpp (1190.bicyclesonthemoon.info/aftertime/post) +// The post edit interface +// 25.04.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include + +#define RM_PATH "/bin/rm" +#define MV_PATH "/bin/mv" +#define CAT_PATH "/bin/cat" +#define MAWK_PATH "/usr/bin/mawk" + +#define POST_PATH "/eizm/www/time/silentbot/post.htm" +#define INFO_PATH "/eizm/www/time/silentbot/info.htm" +#define MPOST_PATH "/eizm/mem/t1i/mpost/" + +#define AWK_PREVIEW "/eizm/pro/t1i/preview.awk" +#define AWK_VIEW "/eizm/pro/t1i/view.awk" +#define TEMP_PATH "/eizm/tmp/t1i/preview." +#define AWK_B2H "/eizm/pro/t1i/bb2html.awk" +#define AWK_VERIFY "/eizm/pro/t1i/verify.awk" + +s_cgi *cgi; +pid_t sub; +int r; +FILE *tempfile; +FILE *postfile; +bool tf=false; +bool pf=false; +char temppath[256]=""; +char temppath2[256]=""; +char postpath[512]=""; + +char zero='\0'; +char *username = &zero; +char *password = &zero; +char *subject = &zero; +char *message = &zero; +char *y = &zero; +char *m = &zero; +char *d = &zero; +char *h = &zero; +char *disable_bbcode = &zero; +char *disable_smilies = &zero; +char *disable_magic_url = &zero; +char *attach_sig = &zero; +char *notify = &zero; +char *Preview = &zero; +char *post =&zero; +char *addquote =&zero; +char *edit =&zero; +char *forceID =&zero; +char *silent =&zero; +char *key =&zero; +char *forcekey =&zero; + +char wrong[256]; + +void submit(); +void preview (const char *text); +void writeArg(FILE *file,const char *name,const char *value, bool all); +void writeArg(FILE *file,const char *name,const char *value, const char *insert); +void writeArgH(FILE *file,const char *name,const char *value, unsigned char br); +void writeArgH(FILE *file,const char *value); +void end(int m); +void id(char *timenumber,unsigned short y, unsigned char m, unsigned short d, unsigned char h, char *name); + +void end(int m) +{ + if(tf) + fclose(tempfile); + if(pf) + fclose(postfile); + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath2,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(pf) + { + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + } + exit(m); +} + +void writeArg(FILE *file,const char *name,const char *value, bool all=false) +{ + unsigned short length, i, v; + fprintf(file,"%s=",name); + for(i=0, length=strlen(value);i='0'&&value[i]<='9')||(value[i]>='A'&&value[i]<='Z')||(value[i]>='a'&&value[i]<='z') + ||value[i]=='.'||value[i]=='~'||value[i]=='-'||value[i]=='_')&&(!all)) + fputc(v,file); + else + fprintf(file,"%%%02X",v); + } + fputc('\n',file); +} + +void writeArg(FILE *file,const char *name,const char *value, const char *insert) +{ + unsigned short length, i, v; + fprintf(file,"%s=",name); + for(i=0, length=strlen(value);i='0'&&value[i]<='9')||(value[i]>='A'&&value[i]<='Z')||(value[i]>='a'&&value[i]<='z') + ||value[i]=='.'||value[i]=='~'||value[i]=='-'||value[i]=='_') + fputc(v,file); + else + fprintf(file,"%%%02X",v); + } + for(i=0, length=strlen(insert);i='0'&&insert[i]<='9')||(insert[i]>='A'&&insert[i]<='Z')||(insert[i]>='a'&&insert[i]<='z') + ||insert[i]=='.'||insert[i]=='~'||insert[i]=='-'||insert[i]=='_') + fputc(v,file); + else + fprintf(file,"%%%02X",v); + } + fputc('\n',file); +} + +void writeArgH(FILE *file,const char *name,const char *value, unsigned char br=0) +{ + unsigned short length, i, v; + fprintf(file,"%s=",name); + for(i=0, length=strlen(value);i"); + case '\r': + if(br&0x01) + break; + case '=': + case '<': + case '>': + case '&': + fprintf(file,"&#%hu;",v); + break; + default: + fputc(v,file); + } + } + fputc('\n',file); +} + +void writeArgH(FILE *file,const char *value) +{ + unsigned short length, i, v; + for(i=0, length=strlen(value);i': + case ' ': + case '\r': + case '\n': + case '=': + fprintf(file,"&#%hu;",v); + break; + default: + fputc(v,file); + } + } +} + +void submit() +{ + time_t posttime; + struct tm *nowS; + char timenumber[256]; + char forcepath[512]; + char yy[8]; + char mm[4]; + char dd[4]; + char hh[4]; + char arg1[256]; + char arg2[256]; + char newkey[33]; + unsigned char tm, td, th; + unsigned short ty; + + posttime=time(NULL); + nowS=gmtime(&posttime); + + if(forcekey[0]=='\0') + sprintf(newkey,"%04X%04X%04X%04X%04X%04X%04X%04X", + (unsigned short)rand(),(unsigned short)rand(),(unsigned short)rand(),(unsigned short)rand(), + (unsigned short)rand(),(unsigned short)rand(),(unsigned short)rand(),(unsigned short)rand()); + else + sprintf(newkey,"%s",forcekey); + + if(y[0]!='\0'){sscanf(y,"%hu",&ty); sprintf(yy,"%04hu",ty); } + if(m[0]!='\0'){sscanf(m,"%hhu",&tm);sprintf(mm,"%02hhu",tm);} + if(d[0]!='\0'){sscanf(d,"%hhu",&td);sprintf(dd,"%02hhu",td);} + if(h[0]!='\0'){sscanf(h,"%hhu",&th);sprintf(hh,"%02hhu",th);} + + if((ty>0x0fff)||(tm>0x0f)||(td>0x1f)||(th>0x1f)) + preview("Time too long"); + // I accept invalid time as long as it's not too long + + + if(ty<1900+nowS->tm_year) + preview("Can't send this post to the past."); + else if(ty==1900+nowS->tm_year) + { + if(tm<1+nowS->tm_mon) + preview("Can't send this post to the past."); + else if(tm==1+nowS->tm_mon) + { + if(tdtm_mday) + preview("Can't send this post to the past."); + else if (td==nowS->tm_mday) + { + if (th<1+nowS->tm_hour) + preview("Can't send this post to the past."); + } + } + } + + + // sprintf(timenumber,"%04hu%02hhu%02hhu%02hhu_%llu",ty,tm,td,th,(unsigned long long)posttime); + id(timenumber,ty,tm,td,th,username); + sprintf(postpath,"%s%s",MPOST_PATH,timenumber); + if(forceID[0]!='\0') + sprintf(forcepath,"%s%s",MPOST_PATH,forceID); + + tempfile=fopen(temppath,"wt"); + if(tempfile==NULL) + preview("Couldn't create file."); + tf=true; + writeArgH(tempfile,"timenumber",timenumber); + writeArgH(tempfile,"key",newkey); + writeArgH(tempfile,"BBHTML",message,1); + writeArgH(tempfile,"BB",message,3); + writeArgH(tempfile,"username_h",username); + writeArgH(tempfile,"subject_h",subject); + if(h[0]!='\0')writeArgH(tempfile,"h",hh); + if(d[0]!='\0')writeArgH(tempfile,"d",dd); + if(m[0]!='\0')writeArgH(tempfile,"m",mm); + if(y[0]!='\0')writeArgH(tempfile,"y",yy); + writeArg (tempfile,"username",username); + writeArg (tempfile,"password",password,1); + writeArg (tempfile,"subject",subject); + writeArg (tempfile,"message",message,(silent[0]!='\0')?"":((disable_bbcode[0]!='\0')?"\n\n-- posted by SilentBot":"[right][size=80]-- posted by SilentBot [img]http://forums.xkcd.com/download/file.php?id=47884[/img][/size][/right]")); + if(disable_bbcode[0]!='\0') + writeArg(tempfile,"disable_bbcode",disable_bbcode); + if(disable_smilies[0]!='\0') + writeArg(tempfile,"disable_smilies",disable_smilies); + if(disable_magic_url[0]!='\0') + writeArg(tempfile,"disable_magic_url",disable_magic_url); + if(attach_sig[0]!='\0') + writeArg(tempfile,"attach_sig",attach_sig); + if(notify[0]!='\0') + writeArg(tempfile,"notify",notify); + if(silent[0]!='\0') + writeArgH(tempfile,"silent",silent); + fclose(tempfile); + tf=false; + + sprintf(arg1,"outfile=%s",temppath); + sprintf(arg2,"tempfile=%s",temppath2); + fflush(stdout); + sub=fork(); + if(sub==0) + { + setvbuf(stdout, NULL, _IONBF, 0); + dup2(fileno(stdout),fileno(stderr)); + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_B2H,"-v",arg1,"-v",arg2,temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + sprintf(arg1,"name=%s",username); + sprintf(arg2,"pass=%s",password); + sub=fork(); + if(sub==0) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_VERIFY,"-v",arg1,"-v",arg2,"-v","reversed=1",(forceID[0]!='\0')?forcepath:postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(!r) + preview("Can't replace this post. Not yours or wrong password?"); + + if(forceID[0]!='\0') + { + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,forcepath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + } + + sub=fork(); + if(sub==0) + { + r=execl(MV_PATH,MV_PATH,temppath,postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + // preview("Couldn't add post to queue."); + preview(postpath); + + printf("Content-type: text/html\n\n"); + sprintf(arg1,"info=

This message has been sent successfully.

View your submitted message

Return to the Silent Chronotransponder

",timenumber,newkey); + // printf("Content-type: text/html\n\n"); + fflush(stdout); + sub=fork(); + if(sub==0) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_VIEW,"-v",arg1,INFO_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("%s",arg1); + end(0); +} +void preview (const char *text) +{ + char arg1[256]; + char arg2[256]; + char yy[8]; + char mm[4]; + char dd[4]; + char hh[4]; + unsigned short ty; + unsigned char tm,td,th; + if(y[0]!='\0'){sscanf(y,"%hu",&ty); ty&=0x0fff;sprintf(yy,"%04hu",ty); } + if(m[0]!='\0'){sscanf(m,"%hhu",&tm);tm&= 0x0f;sprintf(mm,"%02hhu",tm);} + if(d[0]!='\0'){sscanf(d,"%hhu",&td);td&= 0x1f;sprintf(dd,"%02hhu",td);} + if(h[0]!='\0'){sscanf(h,"%hhu",&th);th&= 0x1f;sprintf(hh,"%02hhu",th);} + + tempfile=fopen(temppath,"wt"); + if(tempfile==NULL) + end(1); + tf=true; + + writeArgH(tempfile,"HTML",message,1); + writeArgH(tempfile,"BB",message,3); + writeArgH(tempfile,"wrong",text); + writeArgH(tempfile,"username",username); + writeArgH(tempfile,"subject",subject); + writeArgH(tempfile,"message",message); + if(h[0]!='\0')writeArgH(tempfile,"h",hh); + if(d[0]!='\0')writeArgH(tempfile,"d",dd); + if(m[0]!='\0')writeArgH(tempfile,"m",mm); + if(y[0]!='\0')writeArgH(tempfile,"y",yy); + writeArgH(tempfile,"disable_bbcode",disable_bbcode); + writeArgH(tempfile,"disable_smilies",disable_smilies); + writeArgH(tempfile,"disable_magic_url",disable_magic_url); + writeArgH(tempfile,"attach_sig",attach_sig); + writeArgH(tempfile,"notify",notify); + writeArgH(tempfile,"silent",silent); + writeArgH(tempfile,"addquote",addquote); + writeArgH(tempfile,"edit",edit); + writeArgH(tempfile,"forceID",forceID); + writeArgH(tempfile,"key",forcekey); + fclose(tempfile); + tf=false; + + printf("Content-type: text/html\n\n"); + + sprintf(arg1,"outfile=%s",temppath); + sprintf(arg2,"tempfile=%s",temppath2); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + setvbuf(stdout, NULL, _IONBF, 0); + dup2(fileno(stdout),fileno(stderr)); + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_B2H,"-v",arg1,"-v",arg2,temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + // printf("Content-type: text/html\n\n"); + sprintf(arg1,"argfile=%s",temppath); + sprintf(arg2,"key=%s",key[0]?key:"???"); + fflush(stdout); + sub=fork(); + if(sub==0) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_PREVIEW,"-v",arg1,"-v",arg2,POST_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("

Ch*rpin* M*stard

"); + end(0); +} + +int main() +{ + bool missing=false; + + char *arg; + + cgi=cgiInit(); + srand (time (NULL) + getpid()); + + sprintf(temppath,"%s%lu",TEMP_PATH,(unsigned long)getpid()); + sprintf(temppath2,"%s_%lu",TEMP_PATH,(unsigned long)getpid()); + + arg=cgiGetValue(cgi,"password"); + if(arg!=NULL) + password=arg; + else + { + missing=true; + strcpy(wrong,"Password is missing."); + } + + arg=cgiGetValue(cgi,"username"); + if(arg!=NULL) + username=arg; + else + { + missing=true; + strcpy(wrong,"Name is missing."); + } + + arg=cgiGetValue(cgi,"subject"); + if(arg!=NULL) + subject=arg; + else + { + missing=true; + strcpy(wrong,"Subject was missing. Replaced with default value."); + } + + arg=cgiGetValue(cgi,"message"); + if(arg!=NULL) + message=arg; + else + { + missing=true; + strcpy(wrong,"Post is empty."); + } + + arg=cgiGetValue(cgi,"y"); + if(arg!=NULL) + y=arg; + else + { + missing=true; + strcpy(wrong,"Time not specified."); + } + + arg=cgiGetValue(cgi,"m"); + if(arg!=NULL) + m=arg; + else + { + missing=true; + strcpy(wrong,"Time not specified."); + } + + arg=cgiGetValue(cgi,"d"); + if(arg!=NULL) + d=arg; + else + { + missing=true; + strcpy(wrong,"Time not specified."); + } + + arg=cgiGetValue(cgi,"h"); + if(arg!=NULL) + h=arg; + else + { + missing=true; + strcpy(wrong,"Time not specified."); + } + + arg=cgiGetValue(cgi,"disable_bbcode"); + if(arg!=NULL) + disable_bbcode=arg; + + arg=cgiGetValue(cgi,"disable_smilies"); + if(arg!=NULL) + disable_smilies=arg; + + arg=cgiGetValue(cgi,"disable_magic_url"); + if(arg!=NULL) + disable_magic_url=arg; + + arg=cgiGetValue(cgi,"attach_sig"); + if(arg!=NULL) + attach_sig=arg; + + arg=cgiGetValue(cgi,"notify"); + if(arg!=NULL) + notify=arg; + + arg=cgiGetValue(cgi,"silent"); + if(arg!=NULL) + silent=arg; + + arg=cgiGetValue(cgi,"Preview"); + if(arg!=NULL) + Preview=arg; + + arg=cgiGetValue(cgi,"post"); + if(arg!=NULL) + post=arg; + + arg=cgiGetValue(cgi,"q"); + if(arg!=NULL) + addquote=arg; + + arg=cgiGetValue(cgi,"e"); + if(arg!=NULL) + edit=arg; + + arg=cgiGetValue(cgi,"forceID"); + if(arg!=NULL) + forceID=arg; + + arg=cgiGetValue(cgi,"key"); + if(arg!=NULL) + key=arg; + + arg=cgiGetValue(cgi,"forcekey"); + if(arg!=NULL) + forcekey=arg; + + if(strcmp(post,"Submit")==0) + { + if(missing) + preview(wrong); + else + submit(); + } + else + preview(""); + + return 0; + +} + +void id(char *timenumber,unsigned short y, unsigned char m, unsigned short d, unsigned char h, char *name) +{ + sprintf(timenumber,"%04hu%02hhu%02hhu%02hhu_",y,m,d,h); + for(unsigned short j=0, k=strlen(name);j. + + +BEGIN{ + FS="=" + for(i=0;i<256;++i) + { + ch=sprintf("%c",i) + hex=sprintf("%02X",i); + ch2hex[ch]=hex + } +}; +{ + gsub(/[\r\n]/,"",$0) + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +}; +END{ + if(((pass,!=urldecode(argtab["password"]))||(name!=urldecode(argtab["username"])))&&cat!="st") + exit 1; + if (r2==0) + class="plw" + else + class="plv" + print ""argtab["y"]"-"argtab["m"]"-"argtab["d"]" "argtab["h"]":00"argtab["username_h"]""argtab["subject_h"]"view quote "(cat=="wt"?"edit ":"")"remove"(argtab["ID"]!=""?" OTT":"")"" +} +# function urlencode(name,all, len,iii,escaped,ch) +# { + # len=length(name) + # escaped="" + # for(iii=1;iii<=len;++iii) + # { + # ch=substr(name,iii,1); + # if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all=="")) + # escaped = escaped ch + # else + # escaped = escaped "%" ch2hex[ch] + # } + # return escaped +# } +function urldecode(ht ,i,j,un,num) +{ + while ((i=match(ht, /%[0-9a-fA-F][0-9a-fA-F]/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + num=toupper(substr(ht, 2, 2)) + un=un hex2ch[num] + ht=substr(ht, 4) + } + un=un ht + return un +} \ No newline at end of file diff --git a/posted.c b/posted.c new file mode 100644 index 0000000..08cf4fb --- /dev/null +++ b/posted.c @@ -0,0 +1,187 @@ +// posted.c (1190.bicyclesonthemoon.info/silentbot/list) +// Display the post list +// 26.04.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include +#include +#include +#include +#include + +#define TEMP_PATH "/eizm/tmp/t1i/posted." +#define SENT_PATH "/eizm/mem/t1i/mpost/sent/" +#define WAIT_PATH "/eizm/mem/t1i/mpost/" +#define LS_PATH "/bin/ls" +#define RM_PATH "/bin/rm" +#define MAWK_PATH "/usr/bin/mawk" +#define AWK_POSTED "/eizm/pro/t1i/posted.awk" + +s_cgi *cgi; +pid_t sub; +int r; + +int main(int argc, char **argv) +{ + char temppath[256]=""; + char line[512]; + char filename[512]; + char postpath[512]; + char argp1[256]; + char argp2[256]; + FILE *tempfile; + // FILE *postfile; + unsigned char i; + unsigned char sent; + char zero='\0'; + char *value; + char *username; + char *password; + // dup2(fileno(stdout),fileno(stderr)); + cgi=cgiInit(); + + username=((value=cgiGetValue(cgi,"username"))?value:&zero); + password=((value=cgiGetValue(cgi,"password"))?value:&zero); + sent=cgiGetValue(cgi,"sent"); + sprintf(argp1,"name=%s",username); + sprintf(argp2,"pass=%s",password); + + + sprintf(temppath,"%s%lu",TEMP_PATH,(unsigned long)getpid()); + + printf("Content-type: text/html\n\n"); + printf("\n"); + printf("\n"); + printf("the Silent Chronotransponder • Bicycles on the Moon\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\"1190.bicyclesonthemoon.info\"\n"); + printf("

the Silent Chronotransponder

\n"); + printf("(some explanation)
\n"); + printf("
\n"); + printf("\n",username); + printf("\n"); + printf("\n",sent?" checked":""); + printf("
Username:
Password:
Sent posts:
\n"); + printf("Write a post

\n"); + printf("
\n"); + printf("
(file format - 23.03.2015)


\n"); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + if(freopen(temppath,"wt",stdout)==NULL) + exit(255); + r=execl(LS_PATH,LS_PATH,"-1","--color=never",WAIT_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("No messages.
\n"); + else + { + printf("\n"); + printf("\n"); + + tempfile=fopen(temppath,"rt"); + if(tempfile!=NULL) + { + for(i=0; fgets(line,511,tempfile)!=NULL; ++i) + { + sscanf(line,"%s",filename); + sprintf(postpath,"%s%s",WAIT_PATH,filename); + + fflush(stdout); + sub=fork(); + if(!sub) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_POSTED,"-v",i&0x1?"r2=1":"r2=0","-v","cat=wt","-v",argp1,"-v",argp2,postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + --i; + + } + fclose(tempfile); + } + printf("
Waiting
post timeauthorsubjectaction

\n"); + + } + + if(sent) + { + fflush(stdout); + sub=fork(); + if(sub==0) + { + if(freopen(temppath,"wt",stdout)==NULL) + exit(255); + r=execl(LS_PATH,LS_PATH,"-1","--color=never",SENT_PATH,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + printf("No messages.
\n"); + else + { + printf("
\n"); + printf("\n"); + + tempfile=fopen(temppath,"rt"); + if(tempfile!=NULL) + { + for(i=0; fgets(line,511,tempfile)!=NULL; ++i) + { + sscanf(line,"%s",filename); + sprintf(postpath,"%s%s",SENT_PATH,filename); + + fflush(stdout); + sub=fork(); + if(!sub) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_POSTED,"-v",i&0x1?"r2=1":"r2=0","-v","cat=st","-v",argp1,"-v",argp2,postpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + --i; + + } + fclose(tempfile); + } + + printf("
Sent
post timeauthorsubjectaction
\n"); + } + } + + printf("
Aftertime ONGsystem

1190.bicyclesonthemoon.info\n"); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + return 0; +} diff --git a/postid.awk b/postid.awk new file mode 100644 index 0000000..c5b4946 --- /dev/null +++ b/postid.awk @@ -0,0 +1,31 @@ +#postid.awk +#24.04.2015 +#replaced by notice4.awk + +BEGIN{ + postpath="/eizm/mem/t1i/mpost/sent/" + noticepath="/eizm/mem/t1i/notice/" + tab_len=0 +} +{ + ID=$1 + frame =$NF + + if(frame !~ /t1i-[0-9][0-9][0-9][0-9]/) + next + + frame=substr(frame, 5, 4) + + notice=noticepath frame + + getline OTT < notice + close (notice) + + if(OTT=="") + next + + post=postpath ID + + print "ID="OTT >> post + close(post) +} \ No newline at end of file diff --git a/preview.awk b/preview.awk new file mode 100644 index 0000000..677418e --- /dev/null +++ b/preview.awk @@ -0,0 +1,204 @@ +#// preview.awk +#// Preview a post in the post edit interface +#// 25.04.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + sentpath="/eizm/mem/t1i/mpost/sent/" + waitpath="/eizm/mem/t1i/mpost/" + + HTML="
Preview: %s
%s

" + wrong="
%s
\n" + subject="\n" + username="\n" + time="Y: M: D: H: \n" + message="\n" + # forcetime1="\n" + # forcetime2="fTime: day: month: year: \n" + # img="" + back="back to the Silent Chronotransponder" + + disable_bbcode=" Disable BBcode
\n" + disable_smilies=" Disable smilies
\n" + disable_magic_url=" Do not automatically parse URLs
\n" + attach_sig=" Attach a signature
\n" + notify=" Notify me when a reply is posted
\n" + silent=" Very silent
\n" + + forceID="\n" + forcekey="\n" + + addquote="" + + # print "" + close(argfile) + if(argtab["edit"] ~ /^wt[0-9]+_[0-9a-fA-F]+$/) + { + argtab["forceID"]=substr(argtab["edit"],3) + argfile= waitpath argtab["forceID"] + + while((getline argline < argfile)>0) + { + gsub(/[\r\n]/,"",argline) + eq=index(argline,"=") + if(argline ~ /^key=/) + { + if(substr(argline,eq+1)!=key && argtab["addquote"]~/^wt/) + { + argtab["wrong"]="Invalid key." + break; + } + argtab["key"]=substr(argline,eq+1) + } + else if(argline ~ /^((username)|(subject))_h=/) + argtab[substr(argline,1,eq-3)]=substr(argline,eq+1) + else if(argline ~ /^BBHTML=/) + { + argtab["message"]=substr(argline,eq+1) + gsub(/
/,"\n",argtab["message"]) + } + else if(argline ~ /^((BB)|(username)|(subject)|(message)|(HTML)|(debug))=/) + {} + else + argtab[substr(argline,1,eq-1)]=substr(argline,eq+1) + } + close(argfile) + } + else if(argtab["addquote"] ~ /^[sw]t[0-9]+_[0-9a-fA-F]+$/) + { + if(argtab["addquote"] ~ /^st[0-9]+_[0-9a-fA-F]+$/) + argfile= sentpath substr(argtab["addquote"],3) + if(argtab["addquote"] ~ /^wt[0-9]+_[0-9a-fA-F]+$/) + argfile= waitpath substr(argtab["addquote"],3) + #else + #argfile is not changed = quote self? + while((getline argline < argfile)>0) + { + gsub(/[\r\n]/,"",argline) + eq=index(argline,"=") + if(argline ~ /^key=/) + { + if(substr(argline,eq+1)!=key && argtab["addquote"]~/^wt/) + { + argtab["wrong"]="Invalid key." + break; + } + } + if(argline ~ /^BBHTML=/) + { + addquotehtml=substr(argline,eq+1) + gsub(/
/,"\n",addquotehtml) + } + if(argline ~ /^username_h=/) + addquotename=substr(argline,eq+1) + if(argline ~ /^subject_h/) + { + addquotesub=substr(argline,eq+1) + if(addquotesub ~ /^Re:/) + argtab["subject"]=addquotesub + else + argtab["subject"]="Re: "addquotesub + } + if(argline ~ /^y=/) + { + argtab["y"]=substr(argline,eq+1) + } + if(argline ~ /^d=/) + { + argtab["d"]=substr(argline,eq+1) + } + if(argline ~ /^m=/) + { + argtab["m"]=substr(argline,eq+1) + } + if(argline ~ /^h=/) + { + argtab["h"]=substr(argline,eq+1) + } + } + close(argfile) + if(addquotehtml!="") + addquote="[quote=""addquotename""]"addquotehtml"[/quote]" + } +}; +{ + if ($0 ~ /^###HTML/) + { + if((argtab["HTML"]!="")&&(argtab["wrong"]=="")) + printf(HTML,argtab["subject"],argtab["HTML"]) + } + else if ($0 ~ /^###wrong/) + { + if(argtab["wrong"]!="") + printf(wrong,argtab["wrong"]) + } + else if ($0 ~ /^###subject/) + printf(subject,((argtab["subject"]=="")?"Wait for it.":argtab["subject"])) + else if ($0 ~ /^###username/) + printf(username,argtab["username"]) + else if ($0 ~ /^###message/) + printf(message,argtab["message"],addquote) + else if ($0 ~ /^###time/) + printf(time,argtab["y"],argtab["m"],argtab["d"],argtab["h"]) + + else if ($0 ~ /^###future/) + { + ###no longer supported + } + else if ($0 ~ /^###forceID/) + { + if(argtab["forceID"]!="") + printf(forceID,argtab["forceID"]) + } + else if ($0 ~ /^###forcekey/) + { + if(argtab["key"]!="") + printf(forcekey,argtab["key"]) + } + else if ($0 ~ /^###back/) + { + print back + } + else if ($0 ~ /^###debug/) + { + gsub(/###nl;/,"\n",argtab["debug"]) + gsub(/-/," - ",argtab["debug"]) + print "" + } + else if ($0 ~ /^###disable_bbcode/) + printf(disable_bbcode,(argtab["disable_bbcode"]=="on")?"checked=\"checked\"":"") + else if ($0 ~ /^###disable_smilies/) + printf(disable_smilies,(argtab["disable_smilies"]=="on")?"checked=\"checked\"":"") + else if ($0 ~ /^###disable_magic_url/) + printf(disable_magic_url,(argtab["disable_magic_url"]=="on")?"checked=\"checked\"":"") + else if ($0 ~ /^###attach_sig/) + printf(attach_sig,(argtab["attach_sig"]=="on")?"checked=\"checked\"":"") + else if ($0 ~ /^###notify/) + printf(notify,(argtab["notify"]=="on")?"checked=\"checked\"":"") + else if ($0 ~ /^###silent/) + printf(silent,(argtab["silent"]=="on")?"checked=\"checked\"":"") + else + print $0 +}; diff --git a/remove.c b/remove.c new file mode 100644 index 0000000..4b5a10b --- /dev/null +++ b/remove.c @@ -0,0 +1,115 @@ +// remove.c (1190.bicyclesonthemoon.info/silentbot/remove) +// remove a post +// 25.04.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include + +#define SENT_PATH "/eizm/mem/t1i/mpost/sent/" +#define WAIT_PATH "/eizm/mem/t1i/mpost/" +#define RMOV_PATH "/eizm/mem/t1i/mpost/rm/" +#define MV_PATH "/bin/mv" +#define MAWK_PATH "/usr/bin/mawk" +#define AWK_VERIFY "/eizm/pro/t1i/verify.awk" + +int main(int argc, char **argv) +{ + s_cgi *cgi; + pid_t sub; + int r; + + char zero='\0'; + char *rmov = &zero; + char *arg; + char *username; + char *password; + char inpath[256]; + char outpath[256]; + char argp1[256]; + char argp2[256]; + + cgi=cgiInit(); + + rmov=((arg=cgiGetValue(cgi,"r"))?arg:&zero); + + username=((arg=cgiGetValue(cgi,"username"))?arg:&zero); + password=((arg=cgiGetValue(cgi,"password"))?arg:&zero); + if(username[0]=='\0'||password[0]=='\0') + { + arg=cgiGetValue(cgi,"r"); + if(arg!=NULL) + rmov=arg; + printf("Content-type: text/html\n\n"); + printf("\n"); + printf("\n"); + printf("the Silent Chronotransponder • Bicycles on the Moon\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\"1190.bicyclesonthemoon.info\"\n"); + printf("

the Silent Chronotransponder interface

\n"); + printf("
\n"); + printf("Remove post %s?\n",rmov); + printf("\n",username); + printf("\n"); + printf("
Username:
Password:
\n",rmov); + printf("
1190.bicyclesonthemoon.info\n"); + return 0; + } + + if(rmov[0]=='s'&&rmov[1]=='t') + sprintf(inpath,"%s%s",SENT_PATH,rmov+2); + else if(rmov[0]=='w'&&rmov[1]=='t') + sprintf(inpath,"%s%s",WAIT_PATH,rmov+2); + else + { + cgiRedirect("/silentbot/list"); + return(0); + } + + sprintf(argp1,"name=%s",username); + sprintf(argp2,"pass=%s",password); + + sub=fork(); + if(sub==0) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_VERIFY,"-v",argp1,"-v",argp2,inpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + { + cgiRedirect("/silentbot/list"); + return(0); + } + sprintf(outpath,"%s%s",RMOV_PATH,rmov+2); + + sub=fork(); + if(sub==0) + { + r=execl(MV_PATH,MV_PATH,inpath,outpath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + cgiRedirect("/silentbot/list"); + return 0; +} \ No newline at end of file diff --git a/upload.awk b/upload.awk new file mode 100644 index 0000000..4e9dc44 --- /dev/null +++ b/upload.awk @@ -0,0 +1,894 @@ +#// upload.awk +#// The post upload interface +#// 05.06.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + postpath="/eizm/mem/t1i/mpost/" + stpath="/eizm/mem/t1i/mpost/sent/" + rmpath="/eizm/mem/t1i/mpost/rm/" + bb2html="/eizm/pro/t1i/bb2html.awk" + automome="/eizm/pro/ong1/mome.pl" + memepath="/eizm/mem/ong1/mome.txt" + timecmd="date -u +\"%s\"" + + timecmd | getline thistime + close(timecmd) + + srand(int(thistime) + int( PROCINFO["pid"])) + + for(i=0;i<256;++i) + { + ch=sprintf("%c",i) + hex=sprintf("%02X",i) + hexl=sprintf("%02x",i) + dec=sprintf("%u",i) + ch2hex[ch]=hex + hex2ch[hex]=ch + ch2hexl[ch]=hexl + ch2dec[ch]=dec + } + + year=substr(timetext,1,4) + month=substr(timetext,5,2) + day=substr(timetext,7,2) + hour=substr(timetext,9,2) + + yyy=year+0 + mmm=month+0 + ddd=day+0 + hhh=hour+0 + + ln=0 + memenumber=8 +} +{ + gsub(/[\r\n]/,"",$0) + if (FNR==1) + { + name=$0 + # print "username: "name + next + } + if (FNR==2) + { + pass=$0 + gsub(/./,"*", $0) + # print "password: "$0 + next + } + + if($0=="") + { + if(ln!=0) + { + post() + ln=0 + nobb="" + nosmil="" + nourl="" + sig="" + notify="" + silent="" + quot="" + rmov="" + lst="" + flst="" + h="" + d="" + m="" + y="" + subject="" + content="" + options="" + # replace="" + } + next + } + + ++ln + if(ln==1) + { + y=substr($0,1,4) + m=substr($0,6,2) + d=substr($0,9,2) + h=substr($0,12,2) + # #xxxx-xx-xx xx xxxx-xx-xx xx + # if(length($0)>=27) + # replace=substr($0,15,4)substr($0,20,2)substr($0,23,2)substr($0,26,2) + } + else if(ln==2) + { + options=tolower($0) + if(options ~ /b/) + nobb=1 + if(options ~ /s/) + nosmil=1 + if(options ~ /u/) + nourl=1 + if(options ~ /a/) + sig=1 + if(options ~ /n/) + notify=1 + if(options ~ /v/) + silent=1 + if(options ~ /r/) + rmov=1 + if(options ~ /q/) + quot=1 + if(options ~ /l/) + lst=1 + if(options ~ /f/) + flst=1 + } + else if(ln==3) + { + subject=$0 + } + else + { + if(ln!=4) + content=content "\n" $0 + else + content=$0 + } + +} +END{ + if(ln!=0) + post() +} +function remove( postid,postfile,rmfile,stfile,temp,f,tn,eq,tv) +{ + postid=sprintf("%04d%02d%02d%02d_%s",y,m,d,h,hexencode(name)) + postfile=postpath postid + rmfile=rmpath postid + stfile=stpath postid + printf("%s",postid" ") + + while((getline temp < postfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="username") + { + if(urldecode(tv)!=name) + { + # print "Can't remove, post belongs to "substr(temp,eq+1)"." + print "not removed."substr(temp,eq+1)"." + close(postfile) + return + } + } + else if(tn=="password") + { + if(urldecode(tv)!=pass) + { + # print "Can't remove, wrong password." + print "not removed" + #I shouldn't tell why - the user can't be able to determine if post exists. + close(postfile) + return + } + } + } + + if(f!="") + { + close(postfile) + if(system("mv -f "postfile" "rmfile)==0) + { + print "removed." + return + } + } + f="" + while((getline temp < stfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="username") + { + if(urldecode(tv)!=name) + { + print "Can't remove, post belongs to "substr(temp,eq+1)"." + close(stfile) + return + } + } + else if(tn=="password") + { + if(urldecode(tv)!=pass) + { + print "Can't remove, wrong password." + close(stfile) + return + } + } + } + if(f!="") + { + close(stfile) + if(system("mv -f "stfile" "rmfile)==0) + { + print "removed." + return + } + } + print "not removed." +} + +function quote( postid,postfile,stfile,temp,f,opt,cont,ongt,subj,eq,tn,tv,id) +{ + postid=sprintf("%04d%02d%02d%02d_%s",y,m,d,h,hexencode(name)) + postfile=postpath postid + stfile=stpath postid + + while((getline temp < postfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="username") + { + if(urldecode(tv)!=name) + { + #print "Can't quote, post belongs to "substr(temp,eq+1)"." + print " can't. quote." #I shouldn't tell why + close(postfile) + return + } + } + else if(tn=="password") + { + if(urldecode(tv)!=pass) + { + #print "Can't quote, wrong password." + print " can't quote." #I shouldn't tell why + close(postfile) + return + } + } + else if(tn=="BB") + cont=unhtml(tv) + else if(tn=="brtext") + ongt=tv + else if(tn=="subject_h") + subj=unhtml(tv) + else if(tn=="disable_bbcode") + { + if(tv=="on") + opt=opt"B" + } + else if(tn=="disable_smilies") + { + if(tv=="on") + opt=opt"S" + } + else if(tn=="disable_magic_url") + { + if(tv=="on") + opt=opt"U" + } + else if(tn=="attach_sig") + { + if(tv=="on") + opt=opt"A" + } + else if(tn=="notify") + { + if(tv=="on") + opt=opt"N" + } + else if(tn=="silent") + { + if(tv=="on") + opt=opt"V" + } + } + if(f!="") + { + close(postfile) + if (opt=="") + opt="_" + print postid" subject "subj + print postid" options "opt + print postid" content "((ongt!="")?ongt:cont) + return + } + + while((getline temp < stfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="BB") + cont=unhtml(tv) + else if(tn=="brtext") + ongt=tv + else if(tn=="subject_h") + subj=unhtml(tv) + else if(tn=="ID") + id=tv + else if(tn=="disable_bbcode") + { + if(tv=="on") + opt=opt"B" + } + else if(tn=="disable_smilies") + { + if(tv=="on") + opt=opt"S" + } + else if(tn=="disable_magic_url") + { + if(tv=="on") + opt=opt"U" + } + else if(tn=="attach_sig") + { + if(tv=="on") + opt=opt"A" + } + else if(tn=="notify") + { + if(tv=="on") + opt=opt"N" + } + else if(tn=="silent") + { + if(tv=="on") + opt=opt"V" + } + } + if(f!="") + { + close(stfile) + if (opt=="") + opt="_" + print postid" subject "subj + print postid" options "opt + print postid" content "((ongt!="")?ongt:cont) + if(id!="") + print postid" ID "id + return + } + + else + print postid " can't quote." #I shouldn't tell why +} + +function list( cmd,id,postfile,temp,mt,f,eq,tn,tv) +{ + + if (flst!="") + { + cmd="/bin/ls -1 --color=never "stpath + while ((cmd | getline id)>0) + { + f="" + mt="[0-9]*_"hexencode(name) + if(id !~ mt) + continue + stfile = stpath id + #print id + + while((getline temp < stfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="subject_h") + subj=unhtml(tv) + } + if(f!="") + { + close(stfile) + print id" subject "subj + } + } + close (cmd) + } + + cmd="/bin/ls -1 --color=never "postpath + while ((cmd | getline id)>0) + { + f="" + mt="[0-9]*_"hexencode(name) + if(id !~ mt) + continue + postfile = postpath id + #print id + + while((getline temp < postfile)>0) + { + f=1 + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="username") + { + if(urldecode(tv)!=name) + { + close(postfile) + f="" + break + } + } + else if(tn=="password") + { + if(urldecode(tv)!=pass) + { + close(postfile) + f="" + break + } + } + else if(tn=="subject_h") + subj=unhtml(tv) + } + if(f!="") + { + close(postfile) + print id" subject "subj + } + + + + ########33 + } + close (cmd) +} + +function post( postid,replaceid,postfile,replacefile,temp,i,eq,tn,tv) +{ + if(lst!="") + return list() + if(quot!="") + return quote() + if(rmov!="") + return remove() + postid=sprintf("%04d%02d%02d%02d_%s",y,m,d,h,hexencode(name)) + printf("%s",postid" ") + postfile=postpath postid + + if(options=="") + { + print "No options defined." + return + } + + # if(replace!="") + # { + # replaceid=replace"_"hexencode(name) + # replacefile=postpath replaceid + # } + + if (name=="") + { + print "Username missing." + return + } + if (pass=="") + { + print "Password missing." + return + } + if (subject=="") + { + print "Subject missing." + return + } + if (content=="") + { + print "Post is empty." + return + } + + yy=y+0 + mm=m+0 + dd=d+0 + hh=h+0 + + if(yy0) + { + gsub(/[\r\n]/,"",temp) + eq=index(temp,"=") + tn=substr(temp,1,eq-1) + tv=substr(temp,eq+1) + if(tn=="username") + { + if(urldecode(tv)!=name) + { + print "Can't replace, post belongs to "substr(temp,eq+1) + close(postfile) + return + } + } + else if(tn=="password") + { + if(urldecode(tv)!=pass) + { + print "Can't replace, wrong password" + close(postfile) + return + } + } + else if(tn ~ /^[ou]ngd?-[0-9]+$/) + { + ongtable[tn]=brunescape(tv) + } + else if(tn == "key") + key=tv + } + close(postfile) + + # if(replace!="") + # { + # #print "Repalce post "replaceid + # while((getline temp < replacefile)>0) + # { + # gsub(/[\r\n]/,"",temp) + # eq=index(temp,"=") + # if(substr(temp,1,eq-1)=="username") + # { + # if(substr(temp,eq+1)!=urlencode(name)) + # { + # print "Can't replace, post belongs to "substr(temp,eq+1) + # close(replacefile) + # return + # } + # } + # else if(substr(temp,1,eq-1)=="password") + # { + # if(substr(temp,eq+1)!=urlencode(pass,"all")) + # { + # print "Can't replace, wrong password" + # close(replacefile) + # return + # } + # } + # } + # close(replacefile) + # system("rm -f " replacefile) + + # } + printf("")>postfile + + print "timenumber="htmlescape(postid) >> postfile + print "key="(key==""?newkey():key) >> postfile + print "username="urlencode(name) >> postfile + print "password="urlencode(pass,"all") >> postfile + print "username_h="htmlescape(name) >> postfile + + # print("Post time:\n"d"."m"."y" "h":00") + print "h="htmlescape(h) >> postfile + print "d="htmlescape(d) >> postfile + print "m="htmlescape(m) >> postfile + print "y="htmlescape(y) >> postfile + + if(nobb!="") + print "disable_bbcode=on" >> postfile + if(nosmil!="") + print "disable_smilies=on" >> postfile + if(nourl!="") + print "disable_magic_url=on" >> postfile + if(sig!="") + print "attach_sig=on" >> postfile + if(notify!="") + print "notify=on" >> postfile + if(silent!="") + print "silent=on" >> postfile + + print "subject="urlencode(subject) >> postfile + print "subject_h="htmlescape(subject) >> postfile + + print "brtext="brescape(content) >> postfile + + gsub(/\[br\]/,"\n",content) + + for(i=0; content~/\[ong\]/; ++i) + { + tn=sprintf("ong-%u",i) + ongtext = ongtable[tn] + if (ongtext == "") + ongtext=ong() + print(tn"="brescape(ongtext)) >> postfile + sub(/\[ong\]/,subescape(ongtext),content) + } + for(i=0; content~/\[ung\]/; ++i) + { + tn=sprintf("ung-%u",i) + ongtext = ongtable[tn] + if (ongtext == "") + ongtext=ung() + print(tn"="brescape(ongtext)) >> postfile + sub(/\[ung\]/,subescape(ongtext),content) + } + for(i=0; content~/\[ong=decree\]/; ++i) + { + tn=sprintf("ongd-%u",i) + ongtext = ongtable[tn] + if (ongtext == "") + ongtext=ong("decree") + print(tn"="brescape(ongtext)) >> postfile + sub(/\[ong=decree\]/,subescape(ongtext),content) + } + for(i=0; content~/\[ung=decree\]/; ++i) + { + tn=sprintf("ungd-%u",i) + ongtext = ongtable[tn] + if (ongtext == "") + ongtext=ung("decree") + print(tn"="brescape(ongtext)) >> postfile + sub(/\[ung=decree\]/,subescape(ongtext),content) + } + + # print "content:\n"content + print "BBHTML="htmlescape(content,"","br") >> postfile + print "BB="htmlescape(content,"less","br") >> postfile + print "message="urlencode(content ((silent=="")?(nobb==""?"[right][size=80]-- posted by SilentBot [img]http://forums.xkcd.com/download/file.php?id=47884[/img][/size][/right]":"\n\n-- posted by SilentBot"):"")) >> postfile + + print "posted." + system ("mawk -f "bb2html" -v outfile=\""postfile"\" \""postfile"\"") + system ("wait 1") + close (postfile) +} + +function urlencode(name,all, len,iii,escaped,ch) +{ + len=length(name) + escaped="" + for(iii=1;iii<=len;++iii) + { + ch=substr(name,iii,1); + if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all=="")) + escaped = escaped ch + else + escaped = escaped "%" ch2hex[ch] + } + return escaped +} +function hexencode(name, len,iii,escaped,ch) +{ + len=length(name) + escaped="" + for(iii=1;iii<=len;++iii) + { + ch=substr(name,iii,1) + escaped = escaped ch2hex[ch] + } + return escaped +} +function subescape(subtext) +{ + gsub(/&/,"\\\\\\&",subtext) + return subtext +} + +function htmlescape(name,less,br, len,iii,escaped,ch) +{ + len=length(name) + escaped="" + for(iii=1;iii<=len;++iii) + { + ch=substr(name,iii,1); + if(ch == "\n") + escaped = escaped ((br!="")?"
":"&#"ch2dec[ch]";") + else if(ch =="\r") + escaped = escaped ((br!="")?"":"&#"ch2dec[ch]";") + else if(ch ~ /[\" ]/ && less=="")#"#"\"" + escaped = escaped "&#"ch2dec[ch]";" + else if(ch ~ /[=<>&]/) + escaped = escaped "&#"ch2dec[ch]";" + else + escaped = escaped ch + } + return escaped +} + +function getmeme(decree ,meme,i) +{ + if(decree!="" && lastdecr=="") + { + close(tempfile) + system (automome" -lc 256 -n "memenumber" -d "memepath" -t \"[decr]\" > "tempfile) + } + else if(decree=="" && lastdecr!="") + { + close(tempfile) + system (automome" -lc 256 -n "memenumber" -d "memepath" > "tempfile) + } + for(i=0; ((getline meme < tempfile)<=0) && (i<3); ++i) + { + memenumber=memenumber*2 + close(tempfile) + if(decree!="") + system (automome" -lc 256 -n "memenumber" -d "memepath" -t \"[decr]\" > "tempfile) + else + system (automome" -lc 256 -n "memenumber" -d "memepath" > "tempfile) + } + lastdecr=decree + return meme +} + +function ong(decree, line) +{ + # system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile) + + while((line=getmeme(decree))!="") + { + gsub(/[\r\n]/,"",line) + if(sub(/[AEIOUY]-N-G/,"#O-N-G#",line)>0) + return preparebb(line) + if(sub(/O+N+G+/,"#&#",line)>0) + return preparebb(line) + if(sub(/DON'T/,"D#ON'G#T",line)>0) + return preparebb(line) + if(sub(/[AEIOUY]NG/,"#ONG#",line)>0) + { + if($0!~/TH\[b\]ONG/) + return preparebb(line) + } + if(sub(/ON /,"#ONG# ",line)>0) + return preparebb(line) + if(sub(/O\.?$/,"#ONG# ",$0)>0) + return preparebb(line) + } + return "Ong" +} + +function ung(decree, line) +{ + # system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile) + + while((line=getmeme(decree))!="")#((getline line < tempfile)>0) + { + gsub(/[\r\n]/,"",line) + if(sub(/[AEIOUY]-N-G/,"#U-N-G#",line)>0) + return preparebb(line) + if(sub(/U+N+G+/,"#&#",line)>0) + return preparebb(line) + if(sub(/[AEIOUY]NG/,"#UNG#",line)>0) + return preparebb(line) + if(sub(/UN /,"#UNG# ",line)>0) + return preparebb(line) + if(sub(/U\.?$/,"#UNG# ",$0)>0) + return preparebb(line) + } + return "Ung" +} +function preparebb(rh) +{ + if(nobb=="") + { + gsub(/\*\*/,"¤",rh) + gsub(/\*[^\*]+\*/,"±&±",rh) + gsub(/±\*/,"[i]",rh) + gsub(/\*±/,"[/i]",rh) + gsub(/¤/,"*",rh) + + gsub(/&&/,"¤",rh) + gsub(/&[^&]+&/,"±&±",rh) + gsub(/±&/,"[center][b]",rh) + gsub(/&±/,"[/b][/center]",rh) + gsub(/¤/,"\\&",rh) + + gsub(/__/,"¤",rh) + gsub(/_[^_]+_/,"±&±",rh) + gsub(/±_/,"[u]",rh) + gsub(/_±/,"[/u]",rh) + gsub(/¤/,"_",rh) + + gsub(/##/,"¤",rh) + gsub(/#[^#]+#/,"±&±",rh) + gsub(/±#/,"[b]",rh) + gsub(/#±/,"[/b]",rh) + gsub(/¤/,"#",rh) + + gsub(/\$\$/,"¤",rh) + gsub(/\$[^\$]+\$/,"±&±",rh) + gsub(/±\$/,"[size=80]",rh) + gsub(/\$±/,"[/size]",rh) + gsub(/¤/,"$",rh) + } + + return rh (nobb==""?" -- [url=http://1190.bicyclesonthemoon.info/ongtext?b=on][b]ong[/b]o[/url][url=http://mrob.com/time/automome/]mome[/url]":" -- ongomome") +} +function unhtml(ht ,i,j,un,num) +{ + gsub(//,"[br]",ht) + while ((i=match(ht, /&#[0-9]+;/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + j=index(ht, ";") + num=int(substr(ht, 3, j-3)) + un=un sprintf("%c",num) + ht=substr(ht, j+1) + } + un=un ht + return un +} +function brescape(text) #there will be more +{ + gsub(/\r/,"",text) + gsub(/\n/,"[br]",text) + return text +} +function brunescape(text) #there will be more +{ + gsub(/\[br\]/,"\n",text) + return text +} +function urldecode(ht ,i,j,un,num) +{ + while ((i=match(ht, /%[0-9a-fA-F][0-9a-fA-F]/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + num=toupper(substr(ht, 2, 2)) + un=un hex2ch[num] + ht=substr(ht, 4) + } + un=un ht + return un +} +function newkey( key,i,rn) +{ + for(i=0; i<8; ++i) + { + rn=int(rand()*65536) + key = key sprintf("%04X",rn) + } + return key +} \ No newline at end of file diff --git a/upload.c b/upload.c new file mode 100644 index 0000000..24c5d09 --- /dev/null +++ b/upload.c @@ -0,0 +1,97 @@ +// upload.c (1190.bicyclesonthemoon.info/silentbot/upload) +// The post upload interface +// 28.03.2015 +// +// Copyright (C) 2015 Balthasar Szczepański +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include + +#define RM_PATH "/bin/rm" +#define MAWK_PATH "/usr/bin/mawk" +#define AWK_UPLOAD "/eizm/pro/t1i/upload.awk" +#define TEMP_PATH "/eizm/tmp/t1i/upload." +#define RM_PATH "/bin/rm" + +s_cgi *cgi; +pid_t sub; +int r; + +int main(int argc, char **argv) +{ + char *temppath; + char **up; + time_t posttime; + struct tm *nowS; + char timetext[64]; + char timenumber[64]; + char temppath2[247]; + char temppath3[256]; + + setvbuf(stdout, NULL, _IONBF, 0); + dup2(fileno(stdout),fileno(stderr)); + + cgi=cgiInit(); + + sprintf(temppath2,"%s%lu",TEMP_PATH,(unsigned long)getpid()); + sprintf(temppath3,"tempfile=%s",temppath2); + + printf("Content-type: text\n\n"); + up=cgiGetFiles(cgi); + if (up) + { + temppath=cgiGetFile(cgi,up[0])->tmpfile; + + posttime=time(NULL); + nowS=gmtime(&posttime); + + sprintf(timenumber,"timenumber=%lu",(unsigned long)posttime); + sprintf(timetext,"timetext=%04d%02d%02d%02d",nowS->tm_year+1900,nowS->tm_mon+1,nowS->tm_mday,nowS->tm_hour); + + // printf("%s\n%s\n%s\n",timenumber,timetext,temppath); + + sub=fork(); + if(!sub) + { + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_UPLOAD,"-v",timetext,"-v",timenumber,"-v",temppath3,temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + sub=fork(); + if(!sub) + { + r=execl(RM_PATH,RM_PATH,"-f",temppath2,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + + return 0; + } + printf("File missing\n"); + return 0; +} diff --git a/verify.awk b/verify.awk new file mode 100644 index 0000000..a0ffc4e --- /dev/null +++ b/verify.awk @@ -0,0 +1,77 @@ +#// verify.awk +#// Check if post belongs to user +#// 25.04.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepański +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + +BEGIN{ + FS="=" + for(i=0;i<256;++i) + { + ch=sprintf("%c",i) + hex=sprintf("%02X",i); + ch2hex[ch]=hex + hex2ch[hex]=ch + } + if(reversed!="") + { + ok=1 + fail=0 + } + else + { + ok=0 + fail=1 + } +} +{ + gsub(/[\r\n]/,"",$0) + eq=index($0,"=") + argtab[substr($0,1,eq-1)]=substr($0,eq+1) +} +END{ + if(argtab["username"]==""||argtab["password"]==""||(urldecode(argtab["username"])==name&&urldecode(argtab["password"])==pass)) + exit ok + else + exit fail +} +# function urlencode(name,all, len,iii,escaped,ch) +# { + # len=length(name) + # escaped="" + # for(iii=1;iii<=len;++iii) + # { + # ch=substr(name,iii,1); + # if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all=="")) + # escaped = escaped ch + # else + # escaped = escaped "%" ch2hex[ch] + # } + # return escaped +# } +function urldecode(ht ,i,j,un,num) +{ + while ((i=match(ht, /%[0-9a-fA-F][0-9a-fA-F]/))!=0)# + { + un=un substr(ht, 1, i-1) + ht=substr(ht, i) + num=toupper(substr(ht, 2, 2)) + un=un hex2ch[num] + ht=substr(ht, 4) + } + un=un ht + return un +} diff --git a/view.awk b/view.awk new file mode 100644 index 0000000..fcccc6d --- /dev/null +++ b/view.awk @@ -0,0 +1,59 @@ +#// view.awk +#// insert text +#// 27.03.2015 +#// +#// Copyright (C) 2015 Balthasar Szczepañski +#// +#// This program is free software: you can redistribute it and/or modify +#// it under the terms of the GNU Affero General Public License as +#// published by the Free Software Foundation, either version 3 of the +#// License, or (at your option) any later version. +#// +#// This program is distributed in the hope that it will be useful, +#// but WITHOUT ANY WARRANTY; without even the implied warranty of +#// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#// GNU Affero General Public License for more details. +#// +#// You should have received a copy of the GNU Affero General Public License +#// along with this program. If not, see . + + +###reusedfrommirror; + +{ + # if ($0 ~ /^###sig&/) + # { + # split ($0 ,arr,"&") + # system("cat " sig arr[2]) + # } + # else if ($0 ~ /^###inf&/) + # { + # split ($0 ,arr,"&") + # system("cat " otterinf arr[2]) + # } + # else if ($0 ~ /^###prev/) + # { + # print left + # } + # else if ($0 ~ /^###next/) + # { + # print right + # } + # else if ($0 ~ /^###links/) + # { + # system ("cat " links); + # } + # else + if ($0 ~ /^###info/) + { + print info; + } + else if ($0 ~ /^###title/) + { + print title; + } + else + { + print $0 + } +}; diff --git a/viewer.c b/viewer.c new file mode 100644 index 0000000..2bed7e5 --- /dev/null +++ b/viewer.c @@ -0,0 +1,246 @@ +// viewer.c (1190.bicyclesonthemoon.info/bluet1i/viewer) +// The viewer +// 08.04.2015 +// +// Copyright (C) 2015 Balthasar Szczepań +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#define MAX 1414 +#define NOTICE_PATH "/eizm/mem/aftertime/mpost/" +#define OLD_NOTICE_PATH "/eizm/mem/t1i/notice/" +#define AWK_NOTICE "/eizm/pro/t1i/notice.awk" +#define MAWK_PATH "/usr/bin/mawk" +#define REDIRECT "/aftertime/viewer?story=t1i" + +#include +#include +#include +#include +#include +#include + +s_cgi *cgi; + +int main (int argc, char *argv[]) +{ + s_cgi *cgi; + pid_t sub; + int r; + + char *value; + char *bb; + char *spoiler; + char *blue; + char *nn; + + unsigned char round; + unsigned short cgiFrame; + unsigned char bl; + char alttext[256]; + char notice[256]; + char arg1[256]; + char arg2[256]; + char redirect[256]; + + FILE *file; + unsigned char i; + + cgi=cgiInit(); + + value=cgiGetValue(cgi,"f"); + if(value!=NULL) + sscanf(value,"%hu",&cgiFrame); + else + cgiFrame=0; + + nn=cgiGetValue(cgi,"n"); + if(nn!=NULL) + sscanf(nn,"%hhu",&round); + else + round=0; + + blue=cgiGetValue(cgi,"blue"); + if(blue!=NULL) + sscanf(blue,"%hhu",&bl); + else + bl=1; + + bb=cgiGetValue(cgi,"b"); + spoiler=cgiGetValue(cgi,"s"); + +#if defined REDIRECT + strcpy(redirect,REDIRECT); + if(value!=NULL) + sprintf(redirect+strlen(redirect),"&f=%s",value); + if(nn!=NULL) + sprintf(redirect+strlen(redirect),"&n=%s",nn); + if(blue!=NULL) + sprintf(redirect+strlen(redirect),"&e=%s",blue); + if(bb!=NULL) + sprintf(redirect+strlen(redirect),"&b=%s",bb); + cgiRedirect(redirect); + return 0; +#endif + + if(cgiFrame<0) + cgiFrame=0; + else if(cgiFrame>MAX) + cgiFrame=MAX; + + if(cgiFrame>=1400) + strcpy(alttext,"The end."); + else if(cgiFrame>=1381) + strcpy(alttext,"..."); + else if(cgiFrame>=1196) + strcpy(alttext,"Wait for it."); + else if(cgiFrame>=1192) + strcpy(alttext,"..."); + else if(cgiFrame>=1185) + strcpy(alttext,"Wait for it."); + else if(cgiFrame>=1174) + strcpy(alttext,"..."); + else if(cgiFrame>=1172) + strcpy(alttext,"LOOK OUT!"); + else if(cgiFrame>=1158) + strcpy(alttext,"..."); + else if(cgiFrame>=1046) + strcpy(alttext,"LOOK OUT!"); + else if(cgiFrame>=1039) + strcpy(alttext,"..."); + else if(cgiFrame>=1007) + strcpy(alttext,"Wait for it."); + else if(cgiFrame>=1002) + strcpy(alttext,"..."); + else if(cgiFrame>=972) + strcpy(alttext,"LOOK OUT!"); + else if(cgiFrame>=961) + strcpy(alttext,"..."); + else if(cgiFrame>=715) + strcpy(alttext,"Wait for it."); + else if(cgiFrame>=687) + strcpy(alttext,"..."); + else if(cgiFrame>=653) + strcpy(alttext,"LOOK OUT!"); + else if(cgiFrame>=633) + strcpy(alttext,"..."); + else + strcpy(alttext,"Wait for it."); + + printf("Content-type: text/html\n\n"); + + puts("\n"); + puts("\n"); + printf("%04hu • bluet1i viewer • Bicycles on the Moon\n", cgiFrame); + puts("\n"); + puts("\n"); + puts("\n"); + puts("
\n"); + puts("\"1190.bicyclesonthemoon.info\"
\n"); + printf("

%st1i-%04hu

\n",bl?((bl>1)?((bl>2)?"no fading ":"very blue "):"blue "):"",cgiFrame); + puts("\n",bl); + if(cgiFrame>0) + printf("\n"); + if(cgiFrame%hu >\n",cgiFrame+1,bl,cgiFrame+1); + else + puts("\n"); + printf("\n",MAX,bl,MAX); + + puts("\n"); + + for(i=0;i<=round;++i) + { + sprintf(notice,"%st1i-%04hu-%02hhu",NOTICE_PATH,cgiFrame,i+1); + sprintf(arg1,"url=/bluet1i/viewer?f=%hu&blue=%hhu&n=%hhu",cgiFrame,bl,i+1); + sprintf(arg2,"round=%hhu",round); + + fflush(stdout); + sub=fork(); + if(sub==0) + { + // setvbuf(stdout, NULL, _IONBF, 0); + // dup2(fileno(stdout),fileno(stderr)); + r=execl(MAWK_PATH,MAWK_PATH,"-f",AWK_NOTICE,"-v",arg1,"-v",arg2,notice,(char *)0); + exit(r); + } + waitpid(sub,&r,0); + if(r) + { + if(!i) + { + sprintf(notice,"%s%04hu",OLD_NOTICE_PATH,cgiFrame); + file=fopen(notice,"rt"); + if(file!=NULL) + { + fgets(notice,255,file); + fclose(file); + printf("\n",notice,notice); + } + } + break; + } + + } + + if(bb!=NULL) + { + printf("\n"); + if(spoiler==NULL) + printf("\n",cgiFrame,bl); + } + else + printf("\n",cgiFrame,bl); + + printf("\n",cgiFrame); + + printf("\n",bl); + + puts("
\n"); + + printf("\"the
\n",bl?((bl>1)?((bl>2)?"nofading":"hyperblue"):"bluet1i"):"t1i",cgiFrame,alttext); + + printf("
| < 0< %hu\n",cgiFrame-1,bl,cgiFrame-1); + else + puts("%hu >|
[ "); + if(bl!=0) + printf("original",cgiFrame); + else + puts("original"); + puts(" | "); + if(bl!=1) + printf("blue",cgiFrame); + else + puts("blue"); + puts(" | "); + if(bl!=2) + printf("very blue",cgiFrame); + else + puts("very blue"); + puts(" | "); + if(bl!=3) + printf("no fading",cgiFrame); + else + puts("no fading"); + puts(" ]
Did you notice . . . .
[url=http://1190.bicyclesonthemoon.info/bluet1i/viewer?f=%hu&blue=%hhu][img]http://1190.bicyclesonthemoon.info/bluet1i/%s-%04hu.png[/img][/url]",cgiFrame,bl,bl?((bl>1)?((bl>2)?"nofading":"hyperblue"):"bluet1i"):"t1i",cgiFrame); + if(spoiler!=NULL) + printf("[spoiler]%s[/spoiler]",alttext); + printf("
[spoiler]
[bbcode]
[this frame in mscha's viewer]
go to frame:

\n"); + puts("1190.bicyclesonthemoon.info\n"); + puts("\n"); + puts("
\n"); + + return 0; +} \ No newline at end of file -- 2.30.2