changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > werc / bin/cgilib.rc

changeset 316: a8c8620f7ff7
parent: 73bc0b90cf58
child: 6cc3ea4c97b3
author: uriel@engel.se.cat-v.org
date: Mon, 12 Jan 2009 02:07:31 +0100
permissions: -rw-r--r--
description: Various small cleanups: remove unused code, clarity and reliability fixes here and here, move code to more appropriate locations, improve some comments.
1 ##############################################
2 # Useful CGI functions
3 
4 NEW_LINE='
5 '
6 
7 fn dprint { echo $* >[1=2] }
8 
9 fn escape_html { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' $* }
10 
11 fn perm_redirect {
12  echo 'Status: 301 Moved Permanantly
13 Location: '^$1^'
14 
15 '
16  exit
17 }
18 
19 fn static_file {
20  echo 'Content-Type: '`{select_mime $1}
21  echo
22  cat $1
23  exit
24 }
25 
26 
27 # Status is () if at least one arg is found.
28 fn get_post_args {
29  _status='Args not found'
30  if(! ~ $REQUEST_METHOD POST)
31  _status='No http post!'
32  if not if(~ $#POST_ARGS 0) {
33  ifs='&
34 ' for(pair in `{cat}) {
35  pair=`{echo -n $pair | sed 's/=/\&/'}
36  # Maybe we should urldecode on the first pass?
37  POST_ARGS=( $POST_ARGS $pair )
38  _get_post_args_set_var $pair $*
39  }
40  }
41  if not {
42  pair=$POST_ARGS
43  while(! ~ $#pair 0) {
44  _get_post_args_set_var $pair $*
45  pair=$pair(3-)
46  }
47  }
48  status=$_status
49 }
50 fn _get_post_args_set_var {
51  if(~ $1 $*(3-)) {
52  ifs=() { $1=`{echo -n $2 | urldecode | tr -d '
53 '} }
54  _status=()
55  }
56 }
57 
58 # This seems slightly improve performance, but might depend on httpd buffering behavior.
59 fn awk_buffer {
60  awk '{
61  buf = buf $0"\n"
62  if(length(buf) > 1400) {
63  printf "%s", buf
64  buf = ""
65  }
66  }
67  END { printf "%s", buf }'
68 }
69 
70 fn urldecode {
71 awk '
72 BEGIN {
73  hextab ["0"] = 0; hextab ["8"] = 8;
74  hextab ["1"] = 1; hextab ["9"] = 9;
75  hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
76  hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
77  hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
78  hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
79  hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
80  hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
81 }
82 {
83  decoded = ""
84  i = 1
85  len = length ($0)
86  while ( i <= len ) {
87  c = substr ($0, i, 1)
88  if ( c == "%" ) {
89  if ( i+2 <= len ) {
90  c1 = substr ($0, i+1, 1)
91  c2 = substr ($0, i+2, 1)
92  if ( hextab [c1] == "" || hextab [c2] == "" ) {
93  print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
94  } else {
95  code = 0 + hextab [c1] * 16 + hextab [c2] + 0
96  c = sprintf ("%c", code)
97  i = i + 2
98  }
99  } else {
100  print "WARNING: invalid % encoding: " substr ($0, i, len - i)
101  }
102  } else if ( c == "+" ) {
103  c = " "
104  }
105  decoded = decoded c
106  ++i
107  }
108  printf decoded
109 }
110 '
111 }
112 
113 fn crop_text {
114  ellipsis='...'
115  if(~ $#* 2)
116  ellipsis=$2
117 
118  awk -v max'='^$"1^' ' -v 'ellipsis='$ellipsis '
119  {
120  nc += 1 + length;
121  if(nc > max) {
122  print substr($0, 1, nc - max) ellipsis
123  exit
124  }
125  print
126  }'
127 }
128 
129 
130 # Cookies
131 fn set_cookie {
132  # TODO: should check input values more carefully
133  name=$1
134  val=$2
135  extraHttpHeaders=( $extraHttpHeaders 'Set-cookie: '^$"name^'='^$"val^'; path=/;' )
136 }
137 fn get_cookie {
138  ifs=';' { co = `{ echo $HTTP_COOKIE } }
139 
140  #for(c in $co)
141  # if(~ $c $1^'='*) # This matching doesn't work
142  # echo $c|sed 's/[^=]*=//'
143 
144  # WARNING: we might be adding a trailing new line
145  { for(c in $co) echo $c } | sed -n 's/[^=]*=//p'
146 }
147 
148 fn select_mime {
149  m='text/plain'
150  if(~ $1 *.css)
151  m='text/css'
152  if not if(~ $1 *.ico)
153  m='image/x-icon'
154  if not if(~ $1 *.png)
155  m='image/png'
156  if not if(~ $1 *.jpg *.jpeg)
157  m='image/jpeg'
158  if not if(~ $1 *.gif)
159  m='image/gif'
160  if not if(~ $1 *.pdf)
161  m='application/pdf'
162  echo $m
163 }
164 
165 ##############################################
166 # Generic rc programming helpers
167 
168 fn ll_add {
169  _l=$1^_^$#$1
170  $_l=$*(2-)
171  $1=( $$1 $_l )
172 }
173 
174 
175 ##############################################
176 # Werc-specific functions
177 
178 fn template { awk -f bin/template.awk $* | rc $rcargs }
179 
180 # Auth code
181 
182 # Cookie format: WERC_USER: name:timestamp:hash(name.timestamp.password)
183 # login_user can't be used from a template because it sets a cookie
184 fn login_user {
185  # Note: we set the cookie even if it is already there.
186  if(get_user $*)
187  set_cookie werc_user $"logged_user^':0:'^$"logged_password
188 }
189 
190 # Check loggin status, if called with group arg we check membership too
191 fn check_user {
192  if(! get_user)
193  status='Not logged in'
194  if not if(~ $#1 1 && ! grep -s '^'^$logged_user^'$' etc/groups/$1)
195  status=User $logged_user not in group $1
196  if not
197  status=()
198 }
199 
200 # If not logged in, try to get user login info from POST or from cookie
201 fn get_user {
202  if(~ $#logged_user 0) {
203  if(~ $#* 2) {
204  user_name=$1
205  user_password=$2
206  }
207  if not if(~ $REQUEST_METHOD POST)
208  get_post_args user_name user_password
209 
210  if(~ $#user_name 0) {
211  ifs=':' { cu=`{get_cookie werc_user|tr -d $NEW_LINE} }
212  if(! ~ $#cu 0) {
213  user_name=$cu(1)
214  user_password=$cu(3)
215  }
216  }
217  auth_user $user_name $user_password
218  }
219  if not
220  status=()
221 }
222 
223 # Check if user_name and user_password represent a valid user account
224 # If valid, 'log in' by setting logged_user
225 fn auth_user {
226  user_name=$1
227  user_password=$2
228 
229  pfile='etc/users/'^$"user_name^'/password'
230  if(~ $#user_name 0 || ~ $#user_password 0)
231  status='Auth: missing user name or pass: '^$"user_name^' / '^$"user_password
232  if not if(! test -f $pfile)
233  status='Auth: cant find '^$pfile
234  if not if(! ~ $user_password `{cat $pfile})
235  status='Auth: Pass '$user_password' doesnt match '^`{cat $pfile}
236  if not {
237  logged_user=$user_name
238  logged_password=$user_password
239  dprint Auth: success
240  status=()
241  }
242 }
243 
244 # .md '(meta-)data' extract
245 fn get_md_file_attr {
246  sed -n '/^\* '$2': /p; /^\* '$2': /q; /^$/q' < $1
247 }
248 
249 #app_blog_methods = ( _post index.rss )
250 #fn app_blog__post {
251 # echo
252 #}
253 #
254 #app_blog___default {
255 # if (~ $blog)
256 # call_app blogpost
257 #}
258 #
259 ## --
260 #app_blogpost_methods = ( comment _edit )
261 #
262 #fn app_blogpost_comment {
263 # call_app comments
264 #}
265 #
266 ## --
267 #app_comments_methods = ( _post _edit )
268 #
269 #fn app_comments___default {
270 #
271 #}