initial commit

This commit is contained in:
Quentin W 2024-07-18 14:09:32 -04:00
commit 5b839e0543
174 changed files with 12261 additions and 0 deletions

27
werc/bin/contrib/fix-rc-scripts Executable file
View file

@ -0,0 +1,27 @@
#!/usr/local/plan9/bin/rc
# Fix rc shell scripts to find rc without launching env every time.
# Invoke with rc and plan9 versions of grep and ed in $PATH
# If your system lacks which (e.g. some gnu/linux)
# substitute the full path to rc in this line:
rc=/usr/local/plan9/bin/rc
firstline='#!'$"rc
if(~ $#* 0) files = *
if not files = $*
myname = `{basename $0}
for(file in $files) {
if(test -d $file) $0 $file/*
if not if(~ $file *$myname) {}
if not if(sed 1q $file | grep '^#!/.*[/ ]rc$' > /dev/null) {
{
echo 1c
echo $firstline
echo .
echo wq
} | ed $file > /dev/null
}
}

12
werc/bin/contrib/hgweb.config Executable file
View file

@ -0,0 +1,12 @@
[web]
style = gitweb
allow_archive = bz2
#[paths]
#w9 = /gsoc/hg/w9/
[collections]
#allow_archive = bz2 zip
/gsoc/hg = /gsoc/hg/
#/var/hg = /var/hg/

47
werc/bin/contrib/hgwebdir.cgi Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
#
# An example CGI script to export multiple hgweb repos, edit as necessary
# send python tracebacks to the browser if an error occurs:
import cgitb
cgitb.enable()
# adjust python path if not a system-wide install:
#import sys
#sys.path.insert(0, "/path/to/python/lib")
# If you'd like to serve pages with UTF-8 instead of your default
# locale charset, you can do so by uncommenting the following lines.
# Note that this will cause your .hgrc files to be interpreted in
# UTF-8 and all your repo files to be displayed using UTF-8.
#
#import os
#os.environ["HGENCODING"] = "UTF-8"
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from mercurial.hgweb.request import wsgiapplication
import mercurial.hgweb.wsgicgi as wsgicgi
# The config file looks like this. You can have paths to individual
# repos, collections of repos in a directory tree, or both.
#
# [paths]
# virtual/path = /real/path
# virtual/path = /real/path
#
# [collections]
# /prefix/to/strip/off = /root/of/tree/full/of/repos
#
# collections example: say directory tree /foo contains repos /foo/bar,
# /foo/quux/baz. Give this config section:
# [collections]
# /foo = /foo
# Then repos will list as bar and quux/baz.
#
# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
# or use a dictionary with entries like 'virtual/path': '/real/path'
def make_web_app():
return hgwebdir("hgweb.config")
wsgicgi.launch(wsgiapplication(make_web_app))

1447
werc/bin/contrib/markdown.pl Executable file

File diff suppressed because it is too large Load diff

427
werc/bin/contrib/md2html.awk Executable file
View file

@ -0,0 +1,427 @@
#!/bin/awk -f
#
# by: Jesus Galan (yiyus) 2009
#
# Usage: md2html.awk file.md > file.html
# See: http://4l77.com/src/md2html.awk
function eschtml(t) {
gsub("&", "\\&", t);
gsub("<", "\\&lt;", t);
return t;
}
function oprint(t){
if(nr == 0)
print t;
else
otext = otext "\n" t;
}
function subref(id){
for(; nr > 0 && sub("<<" id, ref[id], otext); nr--);
if(nr == 0 && otext) {
print otext;
otext = "";
}
}
function nextil(t) {
if(!match(t, /[`<&\[*_\\-]|(\!\[)/))
return t;
t1 = substr(t, 1, RSTART - 1);
tag = substr(t, RSTART, RLENGTH);
t2 = substr(t, RSTART + RLENGTH);
if(ilcode && tag != "`")
return eschtml(t1 tag) nextil(t2);
# Backslash escaping
if(tag == "\\"){
if(match(t2, /^[\\`*_{}\[\]()#+\-\.!]/)){
tag = substr(t2, 1, 1);
t2 = substr(t2, 2);
}
return t1 tag nextil(t2);
}
# Dashes
if(tag == "-"){
if(sub(/^-/, "", t2))
tag = "&#8212;";
return t1 tag nextil(t2);
}
# Inline Code
if(tag == "`"){
if(sub(/^`/, "", t2)){
if(!match(t2, /``/))
return t1 "&#8221;" nextil(t2);
ilcode2 = !ilcode2;
}
else if(ilcode2)
return t1 tag nextil(t2);
tag = "<code>";
if(ilcode){
t1 = eschtml(t1);
tag = "</code>";
}
ilcode = !ilcode;
return t1 tag nextil(t2);
}
if(tag == "<"){
# Autolinks
if(match(t2, /^[^ ]+[\.@][^ ]+>/)){
url = eschtml(substr(t2, 1, RLENGTH - 1));
t2 = substr(t2, RLENGTH + 1);
linktext = url;
if(match(url, /@/) && !match(url, /^mailto:/))
url = "mailto:" url;
return t1 "<a href=\"" url "\">" linktext "</a>" nextil(t2);
}
# Html tags
if(match(t2, /^[A-Za-z\/!][^>]*>/)){
tag = tag substr(t2, RSTART, RLENGTH);
t2 = substr(t2, RLENGTH + 1);
return t1 tag nextil(t2);
}
return t1 "&lt;" nextil(t2);
}
# Html special entities
if(tag == "&"){
if(match(t2, /^#?[A-Za-z0-9]+;/)){
tag = tag substr(t2, RSTART, RLENGTH);
t2 = substr(t2, RLENGTH + 1);
return t1 tag nextil(t2);
}
return t1 "&amp;" nextil(t2);
}
# Images
if(tag == "!["){
if(!match(t2, /(\[.*\])|(\(.*\))/))
return t1 tag nextil(t2);
match(t2, /^[^\]]*/);
alt = substr(t2, 1, RLENGTH);
t2 = substr(t2, RLENGTH + 2);
if(match(t2, /^\(/)){
# Inline
sub(/^\(/, "", t2);
match(t2, /^[^\)]+/);
url = eschtml(substr(t2, 1, RLENGTH));
t2 = substr(t2, RLENGTH + 2);
title = "";
if(match(url, /[ ]+\".*\"[ ]*$/)) {
title = substr(url, RSTART, RLENGTH);
url = substr(url, 1, RSTART - 1);
match(title, /\".*\"/);
title = " title=\"" substr(title, RSTART + 1, RLENGTH - 2) "\"";
}
if(match(url, /^<.*>$/))
url = substr(url, 2, RLENGTH - 2);
return t1 "<img src=\"" url "\" alt=\"" alt "\"" title " />" nextil(t2);
}
else{
# Referenced
sub(/^ ?\[/, "", t2);
id = alt;
if(match(t2, /^[^\]]+/))
id = substr(t2, 1, RLENGTH);
t2 = substr(t2, RLENGTH + 2);
if(ref[id])
r = ref[id];
else{
r = "<<" id;
nr++;
}
return t1 "<img src=\"" r "\" alt=\"" alt "\" />" nextil(t2);
}
}
# Links
if(tag == "["){
if(!match(t2, /(\[.*\])|(\(.*\))/))
return t1 tag nextil(t2);
match(t2, /^[^\]]*(\[[^\]]*\][^\]]*)*/);
linktext = substr(t2, 1, RLENGTH);
t2 = substr(t2, RLENGTH + 2);
if(match(t2, /^\(/)){
# Inline
match(t2, /^[^\)]+(\([^\)]+\)[^\)]*)*/);
url = substr(t2, 2, RLENGTH - 1);
pt2 = substr(t2, RLENGTH + 2);
title = "";
if(match(url, /[ ]+\".*\"[ ]*$/)) {
title = substr(url, RSTART, RLENGTH);
url = substr(url, 1, RSTART - 1);
match(title, /\".*\"/);
title = " title=\"" substr(title, RSTART + 1, RLENGTH - 2) "\"";
}
if(match(url, /^<.*>$/))
url = substr(url, 2, RLENGTH - 2);
url = eschtml(url);
return t1 "<a href=\"" url "\"" title ">" nextil(linktext) "</a>" nextil(pt2);
}
else{
# Referenced
sub(/^ ?\[/, "", t2);
id = linktext;
if(match(t2, /^[^\]]+/))
id = substr(t2, 1, RLENGTH);
t2 = substr(t2, RLENGTH + 2);
if(ref[id])
r = ref[id];
else{
r = "<<" id;
nr++;
}
pt2 = t2;
return t1 "<a href=\"" r "\" />" nextil(linktext) "</a>" nextil(pt2);
}
}
# Emphasis
if(match(tag, /[*_]/)){
ntag = tag;
if(sub("^" tag, "", t2)){
if(stag[ns] == tag && match(t2, "^" tag))
t2 = tag t2;
else
ntag = tag tag
}
n = length(ntag);
tag = (n == 2) ? "strong" : "em";
if(match(t1, / $/) && match(t2, /^ /))
return t1 tag nextil(t2);
if(stag[ns] == ntag){
tag = "/" tag;
ns--;
}
else
stag[++ns] = ntag;
tag = "<" tag ">";
return t1 tag nextil(t2);
}
}
function inline(t) {
ilcode = 0;
ilcode2 = 0;
ns = 0;
return nextil(t);
}
function printp(tag) {
if(!match(text, /^[ ]*$/)){
text = inline(text);
if(tag != "")
oprint("<" tag ">" text "</" tag ">");
else
oprint(text);
}
text = "";
}
BEGIN {
blank = 0;
code = 0;
hr = 0;
html = 0;
nl = 0;
nr = 0;
otext = "";
text = "";
par = "p";
}
# References
!code && /^ *\[[^\]]*\]:[ ]+/ {
sub(/^ *\[/, "");
match($0, /\]/);
id = substr($0, 1, RSTART - 1);
sub(id "\\]:[ ]+", "");
title = "";
if(match($0, /\".*\"$/))
title = "\" title=\"" substr($0, RSTART + 1, RLENGTH - 2);
sub(/[ ]+\".*\"$/, "");
url = eschtml($0);
ref[id] = url title;
subref(id);
next;
}
# html
!html && /^<(address|blockquote|center|dir|div|dl|fieldset|form|h[1-6r]|\
isindex|menu|noframes|noscript|ol|p|pre|table|ul|!--)/ {
if(code)
oprint("</pre></code>");
for(; !text && block[nl] == "blockquote"; nl--)
oprint("</blockquote>");
match($0, /^<(address|blockquote|center|dir|div|dl|fieldset|form|h[1-6r]|\
isindex|menu|noframes|noscript|ol|p|pre|table|ul|!--)/);
htag = substr($0, 2, RLENGTH - 1);
if(!match($0, "(<\\/" htag ">)|((^<hr ?\\/?)|(--)>$)"))
html = 1;
if(html && match($0, /^<hr/))
hr = 1;
oprint($0);
next;
}
html && (/(^<\/(address|blockquote|center|dir|div|dl|fieldset|form|h[1-6r]|\
isindex|menu|noframes|noscript|ol|p|pre|table|ul).*)|(--)>$/ ||
(hr && />$/)) {
html = 0;
hr = 0;
oprint($0);
next;
}
html {
oprint($0);
next;
}
# List and quote blocks
# Remove indentation
{
for(nnl = 0; nnl < nl; nnl++)
if((match(block[nnl + 1], /[ou]l/) && !sub(/^( | )/, "")) || \
(block[nnl + 1] == "blockquote" && !sub(/^> ?/, "")))
break;
}
nnl < nl && !blank && text && ! /^ ? ? ?([*+-]|([0-9]+\.)+)( +| )/ { nnl = nl; }
# Quote blocks
{
while(sub(/^> /, ""))
nblock[++nnl] = "blockquote";
}
# Horizontal rules
{ hr = 0; }
(blank || (!text && !code)) && /^ ? ? ?([-*_][ ]*)([-*_][ ]*)([-*_][ ]*)+$/ {
if(code){
oprint("</pre></code>");
code = 0;
}
blank = 0;
nnl = 0;
hr = 1;
}
# List items
block[nl] ~ /[ou]l/ && /^$/ {
blank = 1;
next;
}
{ newli = 0; }
!hr && (nnl != nl || !text || block[nl] ~ /[ou]l/) && /^ ? ? ?[*+-]( +| )/ {
sub(/^ ? ? ?[*+-]( +| )/, "");
nnl++;
nblock[nnl] = "ul";
newli = 1;
}
(nnl != nl || !text || block[nl] ~ /[ou]l/) && /^ ? ? ?([0-9]+\.)+( +| )/ {
sub(/^ ? ? ?([0-9]+\.)+( +| )/, "");
nnl++;
nblock[nnl] = "ol";
newli = 1;
}
newli {
if(blank && nnl == nl && !par)
par = "p";
blank = 0;
printp(par);
if(nnl == nl && block[nl] == nblock[nl])
oprint("</li><li>");
}
blank && ! /^$/ {
if(match(block[nnl], /[ou]l/) && !par)
par = "p";
printp(par);
par = "p";
blank = 0;
}
# Close old blocks and open new ones
nnl != nl || nblock[nl] != block[nl] {
if(code){
oprint("</pre></code>");
code = 0;
}
printp(par);
b = (nnl > nl) ? nblock[nnl] : block[nnl];
par = (match(b, /[ou]l/)) ? "" : "p";
}
nnl < nl || (nnl == nl && nblock[nl] != block[nl]) {
for(; nl > nnl || (nnl == nl && pblock[nl] != block[nl]); nl--){
if(match(block[nl], /[ou]l/))
oprint("</li>");
oprint("</" block[nl] ">");
}
}
nnl > nl {
for(; nl < nnl; nl++){
block[nl + 1] = nblock[nl + 1];
oprint("<" block[nl + 1] ">");
if(match(block[nl + 1], /[ou]l/))
oprint("<li>");
}
}
hr {
oprint("<hr>");
next;
}
# Code blocks
code && /^$/ {
if(blanK)
oprint("");
blank = 1;
next;
}
!text && sub(/^( | )/, "") {
if(blanK)
oprint("");
blank = 0;
if(!code)
oprint("<code><pre>");
code = 1;
$0 = eschtml($0);
oprint($0);
next;
}
code {
oprint("</pre></code>");
code = 0;
}
# Setex-style Headers
text && /^=+$/ {printp("h1"); next;}
text && /^-+$/ {printp("h2"); next;}
# Atx-Style headers
/^#+/ && (!newli || par=="p" || /^##/) {
for(n = 0; n < 6 && sub(/^# */, ""); n++)
sub(/#$/, "");
par = "h" n;
}
# Paragraph
/^$/ {
printp(par);
par = "p";
next;
}
# Add text
{ text = (text ? text " " : "") $0; }
END {
if(code){
oprint("</pre></code>");
code = 0;
}
printp(par);
for(; nl > 0; nl--){
if(match(block[nl], /[ou]l/))
oprint("</li>");
oprint("</" block[nl] ">");
}
gsub(/<<[^\"]*/, "", otext);
print(otext);
}

View file

@ -0,0 +1,6 @@
#!/bin/rc
if(~ $REMOTE_USER ''){
extra_headers=($extra_headers 'WWW-Authenticate: Basic realm="'$"SERVER_NAME'"')
error 401
exit
}

View file

@ -0,0 +1,46 @@
#!/bin/rc
fn filter_headers{
response=(200 OK)
lines=''
done=false
while(~ $done false){
line=`{getline}
head=`{echo $line | awk '{print tolower($1)}'}
if(~ $head status:*)
response=`{echo $line | awk '{$1="" ; print}'}
if not if(~ $line '')
done=true
if not
lines=$"lines^$"line^$cr^'
'
}
echo 'HTTP/1.1' $"response^$cr
echo -n $"lines
do_log $response(1)
}
fn run_cgi {
path=$cgi_path exec $"cgi_bin $params || echo 'Status: 500'
}
cgi_bin=$1
cgi_dir=.
if(! ~ $#* 1)
cgi_dir=$*($#*)
if not if(~ $"cgi_bin /*){
cgi_dir=`{basename -d $"cgi_bin}
cgi_dir=$"cgi_dir
}
if(! ~ $"cgi_bin */*)
cgi_bin=./$"cgi_bin
if(! builtin cd $"cgi_dir >[2]/dev/null || ! test -x $"cgi_bin){
error 500
exit
}
run_cgi | {
filter_headers
emit_extra_headers
echo $cr
exec cat
}

View file

@ -0,0 +1,111 @@
#!/bin/rc
PATH_INFO=`{echo $PATH_INFO | urldecode.awk}
full_path=$"FS_ROOT^$"PATH_INFO
full_path=$"full_path
if(! test -d $full_path){
error 404
exit
}
if(! test -r $full_path -x $full_path){
error 503
exit
}
do_log 200
builtin cd $full_path
if(~ $"NOINDEXFILE ^ $"NOINDEX ''){
ifile=index.htm*
if(! ~ $ifile(1) *'*'){
PATH_INFO=$ifile(1)
FS_ROOT=''
exec serve-static
}
}
title=`{echo $SITE_TITLE | sed s,%s,^$"PATH_INFO^,}
title=$"title
lso=()
switch($2){
case size
# ls has no option to sort by size
# could pipe it through sort, I suppose
case date
lso=-t
}
echo 'HTTP/1.1 200 OK'^$cr
emit_extra_headers
echo 'Content-type: text/html'^$cr
echo $cr
echo '<html>
<head>
<title>'^$title^'</title>
<style type="text/css">
.size {
text-align: right;
padding-right: 4pt;
}
.day {
text-align: right;
padding-right: 3pt;
}
.datetime {
text-align: right;
}
.name {
text-align: right;
padding-left: 3pt;
}
</style>
</head>
<body>'
echo '<h1>'^$title^'</h1>'
if(! ~ $PATH_INFO /)
echo '<a href="../">Parent directory</a>'
echo '<table>'
ls -lQ $lso | awk '
function urlencode(loc){
# very minimal encoding, just enough for our static-file purposes
url=loc
gsub("%", "%25", url) # this one first!
gsub("\\$", "%24", url)
gsub("&", "%26", url)
gsub("\\+", "%2B", url)
gsub("\\?", "%3F", url)
gsub(" ", "%20", url)
gsub("\"", "%22", url)
gsub("#", "%23", url)
return url
}
function hrsize(size){
if(size > 1073741824) return sprintf("%.1fGB", size/1073741824)
if(size > 10485760) return sprintf("%iMB", size/1048576)
if(size > 1048576) return sprintf("%.1fMB", size/1048576)
if(size > 10240) return sprintf("%iKB", size/1024)
if(size > 1024) return sprintf("%.1fKB", size/1024)
return sprintf("%iB", size)
}
/^(-|a)/ {
print "<tr>"
print "<td class=\"size\">"hrsize($6)"</td>"
print "<td class=\"month\">"$7"</td>"
print "<td class=\"day\">"$8"</td>"
print "<td class=\"datetime\">"$9"</td>"
$1="" ; $2="" ; $3="" ; $4="" ; $5="" ; $6="" ; $7="" ; $8="" ; $9=""
sub("^ *?", "")
print "<td><a class=\"file name\" href=\""urlencode($0)"\">"$0"</a></td>"
print "</tr>"
$0=""
}
/^d/ {
print "<tr>"
print "<td class=\"size\"> </td>"
print "<td class=\"month\">"$7"</td>"
print "<td class=\"day\">"$8"</td>"
print "<td class=\"datetime\">"$9"</td>"
$1="" ; $2="" ; $3="" ; $4="" ; $5="" ; $6="" ; $7="" ; $8="" ; $9=""
sub("^ *?", "")
print "<td><a class=\"dir name\" href=\""urlencode($0)"/\">"$0"/</a></td>"
print "</tr>"
}'
echo '</table>
</body>
</html>'

View file

@ -0,0 +1,43 @@
#!/bin/rc
# DO NOT make this script callable directly from the web!
fn do_error{
echo 'HTTP/1.1 '^$1^$cr
emit_extra_headers
echo 'Content-type: text/html'^$cr
echo $cr
echo '<html>
<head>
<title>'^$1^'</title>
</head>
<body>
<h1>'^$1^'</h1>'
echo $2
echo '<p><i>rc-httpd at' $SERVER_NAME '</i>'
echo '
</body>
</html>
'
}
fn 401{
do_error '401 Unauthorized' \
'The requested path '^$"location^' requires authorization.'
}
fn 404{
do_error '404 Not Found' \
'The requested path '^$"location^' was not found on this server.'
}
fn 500{
do_error '500 Internal Server Error' \
'The server has encountered an internal misconfiguration and is unable to satisfy your request.'
}
fn 503{
do_error '503 Forbidden' \
'You do not have permission to access '^$"location^' on this server.'
}
do_log $1
$1

View file

@ -0,0 +1,30 @@
#!/bin/rc
if(~ $#2 0){
error 500
exit
}
switch($1){
case perm*
do_log 301
echo 'HTTP/1.1 301 Moved Permanently'^$cr
case temp*
do_log 302
echo 'HTTP/1.1 302 Moved Temporarily'^$cr
case seeother
do_log 303
echo 'HTTP/1.1 303 See Other'^$cr
case *
error 500
exit
}
echo 'Location: ' ^ $2 ^ $cr
emit_extra_headers
echo 'Content-type: text/html'^$cr
echo $cr
echo '<html><body>'
if(~ $#3 0)
echo 'Browser did not accept redirect.'
if not
echo $3
echo '<a href="'^$"location^'/">Click here</a>'
echo '</body></html>'

View file

@ -0,0 +1,43 @@
#!/bin/rc
full_path=`{echo $"FS_ROOT^$"PATH_INFO | urldecode.awk}
full_path=$"full_path
if(~ $full_path */)
error 503
if(test -d $full_path){
redirect perm $"location^'/' \
'URL not quite right, and browser did not accept redirect.'
exit
}
if(! test -e $full_path){
error 404
exit
}
if(! test -r $full_path){
error 503
exit
}
do_log 200
switch($full_path){
case *.html *.htm
type=text/html
case *.css
type=text/css
case *.txt
type='text/plain; charset=utf-8'
case *.jpg *.jpeg
type=image/jpeg
case *.gif
type=image/gif
case *.png
type=image/png
case *
type=`{file -m $full_path || file -i $full_path} # GROSS
}
max_age=3600 # 1 hour
echo 'HTTP/1.1 200 OK'^$cr
emit_extra_headers
echo 'Content-type: '^$type^'; charset=utf-8'^$cr
echo 'Content-length: '^`{ls -l $full_path | awk '{print $6}'}
echo 'Cache-control: max-age='^$max_age^$cr
echo $cr
exec cat $full_path

View file

@ -0,0 +1,14 @@
#!/bin/rc
cgiargs=$*
fn error{
if(~ $1 404)
exec cgi $cgiargs
if not
$rc_httpd_dir/handlers/error $1
}
if(~ $location */)
exec cgi $cgiargs
if not
exec serve-static

View file

@ -0,0 +1,5 @@
#!/bin/rc
if(~ $PATH_INFO */)
exec dir-index $params
if not
exec serve-static

View file

@ -0,0 +1,39 @@
# taken from werc
BEGIN {
hextab ["0"] = 0; hextab ["8"] = 8;
hextab ["1"] = 1; hextab ["9"] = 9;
hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
}
{
decoded = ""
i = 1
len = length ($0)
while ( i <= len ) {
c = substr ($0, i, 1)
if ( c == "%" ) {
if ( i+2 <= len ) {
c1 = substr ($0, i+1, 1)
c2 = substr ($0, i+2, 1)
if ( hextab [c1] == "" || hextab [c2] == "" ) {
print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
} else {
code = 0 + hextab [c1] * 16 + hextab [c2] + 0
c = sprintf ("%c", code)
i = i + 2
}
} else {
print "WARNING: invalid % encoding: " substr ($0, i, len - i)
}
} else if ( c == "+" ) {
c = " "
}
decoded = decoded c
++i
}
printf "%s", decoded
}

View file

@ -0,0 +1,102 @@
#!/bin/rc
rc_httpd_dir=/home/sl/www/werc/bin/contrib/rc-httpd
libdir = $rc_httpd_dir/lib
path=($PLAN9/bin $rc_httpd_dir/handlers $PATH)
cgi_path=$PLAN9/bin
SERVER_PORT=80 # default for CGI scripts, may be overridden by the Host header
extra_headers='Server: rc-httpd'
cr=
fn do_log{
echo `{date} :: $SERVER_NAME :: $request :: \
$HTTP_USER_AGENT :: $1 :: $HTTP_REFERER >[1=2]
}
fn emit_extra_headers{
for(header in $extra_headers)
echo $"header^$cr
}
fn getline{ read | sed 's/'^$"cr^'$//g' }
fn terminate{
echo `{date} connection terminated >[1=2]
exit terminate
}
fn trim_input{ dd -bs 1 -count $CONTENT_LENGTH }
request=`{getline}
if(~ $#request 0)
terminate
REQUEST_METHOD=$request(1)
REQUEST_URI=$request(2)
reqlines=''
HTTP_COOKIE=''
REMOTE_USER=''
done=false
chunked=no
while(~ $"done false){
line=`{getline}
if(~ $#line 0)
done=true
reqlines=$"reqlines$"line'
'
h=`{echo $line | awk '{print tolower($1)}'}
switch($h){
case ''
done=true
case host:
SERVER_NAME=$line(2)
case referer:
HTTP_REFERER=$line(2)
case user-agent:
HTTP_USER_AGENT=`{echo $line | sed 's;[^:]+:[ ]+;;'}
case content-length:
CONTENT_LENGTH=$line(2)
case content-type:
CONTENT_TYPE=$line(2)
case cookie:
cookie=`{echo $line | sed 's;^[^:]+:[ ]*;;'}
HTTP_COOKIE=$"HTTP_COOKIE^$"cookie^'; '
case authorization:
REMOTE_USER=`{auth/httpauth $line(3)}
case transfer-encoding:
~ $line(2) chunked && chunked=yes
}
}
if(~ $REQUEST_URI *://* //*){
SERVER_NAME=`{echo $REQUEST_URI | sed '
s;^[^:]+:;;
s;^//([^/]+).*;\1;'}
REQUEST_URI=`{echo $REQUEST_URI | sed '
s;^[^:]+:;;
s;^//[^/]+/?;/;'}
}
QUERY_STRING=`{echo $REQUEST_URI | sed 's;[^?]*\??;;'}
params=`{echo $QUERY_STRING | sed 's;\+; ;g'}
location=`{echo $REQUEST_URI | sed 's;\?.*;;'}
location=`{echo $location | sed '
s;[^/]+/\.\./;/;g
s;/\./;/;g
s;//+;/;g
'}
SERVER_NAME=`{echo $SERVER_NAME | sed 's;^(\[[^\]]+\]|[^:]+)\:([0-9]+)$;\1 \2;'}
if(~ $#SERVER_NAME 2){
SERVER_PORT=$SERVER_NAME(2)
SERVER_NAME=$SERVER_NAME(1)
}
if(~ $REQUEST_METHOD (PUT POST)){
if(! ~ $"CONTENT_LENGTH '')
trim_input | exec $rc_httpd_dir/select-handler
if not{
if(~ $chunked yes){
echo 'HTTP/1.1 411 Length required'^$cr
echo $cr
exit
}
exec $rc_httpd_dir/select-handler
}
}
if not
. $rc_httpd_dir/select-handler

View file

@ -0,0 +1,20 @@
#!/bin/rc
rfork n
# Route requests to werc.
# Change paths to match your system.
if(~ $SERVER_NAME 9base.werc.cat-v.org)
PLAN9=/usr/local/9base
if(~ $SERVER_NAME frontbase.werc.cat-v.org)
PLAN9=/usr/local/plan9front
if(~ $SERVER_NAME plan9port.werc.cat-v.org)
PLAN9=/usr/local/plan9
if(~ $SERVER_NAME *){
PATH_INFO=$location
FS_ROOT=/home/sl/www/werc/sites/$SERVER_NAME
exec static-or-cgi /home/sl/www/werc/bin/werc.rc
}
if not
error 503

7
werc/bin/contrib/tcp80 Executable file
View file

@ -0,0 +1,7 @@
#!/bin/rc
# For use with listen(8).
# Change paths to match your system.
# Eitdit rc-httpd/rc-httpd to match your system.
PLAN9=/usr/local/plan9
PATH=($PATH /home/sl/www/werc/bin/contrib)
exec /home/sl/www/werc/bin/contrib/rc-httpd/rc-httpd >>[2]/var/log/rc-httpd

39
werc/bin/contrib/urldecode.awk Executable file
View file

@ -0,0 +1,39 @@
#!/bin/awk -f
BEGIN {
hextab ["0"] = 0; hextab ["8"] = 8;
hextab ["1"] = 1; hextab ["9"] = 9;
hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
}
{
decoded = ""
i = 1
len = length ($0)
while ( i <= len ) {
c = substr ($0, i, 1)
if ( c == "%" ) {
if ( i+2 <= len ) {
c1 = substr ($0, i+1, 1)
c2 = substr ($0, i+2, 1)
if ( hextab [c1] == "" || hextab [c2] == "" ) {
print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
} else {
code = 0 + hextab [c1] * 16 + hextab [c2] + 0
c = sprintf ("%c", code)
i = i + 2
}
} else {
print "WARNING: invalid % encoding: " substr ($0, i, len - i)
}
} else if ( c == "+" ) {
c = " "
}
decoded = decoded c
++i
}
print decoded
}

126
werc/bin/contrib/urlencode.awk Executable file
View file

@ -0,0 +1,126 @@
# Taken from http://www.shelldorado.com/scripts/cmds/urlencode
##########################################################################
# Title : urlencode - encode URL data
# Author : Heiner Steven (heiner.steven@odn.de)
# Date : 2000-03-15
# Requires : awk
# Categories : File Conversion, WWW, CGI
# SCCS-Id. : @(#) urlencode 1.4 06/10/29
##########################################################################
# Description
# Encode data according to
# RFC 1738: "Uniform Resource Locators (URL)" and
# RFC 1866: "Hypertext Markup Language - 2.0" (HTML)
#
# This encoding is used i.e. for the MIME type
# "application/x-www-form-urlencoded"
#
# Notes
# o The default behaviour is not to encode the line endings. This
# may not be what was intended, because the result will be
# multiple lines of output (which cannot be used in an URL or a
# HTTP "POST" request). If the desired output should be one
# line, use the "-l" option.
#
# o The "-l" option assumes, that the end-of-line is denoted by
# the character LF (ASCII 10). This is not true for Windows or
# Mac systems, where the end of a line is denoted by the two
# characters CR LF (ASCII 13 10).
# We use this for symmetry; data processed in the following way:
# cat | urlencode -l | urldecode -l
# should (and will) result in the original data
#
# o Large lines (or binary files) will break many AWK
# implementations. If you get the message
# awk: record `...' too long
# record number xxx
# consider using GNU AWK (gawk).
#
# o urlencode will always terminate it's output with an EOL
# character
#
# Thanks to Stefan Brozinski for pointing out a bug related to non-standard
# locales.
#
# See also
# urldecode
##########################################################################
PN=`basename "$0"` # Program name
VER='1.4'
: ${AWK=awk}
Usage () {
echo >&2 "$PN - encode URL data, $VER
usage: $PN [-l] [file ...]
-l: encode line endings (result will be one line of output)
The default is to encode each input line on its own."
exit 1
}
Msg () {
for MsgLine
do echo "$PN: $MsgLine" >&2
done
}
Fatal () { Msg "$@"; exit 1; }
set -- `getopt hl "$@" 2>/dev/null` || Usage
[ $# -lt 1 ] && Usage # "getopt" detected an error
EncodeEOL=no
while [ $# -gt 0 ]
do
case "$1" in
-l) EncodeEOL=yes;;
--) shift; break;;
-h) Usage;;
-*) Usage;;
*) break;; # First file name
esac
shift
done
LANG=C export LANG
$AWK '
BEGIN {
# We assume an awk implementation that is just plain dumb.
# We will convert an character to its ASCII value with the
# table ord[], and produce two-digit hexadecimal output
# without the printf("%02X") feature.
EOL = "%0A" # "end of line" string (encoded)
split ("1 2 3 4 5 6 7 8 9 A B C D E F", hextab, " ")
hextab [0] = 0
for ( i=1; i<=255; ++i ) ord [ sprintf ("%c", i) "" ] = i + 0
if ("'"$EncodeEOL"'" == "yes") EncodeEOL = 1; else EncodeEOL = 0
}
{
encoded = ""
for ( i=1; i<=length ($0); ++i ) {
c = substr ($0, i, 1)
if ( c ~ /[a-zA-Z0-9.-]/ ) {
encoded = encoded c # safe character
} else if ( c == " " ) {
encoded = encoded "+" # special handling
} else {
# unsafe character, encode it as a two-digit hex-number
lo = ord [c] % 16
hi = int (ord [c] / 16);
encoded = encoded "%" hextab [hi] hextab [lo]
}
}
if ( EncodeEOL ) {
printf ("%s", encoded EOL)
} else {
print encoded
}
}
END {
#if ( EncodeEOL ) print ""
}
' "$@"

30
werc/bin/contrib/webserver.rc Executable file
View file

@ -0,0 +1,30 @@
#!/bin/rc
# A web server in rc by maht
# Originally from http://www.proweb.co.uk/~matt/rc/webserver.rc
ifs=' '
request=`{sed 1q}
url=$request(2)
file=`{echo $url | sed 's/http:\/\/[^\/]*//' | tr -d \012}
if(test -d $file){
file=$file ^'/index.html'
}
if(test -e $file) {
response='200'
}
if not {
response='404'
file='404.html'
}
echo 'HTTP/1.1 ' ^$response
echo 'Date: ' `{date}
echo 'Server: rc shell'
echo 'Content-Length: ' `{cat $file | wc -c | tr -d ' '}
echo 'Content-Type: ' `{file -i $file | awk '{ print $2 }'}
echo 'Connection: close'
echo
cat $file