From a1d12138bba8d81dcf2d01fb3e40209a094ee5e4 Mon Sep 17 00:00:00 2001 From: uriel Date: Sun, 1 Feb 2009 20:06:51 +0100 Subject: [PATCH] Reorg code in five source files: werc.rc, cgilib.rc, corehandlers.rc, wercconf.rc and werclib.rc. --- bin/cgilib.rc | 167 +++++++------------------------------------- bin/corehandlers.rc | 115 ++++++++++++++++++++++++++++++ bin/werc.rc | 139 ++---------------------------------- bin/wercconf.rc | 12 ++++ bin/werclib.rc | 117 +++++++++++++++++++++++++++++++ 5 files changed, 276 insertions(+), 274 deletions(-) create mode 100644 bin/corehandlers.rc create mode 100644 bin/wercconf.rc create mode 100644 bin/werclib.rc diff --git a/bin/cgilib.rc b/bin/cgilib.rc index e36d9a1..0ae1230 100644 --- a/bin/cgilib.rc +++ b/bin/cgilib.rc @@ -1,11 +1,7 @@ -############################################## -# Useful CGI functions - -NEW_LINE=' -' +# Useful CGI stuff fn dprint { echo $* >[1=2] } -fn dprintvars { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; ' }; echo } >[1=2] } +fn dprintv { { for(v in $*) { echo -n $v^'#'^$#$v^'=' $$v '; ' }; echo } >[1=2] } fn escape_html { sed 's/&/\&/g; s//\>/g' $* } @@ -25,13 +21,6 @@ Location: '^$t^' 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 { @@ -117,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 { @@ -149,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) @@ -169,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 crop_text { + ellipsis='...' + if(~ $#* 2) + ellipsis=$2 -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/groups/admin) { - 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 + awk -v max'='^$"1^' ' -v 'ellipsis='$ellipsis ' + { + nc += 1 + length; + if(nc > max) { + print substr($0, 1, nc - max) ellipsis + exit } - 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_password) - 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 new file mode 100644 index 0000000..73281a7 --- /dev/null +++ b/bin/corehandlers.rc @@ -0,0 +1,115 @@ +# Werc builtin handlers + +fn nav_tree { + if(! ~ $#sideBarNavTitle 0) + echo '

'$"sideBarNavTitle':

' + # Ignore stderr, last path element might be a file that doesn't exist (eg., foo for foo.md) + # /./ 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)|\/)$/!d; '$dirclean \ + | 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, "") + lNF = NF + + bname = $NF d + path = $0 d + gsub("_", " ", bname) + + if(index(ENVIRON["req_path"] "/", path) == 1) + print "
  • » " bname "" + else + print "
  • › " bname "
  • " + } + END { p(lNF, 0, "") }' +} + + +fn md_handler { $formatter < $1 } + +fn tpl_handler { template $* } + +fn html_handler { + # body states: 0 = no found, 2 = after , 1 = after , -1 = after + awk 'gsub(".*<[Bb][Oo][Dd][Yy][^>]*>", "") > 0 {body=2} + gsub("]*>.*", "") > 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 '
    '
    +    sed 's//\>/g' < $1 | fmt -l 82 -j
    +    echo '
    ' +} + +fn dir_listing_handler { + d=`{basename -d $1} + if(~ $#d 0) + d='/' + echo $d|sed 's,.*//,,g; s,/$,,; s,/, / ,g; s,.*,

    &

    ' +} + +fn notices_handler { + for(type in notify_errors notify_notes notify_success) + for(n in $$type) + echo '
    '$"n'
    ' +} + +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 apps that don't (eg., comments)? + 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^' - '^$"HTTP_USER_AGENT + } +} + +fn run_handlers { for(h in $*) run_handler $$h } +fn run_handler { $*(1) $*(2-) } + + diff --git a/bin/werc.rc b/bin/werc.rc index 022b68e..a274c7c 100755 --- a/bin/werc.rc +++ b/bin/werc.rc @@ -1,5 +1,8 @@ #!/usr/local/plan9/bin/rc . ./cgilib.rc +. ./werclib.rc +. ./wercconf.rc +. ./corehandlers.rc cd .. forbidden_uri_chars='[^a-zA-Z0-9_+\-\/\.]' @@ -9,132 +12,6 @@ forbidden_uri_chars='[^a-zA-Z0-9_+\-\/\.]' dirfilter='s/\*$//; s,/+\./+,/,g; s,^\./,,; /\/[._][^\/]/d; /'$forbidden_uri_chars'/d; /^\/(robots|sitemap)\.txt$|\/index\.(md|html|txt|tpl)$/d; /_werc\/?$/d; ' dirclean=' s/\.(md|html|txt)$//; ' -# 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; ' -} - -# Standard handlers -fn nav_tree { - if(! ~ $#sideBarNavTitle 0) - echo '

    '$"sideBarNavTitle':

    ' - # Ignore stderr, last path element might be a file that doesn't exist (eg., foo for foo.md) - # /./ 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)|\/)$/!d; '$dirclean \ - | 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, "") - lNF = NF - - bname = $NF d - path = $0 d - gsub("_", " ", bname) - - if(index(ENVIRON["req_path"] "/", path) == 1) - print "
  • » " bname "" - else - print "
  • › " bname "
  • " - } - END { p(lNF, 0, "") }' -} - - -fn md_handler { $formatter < $1 } - -fn tpl_handler { template $* } - -fn html_handler { - # body states: 0 = no found, 2 = after , 1 = after , -1 = after - awk 'gsub(".*<[Bb][Oo][Dd][Yy][^>]*>", "") > 0 {body=2} - gsub("]*>.*", "") > 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 '
    '
    -    sed 's//\>/g' < $1 | fmt -l 82 -j
    -    echo '
    ' -} - -fn dir_listing_handler { - d=`{basename -d $1} - if(~ $#d 0) - d='/' - echo $d|sed 's,.*//,,g; s,/$,,; s,/, / ,g; s,.*,

    &

    ' -} - -fn notices_handler { - for(type in notify_errors notify_notes notify_success) - for(n in $$type) - echo '
    '$"n'
    ' -} - -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 apps that don't (eg., comments)? - 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^' - '^$"HTTP_USER_AGENT - } -} - -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) @@ -144,10 +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 = '' -. ./etc/initrc + . ./etc/initrc if(test -f etc/initrc.local) . ./etc/initrc.local @@ -220,8 +95,8 @@ fn werc_exec_request { } # Set Page title - if(~ $pageTitle '') - pageTitle=$siteTitle' '$siteSubTitle + if(~ $"pageTitle '') + pageTitle=$"siteTitle' '$"siteSubTitle if not pageTitle=$"pageTitle' | '$"siteTitle' '$"siteSubTitle @@ -230,7 +105,7 @@ fn werc_exec_request { if(! ~ $#debug 0) dprint $"SERVER_NAME^$"REQUEST_URI - $"HTTP_USER_AGENT - $"REQUEST_METHOD - $"handler_body_main - $"master_template - template $headers $master_template | awk_buffer + template $headers $master_template #| awk_buffer echo $res_tail } diff --git a/bin/wercconf.rc b/bin/wercconf.rc new file mode 100644 index 0000000..e98cbff --- /dev/null +++ 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 new file mode 100644 index 0000000..fdbc1f1 --- /dev/null +++ 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/groups/admin) { + 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_password) + 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 { +# +#}