Introduction
Introduction Statistics Contact Development Disclaimer Help
Merge. - swerc - anselm's simpler werc fork
git clone git://git.suckless.org/swerc
Log
Files
Refs
README
---
commit 4d495116f0456fabe7aa7988bd53819ea93faa69
parent 4f25d2da49b44924271c90ceb622de93f8f42701
Author: uriel@soma <unknown>
Date: Sun, 1 Feb 2009 19:23:55 +0000
Merge.
Diffstat:
M apps/blagh/app.rc | 6 +++---
M apps/bridge/app.rc | 110 +++++++++++++++++++++++++----…
M apps/bridge/foot.tpl | 39 ++++++++++++++++-------------…
M bin/cgilib.rc | 175 ++++++-----------------------…
A bin/corehandlers.rc | 115 +++++++++++++++++++++++++++++…
M bin/werc.rc | 260 +++++++++--------------------…
A bin/wercconf.rc | 12 ++++++++++++
A bin/werclib.rc | 117 +++++++++++++++++++++++++++++…
M lib/_users/login.tpl | 6 +++---
M lib/headers.tpl | 2 +-
M pub/style/style.css | 12 ++++++++++++
M sites/werc.cat-v.org/_werc/config | 2 +-
12 files changed, 482 insertions(+), 374 deletions(-)
---
diff --git a/apps/blagh/app.rc b/apps/blagh/app.rc
@@ -54,9 +54,9 @@ fn blagh_setup_feed_handlers {
fn blagh_body {
for(p in `{get_post_list $blagh_root^$blagh_dirs}) {
- l=`{echo -n $p|sed 's!'$sitedir^$req_path'!!'}
- sed '1s!.*![&]('$l')!' < $p/index.md | $formatter
- }
+ l=`{echo -n $p|sed 's!'$sitedir^$req_path'./([0-9]+/[0-9][0-9]/[0-9][0…
+ sed '1s!.*![&]('^$l(2)^') ('^$l(1)^')!' < $p/index.md
+ } | $formatter
}
fn get_post_list {
diff --git a/apps/bridge/app.rc b/apps/bridge/app.rc
@@ -1,30 +1,98 @@
comment_file_types=(md html)
+
+fn conf_enable_comments {
+ if(~ $1 -n) {
+ allow_new_user_comments=yes
+ shift
+ }
+ enable_comments=yes
+ groups_allowed_comments=$*
+}
+
fn bridge_init {
- if(! ~ $#enable_comments 0 && ! ~ `{ls $local_path.$comment_file_types >[2…
- ll_add handlers_body_foot template apps/bridge/foot.tpl
- if(get_post_args comment_text) {
- d=`{date -n} # FIXME Obvious race
- d=$local_path^'_werc/comments/'^$d/
-
- u=$logged_user
- if(~ $#logged_user 0) {
- get_post_args comment_user_name comment_user_password
- # XXX Should do this too if user not in required group
- if(! login_user $comment_user_name $comment_user_password) {
- u=$comment_user_name':'$comment_user_password
- d=$d^'_pending'
- }
- if not
- u = $logged_user
- }
+ if(~ $#enable_comments 1) {
+
+ cdir=$sitedir$req_path'_werc/comments'
+ if(test -d $cdir)
+ ll_add handlers_body_foot display_comments $cdir
+
+ if({ check_user $groups_allowed_comments || {~ $#logged_user 0 && ! ~ …
+ ll_add handlers_body_foot template apps/bridge/foot.tpl
+
+ if(~ $REQUEST_METHOD POST && mk_new_comment $cdir)
+ post_redirect $base_url^$post_arg_document_uri
+ if not
+ saved_comment_text=$post_arg_comment_text
+ }
+ }
+}
+
+fn validate_new_user {
+ usr=$1; pass=$2; pass2=$3
+ _status=()
- umask 002
- if(mkdir -m 775 -p $d) { # Rudimentary perm checking
- echo $u > $d/user
- echo $comment_text > $d/body
+ if(~ $"usr '' || ! echo $usr |sed 1q|grep -s '^'$allowed_user_chars'+$')
+ _status='Requested user name is invalid, must match: '^$allowed_user_c…
+ if not if(test -d etc/users/$usr)
+ _status='Sorry, user name '''^$usr^''' already taken, please pick a di…
+
+ if(~ $"pass '' || ! ~ $"pass $"pass2)
+ _status=($_status 'Provided passwords don''t match.')
+
+ status=$_status
+}
+
+
+fn mk_new_comment {
+ _status=()
+ dir=$1
+ if(~ $"post_arg_comment_text '')
+ _status='Provide a comment!'
+ if not if(~ $#logged_user 0) {
+ if(! ~ $#allow_new_user_comments 0) {
+ if(validate_new_user $"post_arg_comment_user $post_arg_comment_pas…
+ u=$post_arg_comment_user':'$post_arg_comment_passwd
+ dir=$cdir^'_pending'
+ # XXX: This doesn't work because we then do a redirect.
+ notify_notes='Saved comment and registration info, they will b…
}
+ if not
+ _status=$status
}
+ if not
+ _status='You need to log in to comment.'
}
+ if not if(check_user $groups_allowed_comments)
+ u=$logged_user
+ if not
+ _status='You are not a memeber of a group allowed to comment.'
+
+ if(~ $#_status 0) {
+ umask 002
+ dir=$dir'/'`{date -n} # FIXME Obvious race
+ mkdir -m 775 -p $dir &&
+ echo $u > $dir/user &&
+ echo $current_date_time > $dir/posted &&
+ echo $post_arg_comment_text > $dir/body
+ _s=$status
+ if(! ~ $"_s '') {
+ dprint 'ERROR XXX: Could not create comment: ' $_s
+ _status='Could not post comment due internal error, sorry.'
+ }
+ }
+ notify_errors=$_status
+ status=$_status
}
+fn display_comments {
+ echo '<hr /><h2>Comments</h2>'
+
+ for(c in `{ls $*/}) {
+ if(test -s $c/body) {
+ ifs=() { echo '<div class="comment"><h5>By: <i>'`{cat $c/user}'</i…
+ cat $c/body | escape_html | sed 's,$,<br />,'
+ echo '<hr /></div>'
+ }
+ }
+}
diff --git a/apps/bridge/foot.tpl b/apps/bridge/foot.tpl
@@ -1,26 +1,27 @@
-% cdir = $local_path^'_werc/comments'
-% if(test -d $cdir) {
- <hr /><h2>Comments</h2>
-% for(c in `{ls $cdir/}) {
- <div><b>By: <i>
-% cat $c/user
- </i></b>
- <br />
-% cat $c/body | escape_html | sed 's,$,<br />,'
- <hr /></div>
-% }
-% }
-
<hr />
+% notices_handler
+% # XXX should post to bridge_post or similar
<form action="" method="post">
- <textarea name="comment_text" id="comment_text" cols="80" rows="16"></text…
+ <textarea name="comment_text" id="comment_text" cols="80" rows="16">%($"sa…
<br />
+ <input type="hidden" name="document_uri" value="%($req_path%)" />
<input type="submit" name="post_comment" value="Post a comment" />
-% if(! check_user) {
- <label>User: <input type="text" name="comment_user_name" value="" /></labe…
- <label>Password: <input type="password" name="comment_user_password" value…
- <div style="font-size: 70%">If you are not registered enter your desired u…
+
+% if(~ $#logged_user 0 && ! ~ $#allow_new_user_comments 0) {
+ <label>New user name:
+ <input type="text" name="comment_user" value="%($"post_arg_comment_use…
+ </label>
+
+ <label>Password:
+ <input type="password" name="comment_passwd" value="" />
+ </label>
+
+ <label>Repeat password:
+ <input type="password" name="comment_passwd2" value="" />
+ </label>
+ <div style="font-size: 70%">
+ Enter your desired user name/password and after your comment has been revi…
+ </div>
% }
</form>
-
diff --git a/bin/cgilib.rc b/bin/cgilib.rc
@@ -1,17 +1,19 @@
-##############################################
-# Useful CGI functions
-
-NEW_LINE='
-'
+# Useful CGI stuff
fn dprint { echo $* >[1=2] }
-fn dprintvars { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; ' }; echo } >…
+fn dprintv { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; ' }; echo } >[1=…
fn escape_html { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' $* }
fn http_redirect {
+ if(~ $1 http:* https:*)
+ t=$1
+ if not if(~ $1 /*)
+ t=$"base_url^$1
+ if not
+ t=$"base_url^$"req_path^$1
echo 'Status: '^$2^'
-Location: '^$1^'
+Location: '^$t^'
'
exit
@@ -19,13 +21,6 @@ Location: '^$1^'
fn perm_redirect { http_redirect $1 '301 Moved Permanantly' }
fn post_redirect { http_redirect $1 '303 See Other' }
-fn static_file {
- echo 'Content-Type: '`{select_mime $1}
- echo
- cat $1
- exit
-}
-
# Note: should check if content type is application/x-www-form-urlencoded?
fn load_post_args {
@@ -111,22 +106,6 @@ BEGIN {
'
}
-fn crop_text {
- ellipsis='...'
- if(~ $#* 2)
- ellipsis=$2
-
- awk -v max'='^$"1^' ' -v 'ellipsis='$ellipsis '
- {
- nc += 1 + length;
- if(nc > max) {
- print substr($0, 1, nc - max) ellipsis
- exit
- }
- print
- }'
-}
-
# Cookies
fn set_cookie {
@@ -143,6 +122,14 @@ fn get_cookie {
{ for(c in $co) echo $c } | sed -n 's/^ ?'$1'=//p'
}
+
+fn static_file {
+ echo 'Content-Type: '`{select_mime $1}
+ echo
+ cat $1
+ exit
+}
+
fn select_mime {
m='text/plain'
if(~ $1 *.css)
@@ -163,128 +150,30 @@ fn select_mime {
##############################################
# Generic rc programming helpers
+# Manage nested lists
fn ll_add {
_l=$1^_^$#$1
$_l=$*(2-)
$1=( $$1 $_l )
}
+NEW_LINE='
+'
-##############################################
-# Werc-specific functions
-
-fn get_lib_file {
- if(! ~ $#sitedir 0 && test -f $sitedir/_werc/lib/$1)
- echo -n $sitedir/_werc/lib/$1
- if not if(! ~ $#masterSite 0 && test -f $sitesdir/$masterSite/_werc/lib/$1)
- echo -n $sitesdir/$masterSite/_werc/lib/$1
- if not if(test -f lib/$1)
- echo -n lib/$1
- if not if(~ $#* 2)
- echo -n $2
- if not
- status='Can''t find lib file: '$1
-}
-
-fn template { awk -f bin/template.awk $* | rc $rcargs }
-
-# Auth code
-
-# Cookie format: WERC_USER: name:timestamp:hash(name.timestamp.password)
-# login_user can't be used from a template because it sets a cookie
-fn login_user {
- # Note: we set the cookie even if it is already there.
- if(get_user $*)
- set_cookie werc_user $"logged_user^':0:'^$"logged_password
-}
-
-# Check loggin status, if called with group arg we check membership too
-fn check_user {
- get_user
- _status=$status
- if(! ~ $#_status 0 )
- _status=(Not logged in: $"_status)
- if not if(! ~ $#* 0 && ! grep -s '^'^$logged_user^'$' etc/groups/$*) {
- dprint NOT IN GROUP
- _status=(User $logged_user not in groups $*)
- }
- status=$_status
-}
-
-# If not logged in, try to get user login info from POST or from cookie
-fn get_user {
- if(~ $#logged_user 0) {
- if(~ $#* 2) {
- user_name=$1
- user_password=$2
- }
- if not if(~ $REQUEST_METHOD POST)
- get_post_args user_name user_password
+fn crop_text {
+ ellipsis='...'
+ if(~ $#* 2)
+ ellipsis=$2
- if(~ $#user_name 0) {
- ifs=':' { cu=`{get_cookie werc_user|tr -d $NEW_LINE} }
- if(! ~ $#cu 0) {
- user_name=$cu(1)
- user_password=$cu(3)
- }
+ awk -v max'='^$"1^' ' -v 'ellipsis='$ellipsis '
+ {
+ nc += 1 + length;
+ if(nc > max) {
+ print substr($0, 1, nc - max) ellipsis
+ exit
}
- auth_user $user_name $user_password
- }
- if not
- status=()
-}
-
-# Check if user_name and user_password represent a valid user account
-# If valid, 'log in' by setting logged_user
-fn auth_user {
- user_name=$1
- user_password=$2
-
- pfile='etc/users/'^$"user_name^'/password'
- if(~ $#user_name 0 || ~ $#user_password 0)
- status=('Auth: missing user name or pass: '^$"user_name^' / '^$"user_p…
- if not if(! test -f $pfile)
- status=('Auth: cant find '^$pfile)
- if not if(! ~ $user_password `{cat $pfile})
- status=('Auth: Pass '$user_password' doesnt match '^`{cat $pfile})
- if not {
- logged_user=$user_name
- logged_password=$user_password
- dprint Auth: success
- status=()
- }
-}
-
-fn user_controls {
- echo User: $"logged_user
+ print
+ }'
}
-# .md '(meta-)data' extract
-fn get_md_file_attr {
- sed -n '/^\* '$2': /p; /^\* '$2': /q; /^$/q' < $1
-}
-
-#app_blog_methods = ( _post index.rss )
-#fn app_blog__post {
-# echo
-#}
-#
-#app_blog___default {
-# if (~ $blog)
-# call_app blogpost
-#}
-#
-## --
-#app_blogpost_methods = ( comment _edit )
-#
-#fn app_blogpost_comment {
-# call_app comments
-#}
-#
-## --
-#app_comments_methods = ( _post _edit )
-#
-#fn app_comments___default {
-#
-#}
diff --git a/bin/corehandlers.rc b/bin/corehandlers.rc
@@ -0,0 +1,115 @@
+# Werc builtin handlers
+
+fn nav_tree {
+ if(! ~ $#sideBarNavTitle 0)
+ echo '<p class="sideBarTitle">'$"sideBarNavTitle':</p>'
+ # Ignore stderr, last path element might be a file that doesn't exist (eg.…
+ # /./ to deal with p9p's ls failure to follow dir symlinks otherwise
+ ls -F $sitedir/./$req_paths_list >[2]/dev/null \
+ | sed 's!^'$sitedir'!!; '$dirfilter'/\/[^_.\/][^\/]*(\.(md|txt|html)|\…
+ | sort -u | awk -F/ '
+ function p(x, y, s) { for(i=0; i < x-y; i+=1) print s }
+ {
+ d = ""
+ if(match($0, "/$"))
+ d = "/"
+ sub("/$", "") # Strip trailing / for dirs so NF is consistent
+
+ p(NF, lNF, "<ul class=\"side-bar\">")
+ p(lNF, NF, "</ul>")
+ lNF = NF
+
+ bname = $NF d
+ path = $0 d
+ gsub("_", " ", bname)
+
+ if(index(ENVIRON["req_path"] "/", path) == 1)
+ print "<li><a href=\"" path "\" class=\"thisPage\">&raquo;<i> " bn…
+ else
+ print "<li><a href=\"" path "\">&rsaquo; " bname "</a></li>"
+ }
+ END { p(lNF, 0, "</ul>") }'
+}
+
+
+fn md_handler { $formatter < $1 }
+
+fn tpl_handler { template $* }
+
+fn html_handler {
+ # body states: 0 = no <body> found, 2 = after <body>, 1 = after <body></bo…
+ awk 'gsub(".*<[Bb][Oo][Dd][Yy][^>]*>", "") > 0 {body=2}
+ gsub("</ *[Bb][Oo][Dd][Yy][^>]*>.*", "") > 0 {print; body=body-1}
+ body==2 {print}
+ body==0 {buf=buf "\n" $0}
+ END {if(body<=0) {print buf}}' < $1
+}
+
+fn txt_handler {
+ # Note: Words are not broken, even if they are way beyond 82 chars long
+ echo '<pre>'
+ sed 's/</\&lt;/g; s/>/\&gt;/g' < $1 | fmt -l 82 -j
+ echo '</pre>'
+}
+
+fn dir_listing_handler {
+ d=`{basename -d $1}
+ if(~ $#d 0)
+ d='/'
+ echo $d|sed 's,.*//,,g; s,/$,,; s,/, / ,g; s,.*,<h1 class="dir-list-head">…
+ # Symlinks suck: '/.' forces ls to list the linked dir if $d is a symlink.
+ ls -F $dir_listing_ls_opts $sitedir$d/. | sed $dirfilter$dirclean' s,.*/([…
+ echo '</ul>'
+}
+
+fn notices_handler {
+ for(type in notify_errors notify_notes notify_success)
+ for(n in $$type)
+ echo '<div class="'$type'"><b>'$"n'</b></div>'
+}
+
+fn setup_handlers {
+
+ if(test -f $local_path.md)
+ handler_body_main=(md_handler $local_path.md)
+ if not if(test -f $local_path.tpl)
+ handler_body_main=(tpl_handler $local_path.tpl)
+ if not if(test -f $local_path.html)
+ handler_body_main=(html_handler $local_path.html)
+ # Global tpl (eg sitemap.tpl), should take precedence over txt handler!
+ if not if(test -f lib^$req_path^.tpl)
+ handler_body_main=(tpl_handler lib^$req_path^.tpl)
+ if not if(test -f $local_path.txt)
+ handler_body_main=(txt_handler $local_path.txt)
+
+ # XXX Should check that $enabled_apps exist in $werc_apps?
+ # XXX Should split init of apps that provide main handler (eg., blog) and …
+ if(! ~ $#enabled_apps 0)
+ for(a in $enabled_apps)
+ $a^'_init'
+
+ if(! ~ $#handler_body_main 0)
+ { } # We are done
+ # Dir listing
+ if not if(~ $local_path */index)
+ handler_body_main=(dir_listing_handler $req_path)
+ # Canonize explicit .html urls, the web server might handle this first!
+ if not if(~ $local_path *.html && test -f $local_path)
+ perm_redirect `{ echo $req_path|sed 's/.html$//' }
+ # Fallback static file handler
+ if not if(test -f $local_path)
+ static_file $local_path
+ if not if(~ $req_path /pub/* && test -f .$req_path)
+ static_file .$req_path
+ # File not found
+ if not {
+ handler_body_main=(tpl_handler `{get_lib_file 404.tpl})
+ echo 'Status: 404 Not Found'
+ dprint 'NOT FOUND: '$SERVER_NAME^$"REQUEST_URI^' - '^$"HTTP_REFERER^' …
+ }
+}
+
+fn run_handlers { for(h in $*) run_handler $$h }
+fn run_handler { $*(1) $*(2-) }
+
+
diff --git a/bin/werc.rc b/bin/werc.rc
@@ -1,126 +1,17 @@
#!/usr/local/plan9/bin/rc
. ./cgilib.rc
+. ./werclib.rc
+. ./wercconf.rc
+. ./corehandlers.rc
cd ..
forbidden_uri_chars='[^a-zA-Z0-9_+\-\/\.]'
# Expected input: ls -F style, $sitedir/path/to/files/
# <ls -F+x><symlink hack><Useless?><hiden files >
-dirfilter='s/\*$//; s,/+\./+,/,g; s,^\./,,; /\/[._][^\/]/d; /'^$forbidden_uri_…
+dirfilter='s/\*$//; s,/+\./+,/,g; s,^\./,,; /\/[._][^\/]/d; /'$forbidden_uri_c…
dirclean=' s/\.(md|html|txt)$//; '
-# To be used from config files
-fn hide_paths {
- for(i in $*)
- dirfilter=$dirfilter^'/^'$i'$/d; '
-}
-
-# Sidebar
-fn nav_tree {
- if(! ~ $#sideBarNavTitle 0)
- echo '<p class="sideBarTitle">'$"sideBarNavTitle':</p>'
- # Ignore stderr, last path element might be a file that doesn't exist (eg.…
- # /./ to deal with p9p's ls failure to follow dir symlinks otherwise
- ls -F $sitedir/./$req_paths_list >[2]/dev/null \
- | sed 's!^'$sitedir'!!; '^$dirfilter^'/\/[^_.\/][^\/]*(\.(md|txt|html)…
- | sort -u | awk -F/ '
- function p(x, y, s) { for(i=0; i < x-y; i+=1) print s }
- {
- d = ""
- if(match($0, "/$"))
- d = "/"
- sub("/$", "") # Strip trailing / for dirs so NF is consistent
-
- p(NF, lNF, "<ul class=\"side-bar\">")
- p(lNF, NF, "</ul>")
- lNF = NF
-
- bname = $NF d
- path = $0 d
- gsub("_", " ", bname)
-
- if(index(ENVIRON["req_path"] "/", path) == 1)
- print "<li><a href=\"" path "\" class=\"thisPage\">&raquo;<i> " bn…
- else
- print "<li><a href=\"" path "\">&rsaquo; " bname "</a></li>"
- }
- END { p(lNF, 0, "</ul>") }'
-}
-
-
-# Handlers
-fn md_handler { $formatter < $1 }
-
-fn tpl_handler { template $* }
-
-fn html_handler {
- # body states: 0 = no <body> found, 2 = after <body>, 1 = after <body></bo…
- awk 'gsub(".*<[Bb][Oo][Dd][Yy][^>]*>", "") > 0 {body=2}
- gsub("</ *[Bb][Oo][Dd][Yy][^>]*>.*", "") > 0 {print; body=body-1}
- body==2 {print}
- body==0 {buf=buf "\n" $0}
- END {if(body<=0) {print buf}}' < $1
-}
-
-fn txt_handler {
- # Note: Words are not broken, even if they are way beyond 82 chars long
- echo '<pre>' `{ sed 's/</\&lt;/g; s/>/\&gt;/g' < $1 | fmt -l 82 -j } '</pr…
-}
-
-fn dir_listing_handler {
- d=`{basename -d $1}
- if(~ $#d 0)
- d='/'
- echo $d|sed 's,.*//,,g; s,/$,,; s,/, / ,g; s,.*,<h1 class="dir-list-head">…
- # Symlinks suck: '/.' forces ls to list the linked dir if $d is a symlink.
- ls -F $dir_listing_ls_opts $sitedir$d/. | sed $dirfilter$dirclean' s,.*/([…
- echo '</ul>'
-}
-
-fn setup_handlers {
-
- if(test -f $local_path.md)
- handler_body_main=(md_handler $local_path.md)
- if not if(test -f $local_path.tpl)
- handler_body_main=(tpl_handler $local_path.tpl)
- if not if(test -f $local_path.html)
- handler_body_main=(html_handler $local_path.html)
- # Global tpl (eg sitemap.tpl), should take precedence over txt handler!
- if not if(test -f lib^$req_path^.tpl)
- handler_body_main=(tpl_handler lib^$req_path^.tpl)
- if not if(test -f $local_path.txt)
- handler_body_main=(txt_handler $local_path.txt)
-
- # XXX Should check that $enabled_apps exist in $werc_apps?
- # XXX Should split init of apps that provide main handler (eg., blog) and …
- if(! ~ $#enabled_apps 0)
- for(a in $enabled_apps)
- $a^'_init'
-
- if(! ~ $#handler_body_main 0)
- { } # We are done
- # Dir listing
- if not if(~ $local_path */index)
- handler_body_main=(dir_listing_handler $req_path)
- # Canonize explicit .html urls, the web server might handle this first!
- if not if(~ $local_path *.html && test -f $local_path)
- perm_redirect `{ echo $req_path|sed 's/.html$//' }
- # Fallback static file handler
- if not if(test -f $local_path)
- static_file $local_path
- if not if(~ $req_path /pub/* && test -f .$req_path)
- static_file .$req_path
- # File not found
- if not {
- handler_body_main=(tpl_handler `{get_lib_file 404.tpl})
- echo 'Status: 404 Not Found'
- dprint 'NOT FOUND: '$SERVER_NAME^$"REQUEST_URI^' - '^$"HTTP_REFERER^' …
- }
-}
-
-fn run_handlers { for(h in $*) run_handler $$h }
-fn run_handler { $*(1) $*(2-) }
-
# Careful, the proper p9p path might not be set until initrc.local is sourced
path=(. $PLAN9/bin ./bin/ /bin/ /usr/bin)
@@ -130,17 +21,8 @@ ll_add handlers_bar_left nav_tree
werc_apps=( apps/* )
werc_root=`{pwd}
sitesdir=sites
-for(i in siteTitle siteSubTitle pageTitle extraHeaders)
- $i = ''
-
-# TODO: Per-req variables should move after initrc loading.
-site=$SERVER_NAME
-base_url=http://$site/
-sitedir=$sitesdir/$site
-master_template=`{get_lib_file default_master.tpl}
-current_date_time=`{date}
-. ./etc/initrc
+ . ./etc/initrc
if(test -f etc/initrc.local)
. ./etc/initrc.local
@@ -148,71 +30,83 @@ if(test -f etc/initrc.local)
for(a in $werc_apps)
. ./$a/app.rc
-# Parse request URL
-# NOTE: $REQUEST_URI is not officially in CGI 1.1, but seems to be de-facto
-req_path=`{echo -n $REQUEST_URI | sed 's/\?.*//; s/'^$forbidden_uri_chars^'//g…
-local_path=$sitedir$req_path
-ifs='/' { args=`{echo -n $req_path} }
-
-# Hack: preload post data so we can access it from templates where cgi's stdin…
-if(~ $REQUEST_METHOD POST) {
- load_post_args
- login_user
-}
-
-if(! ~ $#args 0)
- pageTitle=`{ echo $args|sed -e 's/ / - /g' -e 's/_/ /g' }
+fn werc_exec_request {
+ site=$SERVER_NAME
+ base_url=http://$site
+ sitedir=$sitesdir/$site
+ master_template=`{get_lib_file default_master.tpl}
+ current_date_time=`{date}
+
+ # Note: $REQUEST_URI is not officially in CGI 1.1, but seems to be de-facto
+ req_path=`{echo -n $REQUEST_URI | sed 's/\?.*//; s!//+!/!g; s/'^$forbidden…
+ local_path=$sitedir$req_path
+ ifs='/' { args=`{echo -n $req_path} }
+
+ # Preload post args for templates where cgi's stdin is not accessible
+ if(~ $REQUEST_METHOD POST) {
+ load_post_args
+ login_user
+ }
-if(~ $req_path */index)
- perm_redirect `{echo $req_path | sed 's,/index$,/,'}
+ if(~ $req_path */index)
+ perm_redirect `{echo $req_path | sed 's,/index$,/,'}
-if(~ $local_path */) {
- if(test -d $local_path)
- local_path=$local_path^'index'
- if not # XXX: This redir might step on apps with synthetic dirs.
- perm_redirect `{echo $req_path|sed 's,/+$,,'}
-}
-if not if(test -d $local_path)
- perm_redirect $req_path^'/'
-
-cd $sitedir
-req_paths_list='/' # Note: req_paths_list doesn't include 'stnythetic' dirs.
-conf_wd='/' # Used in config files to know where we are in the document tree.
-if(test -f _werc/config)
- . _werc/config
-for(i in $args) {
- conf_wd=$conf_wd^$i
- req_paths_list=($req_paths_list $conf_wd)
- if(test -d $i) {
- conf_wd=$conf_wd^'/'
- cd $i
- if(test -f _werc/config)
- . _werc/config
+ if(~ $local_path */) {
+ if(test -d $local_path)
+ local_path=$local_path^'index'
+ if not # XXX: This redir might step on apps with synthetic dirs.
+ perm_redirect `{echo $req_path|sed 's,/+$,,'}
+ }
+ if not if(test -d $local_path)
+ perm_redirect $base_url^$req_path^'/'
+
+ if(! ~ $#args 0)
+ pageTitle=`{ echo $args|sed -e 's/ / - /g' -e 's/_/ /g' }
+
+ cd $sitedir
+ req_paths_list='/' # Note: req_paths_list doesn't include 'stnythetic' dir…
+ conf_wd='/' # Used in config files to know where we are in the document tr…
+ if(test -f _werc/config)
+ . _werc/config
+ for(i in $args) {
+ conf_wd=$conf_wd^$i
+ req_paths_list=($req_paths_list $conf_wd)
+ if(test -d $i) {
+ conf_wd=$conf_wd'/'
+ cd $i
+ if(test -f _werc/config)
+ . _werc/config
+ }
+ }
+ cd $werc_root
+
+ f=();t=()
+ for(i in $perm_redir_patterns) {
+ if(~ $#f 0)
+ f=$i
+ if not {
+ t=$i
+ from=$base_url^$req_path
+ to=`{ echo $from | sed 's!'$f'!'$t'!' }
+ if(! ~ $to $from)
+ perm_redirect $to
+ f=()
+ }
}
-}
-cd $werc_root
-# Redirections and other preprocessing
-if(~ $#redirectPermanent 1) {
- perm_redirect $"redirectPermanent
-}
-if not if(~ $#redirectPermanent 2) {
- from='http://'^$SERVER_NAME^$req_path
- to=`{echo $from|sed 's@'^$redirectPermanent(1)^'@'^$redirectPermanent(2)^'…
- if(! ~ $to $from)
- perm_redirect $to
-}
+ # Set Page title
+ if(~ $"pageTitle '')
+ pageTitle=$"siteTitle' '$"siteSubTitle
+ if not
+ pageTitle=$"pageTitle' | '$"siteTitle' '$"siteSubTitle
-# Set Page title
-if(~ $pageTitle '')
- pageTitle=$siteTitle^' '^$siteSubTitle
-if not
- pageTitle=$"pageTitle^' | '^$"siteTitle^' '^$"siteSubTitle
+ setup_handlers
-setup_handlers
+ if(! ~ $#debug 0)
+ dprint $"SERVER_NAME^$"REQUEST_URI - $"HTTP_USER_AGENT - $"REQUEST_MET…
-if(! ~ $#debug 0)
- dprint ' '$"SERVER_NAME^$"REQUEST_URI' - '$"HTTP_USER_AGENT' - '$"REQUEST…
+ template $headers $master_template #| awk_buffer
+ echo $res_tail
+}
-template $headers $master_template | awk_buffer
-echo $res_tail
+werc_exec_request
diff --git a/bin/wercconf.rc b/bin/wercconf.rc
@@ -0,0 +1,12 @@
+# To be used from config files
+fn conf_perm_redirect {
+ if(~ $#* 1)
+ perm_redirect $1
+ if not
+ perm_redir_patterns=($perm_redir_patterns $1 $2)
+}
+
+fn conf_hide_paths {
+ for(i in $*)
+ dirfilter=$dirfilter^'/^'$i'$/d; '
+}
diff --git a/bin/werclib.rc b/bin/werclib.rc
@@ -0,0 +1,117 @@
+fn get_lib_file {
+ if(! ~ $#sitedir 0 && test -f $sitedir/_werc/lib/$1)
+ echo -n $sitedir/_werc/lib/$1
+ if not if(! ~ $#masterSite 0 && test -f $sitesdir/$masterSite/_werc/lib/$1)
+ echo -n $sitesdir/$masterSite/_werc/lib/$1
+ if not if(test -f lib/$1)
+ echo -n lib/$1
+ if not if(~ $#* 2)
+ echo -n $2
+ if not
+ status='Can''t find lib file: '$1
+}
+
+fn template { awk -f bin/template.awk $* | rc $rcargs }
+
+# Auth code
+allowed_user_chars='[a-zA-Z0-9_]'
+# Cookie format: WERC_USER: name:timestamp:hash(name.timestamp.password)
+# login_user can't be used from a template because it sets a cookie
+fn login_user {
+ # Note: we set the cookie even if it is already there.
+ if(get_user $*)
+ set_cookie werc_user $"logged_user^':0:'^$"logged_password
+}
+
+# Check login status, if called with group arg we check membership too
+fn check_user {
+ get_user
+ _status=$status
+ if(! ~ $"_status '')
+ _status=(Not logged in: $"_status)
+ if not if(! ~ $#* 0 && ! grep -s '^'^$logged_user^'$' etc/groups/$* etc/gr…
+ dprint NOT IN GROUP
+ _status=(User $logged_user not in groups $*)
+ }
+ status=$_status
+}
+
+# If not logged in, try to get user login info from POST or from cookie
+fn get_user {
+ if(~ $#logged_user 0) {
+ if(~ $#* 2) {
+ user_name=$1
+ user_password=$2
+ }
+ if not if(~ $REQUEST_METHOD POST)
+ get_post_args user_name user_password
+
+ if(~ $#user_name 0) {
+ ifs=':' { cu=`{get_cookie werc_user|tr -d $NEW_LINE} }
+ if(! ~ $#cu 0) {
+ user_name=$cu(1)
+ user_password=$cu(3)
+ }
+ }
+ auth_user $user_name $user_password
+ }
+ if not
+ status=()
+}
+
+# Check if user_name and user_password represent a valid user account
+# If valid, 'log in' by setting logged_user
+fn auth_user {
+ user_name=$1
+ user_password=$2
+
+ pfile='etc/users/'^$"user_name^'/password'
+ if(~ $#user_name 0 || ~ $#user_password 0)
+ status=('Auth: missing user name or pass: '^$"user_name^' / '^$"user_p…
+ if not if(! test -f $pfile)
+ status=('Auth: cant find '^$pfile)
+ if not if(! ~ $user_password `{cat $pfile})
+ status=('Auth: Pass '$user_password' doesnt match '^`{cat $pfile})
+ if not {
+ logged_user=$user_name
+ logged_password=$user_password
+ dprint Auth: success
+ status=()
+ }
+}
+
+fn user_controls {
+ echo User: $"logged_user
+}
+
+
+# .md '(meta-)data' extract
+fn get_md_file_attr {
+ sed -n '/^\* '$2': /p; /^\* '$2': /q; /^$/q' < $1
+}
+
+##########################################################################
+##########################################################################
+#app_blog_methods = ( _post index.rss )
+#fn app_blog__post {
+# echo
+#}
+#
+#app_blog___default {
+# if (~ $blog)
+# call_app blogpost
+#}
+#
+## --
+#app_blogpost_methods = ( comment _edit )
+#
+#fn app_blogpost_comment {
+# call_app comments
+#}
+#
+## --
+#app_comments_methods = ( _post _edit )
+#
+#fn app_comments___default {
+#
+#}
diff --git a/lib/_users/login.tpl b/lib/_users/login.tpl
@@ -5,9 +5,9 @@
% }
% if not {
% if (~ $REQUEST_METHOD POST)
-% echo 'Login failed!'
-<form method="POST">
- <label>User name: <input type="text" name="user_name" /></label><br />
+% echo '<div class="notify_errors">Login failed!</div>'
+<form method="POST" style="text-align: right; float: left;">
+ <label>User name: <input type="text" name="user_name" value="%($"post_arg_…
<lavel>User password: <input type="password" name="user_password" /></labe…
<input name="s" type="submit" value="Login" />
</form>
diff --git a/lib/headers.tpl b/lib/headers.tpl
@@ -27,7 +27,7 @@ Content-Type: text/html
% if(! ~ $#h 0)
% cat $h
- %($extraHeaders%)
+ %($"extraHeaders%)
</head>
<body>
diff --git a/pub/style/style.css b/pub/style/style.css
@@ -334,6 +334,18 @@ blockquote {
.doNotDisplay { display: none; }
+.notify_errors,
+.notify_notes,
+.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
+
+.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
+.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; }
+.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
+.notify_errors a { color: #8a1f11; }
+.notify_notes a { color: #514721; }
+.notify_success a { color: #264409; }
+
+
/* # Page/Handler specific # */
h1.dir-list-head, ul.dir-list {
text-transform: capitalize;
diff --git a/sites/werc.cat-v.org/_werc/config b/sites/werc.cat-v.org/_werc/con…
@@ -1,5 +1,5 @@
siteTitle='werc'
siteSubTitle=' Bringing minimalism and sanity to the web'
-enable_comments=yes
+conf_enable_comments
enabled_apps=($enabled_apps hello dirdir )
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.