diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
| commit | 5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch) | |
| tree | 1a81af141708b826e9c61e8a04019994fcca8298 /src/sh | |
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/sh')
| -rw-r--r-- | src/sh/convert.cc | 376 | ||||
| -rw-r--r-- | src/sh/dates.cc | 138 | ||||
| -rw-r--r-- | src/sh/file.cc | 367 | ||||
| -rw-r--r-- | src/sh/htc.cc | 92 | ||||
| -rw-r--r-- | src/sh/htc.h | 77 | ||||
| -rw-r--r-- | src/sh/main.cc | 129 | ||||
| -rw-r--r-- | src/sh/net.cc | 122 | ||||
| -rw-r--r-- | src/sh/string.cc | 32 | ||||
| -rw-r--r-- | src/sh/sys.cc | 152 | ||||
| -rw-r--r-- | src/sh/tree.cc | 304 | ||||
| -rw-r--r-- | src/sh/user.cc | 445 | ||||
| -rw-r--r-- | src/sh/user.h | 92 |
12 files changed, 2326 insertions, 0 deletions
diff --git a/src/sh/convert.cc b/src/sh/convert.cc new file mode 100644 index 0000000..8828c34 --- /dev/null +++ b/src/sh/convert.cc | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <http/http.h> | ||
| 23 | |||
| 24 | static const charset htcmask("{}\\%&*$;"); | ||
| 25 | static const charset htmlmask("<&>\""); | ||
| 26 | |||
| 27 | static void Mask(mstream& out,const charset& mask,const sref& msg) | ||
| 28 | { | ||
| 29 | sref q,p=msg; | ||
| 30 | while(p.nempty()) { | ||
| 31 | p=p.adv(q=p.left_first_of(mask)); | ||
| 32 | out<<q; | ||
| 33 | while(mask.test(p.front())) { | ||
| 34 | unsigned code=(unsigned char)*p; p=p.popf(); | ||
| 35 | out<<"&#"<<code<<";"; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | TOK_IMPL(mask_htc) { | ||
| 41 | Mask(out,htcmask,env[0]); | ||
| 42 | } | ||
| 43 | |||
| 44 | TOK_IMPL(mask_html) { | ||
| 45 | Mask(out,htmlmask,env[0]); | ||
| 46 | } | ||
| 47 | |||
| 48 | TOK_IMPL(cdata) { | ||
| 49 | out.put('\"'); Mask(out,htmlmask,env[0]); out.put('\"'); | ||
| 50 | } | ||
| 51 | |||
| 52 | ////////////////////////////////////////////////////////// | ||
| 53 | |||
| 54 | TOK_IMPL(wrap) { | ||
| 55 | int num=atoi(env[0]); | ||
| 56 | sref body=env[1]; | ||
| 57 | int col=0; | ||
| 58 | for(int i=0;i<body.size();i++) { | ||
| 59 | if(cset_newl.test(body[i])) col=0; else col++; | ||
| 60 | if(cset_spaces.test(body[i])&&col>num) { out.put('\n'); col=0; } | ||
| 61 | else out.put(body[i]); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(htmlize) { | ||
| 66 | sref first,rest=env[0]; | ||
| 67 | while(Splitln(first,rest)) { | ||
| 68 | Mask(out,htmlmask,first); | ||
| 69 | out<<"<br>\n"; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | TOK_IMPL(lf2crlf) { | ||
| 74 | LF2CRLF(out,env[0]); | ||
| 75 | } | ||
| 76 | TOK_IMPL(crlf2lf) { | ||
| 77 | CRLF2LF(out,env[0]); | ||
| 78 | } | ||
| 79 | |||
| 80 | ////////////////////////////////////////////////////////// | ||
| 81 | |||
| 82 | TOK_IMPL(twocolumn) { | ||
| 83 | int num=atoi(env[0]); | ||
| 84 | int page=atoi(env[1]); | ||
| 85 | sref head=env[2],mid=env[3],foot=env[4],body=env[5]; | ||
| 86 | int row=0,col=0,pg=1; | ||
| 87 | out<<head; | ||
| 88 | for(int i=0;i<body.size()&&pg<=page;i++) { | ||
| 89 | if(pg==page) out.put(body[i]); | ||
| 90 | if(body[i]=='\n') { | ||
| 91 | row++; | ||
| 92 | if(row>=num) { | ||
| 93 | row=0; | ||
| 94 | col++; | ||
| 95 | if(col>=2) { col=0; pg++; } | ||
| 96 | else if(pg==page) { out<<mid; } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | out<<foot; | ||
| 101 | } | ||
| 102 | |||
| 103 | ////////////////////////////////////////////////////////// | ||
| 104 | |||
| 105 | TOK_IMPL(encode) { | ||
| 106 | Pack(out,env[0]); | ||
| 107 | } | ||
| 108 | |||
| 109 | TOK_IMPL(decode) { | ||
| 110 | Unpack(out,env[0]); | ||
| 111 | } | ||
| 112 | |||
| 113 | TOK_IMPL(encode_header) { | ||
| 114 | encodeHeader(out,mime_default,env[0]); | ||
| 115 | } | ||
| 116 | |||
| 117 | TOK_IMPL(encode_base64) { | ||
| 118 | mstring buffer,path=DocPath(env,env[0]); | ||
| 119 | LoadBuffer(buffer,path); | ||
| 120 | encode64(out,buffer); | ||
| 121 | } | ||
| 122 | |||
| 123 | TOK_IMPL(pack) { | ||
| 124 | rrpile pile; | ||
| 125 | spile var(env.args); | ||
| 126 | for(int i=0;i<env.args;i++) { | ||
| 127 | env.parg(var[i],i); | ||
| 128 | pile.push_back(rrstring(var[i],env.glob(var[i]))); | ||
| 129 | } | ||
| 130 | Pack(out,pile); | ||
| 131 | } | ||
| 132 | |||
| 133 | ////////////////////////////////////////////////////////// | ||
| 134 | |||
| 135 | TOK_IMPL(decode_base64) { | ||
| 136 | mstring buffer,name=env.parg(-1),uri=env.URI(env[0]),path=DocPath(env,env[0]); | ||
| 137 | LoadBuffer(buffer,path); | ||
| 138 | if(name.nempty()) { | ||
| 139 | swrite sw(Reference(*env.toks,name,uri,1)->data); | ||
| 140 | decode64(sw,buffer); | ||
| 141 | } | ||
| 142 | else decode64(out,buffer); | ||
| 143 | } | ||
| 144 | |||
| 145 | ////////////////////////////////////////////////////////// | ||
| 146 | |||
| 147 | TOK_IMPL(strip) { | ||
| 148 | sref s=env[0],a=env[1]; | ||
| 149 | for(int i=0;i<s.size();i++) if(a.find(s[i])<0) out.put(s[i]); | ||
| 150 | } | ||
| 151 | |||
| 152 | TOK_IMPL(replace) { | ||
| 153 | mstring s=env[0]; sref a=env[1],b=env[2]; | ||
| 154 | if(a!=b) { int p; while((p=s.find(a))>=0) s.replace(p,a.size(),b); } | ||
| 155 | out<<s; | ||
| 156 | } | ||
| 157 | |||
| 158 | ////////////////////////////////////////////////////////// | ||
| 159 | |||
| 160 | TOK_IMPL(left) { | ||
| 161 | int pad=atoi(env[1])-env[0].size(); | ||
| 162 | out<<env[0]; while(pad-->0) out.put(' '); | ||
| 163 | } | ||
| 164 | TOK_IMPL(right) { | ||
| 165 | int pad=atoi(env[1])-env[0].size(); | ||
| 166 | while(pad-->0) out.put(' '); out<<env[0]; | ||
| 167 | } | ||
| 168 | |||
| 169 | TOK_IMPL(sub) {out<<env[0](atoi(env[1]),atoi(env[2]));} | ||
| 170 | |||
| 171 | ////////////////////////////////////////////////////////// | ||
| 172 | |||
| 173 | TOK_IMPL(file2mime) { | ||
| 174 | const sref* p=file2mime(env[0]); | ||
| 175 | if(p) out<<*p; else out<<http_mime_default; | ||
| 176 | } | ||
| 177 | |||
| 178 | ////////////////////////////////////////////////////////// | ||
| 179 | |||
| 180 | TOK_IMPL(minilang) { | ||
| 181 | static const mstring lang_tag("\\lang"); | ||
| 182 | sref p=env[0]; | ||
| 183 | while(p.nempty()) { | ||
| 184 | sref e=p.left_first(lang_tag); | ||
| 185 | out<<e; | ||
| 186 | p=p.adv(e); | ||
| 187 | if(p.nempty()) { | ||
| 188 | p=p.adv(lang_tag.size()); | ||
| 189 | e=p.right_first_not_of(cset_ws); | ||
| 190 | int n=0,s=e.skip(cset_braces); | ||
| 191 | while(s>0) { | ||
| 192 | p=e.adv(s); | ||
| 193 | if(n==env.req->lang) out<<e(1,s-2); | ||
| 194 | e=p.right_first_not_of(cset_ws); | ||
| 195 | s=e.skip(cset_braces); | ||
| 196 | n++; | ||
| 197 | } | ||
| 198 | if(n==0) out<<lang_tag; | ||
| 199 | if(*p==';') p=p.adv(1); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | ////////////////////////////////////////////////////////// | ||
| 205 | |||
| 206 | void envAddConvert(tokmap& T) | ||
| 207 | { | ||
| 208 | TOK_ADD(mask_htc,"x",tok_t::SYSONLY, | ||
| 209 | "%Mask HTC language\n" | ||
| 210 | "%Syntax: \\mask.htc{text}\n" | ||
| 211 | "%\n" | ||
| 212 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 213 | "%CDATA encoding: &#hex;\n" | ||
| 214 | ); | ||
| 215 | TOK_ADD(mask_html,"x",tok_t::PUBLIC, | ||
| 216 | "%Mask HTML language\n" | ||
| 217 | "%Syntax: \\mask.html{text}\n" | ||
| 218 | "%\n" | ||
| 219 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 220 | "%CDATA encoding: &#hex;\n" | ||
| 221 | ); | ||
| 222 | TOK_ADD(cdata,"x",tok_t::PUBLIC, | ||
| 223 | "%Convert to CDATA\n" | ||
| 224 | "%Syntax: \\cdata{text}\n" | ||
| 225 | "%\n" | ||
| 226 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 227 | "%and encloses in \" characters\n" | ||
| 228 | "%\n" | ||
| 229 | "%HTML parsors usually does not nest the \" character,\n" | ||
| 230 | "%so this function is used extensively in arguments to\n" | ||
| 231 | "%HTML commands.\n" | ||
| 232 | ); | ||
| 233 | |||
| 234 | /////////////////////////////////////////////// | ||
| 235 | |||
| 236 | TOK_ADD(wrap,"xx",tok_t::PUBLIC, | ||
| 237 | "%Wrap long lines\n" | ||
| 238 | "%Syntax: \\wrap{at column}{text}\n" | ||
| 239 | "%\n" | ||
| 240 | "%Wraps words that extend the given column by inserting\n" | ||
| 241 | "%newline characters.\n" | ||
| 242 | ); | ||
| 243 | TOK_ADD(htmlize,"x",tok_t::PUBLIC, | ||
| 244 | "%HTMLize plain text\n" | ||
| 245 | "%Syntax: \\htmlize{text}\n" | ||
| 246 | "%\n" | ||
| 247 | "%Inserts a HTML break at each newline.\n" | ||
| 248 | ); | ||
| 249 | TOK_ADD(lf2crlf,"x",tok_t::PUBLIC, | ||
| 250 | "%LF to CRLF\n" | ||
| 251 | "%Syntax: \\lf2crlf{text}\n" | ||
| 252 | "%\n" | ||
| 253 | "%Inserts a carriage return (CR) at each newline.\n" | ||
| 254 | ); | ||
| 255 | TOK_ADD(crlf2lf,"x",tok_t::PUBLIC, | ||
| 256 | "%CRLF to LF\n" | ||
| 257 | "%Syntax: \\crlf2lf{text}\n" | ||
| 258 | "%\n" | ||
| 259 | "%Removes all carriage return (CR) characters.\n" | ||
| 260 | ); | ||
| 261 | |||
| 262 | /////////////////////////////////////////////// | ||
| 263 | |||
| 264 | TOK_ADD(twocolumn,"xxxxxx",tok_t::PUBLIC, | ||
| 265 | "%Output column text\n" | ||
| 266 | "%Syntax: \\twocolumn{rows}{page}{head}{mid}{foot}{body}\n" | ||
| 267 | ); | ||
| 268 | |||
| 269 | /////////////////////////////////////////////// | ||
| 270 | |||
| 271 | TOK_ADD(encode,"x",tok_t::PUBLIC, | ||
| 272 | "%Encode text\n" | ||
| 273 | "%Syntax: \\encode{text}\n" | ||
| 274 | "%\n" | ||
| 275 | "%Encodes text in x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 276 | ); | ||
| 277 | TOK_ADD(decode,"x",tok_t::PUBLIC, | ||
| 278 | "%Decode text\n" | ||
| 279 | "%Syntax: \\decode{text}\n" | ||
| 280 | "%\n" | ||
| 281 | "%Decodes text given in x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 282 | ); | ||
| 283 | |||
| 284 | TOK_ADD(encode_header,"x",tok_t::PUBLIC, | ||
| 285 | "%Encode header\n" | ||
| 286 | "%Syntax: \\encode.header{text}\n" | ||
| 287 | "%\n" | ||
| 288 | "%Encodes text in Quoted-printable header format (RFC MIME)\n" | ||
| 289 | ); | ||
| 290 | TOK_ADD(encode_base64,"x",tok_t::PUBLIC, | ||
| 291 | "%Encode base64\n" | ||
| 292 | "%Syntax: \\encode.base64{uri}\n" | ||
| 293 | "%\n" | ||
| 294 | "%Encodes the uri, possible containing binary data,\n" | ||
| 295 | "%in BASE64 format (RFC MIME)\n" | ||
| 296 | ); | ||
| 297 | TOK_ADD(decode_base64,"?x",tok_t::PUBLIC, | ||
| 298 | "%Decode base64\n" | ||
| 299 | "%Syntax: \\decode.base64{var}{uri}\n" | ||
| 300 | "%\n" | ||
| 301 | "%Encodes the uri, presumed to be in BASE64 format,\n" | ||
| 302 | "%and outputs or saves in var. (RFC MIME)\n" | ||
| 303 | ); | ||
| 304 | TOK_ADD(pack,"*",tok_t::PUBLIC, | ||
| 305 | "%Encode text\n" | ||
| 306 | "%Syntax: \\pack<var><var>..\n" | ||
| 307 | "%\n" | ||
| 308 | "%Encodes a sequence of variables in\n" | ||
| 309 | "%x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 310 | ); | ||
| 311 | |||
| 312 | /////////////////////////////////////////////// | ||
| 313 | |||
| 314 | TOK_ADD(strip,"xx",tok_t::PUBLIC, | ||
| 315 | "%Strip text from special characters\n" | ||
| 316 | "%Syntax: \\stip{text}{chars}\n" | ||
| 317 | ); | ||
| 318 | TOK_ADD(replace,"xxx",tok_t::PUBLIC, | ||
| 319 | "%Replace text\n" | ||
| 320 | "%Syntax: \\replace{text}{string}{subst}\n" | ||
| 321 | "%\n" | ||
| 322 | "%Replaces each occurence of string in text with subst.\n" | ||
| 323 | ); | ||
| 324 | |||
| 325 | /////////////////////////////////////////////// | ||
| 326 | |||
| 327 | TOK_ADD(left,"xx",tok_t::PUBLIC, | ||
| 328 | "%Left-adjust text\n" | ||
| 329 | "%Syntax: \\left{text}{n}\n" | ||
| 330 | "%\n" | ||
| 331 | "%Outputs n characters, padding with spaces to the right.\n" | ||
| 332 | "%\n" | ||
| 333 | "%Writes out the full text if longer than n.\n" | ||
| 334 | ); | ||
| 335 | TOK_ADD(right,"xx",tok_t::PUBLIC, | ||
| 336 | "%Right-adjust text\n" | ||
| 337 | "%Syntax: \\right{text}{n}\n" | ||
| 338 | "%\n" | ||
| 339 | "%Outputs n characters, padding with spaces to the left.\n" | ||
| 340 | "%\n" | ||
| 341 | "%Writes out the full text if longer than n.\n" | ||
| 342 | ); | ||
| 343 | |||
| 344 | /////////////////////////////////////////////// | ||
| 345 | |||
| 346 | TOK_ADD(sub,"xxx",tok_t::PUBLIC, | ||
| 347 | "%Substring\n" | ||
| 348 | "%Syntax: \\sub{string}{pos}{n}\n" | ||
| 349 | "%\n" | ||
| 350 | "%Gets a substring of n characters, beginning at pos, from string.\n" | ||
| 351 | "%\n" | ||
| 352 | "%Negative pos values wraps to end.\n" | ||
| 353 | "%Negative n values wraps to 1+size.\n" | ||
| 354 | ); | ||
| 355 | |||
| 356 | /////////////////////////////////////////////// | ||
| 357 | |||
| 358 | TOK_ADD(file2mime,"x",tok_t::PUBLIC, | ||
| 359 | "%Get MIME type\n" | ||
| 360 | "%Syntax: \\file2mime{path}\n" | ||
| 361 | "%\n" | ||
| 362 | "%Looks up the MIME type mapped to the extension of path.\n" | ||
| 363 | "%\n" | ||
| 364 | "%Defaults to application/octet-stream if not found.\n" | ||
| 365 | ); | ||
| 366 | |||
| 367 | /////////////////////////////////////////////// | ||
| 368 | |||
| 369 | TOK_ADD(minilang,"x",tok_t::PUBLIC, | ||
| 370 | "%Parse lang only\n" | ||
| 371 | "%Syntax: \\minilang{body}\n" | ||
| 372 | "%\n" | ||
| 373 | "%This function is used to enable lang in html files,\n" | ||
| 374 | "%which otherwise are not parsed.\n" | ||
| 375 | ); | ||
| 376 | } | ||
diff --git a/src/sh/dates.cc b/src/sh/dates.cc new file mode 100644 index 0000000..a37103b --- /dev/null +++ b/src/sh/dates.cc | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <mt/dates.h> | ||
| 22 | #include <limits.h> | ||
| 23 | |||
| 24 | const int ENDTIME=INT_MAX-4*SEC_PER_DAY; | ||
| 25 | |||
| 26 | TOK_IMPL(endtime) { out<<ENDTIME; } | ||
| 27 | TOK_IMPL(now) { out<<Now(); } | ||
| 28 | TOK_IMPL(minutes) { out<<(60*atoi(env[0])); } | ||
| 29 | TOK_IMPL(days) { out<<Days(atoi(env[0])); } | ||
| 30 | TOK_IMPL(today) { out<<Today(atoi(env[0])); } | ||
| 31 | TOK_IMPL(sunday) { out<<Sunday(atoi(env[0])); } | ||
| 32 | TOK_IMPL(week) { out<<Week(env.req->lang,atoi(env[0])); } | ||
| 33 | TOK_IMPL(month) { out<<Month(env.req->lang,atoi(env[0])); } | ||
| 34 | TOK_IMPL(sweek) { out<<SWeek(env.req->lang,atoi(env[0])); } | ||
| 35 | TOK_IMPL(smonth) { out<<SMonth(env.req->lang,atoi(env[0])); } | ||
| 36 | |||
| 37 | //////////////////////////////////////////////////////////// | ||
| 38 | |||
| 39 | TOK_IMPL(time2http) { out<<httpTime(atoi(env[0])); } | ||
| 40 | TOK_IMPL(time2htc) { out<<htcTime(env.req->lang,atoi(env[0])); } | ||
| 41 | TOK_IMPL(htc2time) { out<<htcTime(env.req->lang,env[0]); } | ||
| 42 | TOK_IMPL(cvttime) { out<<cvtTime(env[0]); } | ||
| 43 | |||
| 44 | //////////////////////////////////////////////////////////// | ||
| 45 | |||
| 46 | void envAddDates(tokmap& T) | ||
| 47 | { | ||
| 48 | TOK_ADD(endtime,"",tok_t::PUBLIC, | ||
| 49 | "%Endtime\n" | ||
| 50 | "%Syntax: \\endtime\n" | ||
| 51 | "%\n" | ||
| 52 | "%Last time (safely) representable by internal format\n" | ||
| 53 | ); | ||
| 54 | TOK_ADD(now,"",tok_t::PUBLIC, | ||
| 55 | "%Now\n" | ||
| 56 | "%Syntax: \\now\n" | ||
| 57 | "%\n" | ||
| 58 | "%Current system time. Note that this may be out of\n" | ||
| 59 | "%sync with filesystem.\n" | ||
| 60 | ); | ||
| 61 | TOK_ADD(minutes,"x",tok_t::PUBLIC, | ||
| 62 | "%Minutes in seconds\n" | ||
| 63 | "%Syntax: \\minutes{m}\n" | ||
| 64 | ); | ||
| 65 | TOK_ADD(days,"x",tok_t::PUBLIC, | ||
| 66 | "%Days in seconds\n" | ||
| 67 | "%Syntax: \\days{d}\n" | ||
| 68 | ); | ||
| 69 | TOK_ADD(today,"x",tok_t::PUBLIC, | ||
| 70 | "%Beginning of day\n" | ||
| 71 | "%Syntax: \\today{t}\n" | ||
| 72 | "%\n" | ||
| 73 | "%Get beginning of day.\n" | ||
| 74 | ); | ||
| 75 | TOK_ADD(sunday,"x",tok_t::PUBLIC, | ||
| 76 | "%Last sunday\n" | ||
| 77 | "%Syntax: \\sunday{t}\n" | ||
| 78 | "%\n" | ||
| 79 | "%Get beginning of last sunday.\n" | ||
| 80 | ); | ||
| 81 | TOK_ADD(week,"x",tok_t::PUBLIC, | ||
| 82 | "%Weekday (long)\n" | ||
| 83 | "%Syntax: \\week{t}\n" | ||
| 84 | "%\n" | ||
| 85 | "%Get long weekday format.\n" | ||
| 86 | "%Output in current language.\n" | ||
| 87 | ); | ||
| 88 | TOK_ADD(month,"x",tok_t::PUBLIC, | ||
| 89 | "%Month (long)\n" | ||
| 90 | "%Syntax: \\month{t}\n" | ||
| 91 | "%\n" | ||
| 92 | "%Get long month format.\n" | ||
| 93 | "%Output in current language.\n" | ||
| 94 | ); | ||
| 95 | TOK_ADD(sweek,"x",tok_t::PUBLIC, | ||
| 96 | "%Weekday (short)\n" | ||
| 97 | "%Syntax: \\sweek{t}\n" | ||
| 98 | "%\n" | ||
| 99 | "%Get short weekday format.\n" | ||
| 100 | "%Output in current language.\n" | ||
| 101 | ); | ||
| 102 | TOK_ADD(smonth,"x",tok_t::PUBLIC, | ||
| 103 | "%Month (short)\n" | ||
| 104 | "%Syntax: \\smonth{t}\n" | ||
| 105 | "%\n" | ||
| 106 | "%Get short month format.\n" | ||
| 107 | "%Output in current language.\n" | ||
| 108 | ); | ||
| 109 | |||
| 110 | ////////////////////////////////////////////////////// | ||
| 111 | |||
| 112 | TOK_ADD(time2http,"x",tok_t::PUBLIC, | ||
| 113 | "%HTTP Standard Time (GMT)\n" | ||
| 114 | "%Syntax: \\time2http{t}\n" | ||
| 115 | "%\n" | ||
| 116 | "%Outputs time in standard HTTP format.\n" | ||
| 117 | ); | ||
| 118 | TOK_ADD(time2htc,"x",tok_t::PUBLIC, | ||
| 119 | "%HTC Standard Time (Local)\n" | ||
| 120 | "%Syntax: \\time2htc{t}\n" | ||
| 121 | "%\n" | ||
| 122 | "%Outputs time in standard HTC format, which is local time.\n" | ||
| 123 | "%Output in current language.\n" | ||
| 124 | ); | ||
| 125 | TOK_ADD(htc2time,"x",tok_t::PUBLIC, | ||
| 126 | "%Convert to time from HTC (Local)\n" | ||
| 127 | "%Syntax: \\htc2time{timestring}\n" | ||
| 128 | "%\n" | ||
| 129 | "%Converts text to local time internal format.\n" | ||
| 130 | ); | ||
| 131 | TOK_ADD(cvttime,"x",tok_t::PUBLIC, | ||
| 132 | "%Convert user input time (Local)\n" | ||
| 133 | "%Syntax: \\cvttime{timestring}\n" | ||
| 134 | "%\n" | ||
| 135 | "%Tries to make an intelligent conversion of user input\n" | ||
| 136 | "%under the assumption that a local time is given.\n" | ||
| 137 | ); | ||
| 138 | } | ||
diff --git a/src/sh/file.cc b/src/sh/file.cc new file mode 100644 index 0000000..3d885c5 --- /dev/null +++ b/src/sh/file.cc | |||
| @@ -0,0 +1,367 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/dates.h> | ||
| 23 | #include <dirent.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | |||
| 26 | const mstring sdot=".",sdots=".."; | ||
| 27 | |||
| 28 | /////////////////////////////////////////////////////////////////// | ||
| 29 | |||
| 30 | inline void stat(struct stat& fs,Env& env,const sref& path) throw(merror_t) { | ||
| 31 | if(::stat(DocPath(env,path).c_str(),&fs)<0) | ||
| 32 | THROW("htc: could not stat "<<path<<" - not found"); | ||
| 33 | } | ||
| 34 | |||
| 35 | /////////////////////////////////////////////////////////////////// | ||
| 36 | |||
| 37 | TOK_IMPL(remfile) { | ||
| 38 | mstring path=DocPath(env,env[0]); | ||
| 39 | if(remove(path.c_str())<0) THROW("htc: Could not remove "<<path); | ||
| 40 | } | ||
| 41 | |||
| 42 | TOK_IMPL(renfile) { | ||
| 43 | mstring oldpath=DocPath(env,env[0]),newpath=DocPath(env,env[1]); | ||
| 44 | if(rename(oldpath.c_str(),newpath.c_str())<0) | ||
| 45 | THROW("htc: Could not rename "<<oldpath<<" to "<<newpath); | ||
| 46 | } | ||
| 47 | |||
| 48 | TOK_IMPL(filesafe) { | ||
| 49 | static const charset fsafe=cset_alphareal|'_'; | ||
| 50 | mstring file=env[0]; | ||
| 51 | int pos=file.rfind('/'); if(pos>=0) file=file.past(pos,1); | ||
| 52 | pos=file.rfind('\\'); if(pos>=0) file=file.past(pos,1); | ||
| 53 | while((pos=file.find(sdots))>=0) file.erase(pos,2); | ||
| 54 | mstring acc; | ||
| 55 | for(int i=0;i<file.size();i++) if(fsafe.test(file[i])) acc.append(1,file[i]); | ||
| 56 | out<<acc; | ||
| 57 | } | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | TOK_IMPL(seturi) { | ||
| 62 | Req(env)->uri=env[0]; | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(uri) { | ||
| 66 | out<<Req(env)->uri; | ||
| 67 | } | ||
| 68 | |||
| 69 | TOK_IMPL(pwd) { | ||
| 70 | out<<Req(env)->uri.left_last('/'); | ||
| 71 | } | ||
| 72 | |||
| 73 | TOK_IMPL(npwd) { | ||
| 74 | mstring s=Req(env)->uri.left_last('/'); | ||
| 75 | for(int i=0;i<MAXLANG;i++) { | ||
| 76 | if(s.past_first('/').left_first('/')==LANG[i]) { | ||
| 77 | s=s.past_first('/').right_first('/'); | ||
| 78 | break; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | out<<s; | ||
| 82 | } | ||
| 83 | |||
| 84 | TOK_IMPL(home) { | ||
| 85 | if(Req(env)->htc()->docroot.nempty()) | ||
| 86 | THROW("htc: home only works in absolute file mode"); | ||
| 87 | out<<htchome(); | ||
| 88 | } | ||
| 89 | |||
| 90 | /////////////////////////////////////////////////////////////////// | ||
| 91 | |||
| 92 | TOK_IMPL(load) { | ||
| 93 | mstring name=env.parg(-1),uri=env.URI(env[0]),path=DocPath(env,uri); | ||
| 94 | if(name.nempty()) LoadBuffer(Reference(*env.toks,name,uri,1)->data,path); | ||
| 95 | else { mstring buffer; LoadBuffer(buffer,path); out<<buffer; } | ||
| 96 | } | ||
| 97 | |||
| 98 | TOK_IMPL(open) { | ||
| 99 | mstring name=env[0],uri=env.URI(env[1]),path=DocPath(env,uri); | ||
| 100 | dbref_t* ref=DBRef(*env.toks,env[0],ms_empty,tok_t::PRIVATE,1); | ||
| 101 | ref->db.Open(path,atoi(env.parg(-1))); | ||
| 102 | } | ||
| 103 | |||
| 104 | TOK_IMPL(save) { | ||
| 105 | mstring path=DocPath(env,env[0]),var=env[1]; | ||
| 106 | int prot=atoi(env.parg(2)); if(!prot) prot=0600; | ||
| 107 | tok_t* p=env.toks->get(var); | ||
| 108 | if(!p) THROW("htc: "<<var<<": no such variable"); | ||
| 109 | if(p->is_reference()) SaveBuffer(((reference_t*)p)->data,path,prot); | ||
| 110 | else if(p->is_dbref()) ((dbref_t*)p)->db.Saveas(path,prot); | ||
| 111 | else SaveBuffer(p->body,path,prot); | ||
| 112 | } | ||
| 113 | |||
| 114 | TOK_IMPL(dbmod) { | ||
| 115 | dbref_t* p=(dbref_t*)env.toks->get(env[0]); | ||
| 116 | if(!p&&!p->is_dbref()) THROW("htc: "<<env[0]<<": no such database"); | ||
| 117 | out<<p->db.Lastmod(); | ||
| 118 | } | ||
| 119 | |||
| 120 | /////////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | static void Run(mstream& out,Env& env,const mstring& path) throw(merror_t) { | ||
| 123 | mstring buffer; | ||
| 124 | LoadBuffer(buffer,path); | ||
| 125 | env.parse(out,buffer); | ||
| 126 | } | ||
| 127 | |||
| 128 | TOK_IMPL(include) { | ||
| 129 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 130 | if(!env.glob_find(cwd)) { | ||
| 131 | env.toks->add(new tok_t(cwd,ms_empty,tok_t::CONSTANT|tok_t::PRIVATE),0,1); | ||
| 132 | mstream m; | ||
| 133 | Env e(env,env.mod,cwd); | ||
| 134 | Run(m,e,path); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | TOK_IMPL(parse) { | ||
| 139 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 140 | Env e(env,env.mod,cwd); | ||
| 141 | Run(out,e,path); | ||
| 142 | } | ||
| 143 | |||
| 144 | TOK_IMPL(parse_private) { | ||
| 145 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 146 | Env e(env,XPRIVATE,cwd); | ||
| 147 | Run(out,e,path); | ||
| 148 | } | ||
| 149 | |||
| 150 | TOK_IMPL(parse_public) { | ||
| 151 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 152 | Env e(env,XPUBLIC,cwd); | ||
| 153 | Run(out,e,path); | ||
| 154 | } | ||
| 155 | |||
| 156 | /////////////////////////////////////////////////////////////////// | ||
| 157 | |||
| 158 | TOK_IMPL(dirent) { | ||
| 159 | mstring uri=env.URI(env[0]); | ||
| 160 | sref uribase=uri.leftand_last('/'),ext=uri.adv(uribase); | ||
| 161 | mstring dirpath=DocPath(env,uribase); | ||
| 162 | DIR* dir=opendir(dirpath.c_str()); | ||
| 163 | if(dir) { | ||
| 164 | dirent* p; | ||
| 165 | while((p=readdir(dir))!=0) { | ||
| 166 | sref name(p->d_name); | ||
| 167 | if(name.empty()||name==sdot||name==sdots) continue; | ||
| 168 | if(ext.empty()||name.right(-ext.size()-1)==ext) out<<uribase<<name<<"\n"; | ||
| 169 | } | ||
| 170 | closedir(dir); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | TOK_IMPL(dirmod) { | ||
| 175 | struct stat fs; | ||
| 176 | if(::stat(DocPath(env,env[0]).c_str(),&fs)>=0) out<<fs.st_mode; | ||
| 177 | else out<<(int)0; | ||
| 178 | } | ||
| 179 | |||
| 180 | TOK_IMPL(dirmtime) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_mtime; } | ||
| 181 | TOK_IMPL(diruid) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_uid; } | ||
| 182 | TOK_IMPL(dirgid) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_gid; } | ||
| 183 | TOK_IMPL(filesize) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_size; } | ||
| 184 | |||
| 185 | TOK_IMPL(setperm) { | ||
| 186 | mstring path=DocPath(env,env[0]); | ||
| 187 | if(chmod(path.c_str(),atoi(env[1]))<0) | ||
| 188 | THROW("htc: could not set file permission for "<<path); | ||
| 189 | } | ||
| 190 | |||
| 191 | /////////////////////////////////////////////////////////////////// | ||
| 192 | |||
| 193 | void envAddFile(tokmap& T) | ||
| 194 | { | ||
| 195 | TOK_ADD(remfile,"x",tok_t::SYSONLY, | ||
| 196 | "%Remove file\n" | ||
| 197 | "%Syntax: \\remfile{uri}\n" | ||
| 198 | ); | ||
| 199 | TOK_ADD(renfile,"xx",tok_t::SYSONLY, | ||
| 200 | "%Rename file\n" | ||
| 201 | "%Syntax: \\renfile{olduri}{newuri}\n" | ||
| 202 | ); | ||
| 203 | TOK_ADD(filesafe,"x",tok_t::PUBLIC, | ||
| 204 | "%Transform uri to something safe to save\n" | ||
| 205 | "%Syntax: \\filesafe{uri}\n" | ||
| 206 | "%\n" | ||
| 207 | "%Basically removes eventual path information and\n" | ||
| 208 | "%odd characters.\n" | ||
| 209 | ); | ||
| 210 | |||
| 211 | //////////////////////////////////////////////////////// | ||
| 212 | |||
| 213 | TOK_ADD(seturi,"x",tok_t::SYSONLY, | ||
| 214 | "%Set current uri of current request\n" | ||
| 215 | "%Syntax: \\seturi\n" | ||
| 216 | "%\n" | ||
| 217 | "%Always points to a (virtual) uri.\n" | ||
| 218 | ); | ||
| 219 | TOK_ADD(uri,"",tok_t::PUBLIC, | ||
| 220 | "%uri of current request\n" | ||
| 221 | "%Syntax: \\uri\n" | ||
| 222 | "%\n" | ||
| 223 | "%Always points to a (virtual) uri.\n" | ||
| 224 | ); | ||
| 225 | TOK_ADD(pwd,"",tok_t::PUBLIC, | ||
| 226 | "%uri/directory of current request\n" | ||
| 227 | "%Syntax: \\pwd\n" | ||
| 228 | "%\n" | ||
| 229 | "%Always points to a (virtual) directory, and never contain any\n" | ||
| 230 | "%trailing slashes.\n" | ||
| 231 | ); | ||
| 232 | TOK_ADD(npwd,"",tok_t::PUBLIC, | ||
| 233 | "%uri/directory of current request, without language reference\n" | ||
| 234 | "%Syntax: \\npwd\n" | ||
| 235 | "%\n" | ||
| 236 | "%Always points to a (virtual) directory, and never contain any\n" | ||
| 237 | "%trailing slashes.\n" | ||
| 238 | ); | ||
| 239 | TOK_ADD(home,"",tok_t::PRIVATE, | ||
| 240 | "%Home directory\n" | ||
| 241 | "%Syntax: \\home\n" | ||
| 242 | "%\n" | ||
| 243 | "%Only works in absolute path mode, i.e. when no docroot is set.\n" | ||
| 244 | ); | ||
| 245 | |||
| 246 | //////////////////////////////////////////////////////// | ||
| 247 | |||
| 248 | TOK_ADD(load,"?x",tok_t::PRIVATE, | ||
| 249 | "%Load file directly to output or to variable\n" | ||
| 250 | "%Syntax: \\load<varname>{uri}\n" | ||
| 251 | ); | ||
| 252 | TOK_ADD(open,"xx?",tok_t::SYSONLY, | ||
| 253 | "%Open database to variable\n" | ||
| 254 | "%Syntax: \\load{varname}{uri}<update>\n" | ||
| 255 | "%\n" | ||
| 256 | "%If update is true, the database is opened for reading\n" | ||
| 257 | "%and writing. NOTE that all updates are syncronous and\n" | ||
| 258 | "%instantly - saves or locks are not needed.\n" | ||
| 259 | ); | ||
| 260 | TOK_ADD(save,"xx?",tok_t::SYSONLY, | ||
| 261 | "%Save variable to file\n" | ||
| 262 | "%Syntax: \\save{uri}{varname}<prot>\n" | ||
| 263 | "%\n" | ||
| 264 | "%If the variable points to a reference object, the\n" | ||
| 265 | "%reference is saved. If it points to a database,\n" | ||
| 266 | "%the database is saved. For globals and functions,\n" | ||
| 267 | "%the body is saved.\n" | ||
| 268 | "%\n" | ||
| 269 | "%The optional prot argument is a (base 10) integer\n" | ||
| 270 | "%defining the creation mode mask (unix).\n" | ||
| 271 | ); | ||
| 272 | TOK_ADD(dbmod,"x",tok_t::PUBLIC, | ||
| 273 | "%Get modification time of open database\n" | ||
| 274 | "%Syntax: \\dbmod{var}\n" | ||
| 275 | ); | ||
| 276 | |||
| 277 | //////////////////////////////////////////////////////// | ||
| 278 | |||
| 279 | TOK_ADD(include,"x",tok_t::PRIVATE, | ||
| 280 | "%Include file in current running mode\n" | ||
| 281 | "%Syntax: \\include{uri}\n" | ||
| 282 | "%\n" | ||
| 283 | "%The file is loaded and evaluated, but produces no output\n" | ||
| 284 | "%Any uri can only be included once, so it is safe to use\n" | ||
| 285 | "%include as a precondition.\n" | ||
| 286 | "%\n" | ||
| 287 | "%NOTE that files parsed this way must be known to\n" | ||
| 288 | "%the super-user in order not to create a security hole -\n" | ||
| 289 | "%especially since this command is open in private mode also.\n" | ||
| 290 | ); | ||
| 291 | |||
| 292 | TOK_ADD(parse,"x",tok_t::SYSONLY, | ||
| 293 | "%Parse file in current running mode\n" | ||
| 294 | "%Syntax: \\parse{uri}\n" | ||
| 295 | "%\n" | ||
| 296 | "%The file is loaded and evaluated to output.\n" | ||
| 297 | "%\n" | ||
| 298 | "%NOTE that files parsed this way must be known to\n" | ||
| 299 | "%the super-user in order not to create a security hole.\n" | ||
| 300 | ); | ||
| 301 | |||
| 302 | TOK_ADD(parse_private,"x",tok_t::PRIVATE, | ||
| 303 | "%Parse file in private mode\n" | ||
| 304 | "%Syntax: \\parse.private{uri}\n" | ||
| 305 | "%\n" | ||
| 306 | "%The file is loaded and evaluated to output.\n" | ||
| 307 | "%\n" | ||
| 308 | "%System-mode commands are silently ignored.\n" | ||
| 309 | ); | ||
| 310 | |||
| 311 | TOK_ADD(parse_public,"x",tok_t::PRIVATE, | ||
| 312 | "%Parse file in public mode\n" | ||
| 313 | "%Syntax: \\parse.public{uri}\n" | ||
| 314 | "%\n" | ||
| 315 | "%The file is loaded and evaluated to output.\n" | ||
| 316 | "%\n" | ||
| 317 | "%System/Private mode commands are silently ignored.\n" | ||
| 318 | ); | ||
| 319 | |||
| 320 | //////////////////////////////////////////////////////// | ||
| 321 | |||
| 322 | TOK_ADD(dirent,"x",tok_t::SYSONLY, | ||
| 323 | "%Collect directory entries\n" | ||
| 324 | "%Syntax: \\dirent{uri/match}\n" | ||
| 325 | "%\n" | ||
| 326 | "%An argument of anydir/ collects all files in anydir.\n" | ||
| 327 | "%An argument of anydir/.ext collects all files ending with .ext\n" | ||
| 328 | "%\n" | ||
| 329 | "%Note that an argument of anydir collects files in the parent\n" | ||
| 330 | "%directory of anydir which end whith anydir, which probably is\n" | ||
| 331 | "%not what you want. Trailing slashes are important.\n" | ||
| 332 | ); | ||
| 333 | TOK_ADD(dirmod,"x",tok_t::SYSONLY, | ||
| 334 | "%Return file mode of uri\n" | ||
| 335 | "%Syntax: \\dirmod{uri}\n" | ||
| 336 | "%\n" | ||
| 337 | "%dirmod uses the unix stat function.\n" | ||
| 338 | "%On failure to read, returns zero.\n" | ||
| 339 | ); | ||
| 340 | TOK_ADD(dirmtime,"x",tok_t::SYSONLY, | ||
| 341 | "%Return modification time of uri\n" | ||
| 342 | "%Syntax: \\dirmtime{uri}\n" | ||
| 343 | ); | ||
| 344 | TOK_ADD(diruid,"x",tok_t::SYSONLY, | ||
| 345 | "%Return UNIX uid of uri\n" | ||
| 346 | "%Syntax: \\diruid{uri}\n" | ||
| 347 | "%\n" | ||
| 348 | "%Note that the UNIX uid is different from the HTC one.\n" | ||
| 349 | ); | ||
| 350 | TOK_ADD(dirgid,"x",tok_t::SYSONLY, | ||
| 351 | "%Return UNIX gid of uri\n" | ||
| 352 | "%Syntax: \\dirgid{uri}\n" | ||
| 353 | "%\n" | ||
| 354 | "%Note that the UNIX gid is different from the HTC one.\n" | ||
| 355 | ); | ||
| 356 | TOK_ADD(filesize,"x",tok_t::SYSONLY, | ||
| 357 | "%Return filesize of uri\n" | ||
| 358 | "%Syntax: \\filesize{uri}\n" | ||
| 359 | ); | ||
| 360 | TOK_ADD(setperm,"xx",tok_t::SYSONLY, | ||
| 361 | "%Set file permissions of uri\n" | ||
| 362 | "%Syntax: \\setperm{uri}{mode}\n" | ||
| 363 | "%\n" | ||
| 364 | "%Mode is an integer bitmask compliant with fcntl.\n" | ||
| 365 | ); | ||
| 366 | |||
| 367 | } | ||
diff --git a/src/sh/htc.cc b/src/sh/htc.cc new file mode 100644 index 0000000..9a87f2c --- /dev/null +++ b/src/sh/htc.cc | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/lock.h> | ||
| 23 | |||
| 24 | const mstring RCPATH=htchome()+sref("/htc/htc.rc"); | ||
| 25 | const mstring left="{",right="}"; | ||
| 26 | static fp_stream mout(stdout),merr(stderr); | ||
| 27 | |||
| 28 | static int unbalanced(const sref& in) | ||
| 29 | { | ||
| 30 | static const charset tag("{[("); | ||
| 31 | if(in.empty()) return 1; | ||
| 32 | sref s=in.right_first_of(tag); | ||
| 33 | while(s.nempty()) { | ||
| 34 | int p=-1; | ||
| 35 | switch(*s) { | ||
| 36 | case '{': p=s.skip(cset_braces); break; | ||
| 37 | case '[': p=s.skip(cset_indices); break; | ||
| 38 | case '(': p=s.skip(cset_para); break; | ||
| 39 | } | ||
| 40 | if(p<0) return 1; | ||
| 41 | s=s.adv(p).right_first_of(tag); | ||
| 42 | } | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | main(int argc,char* argv[]) try | ||
| 47 | { | ||
| 48 | NODELOCK(USERMAP); | ||
| 49 | HTC htc(ms_empty); | ||
| 50 | htc_user user(htc.toks); | ||
| 51 | htc_req req(htc,user.toks); req.uri=Cwd(); | ||
| 52 | Env env(htc.ops,req,XSYSTEM); | ||
| 53 | if(argc>1) { | ||
| 54 | for(int i=2;i<argc;i++) env.xpush(left+sref(argv[i])+right); | ||
| 55 | mstring buffer; LoadBuffer(buffer,argv[1]); | ||
| 56 | if(*buffer=='#') buffer.erase(0,buffer.find('\n')+1); | ||
| 57 | env.eval(mout,buffer,1); | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | mstring buffer,line; | ||
| 61 | if(buffer.load(RCPATH.c_str())>=0) { | ||
| 62 | Env e(env,user.toks,RCPATH); | ||
| 63 | mstream m; | ||
| 64 | e.parse(m,buffer); | ||
| 65 | } | ||
| 66 | while(!feof(stdin)) { | ||
| 67 | merr<<"htc>"; | ||
| 68 | buffer.clear(); | ||
| 69 | while(!feof(stdin)&&unbalanced(buffer)) { | ||
| 70 | getline(line,stdin); | ||
| 71 | buffer.append(line); | ||
| 72 | buffer+='\n'; | ||
| 73 | } | ||
| 74 | try { | ||
| 75 | env.parse(mout,buffer); | ||
| 76 | mout<<"\n"; | ||
| 77 | } | ||
| 78 | catch(const merror_t& e) { | ||
| 79 | merr<<e.desc<<"\n"; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | catch(const merror_t& e) { | ||
| 86 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 87 | return -1; | ||
| 88 | } | ||
| 89 | catch(...) { | ||
| 90 | merr<<"ERROR: [FATAL]\n"; | ||
| 91 | return -1; | ||
| 92 | } | ||
diff --git a/src/sh/htc.h b/src/sh/htc.h new file mode 100644 index 0000000..b566176 --- /dev/null +++ b/src/sh/htc.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef HTCH | ||
| 21 | #define HTCH | ||
| 22 | |||
| 23 | #include <sh/user.h> | ||
| 24 | #include <lang/env.h> | ||
| 25 | #include <mt/config.h> | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | mstring Cwd(); | ||
| 30 | |||
| 31 | const mstring USERMAP=htchome()+sref("/htc/users.hdb"); | ||
| 32 | |||
| 33 | /////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | struct HTC : public Lang { | ||
| 36 | fp_stream syslog; | ||
| 37 | mstring docroot,username; | ||
| 38 | mstring host,domain,mailer; | ||
| 39 | IPnode node; | ||
| 40 | int port; | ||
| 41 | |||
| 42 | HTC(const sref& root); | ||
| 43 | ~HTC(); | ||
| 44 | |||
| 45 | void setHost(const sref& s); | ||
| 46 | void setDomain(const sref& s); | ||
| 47 | void setPort(int p); | ||
| 48 | void setMailer(const sref& s); | ||
| 49 | }; | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | struct htc_user { | ||
| 54 | tokmap toks; | ||
| 55 | |||
| 56 | htc_user(tokmap& p); | ||
| 57 | }; | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | struct htc_req : public req_env { | ||
| 62 | mstring group; | ||
| 63 | user_t user; | ||
| 64 | |||
| 65 | HTC* htc() { return (HTC*)glob; } | ||
| 66 | |||
| 67 | htc_req(HTC& g,tokmap& p); | ||
| 68 | }; | ||
| 69 | |||
| 70 | inline htc_req* Req(Env& env) { return (htc_req*)env.req; } | ||
| 71 | inline const sref& DocRoot(Env& env) { return Req(env)->htc()->docroot; } | ||
| 72 | inline mstring DocPath(Env& env,const sref& uri) { return DocRoot(env)+env.URI(uri); } | ||
| 73 | |||
| 74 | /////////////////////////////////////////////////// | ||
| 75 | |||
| 76 | #endif | ||
| 77 | |||
diff --git a/src/sh/main.cc b/src/sh/main.cc new file mode 100644 index 0000000..4926b77 --- /dev/null +++ b/src/sh/main.cc | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <pwd.h> | ||
| 22 | #include <sys/stat.h> | ||
| 23 | #include <sys/utsname.h> | ||
| 24 | |||
| 25 | const mstring PREFSMAP=htchome()+sref("/htc/prefs.hdb"); | ||
| 26 | const mstring SYSLOG=htchome()+sref("/log/htc.log"); | ||
| 27 | |||
| 28 | static fp_stream mout(stdout),merr(stderr); | ||
| 29 | |||
| 30 | /////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | mstring Cwd() { | ||
| 33 | static char buf[1024]; | ||
| 34 | mstring cwd=getcwd(buf,1024); | ||
| 35 | cwd+='/'; | ||
| 36 | return cwd; | ||
| 37 | } | ||
| 38 | |||
| 39 | /////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | static void OpenUSERS(dbmap& db) | ||
| 42 | { | ||
| 43 | db.Open(USERMAP,1); | ||
| 44 | if(db.Tables()==0) for(int i=0;i<user_tabs;i++) db.InsertTable(i,user_tab[i]); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void OpenPREFS(dbmap& db) | ||
| 48 | { | ||
| 49 | db.Open(PREFSMAP,1); | ||
| 50 | if(db.Tables()==0) for(int i=0;i<prefs_tabs;i++) db.InsertTable(i,prefs_tab[i]); | ||
| 51 | } | ||
| 52 | |||
| 53 | htc_user::htc_user(tokmap& p) : toks(p) | ||
| 54 | { | ||
| 55 | OpenUSERS(DBRef(toks,USERS_tag,ms_empty,tok_t::SYSONLY)->db); | ||
| 56 | OpenPREFS(DBRef(toks,PREFS_tag,ms_empty,tok_t::SYSONLY)->db); | ||
| 57 | } | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | htc_req::htc_req(HTC& g,tokmap& p) : req_env(g,p) | ||
| 62 | { | ||
| 63 | user.reset(); | ||
| 64 | } | ||
| 65 | |||
| 66 | /////////////////////////////////////////////////// | ||
| 67 | |||
| 68 | void envAddFile(tokmap& map); | ||
| 69 | void envAddConvert(tokmap& map); | ||
| 70 | void envAddDates(tokmap& map); | ||
| 71 | void envAddUser(tokmap& map) throw(merror_t); | ||
| 72 | void envAddTree(tokmap& map); | ||
| 73 | void envAddSys(tokmap& map); | ||
| 74 | void envAddNet(tokmap& map); | ||
| 75 | |||
| 76 | /////////////////////////////////////////////////// | ||
| 77 | |||
| 78 | HTC::HTC(const sref& root): | ||
| 79 | syslog(fopen(SYSLOG.c_str(),"a+")) | ||
| 80 | { | ||
| 81 | docroot=root; if(docroot.back()=='/') docroot=docroot.popb(); | ||
| 82 | username=getpwuid(getuid())->pw_name; | ||
| 83 | |||
| 84 | envAddFile(toks); | ||
| 85 | envAddConvert(toks); | ||
| 86 | envAddDates(toks); | ||
| 87 | envAddUser(toks); | ||
| 88 | envAddTree(toks); | ||
| 89 | envAddSys(toks); | ||
| 90 | envAddNet(toks); | ||
| 91 | } | ||
| 92 | |||
| 93 | /////////////////////////////////////////////////// | ||
| 94 | |||
| 95 | HTC::~HTC() | ||
| 96 | { | ||
| 97 | fclose(syslog.fp); | ||
| 98 | } | ||
| 99 | |||
| 100 | /////////////////////////////////////////////////// | ||
| 101 | |||
| 102 | void HTC::setHost(const sref& s) | ||
| 103 | { | ||
| 104 | host=s; | ||
| 105 | if(!Lookup(node,host)) THROW("sys: host "<<host<<" not listed in nameserver"); | ||
| 106 | } | ||
| 107 | |||
| 108 | /////////////////////////////////////////////////// | ||
| 109 | |||
| 110 | void HTC::setDomain(const sref& s) | ||
| 111 | { | ||
| 112 | domain=s; | ||
| 113 | } | ||
| 114 | |||
| 115 | /////////////////////////////////////////////////// | ||
| 116 | |||
| 117 | void HTC::setPort(int p) | ||
| 118 | { | ||
| 119 | port=p; | ||
| 120 | } | ||
| 121 | |||
| 122 | /////////////////////////////////////////////////// | ||
| 123 | |||
| 124 | void HTC::setMailer(const sref& s) | ||
| 125 | { | ||
| 126 | mailer=s; | ||
| 127 | } | ||
| 128 | |||
| 129 | /////////////////////////////////////////////////// | ||
diff --git a/src/sh/net.cc b/src/sh/net.cc new file mode 100644 index 0000000..dc03901 --- /dev/null +++ b/src/sh/net.cc | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | |||
| 22 | ///////////////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | TOK_IMPL(sethost) | ||
| 25 | { | ||
| 26 | Req(env)->htc()->setHost(env[0]); | ||
| 27 | } | ||
| 28 | TOK_IMPL(setdomain) | ||
| 29 | { | ||
| 30 | Req(env)->htc()->setDomain(env[0]); | ||
| 31 | } | ||
| 32 | TOK_IMPL(setport) | ||
| 33 | { | ||
| 34 | Req(env)->htc()->setPort(atoi(env[0])); | ||
| 35 | } | ||
| 36 | TOK_IMPL(setmailer) | ||
| 37 | { | ||
| 38 | Req(env)->htc()->setMailer(env[0]); | ||
| 39 | } | ||
| 40 | |||
| 41 | ///////////////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | TOK_IMPL(HOST) { | ||
| 44 | out<<Req(env)->htc()->host; | ||
| 45 | } | ||
| 46 | |||
| 47 | TOK_IMPL(HOSTIP) { | ||
| 48 | out<<Req(env)->htc()->node.ip; | ||
| 49 | } | ||
| 50 | |||
| 51 | TOK_IMPL(DOMAIN) { | ||
| 52 | out<<Req(env)->htc()->domain; | ||
| 53 | } | ||
| 54 | |||
| 55 | TOK_IMPL(ROOT) { | ||
| 56 | out<<Req(env)->htc()->username; | ||
| 57 | if(Req(env)->htc()->domain.size()) out<<"@"<<Req(env)->htc()->domain; | ||
| 58 | } | ||
| 59 | |||
| 60 | TOK_IMPL(ADMIN) { | ||
| 61 | out<<Req(env)->htc()->username; | ||
| 62 | if(Req(env)->htc()->domain.size()) out<<"@"<<Req(env)->htc()->domain; | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(port) | ||
| 66 | { | ||
| 67 | out<<Req(env)->htc()->port; | ||
| 68 | } | ||
| 69 | |||
| 70 | ///////////////////////////////////////////////////////////// | ||
| 71 | |||
| 72 | void envAddNet(tokmap& T) | ||
| 73 | { | ||
| 74 | TOK_ADD(sethost,"x",tok_t::SYSONLY, | ||
| 75 | "%Set host name\n" | ||
| 76 | "%Syntax: \\sethost{host}\n" | ||
| 77 | ); | ||
| 78 | TOK_ADD(setdomain,"x",tok_t::SYSONLY, | ||
| 79 | "%Set default domain\n" | ||
| 80 | "%Syntax: \\setdomain{domain}\n" | ||
| 81 | ); | ||
| 82 | TOK_ADD(setport,"x",tok_t::SYSONLY, | ||
| 83 | "%Set host port number\n" | ||
| 84 | "%Syntax: \\setport{port}\n" | ||
| 85 | ); | ||
| 86 | TOK_ADD(setmailer,"x",tok_t::SYSONLY, | ||
| 87 | "%Set mail program path\n" | ||
| 88 | "%Syntax: \\setmailer{path}\n" | ||
| 89 | ); | ||
| 90 | |||
| 91 | ///////////////////////////////////////////////////////////// | ||
| 92 | |||
| 93 | TOK_ADD(HOST,"",tok_t::PUBLIC, | ||
| 94 | "%Host name\n" | ||
| 95 | "%Syntax: \\HOST\n" | ||
| 96 | ); | ||
| 97 | |||
| 98 | TOK_ADD(HOSTIP,"",tok_t::PUBLIC, | ||
| 99 | "%Host IP address\n" | ||
| 100 | "%Syntax: \\HOSTIP\n" | ||
| 101 | ); | ||
| 102 | |||
| 103 | TOK_ADD(DOMAIN,"",tok_t::PUBLIC, | ||
| 104 | "%Default domain\n" | ||
| 105 | "%Syntax: \\DOMAIN\n" | ||
| 106 | ); | ||
| 107 | |||
| 108 | TOK_ADD(ROOT,"",tok_t::PUBLIC, | ||
| 109 | "%htcroot email address\n" | ||
| 110 | "%Syntax: \\ROOT\n" | ||
| 111 | ); | ||
| 112 | |||
| 113 | TOK_ADD(ADMIN,"",tok_t::PUBLIC, | ||
| 114 | "%admin email address\n" | ||
| 115 | "%Syntax: \\ADMIN\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | TOK_ADD(port,"",tok_t::PUBLIC, | ||
| 119 | "%Host port number\n" | ||
| 120 | "%Syntax: \\port\n" | ||
| 121 | ); | ||
| 122 | } | ||
diff --git a/src/sh/string.cc b/src/sh/string.cc new file mode 100644 index 0000000..8075a5b --- /dev/null +++ b/src/sh/string.cc | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <htc.h> | ||
| 21 | #include <mset.h> | ||
| 22 | |||
| 23 | static mstring empty; | ||
| 24 | |||
| 25 | TOK_IMPL(tolower) {mstring s=env[0];s.tolower();out<<s;} | ||
| 26 | TOK_IMPL(toupper) {mstring s=env[0];s.toupper();out<<s;} | ||
| 27 | |||
| 28 | void envAddString(tokmap& T) | ||
| 29 | { | ||
| 30 | TOK_ADD(tolower,1,0,tok_t::PUBLIC,"%(s)"); | ||
| 31 | TOK_ADD(toupper,1,0,tok_t::PUBLIC,"%(s)"); | ||
| 32 | } | ||
diff --git a/src/sh/sys.cc b/src/sh/sys.cc new file mode 100644 index 0000000..b70991b --- /dev/null +++ b/src/sh/sys.cc | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <mime/mime.h> | ||
| 22 | #include <mt/lookup.h> | ||
| 23 | #include <mt/issue.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | |||
| 27 | //////////////////////////////////////////// | ||
| 28 | |||
| 29 | TOK_IMPL(sleep) { sleep(atoi(env[0])); } | ||
| 30 | TOK_IMPL(throw) { THROW(env[0]); } | ||
| 31 | |||
| 32 | //////////////////////////////////////////// | ||
| 33 | |||
| 34 | TOK_IMPL(sync) { dbmap::Sync(); } | ||
| 35 | |||
| 36 | //////////////////////////////////////////// | ||
| 37 | |||
| 38 | TOK_IMPL(gethost) { | ||
| 39 | IPnode node; if(Lookup(node,env[0])) out<<node.name; else out<<"UNKNOWN"; | ||
| 40 | } | ||
| 41 | |||
| 42 | //////////////////////////////////////////// | ||
| 43 | |||
| 44 | TOK_IMPL(mail) { | ||
| 45 | mswrite ms; | ||
| 46 | if(env[0].size()<2) return; | ||
| 47 | ms<<"From: "; encodeHeader(ms,mime_default,env[3]); ms<<" <"<<env[0]<<">\n"; | ||
| 48 | |||
| 49 | //if(env[1].nempty()) ms<<"Reply-To: "<<env[1]<<"\n"; | ||
| 50 | //!! neat simple hack - never used except as should be | ||
| 51 | if(env[1].nempty()) ms<<"To: "<<env[1]<<"\n"; | ||
| 52 | |||
| 53 | ms<<"Date: "<<httpTime(atoi(env[4]))<<"\n"; | ||
| 54 | ms<<"Subject: "; encodeHeader(ms,mime_default,env[5]); ms<<"\n"; | ||
| 55 | ms<<"MIME-Version: 1.0\n"; | ||
| 56 | ms<<"Content-Transfer-Encoding: Quoted-Printable\n"; | ||
| 57 | ms<<"Content-Type: "<<env[6]<<"\n"; | ||
| 58 | mswrite body; encodeQP(body,env[7]); | ||
| 59 | ms<<"Content-Length: "<<body.str().size()<<"\n"; | ||
| 60 | ms<<"\n"; | ||
| 61 | ms<<body.str(); | ||
| 62 | HTC* htc=Req(env)->htc(); | ||
| 63 | if(htc->mailer.size()) { | ||
| 64 | issue_t cmd(htc->mailer+sref(" ")+env[2]); | ||
| 65 | mstream m; | ||
| 66 | cmd.run(m,ms.str()); | ||
| 67 | htc->syslog<<"["<<time(0)<<"][mail]["<<env[2]<<"]\n"; | ||
| 68 | } | ||
| 69 | else { | ||
| 70 | htc->syslog<<"["<<time(0)<<"][NOT SET]["<<env[2]<<"]\n"; | ||
| 71 | htc->syslog<<"-----------------------------------------\n"; | ||
| 72 | htc->syslog<<ms.str()<<"\n"; | ||
| 73 | htc->syslog<<"=========================================\n"; | ||
| 74 | } | ||
| 75 | htc->syslog.flush(); | ||
| 76 | } | ||
| 77 | |||
| 78 | //////////////////////////////////////////// | ||
| 79 | |||
| 80 | TOK_IMPL(issue) { | ||
| 81 | HTC* htc=Req(env)->htc(); | ||
| 82 | htc->syslog<<"["<<time(0)<<"][issue]["<<env[0]<<"]\n"; | ||
| 83 | htc->syslog.flush(); | ||
| 84 | issue_t cmd(DocPath(env,env[0])); | ||
| 85 | cmd.run(out,env[1]); | ||
| 86 | htc->syslog<<"["<<time(0)<<"][finish]["<<env[0]<<"]\n"; | ||
| 87 | htc->syslog.flush(); | ||
| 88 | } | ||
| 89 | |||
| 90 | ////////////////////////////////////////////////////////// | ||
| 91 | |||
| 92 | void envAddSys(tokmap& T) | ||
| 93 | { | ||
| 94 | TOK_ADD(sleep,"x",tok_t::SYSONLY, | ||
| 95 | "%Sleep for seconds\n" | ||
| 96 | "%Syntax: \\sleep{t}\n" | ||
| 97 | "%\n" | ||
| 98 | "%This one works just like the UNIX command\n" | ||
| 99 | ); | ||
| 100 | TOK_ADD(throw,"x",tok_t::SYSONLY, | ||
| 101 | "%Throw an exception\n" | ||
| 102 | "%Syntax: \\throw{text}\n" | ||
| 103 | "%\n" | ||
| 104 | "%Throw a, for the HTC system, standard error\n" | ||
| 105 | "%expection, which also many of the built-in\n" | ||
| 106 | "%do. Enables well-behaved error handling.\n" | ||
| 107 | ); | ||
| 108 | |||
| 109 | ///////////////////////////////////////////////////////////// | ||
| 110 | |||
| 111 | TOK_ADD(sync,"",tok_t::SYSONLY, | ||
| 112 | "%Syncronize all open writable databases\n" | ||
| 113 | "%Syntax: \\sync\n" | ||
| 114 | "%\n" | ||
| 115 | "%Use in crontab only.\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | ///////////////////////////////////////////////////////////// | ||
| 119 | |||
| 120 | TOK_ADD(gethost,"x",tok_t::SYSONLY, | ||
| 121 | "%Lookup hostname on nameserver\n" | ||
| 122 | "%Syntax: \\gethost{IP address}\n" | ||
| 123 | "%\n" | ||
| 124 | "%Normally performed automatically by the server.\n" | ||
| 125 | ); | ||
| 126 | |||
| 127 | ///////////////////////////////////////////////////////////// | ||
| 128 | |||
| 129 | TOK_ADD(mail,"xxxxxxxx",tok_t::SYSONLY, | ||
| 130 | "%System mail\n" | ||
| 131 | "%Syntax: \\mail{from}{replyto}{to}{fromname}{date}{subject}{mime}{body}\n" | ||
| 132 | "%\n" | ||
| 133 | "%This mail command can do almost anything, so be careful!\n" | ||
| 134 | "%Usually there are several htc commands simplifying the use\n" | ||
| 135 | "%of this one.\n" | ||
| 136 | ); | ||
| 137 | |||
| 138 | ///////////////////////////////////////////////////////////// | ||
| 139 | |||
| 140 | TOK_ADD(issue,"xx",tok_t::SYSONLY, | ||
| 141 | "%Issue piped command\n" | ||
| 142 | "%Syntax: \\issue{uri}{stdin}\n" | ||
| 143 | "%\n" | ||
| 144 | "%Pipes stdin to cmd and output stdout.\n" | ||
| 145 | "%An extremely powerful command that may be used\n" | ||
| 146 | "%to run external programs via the web.\n" | ||
| 147 | "%\n" | ||
| 148 | "%Note that the normal uri handling is performed.\n" | ||
| 149 | ); | ||
| 150 | |||
| 151 | ///////////////////////////////////////////////////////////// | ||
| 152 | } | ||
diff --git a/src/sh/tree.cc b/src/sh/tree.cc new file mode 100644 index 0000000..0ec8f16 --- /dev/null +++ b/src/sh/tree.cc | |||
| @@ -0,0 +1,304 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <sh/user.h> | ||
| 22 | #include <hdb/buffer.h> | ||
| 23 | #include <http/http.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | #include <sys/stat.h> | ||
| 26 | |||
| 27 | const mstring index_tag="index.htc"; | ||
| 28 | const mstring sindex_tag="/index.htc"; | ||
| 29 | const mstring htc_mime="text/x-htc"; | ||
| 30 | const mstring htx_mime="text/x-htx"; | ||
| 31 | const mstring html_mime="text/html"; | ||
| 32 | |||
| 33 | const mstring uri_tag="stat.URI"; | ||
| 34 | const mstring refer_tag="stat.REFER"; | ||
| 35 | const mstring parent_tag="stat.PARENT"; | ||
| 36 | const mstring mime_tag="stat.MIME"; | ||
| 37 | |||
| 38 | const mstring mod_tag="stat.MOD"; | ||
| 39 | const mstring mtime_tag="stat.LASTMOD"; | ||
| 40 | const mstring uid_tag="stat.UID"; | ||
| 41 | const mstring gid_tag="stat.GID"; | ||
| 42 | const mstring size_tag="stat.SIZE"; | ||
| 43 | |||
| 44 | const mstring alias_tag="stat.ALIAS"; | ||
| 45 | const mstring banner_tag="stat.BANNER"; | ||
| 46 | |||
| 47 | const mstring xclear_tag="stat.X.CLEAR"; | ||
| 48 | const mstring xcookie_tag="stat.X.COOKIE"; | ||
| 49 | const mstring domain_tag="stat.X.DOMAIN"; | ||
| 50 | const mstring user_tag="stat.X.USER"; | ||
| 51 | const mstring xcache_tag="stat.X.CACHE"; | ||
| 52 | |||
| 53 | const mstring xmod_tag="stat.XMOD"; | ||
| 54 | |||
| 55 | ///////////////////////////////////////////////////////////////// | ||
| 56 | |||
| 57 | TOK_IMPL(alias) { | ||
| 58 | mstring acc; | ||
| 59 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 60 | acc=env.arg(0)->expr; | ||
| 61 | nenv.sloc(alias_tag,acc); | ||
| 62 | } | ||
| 63 | |||
| 64 | TOK_IMPL(banner) { | ||
| 65 | mstring acc1; | ||
| 66 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 67 | swrite sw(acc1); | ||
| 68 | nenv.parse(sw,env.arg(0)); | ||
| 69 | acc1+=' '; acc1+=env.arg(1)->expr; | ||
| 70 | nenv.sloc(banner_tag,acc1); | ||
| 71 | } | ||
| 72 | |||
| 73 | ///////////////////////////////////////////////////////////////// | ||
| 74 | |||
| 75 | TOK_IMPL(clearance) { | ||
| 76 | mstring acc; | ||
| 77 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 78 | swrite sw(acc); | ||
| 79 | nenv.parse(sw,env.arg(0)); | ||
| 80 | sref first,rest=acc; | ||
| 81 | while(Split(first,rest)) | ||
| 82 | if(first==root_tag) THROW("user: ROOT group not allowed in clearance"); | ||
| 83 | nenv.sloc(xclear_tag,acc); | ||
| 84 | } | ||
| 85 | |||
| 86 | TOK_IMPL(clearance_cookie) { | ||
| 87 | mstring acc1,acc2; | ||
| 88 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 89 | swrite sw1(acc1); | ||
| 90 | nenv.parse(sw1,env.arg(0)); | ||
| 91 | swrite sw2(acc2); | ||
| 92 | nenv.parse(sw2,env.arg(1)); | ||
| 93 | acc1+=' '; acc1+=acc2; | ||
| 94 | nenv.sloc(xcookie_tag,acc1); | ||
| 95 | } | ||
| 96 | |||
| 97 | TOK_IMPL(clearance_domain) { | ||
| 98 | mstring acc; | ||
| 99 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 100 | swrite sw(acc); | ||
| 101 | nenv.parse(sw,env.arg(0)); | ||
| 102 | nenv.sloc(domain_tag,acc); | ||
| 103 | } | ||
| 104 | |||
| 105 | TOK_IMPL(clearance_user) { | ||
| 106 | mstring acc; | ||
| 107 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 108 | swrite sw(acc); | ||
| 109 | nenv.parse(sw,env.arg(0)); | ||
| 110 | nenv.sloc(user_tag,acc); | ||
| 111 | } | ||
| 112 | |||
| 113 | TOK_IMPL(cache) { | ||
| 114 | mstring acc; | ||
| 115 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 116 | swrite sw(acc); | ||
| 117 | nenv.parse(sw,env.arg(0)); | ||
| 118 | nenv.sloc(xcache_tag,acc); | ||
| 119 | } | ||
| 120 | |||
| 121 | ///////////////////////////////////////////////////////////////// | ||
| 122 | |||
| 123 | inline int reachable(const sref& uri) | ||
| 124 | { | ||
| 125 | static const mstring sys_tag="/sys/"; | ||
| 126 | static const mstring bin_tag="/bin/"; | ||
| 127 | static const mstring htc_tag="/htc/"; | ||
| 128 | static const mstring sccs_tag="/SCCS/"; | ||
| 129 | static const mstring cvs_tag="/CVS/"; | ||
| 130 | if(uri.right_last(sindex_tag)==sindex_tag) return 0; | ||
| 131 | if(uri.find(sys_tag)>=0) return 0; | ||
| 132 | if(uri.find(bin_tag)>=0) return 0; | ||
| 133 | if(uri.find(htc_tag)>=0) return 0; | ||
| 134 | if(uri.find(sccs_tag)>=0) return 0; | ||
| 135 | if(uri.find(cvs_tag)>=0) return 0; | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | |||
| 139 | TOK_IMPL(staturi) { | ||
| 140 | struct stat fs; int ok=0; | ||
| 141 | mstring parent,refer,uri=env.URI(env[0]); | ||
| 142 | if(reachable(uri)) { | ||
| 143 | refer=uri; parent=refer.leftand_last('/'); | ||
| 144 | if(refer.back()=='/') { refer+=index_tag; parent=parent.popb().leftand_last('/'); } | ||
| 145 | int s=stat(DocPath(env,refer).c_str(),&fs); | ||
| 146 | if(s>=0) { | ||
| 147 | if(fs.st_mode&24576) { | ||
| 148 | uri+='/'; refer=uri+index_tag; | ||
| 149 | s=stat(DocPath(env,refer).c_str(),&fs); | ||
| 150 | } | ||
| 151 | if(s>=0) { | ||
| 152 | const sref* pmime=file2mime(refer); | ||
| 153 | mstring mime=pmime?*pmime:http_mime_default; | ||
| 154 | mstring index=refer.leftand_last('/')+index_tag; | ||
| 155 | |||
| 156 | Env nenv(env); | ||
| 157 | nenv.aloc(uri_tag,uri); | ||
| 158 | nenv.aloc(refer_tag,refer); | ||
| 159 | nenv.aloc(parent_tag,parent); | ||
| 160 | nenv.aloc(mime_tag,mime); | ||
| 161 | |||
| 162 | nenv.aloc(mod_tag,itoa(fs.st_mode)); | ||
| 163 | nenv.aloc(uid_tag,itoa(fs.st_uid)); | ||
| 164 | nenv.aloc(gid_tag,itoa(fs.st_gid)); | ||
| 165 | nenv.aloc(size_tag,itoa(fs.st_size)); | ||
| 166 | nenv.aloc(mtime_tag,itoa(fs.st_mtime)); | ||
| 167 | |||
| 168 | nenv.aloc(alias_tag,ms_empty); | ||
| 169 | nenv.aloc(banner_tag,ms_empty); | ||
| 170 | |||
| 171 | nenv.aloc(xclear_tag,root_tag); | ||
| 172 | nenv.aloc(xcookie_tag,ms_empty); | ||
| 173 | nenv.aloc(domain_tag,ms_empty); | ||
| 174 | nenv.aloc(user_tag,ms_empty); | ||
| 175 | nenv.aloc(xcache_tag,ms_empty); | ||
| 176 | |||
| 177 | nenv.aloc(xmod_tag,itoa(time(0))); | ||
| 178 | |||
| 179 | mstring buffer; | ||
| 180 | if(mime==htc_mime||mime==htx_mime||mime==html_mime) { | ||
| 181 | LoadBuffer(buffer,DocPath(nenv,refer)); | ||
| 182 | try { | ||
| 183 | Env e(nenv,XINIT,refer); | ||
| 184 | mstream m; | ||
| 185 | e.parse(m,buffer); | ||
| 186 | } | ||
| 187 | catch(const merror_t& e) { | ||
| 188 | THROW(refer<<": "<<e.desc); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | if(mime!=htc_mime&&nenv.gloc(xclear_tag)==root_tag) { | ||
| 192 | if(buffer.load(DocPath(nenv,index).c_str())>=0) { | ||
| 193 | try { | ||
| 194 | Env e(nenv,XINIT,index); | ||
| 195 | mstream m; | ||
| 196 | e.parse(m,buffer); | ||
| 197 | nenv.sloc(alias_tag,ms_empty); | ||
| 198 | nenv.sloc(banner_tag,ms_empty); | ||
| 199 | } | ||
| 200 | catch(const merror_t& e) { | ||
| 201 | THROW(index<<": "<<e.desc); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | nenv.parse(out,env.arg(1)); | ||
| 206 | ok=1; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | if(!ok) env.parg(out,2); | ||
| 211 | } | ||
| 212 | |||
| 213 | ///////////////////////////////////////////////////////////////// | ||
| 214 | |||
| 215 | void envAddTree(tokmap& T) | ||
| 216 | { | ||
| 217 | TOK_ADD(alias,"r",tok_t::INIT, | ||
| 218 | "%Set alias used in sitemap\n" | ||
| 219 | "%Syntax: \\alias{name}\n" | ||
| 220 | "%\n" | ||
| 221 | "%If set, the URI appears in the automatic tree system.\n" | ||
| 222 | ); | ||
| 223 | |||
| 224 | TOK_ADD(banner,"rr",tok_t::INIT, | ||
| 225 | "%Set banner used in layout\n" | ||
| 226 | "%Syntax: \\banner{height}{body}\n" | ||
| 227 | "%\n" | ||
| 228 | "%If set in index file, all URI descendants will use it.\n" | ||
| 229 | ); | ||
| 230 | |||
| 231 | /////////////////////////////////////////////////////// | ||
| 232 | |||
| 233 | TOK_ADD(clearance,"r",tok_t::INIT, | ||
| 234 | "%Set clearance\n" | ||
| 235 | "%Syntax: \\clearance{group list}\n" | ||
| 236 | "%\n" | ||
| 237 | "%A user must have clearance to all groups in order\n" | ||
| 238 | "%to get access.\n" | ||
| 239 | ); | ||
| 240 | TOK_ADD(clearance_domain,"r",tok_t::INIT, | ||
| 241 | "%Restrict clearance to domain\n" | ||
| 242 | "%Syntax: \\clearance.domain{domain list}\n" | ||
| 243 | "%\n" | ||
| 244 | "%A user must have clearance to at least one domain\n" | ||
| 245 | "%in order to get access.\n" | ||
| 246 | ); | ||
| 247 | TOK_ADD(clearance_cookie,"rr",tok_t::INIT, | ||
| 248 | "%Restrict by cookie\n" | ||
| 249 | "%Syntax: \\clearance.cookie{name}{value}\n" | ||
| 250 | "%\n" | ||
| 251 | "%A user must have the cookie set to get access.\n" | ||
| 252 | ); | ||
| 253 | TOK_ADD(clearance_user,"r",tok_t::INIT, | ||
| 254 | "%Restrict by user\n" | ||
| 255 | "%Syntax: \\clearance.user{user list}\n" | ||
| 256 | "%\n" | ||
| 257 | "%A user must appear in the list in order to get access.\n" | ||
| 258 | ); | ||
| 259 | |||
| 260 | /////////////////////////////////////////////////////// | ||
| 261 | |||
| 262 | TOK_ADD(cache,"r",tok_t::INIT, | ||
| 263 | "%Set cache time in seconds\n" | ||
| 264 | "%Syntax: \\cache{t}\n" | ||
| 265 | "%\n" | ||
| 266 | "%If set, normal output is cached for the given time.\n" | ||
| 267 | "%\n" | ||
| 268 | "%There are a number of advantages of caching, the most\n" | ||
| 269 | "%pronounced being server load. Appropriate cache time\n" | ||
| 270 | "%is crucial to get a smooth server.\n" | ||
| 271 | ); | ||
| 272 | |||
| 273 | /////////////////////////////////////////////////////// | ||
| 274 | |||
| 275 | TOK_ADD(staturi,"xr?",tok_t::SYSONLY, | ||
| 276 | "%Retrieve STAT and INIT information for URI\n" | ||
| 277 | "%Syntax: \\staturi{uri}{body}<else>\n" | ||
| 278 | "%\n" | ||
| 279 | "%Do body if a reference to uri is found.\n" | ||
| 280 | "%In the body environment, the record stat. is set\n" | ||
| 281 | "%with the following variables:\n" | ||
| 282 | "%\n" | ||
| 283 | "%URI the canonized URI\n" | ||
| 284 | "%REFER the file uri it refers to\n" | ||
| 285 | "%PARENT the parent uri\n" | ||
| 286 | "%MOD the file mode bits (unix)\n" | ||
| 287 | "%UID the file uid (unix)\n" | ||
| 288 | "%GID the file gid (unix)\n" | ||
| 289 | "%SIZE the file size (unix)\n" | ||
| 290 | "%LASTMOD the file modification time (unix)\n" | ||
| 291 | "%MIME the MIME type\n" | ||
| 292 | "%ALIAS alias used in tree\n" | ||
| 293 | "%X.CLEAR clerarance\n" | ||
| 294 | "%X.COOKIE cookie clearance\n" | ||
| 295 | "%X.DOMAIN domain clearance\n" | ||
| 296 | "%X.USER user clearance\n" | ||
| 297 | "%X.CACHE cache time in seconds\n" | ||
| 298 | "%\n" | ||
| 299 | "%The X. variables are inherited from index.htc\n" | ||
| 300 | "%if X.CLEAR remains equal to ROOT after init.\n" | ||
| 301 | "%\n" | ||
| 302 | "%Unreachable directories: /sys/, /bin/, /htc/, /SCCS/ and /CVS/.\n" | ||
| 303 | ); | ||
| 304 | } | ||
diff --git a/src/sh/user.cc b/src/sh/user.cc new file mode 100644 index 0000000..94285ef --- /dev/null +++ b/src/sh/user.cc | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | |||
| 22 | int allow(const sref& s,const sref& grp,time_t now,int rootok) | ||
| 23 | { | ||
| 24 | if(grp.empty()) return 1; | ||
| 25 | int n=s.find(':'); | ||
| 26 | sref a=s.left(n); | ||
| 27 | if(rootok>=0&&a==root_tag) return rootok; | ||
| 28 | else if(grp==root_tag||a!=grp) return 0; | ||
| 29 | n=(a=s.past(n,1)).find(':'); sref b=a.past(n,1); a=a.left(n); | ||
| 30 | return (a.empty()||atoi(a)<=now)&&(b.empty()||now<atoi(b)); | ||
| 31 | } | ||
| 32 | |||
| 33 | //////////////////////////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | user_t::user_t(const user_t& us) : list(user_tabs) | ||
| 36 | { | ||
| 37 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 38 | } | ||
| 39 | |||
| 40 | void user_t::operator=(const user_t& us) | ||
| 41 | { | ||
| 42 | list.resize(user_tabs); | ||
| 43 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 44 | } | ||
| 45 | |||
| 46 | void user_t::reset() | ||
| 47 | { | ||
| 48 | list.resize(user_tabs); | ||
| 49 | uid()=itoa(0); | ||
| 50 | group()=itoa(0); | ||
| 51 | fail()=itoa(0); | ||
| 52 | pin().clear(); | ||
| 53 | alias().clear(); | ||
| 54 | email().clear(); | ||
| 55 | name().clear(); | ||
| 56 | last()=itoa(0); | ||
| 57 | lastin()=lastin_def; | ||
| 58 | access().clear(); | ||
| 59 | } | ||
| 60 | |||
| 61 | int user_t::allow(const sref& grp,time_t now,int rootok) | ||
| 62 | { | ||
| 63 | sref first,rest=access(); | ||
| 64 | while(Split(first,rest)) if(::allow(first,grp,now,rootok)) return 1; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | int user_t::allow_list(const sref& grps,time_t now,int rootok) | ||
| 69 | { | ||
| 70 | sref first,rest=grps; | ||
| 71 | while(Split(first,rest)) if(!allow(first,now,rootok)) return 0; | ||
| 72 | return 1; | ||
| 73 | } | ||
| 74 | |||
| 75 | void user_t::add(const sref& grp) | ||
| 76 | { | ||
| 77 | sref first,rest=access(); | ||
| 78 | while(Split(first,rest)) if(first.left_first(':')==grp.left_first(':')) return; | ||
| 79 | mstring clear=grp; | ||
| 80 | if(clear.find(':')<0) { clear+=':'; clear+=itoa(time(0)); } | ||
| 81 | if(access().nempty()) access()+=' '; access()+=clear; | ||
| 82 | } | ||
| 83 | |||
| 84 | void user_t::add_list(const sref& grps) { | ||
| 85 | sref first,rest=grps; | ||
| 86 | while(Split(first,rest)) add(first); | ||
| 87 | } | ||
| 88 | |||
| 89 | void user_t::rem(const sref& grp) | ||
| 90 | { | ||
| 91 | mstring m; | ||
| 92 | sref first,rest=access(); | ||
| 93 | while(Split(first,rest)) | ||
| 94 | if(first.left_first(':')!=grp) { if(m.nempty()) m+=' '; m+=first; } | ||
| 95 | access()=m; | ||
| 96 | } | ||
| 97 | |||
| 98 | void user_t::rem_list(const sref& grps) | ||
| 99 | { | ||
| 100 | sref first,rest=grps; | ||
| 101 | while(Split(first,rest)) rem(first); | ||
| 102 | } | ||
| 103 | |||
| 104 | //////////////////////////////////////////////////////////////////////// | ||
| 105 | |||
| 106 | static dbmap* GetDB(Env& env,const sref& name) | ||
| 107 | { | ||
| 108 | dbref_t* p=(dbref_t*)env.toks->get(name); | ||
| 109 | if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find system db "<<name); | ||
| 110 | p->db.remap(); | ||
| 111 | return &p->db; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int FindUser(Env& env,const sref& name) | ||
| 115 | { | ||
| 116 | dbmap* users=GetDB(env,USERS_tag); | ||
| 117 | for(int i=0;i<users->size();i++) { | ||
| 118 | if(users->at(i,user_alias)==name) return atoi(users->at(i,user_uid)); | ||
| 119 | sref first,rest=users->at(i,user_email); | ||
| 120 | while(Split(first,rest)) if(eqn(first,name)) return atoi(users->at(i,user_uid)); | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | //////////////////////////////////////////////////////////////////////// | ||
| 126 | |||
| 127 | TOK_IMPL(setgroup) { Req(env)->group=First(env[0]); } | ||
| 128 | TOK_IMPL(group) { out<<Req(env)->group; } | ||
| 129 | |||
| 130 | TOK_IMPL(getgroups) { | ||
| 131 | dbmap* users=GetDB(env,USERS_tag); | ||
| 132 | mset m; | ||
| 133 | for(int i=0;i<users->size();i++) { | ||
| 134 | sref first,rest=users->at(i,user_access); | ||
| 135 | while(Split(first,rest)) m.insert(first.left_first(':')); | ||
| 136 | } | ||
| 137 | out<<m; | ||
| 138 | } | ||
| 139 | |||
| 140 | //////////////////////////////////////////////////////////////////////// | ||
| 141 | |||
| 142 | TOK_IMPL(getuser) { | ||
| 143 | out<<FindUser(env,env[0]); | ||
| 144 | } | ||
| 145 | |||
| 146 | TOK_IMPL(setuser) { | ||
| 147 | dbmap* users=GetDB(env,USERS_tag); | ||
| 148 | int row=users->Find(env[0]); | ||
| 149 | if(row>=0) users->Get(row,Req(env)->user.list); | ||
| 150 | else Req(env)->user.reset(); | ||
| 151 | } | ||
| 152 | |||
| 153 | TOK_IMPL(remuser) { | ||
| 154 | dbmap* users=GetDB(env,USERS_tag); | ||
| 155 | int row=users->Find(env[0]); | ||
| 156 | if(row>=0) users->Rem(row); | ||
| 157 | } | ||
| 158 | |||
| 159 | TOK_IMPL(newuser) { | ||
| 160 | static const charset namends("*@.+"); | ||
| 161 | user_t user; | ||
| 162 | sref first,rest=env[0]; | ||
| 163 | Split(first,rest); | ||
| 164 | user.group()=first.left_first(':'); | ||
| 165 | do user.add(first); | ||
| 166 | while(Split(first,rest)); | ||
| 167 | user.pin()=Random(4); | ||
| 168 | user.email()=env[1]; | ||
| 169 | rest=env[1]; while(Split(first,rest)) if(FindUser(env,first)) { out<<0; return; } | ||
| 170 | mstring tag,alias=env[1].left_first_of(namends); | ||
| 171 | while(FindUser(env,alias+tag)) tag=itoa(atoi(tag)+1); | ||
| 172 | user.alias()=alias+tag; | ||
| 173 | user.name()=env[2]; | ||
| 174 | dbmap* users=GetDB(env,USERS_tag); | ||
| 175 | if(users->empty()) user.uid()=itoa(1); | ||
| 176 | else user.uid()=itoa(atoi(users->at(users->size()-1,user_uid))+1); | ||
| 177 | int row=users->Insert(user.list,1); | ||
| 178 | if(row<0) THROW("htc: could not add user - record not unique"); | ||
| 179 | out<<user.uid(); | ||
| 180 | } | ||
| 181 | |||
| 182 | ////////////////////////////////////////////////////////////////////////// | ||
| 183 | |||
| 184 | TOK_IMPL(user_id) { out<<Req(env)->user.uid(); } | ||
| 185 | TOK_IMPL(user_group) { out<<Req(env)->user.group(); } | ||
| 186 | TOK_IMPL(user_access) { out<<Req(env)->user.access(); } | ||
| 187 | TOK_IMPL(user_clear) { | ||
| 188 | sref first,rest=Req(env)->user.access(); int n=0; | ||
| 189 | while(Split(first,rest)) { if(n++) out.put(' '); out<<first.left_first(':'); } | ||
| 190 | } | ||
| 191 | |||
| 192 | TOK_IMPL(user_fail) { out<<Req(env)->user.fail(); } | ||
| 193 | TOK_IMPL(user_pin) { out<<Req(env)->user.pin(); } | ||
| 194 | TOK_IMPL(user_alias) { out<<Req(env)->user.alias(); } | ||
| 195 | TOK_IMPL(user_email) { out<<First(Req(env)->user.email()); } | ||
| 196 | TOK_IMPL(user_emails) { out<<Req(env)->user.email(); } | ||
| 197 | TOK_IMPL(user_name) { out<<Req(env)->user.name(); } | ||
| 198 | TOK_IMPL(user_last) { out<<Req(env)->user.last(); } | ||
| 199 | TOK_IMPL(user_lastin) { out<<Req(env)->user.lastin(); } | ||
| 200 | |||
| 201 | ////////////////////////////////////////////////////////////////////////// | ||
| 202 | |||
| 203 | TOK_IMPL(user_group_set) { Req(env)->user.group()=env[0]; } | ||
| 204 | TOK_IMPL(user_access_add) { Req(env)->user.add_list(env[0]); } | ||
| 205 | TOK_IMPL(user_access_rem) { Req(env)->user.rem_list(env[0]); } | ||
| 206 | TOK_IMPL(user_fail_set) { Req(env)->user.fail()=env[0]; } | ||
| 207 | TOK_IMPL(user_pin_set) { Req(env)->user.pin()=env[0]; } | ||
| 208 | TOK_IMPL(user_alias_set) { Req(env)->user.alias()=env[0]; } | ||
| 209 | TOK_IMPL(user_emails_set) { Req(env)->user.email()=env[0]; } | ||
| 210 | TOK_IMPL(user_name_set) { Req(env)->user.name()=env[0]; } | ||
| 211 | TOK_IMPL(user_last_set) { Req(env)->user.last()=env[0]; } | ||
| 212 | TOK_IMPL(user_lastin_set) { Req(env)->user.lastin()=env[0]; } | ||
| 213 | |||
| 214 | ////////////////////////////////////////////////////////// | ||
| 215 | |||
| 216 | TOK_IMPL(user_update) { | ||
| 217 | htc_req* htc=Req(env); | ||
| 218 | int uid=atoi(htc->user.uid()); | ||
| 219 | int who=FindUser(env,htc->user.alias()); | ||
| 220 | if(who&&who!=uid) return; | ||
| 221 | sref first,rest=htc->user.email(); | ||
| 222 | while(Split(first,rest)) { | ||
| 223 | who=FindUser(env,first); | ||
| 224 | if(who&&who!=uid) return; | ||
| 225 | } | ||
| 226 | dbmap* users=GetDB(env,USERS_tag); | ||
| 227 | int row=users->Find(htc->user.uid()); | ||
| 228 | if(row>=0) users->Set(row,htc->user.list); | ||
| 229 | } | ||
| 230 | |||
| 231 | ////////////////////////////////////////////////////////// | ||
| 232 | |||
| 233 | TOK_IMPL(su) { | ||
| 234 | htc_req* htc=Req(env); | ||
| 235 | user_t tmp(htc->user); | ||
| 236 | dbmap* users=GetDB(env,USERS_tag); | ||
| 237 | int row=users->Find(env[0]); | ||
| 238 | if(row>=0) { | ||
| 239 | try { | ||
| 240 | users->Get(row,htc->user.list); | ||
| 241 | env.parg(out,1); | ||
| 242 | htc->user=tmp; | ||
| 243 | } | ||
| 244 | catch(...) { | ||
| 245 | htc->user=tmp; | ||
| 246 | throw; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | else env.parg(out,2); | ||
| 250 | } | ||
| 251 | |||
| 252 | ////////////////////////////////////////////////////////// | ||
| 253 | |||
| 254 | void envAddUser(tokmap& T) throw(merror_t) | ||
| 255 | { | ||
| 256 | TOK_ADD(setgroup,"x",tok_t::SYSONLY, | ||
| 257 | "%Set current group\n" | ||
| 258 | "%Syntax: \\setgroup{group}\n" | ||
| 259 | "%\n" | ||
| 260 | "%Nop function; only for logging and structure.\n" | ||
| 261 | ); | ||
| 262 | TOK_ADD(group,"",tok_t::PUBLIC, | ||
| 263 | "%Get current group\n" | ||
| 264 | "%Syntax: \\group\n" | ||
| 265 | "%\n" | ||
| 266 | "%Nop function; only for logging and structure.\n" | ||
| 267 | ); | ||
| 268 | |||
| 269 | TOK_ADD(getgroups,"",tok_t::PUBLIC, | ||
| 270 | "%Get all groups\n" | ||
| 271 | "%Syntax: \\getgroups\n" | ||
| 272 | "%\n" | ||
| 273 | "%Scans users db for all groups used\n" | ||
| 274 | ); | ||
| 275 | |||
| 276 | /////////////////////////////////////////////////// | ||
| 277 | |||
| 278 | TOK_ADD(getuser,"x",tok_t::SYSONLY, | ||
| 279 | "%Get user ID\n" | ||
| 280 | "%Syntax: \\getuser{alias/email}\n" | ||
| 281 | "%\n" | ||
| 282 | "%Returns the uid if found, or zero if not found\n" | ||
| 283 | ); | ||
| 284 | TOK_ADD(setuser,"x",tok_t::SYSONLY, | ||
| 285 | "%Set current user\n" | ||
| 286 | "%Syntax: \\setuser{uid}\n" | ||
| 287 | ); | ||
| 288 | TOK_ADD(remuser,"x",tok_t::SYSONLY, | ||
| 289 | "%Remove user\n" | ||
| 290 | "%Syntax: \\remuser{uid}\n" | ||
| 291 | ); | ||
| 292 | TOK_ADD(newuser,"xxx",tok_t::SYSONLY, | ||
| 293 | "%Add a new user\n" | ||
| 294 | "%Syntax: \\newuser{clear}{email}{name}\n" | ||
| 295 | "%\n" | ||
| 296 | "%Returns the new uid if successful, otherwise zero.\n" | ||
| 297 | ); | ||
| 298 | |||
| 299 | /////////////////////////////////////////////////// | ||
| 300 | |||
| 301 | TOK_ADD(user_id,"",tok_t::PUBLIC, | ||
| 302 | "%Get uid of current user\n" | ||
| 303 | "%Syntax: \\user.id\n" | ||
| 304 | ); | ||
| 305 | TOK_ADD(user_group,"",tok_t::PUBLIC, | ||
| 306 | "%Get group of current user\n" | ||
| 307 | "%Syntax: \\user.group\n" | ||
| 308 | ); | ||
| 309 | TOK_ADD(user_access,"",tok_t::PUBLIC, | ||
| 310 | "%Get access of current user\n" | ||
| 311 | "%Syntax: \\user.access\n" | ||
| 312 | ); | ||
| 313 | TOK_ADD(user_clear,"",tok_t::PUBLIC, | ||
| 314 | "%Get clearance of current user\n" | ||
| 315 | "%Syntax: \\user.clear\n" | ||
| 316 | "%\n" | ||
| 317 | "%This is a compiled list, without the time info.\n" | ||
| 318 | ); | ||
| 319 | TOK_ADD(user_fail,"",tok_t::PUBLIC, | ||
| 320 | "%Get fail number of current user\n" | ||
| 321 | "%Syntax: \\user.fail\n" | ||
| 322 | ); | ||
| 323 | TOK_ADD(user_pin,"",tok_t::SYSONLY, | ||
| 324 | "%Get pin of current user\n" | ||
| 325 | "%Syntax: \\user.pin\n" | ||
| 326 | ); | ||
| 327 | TOK_ADD(user_alias,"",tok_t::PUBLIC, | ||
| 328 | "%Get alias of current user\n" | ||
| 329 | "%Syntax: \\user.alias\n" | ||
| 330 | ); | ||
| 331 | TOK_ADD(user_email,"",tok_t::PUBLIC, | ||
| 332 | "%Get email of current user\n" | ||
| 333 | "%Syntax: \\user.email\n" | ||
| 334 | "%\n" | ||
| 335 | "%Note that the email list may contain several addresses;\n" | ||
| 336 | "%this function returns the first in the list.\n" | ||
| 337 | ); | ||
| 338 | TOK_ADD(user_emails,"",tok_t::PUBLIC, | ||
| 339 | "%Get all email addresses of current user\n" | ||
| 340 | "%Syntax: \\user.emails\n" | ||
| 341 | ); | ||
| 342 | TOK_ADD(user_name,"",tok_t::PUBLIC, | ||
| 343 | "%Get name of current user\n" | ||
| 344 | "%Syntax: \\user.name\n" | ||
| 345 | ); | ||
| 346 | TOK_ADD(user_last,"",tok_t::PUBLIC, | ||
| 347 | "%Get last time logged in of current user\n" | ||
| 348 | "%Syntax: \\user.last\n" | ||
| 349 | ); | ||
| 350 | TOK_ADD(user_lastin,"",tok_t::PUBLIC, | ||
| 351 | "%Get last IP address of current user\n" | ||
| 352 | "%Syntax: \\user.lastin\n" | ||
| 353 | ); | ||
| 354 | |||
| 355 | /////////////////////////////////////////////////// | ||
| 356 | |||
| 357 | TOK_ADD(user_group_set,"x",tok_t::SYSONLY, | ||
| 358 | "%Set group of current user\n" | ||
| 359 | "%Syntax: \\user.group.set{group}\n" | ||
| 360 | "%\n" | ||
| 361 | "%Note that the changes take effect after a \\user.update\n" | ||
| 362 | ); | ||
| 363 | TOK_ADD(user_access_add,"x",tok_t::SYSONLY, | ||
| 364 | "%Add access to current user\n" | ||
| 365 | "%Syntax: \\user.access.add{group:start:stop}\n" | ||
| 366 | "%\n" | ||
| 367 | "%The :start:stop part may be omitted, in which case\n" | ||
| 368 | "%a start value of now, and a stop value of nil is set.\n" | ||
| 369 | "%\n" | ||
| 370 | "%In case of several group strings, they are all added.\n" | ||
| 371 | "%\n" | ||
| 372 | "%Note that the changes take effect after a \\user.update\n" | ||
| 373 | ); | ||
| 374 | TOK_ADD(user_access_rem,"x",tok_t::SYSONLY, | ||
| 375 | "%Remove access from current user\n" | ||
| 376 | "%Syntax: \\user.access.rem{group}\n" | ||
| 377 | "%\n" | ||
| 378 | "%In case of several groups, they are all removed.\n" | ||
| 379 | "%\n" | ||
| 380 | "%Note that the changes take effect after a \\user.update\n" | ||
| 381 | ); | ||
| 382 | TOK_ADD(user_fail_set,"x",tok_t::SYSONLY, | ||
| 383 | "%Set fail number of current user\n" | ||
| 384 | "%Syntax: \\user.fail.set{fail}\n" | ||
| 385 | "%\n" | ||
| 386 | "%Note that the changes take effect after a \\user.update\n" | ||
| 387 | ); | ||
| 388 | TOK_ADD(user_pin_set,"x",tok_t::SYSONLY, | ||
| 389 | "%Set pin of current user\n" | ||
| 390 | "%Syntax: \\user.pin.set{pin}\n" | ||
| 391 | "%\n" | ||
| 392 | "%Note that the changes take effect after a \\user.update\n" | ||
| 393 | ); | ||
| 394 | TOK_ADD(user_alias_set,"x",tok_t::SYSONLY, | ||
| 395 | "%Set alias of current user\n" | ||
| 396 | "%Syntax: \\user.alias.set{alias}\n" | ||
| 397 | "%\n" | ||
| 398 | "%Note that the changes take effect after a \\user.update\n" | ||
| 399 | ); | ||
| 400 | TOK_ADD(user_emails_set,"x",tok_t::SYSONLY, | ||
| 401 | "%Set all email addresses of current user\n" | ||
| 402 | "%Syntax: \\user.emails.set{emails}\n" | ||
| 403 | "%\n" | ||
| 404 | "%Note that the changes take effect after a \\user.update\n" | ||
| 405 | ); | ||
| 406 | TOK_ADD(user_name_set,"x",tok_t::SYSONLY, | ||
| 407 | "%Set name of current user\n" | ||
| 408 | "%Syntax: \\user.name.set{name}\n" | ||
| 409 | "%\n" | ||
| 410 | "%Note that the changes take effect after a \\user.update\n" | ||
| 411 | ); | ||
| 412 | TOK_ADD(user_last_set,"x",tok_t::SYSONLY, | ||
| 413 | "%Set last time logged in of current user\n" | ||
| 414 | "%Syntax: \\user.last.set{last}\n" | ||
| 415 | "%\n" | ||
| 416 | "%Note that the changes take effect after a \\user.update\n" | ||
| 417 | ); | ||
| 418 | TOK_ADD(user_lastin_set,"x",tok_t::SYSONLY, | ||
| 419 | "%Set last IP address of current user\n" | ||
| 420 | "%Syntax: \\user.lastin.set{addr}\n" | ||
| 421 | "%\n" | ||
| 422 | "%Note that the changes take effect after a \\user.update\n" | ||
| 423 | ); | ||
| 424 | |||
| 425 | /////////////////////////////////////////////////// | ||
| 426 | |||
| 427 | TOK_ADD(user_update,"",tok_t::SYSONLY, | ||
| 428 | "%Update the current user\n" | ||
| 429 | "%Syntax: \\user.update\n" | ||
| 430 | "%\n" | ||
| 431 | "%All changes a synchronous and immediately available.\n" | ||
| 432 | ); | ||
| 433 | |||
| 434 | /////////////////////////////////////////////////// | ||
| 435 | |||
| 436 | TOK_ADD(su,"xr?",tok_t::SYSONLY, | ||
| 437 | "%Set user temporary\n" | ||
| 438 | "%Syntax: \\su{uid}{body}<else>\n" | ||
| 439 | "%\n" | ||
| 440 | "%If set successfully, evaluates body, otherwise <else>.\n" | ||
| 441 | ); | ||
| 442 | |||
| 443 | /////////////////////////////////////////////////// | ||
| 444 | |||
| 445 | } | ||
diff --git a/src/sh/user.h b/src/sh/user.h new file mode 100644 index 0000000..cc00e21 --- /dev/null +++ b/src/sh/user.h | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef USERH | ||
| 21 | #define USERH | ||
| 22 | |||
| 23 | #include <lang/env.h> | ||
| 24 | #include <mt/lookup.h> | ||
| 25 | |||
| 26 | ///////////////////////////////////////////////////////// | ||
| 27 | |||
| 28 | const mstring root_tag="ROOT"; | ||
| 29 | const mstring lastin_def="0.0.0.0"; | ||
| 30 | |||
| 31 | const mstring USERS_tag="USERS"; | ||
| 32 | const mstring PREFS_tag="PREFS"; | ||
| 33 | const mstring TREE_tag="TREE"; | ||
| 34 | |||
| 35 | const int user_tabs=10,user_uid=0,user_alias=4,user_email=5,user_access=9; | ||
| 36 | const mstring user_tab[user_tabs]={ | ||
| 37 | "UID","GROUP","FAIL","PIN","ALIAS","EMAIL","NAME","LAST","LASTIN","ACCESS" | ||
| 38 | }; | ||
| 39 | |||
| 40 | const int prefs_tabs=8; | ||
| 41 | const mstring prefs_tab[prefs_tabs]={ | ||
| 42 | "ID","EXT","ROOM","URL","POSIT","NOTE","ABSTRACT","LASTMOD" | ||
| 43 | }; | ||
| 44 | |||
| 45 | const int tree_tabs=17; | ||
| 46 | const mstring tree_tab[tree_tabs]={ | ||
| 47 | "URI","REFER","PARENT","MIME", | ||
| 48 | "MOD","UID","GID","SIZE","LASTMOD", | ||
| 49 | "ALIAS","BANNER", | ||
| 50 | "X.CLEAR","X.COOKIE","X.DOMAIN","X.USER","X.CACHE", | ||
| 51 | "XMOD" | ||
| 52 | }; | ||
| 53 | |||
| 54 | int allow(const sref& s,const sref& grp,time_t now,int rootok=0); | ||
| 55 | |||
| 56 | struct user_t { | ||
| 57 | spile list; | ||
| 58 | |||
| 59 | user_t() : list(user_tabs) {} | ||
| 60 | user_t(const user_t& us); | ||
| 61 | |||
| 62 | void operator=(const user_t&); | ||
| 63 | |||
| 64 | mstring& uid() { return list[0]; } | ||
| 65 | mstring& group() { return list[1]; } | ||
| 66 | mstring& fail() { return list[2]; } | ||
| 67 | mstring& pin() { return list[3]; } | ||
| 68 | mstring& alias() { return list[4]; } | ||
| 69 | mstring& email() { return list[5]; } | ||
| 70 | mstring& name() { return list[6]; } | ||
| 71 | mstring& last() { return list[7]; } | ||
| 72 | mstring& lastin() { return list[8]; } | ||
| 73 | mstring& access() { return list[9]; } | ||
| 74 | |||
| 75 | void reset(); | ||
| 76 | int allow(const sref& grp,time_t now,int rootok=0); | ||
| 77 | int allow_list(const sref& grps,time_t now,int rootok=0); | ||
| 78 | // rootok<0 -> ignore special root handling (new; should not interfere) | ||
| 79 | // rootok==0 -> root not allowed here | ||
| 80 | // rootok>0 -> root always allowed here | ||
| 81 | |||
| 82 | void add(const sref& grp); | ||
| 83 | void add_list(const sref& grps); | ||
| 84 | void rem(const sref& grp); | ||
| 85 | void rem_list(const sref& grps); | ||
| 86 | }; | ||
| 87 | |||
| 88 | ///////////////////////////////////////////////////////// | ||
| 89 | |||
| 90 | void envAddUser(tokmap& T) throw(merror_t); | ||
| 91 | |||
| 92 | #endif | ||
