From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/sh/file.cc | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 src/sh/file.cc (limited to 'src/sh/file.cc') 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +const mstring sdot=".",sdots=".."; + +/////////////////////////////////////////////////////////////////// + +inline void stat(struct stat& fs,Env& env,const sref& path) throw(merror_t) { + if(::stat(DocPath(env,path).c_str(),&fs)<0) + THROW("htc: could not stat "<=0) file=file.past(pos,1); + pos=file.rfind('\\'); if(pos>=0) file=file.past(pos,1); + while((pos=file.find(sdots))>=0) file.erase(pos,2); + mstring acc; + for(int i=0;iuri=env[0]; +} + +TOK_IMPL(uri) { + out<uri; +} + +TOK_IMPL(pwd) { + out<uri.left_last('/'); +} + +TOK_IMPL(npwd) { + mstring s=Req(env)->uri.left_last('/'); + for(int i=0;ihtc()->docroot.nempty()) + THROW("htc: home only works in absolute file mode"); + out<data,path); + else { mstring buffer; LoadBuffer(buffer,path); out<db.Open(path,atoi(env.parg(-1))); +} + +TOK_IMPL(save) { + mstring path=DocPath(env,env[0]),var=env[1]; + int prot=atoi(env.parg(2)); if(!prot) prot=0600; + tok_t* p=env.toks->get(var); + if(!p) THROW("htc: "<is_reference()) SaveBuffer(((reference_t*)p)->data,path,prot); + else if(p->is_dbref()) ((dbref_t*)p)->db.Saveas(path,prot); + else SaveBuffer(p->body,path,prot); +} + +TOK_IMPL(dbmod) { + dbref_t* p=(dbref_t*)env.toks->get(env[0]); + if(!p&&!p->is_dbref()) THROW("htc: "<db.Lastmod(); +} + +/////////////////////////////////////////////////////////////////// + +static void Run(mstream& out,Env& env,const mstring& path) throw(merror_t) { + mstring buffer; + LoadBuffer(buffer,path); + env.parse(out,buffer); +} + +TOK_IMPL(include) { + mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); + if(!env.glob_find(cwd)) { + env.toks->add(new tok_t(cwd,ms_empty,tok_t::CONSTANT|tok_t::PRIVATE),0,1); + mstream m; + Env e(env,env.mod,cwd); + Run(m,e,path); + } +} + +TOK_IMPL(parse) { + mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); + Env e(env,env.mod,cwd); + Run(out,e,path); +} + +TOK_IMPL(parse_private) { + mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); + Env e(env,XPRIVATE,cwd); + Run(out,e,path); +} + +TOK_IMPL(parse_public) { + mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); + Env e(env,XPUBLIC,cwd); + Run(out,e,path); +} + +/////////////////////////////////////////////////////////////////// + +TOK_IMPL(dirent) { + mstring uri=env.URI(env[0]); + sref uribase=uri.leftand_last('/'),ext=uri.adv(uribase); + mstring dirpath=DocPath(env,uribase); + DIR* dir=opendir(dirpath.c_str()); + if(dir) { + dirent* p; + while((p=readdir(dir))!=0) { + sref name(p->d_name); + if(name.empty()||name==sdot||name==sdots) continue; + if(ext.empty()||name.right(-ext.size()-1)==ext) out<=0) out<{uri}\n" + ); + TOK_ADD(open,"xx?",tok_t::SYSONLY, + "%Open database to variable\n" + "%Syntax: \\load{varname}{uri}\n" + "%\n" + "%If update is true, the database is opened for reading\n" + "%and writing. NOTE that all updates are syncronous and\n" + "%instantly - saves or locks are not needed.\n" + ); + TOK_ADD(save,"xx?",tok_t::SYSONLY, + "%Save variable to file\n" + "%Syntax: \\save{uri}{varname}\n" + "%\n" + "%If the variable points to a reference object, the\n" + "%reference is saved. If it points to a database,\n" + "%the database is saved. For globals and functions,\n" + "%the body is saved.\n" + "%\n" + "%The optional prot argument is a (base 10) integer\n" + "%defining the creation mode mask (unix).\n" + ); + TOK_ADD(dbmod,"x",tok_t::PUBLIC, + "%Get modification time of open database\n" + "%Syntax: \\dbmod{var}\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(include,"x",tok_t::PRIVATE, + "%Include file in current running mode\n" + "%Syntax: \\include{uri}\n" + "%\n" + "%The file is loaded and evaluated, but produces no output\n" + "%Any uri can only be included once, so it is safe to use\n" + "%include as a precondition.\n" + "%\n" + "%NOTE that files parsed this way must be known to\n" + "%the super-user in order not to create a security hole -\n" + "%especially since this command is open in private mode also.\n" + ); + + TOK_ADD(parse,"x",tok_t::SYSONLY, + "%Parse file in current running mode\n" + "%Syntax: \\parse{uri}\n" + "%\n" + "%The file is loaded and evaluated to output.\n" + "%\n" + "%NOTE that files parsed this way must be known to\n" + "%the super-user in order not to create a security hole.\n" + ); + + TOK_ADD(parse_private,"x",tok_t::PRIVATE, + "%Parse file in private mode\n" + "%Syntax: \\parse.private{uri}\n" + "%\n" + "%The file is loaded and evaluated to output.\n" + "%\n" + "%System-mode commands are silently ignored.\n" + ); + + TOK_ADD(parse_public,"x",tok_t::PRIVATE, + "%Parse file in public mode\n" + "%Syntax: \\parse.public{uri}\n" + "%\n" + "%The file is loaded and evaluated to output.\n" + "%\n" + "%System/Private mode commands are silently ignored.\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(dirent,"x",tok_t::SYSONLY, + "%Collect directory entries\n" + "%Syntax: \\dirent{uri/match}\n" + "%\n" + "%An argument of anydir/ collects all files in anydir.\n" + "%An argument of anydir/.ext collects all files ending with .ext\n" + "%\n" + "%Note that an argument of anydir collects files in the parent\n" + "%directory of anydir which end whith anydir, which probably is\n" + "%not what you want. Trailing slashes are important.\n" + ); + TOK_ADD(dirmod,"x",tok_t::SYSONLY, + "%Return file mode of uri\n" + "%Syntax: \\dirmod{uri}\n" + "%\n" + "%dirmod uses the unix stat function.\n" + "%On failure to read, returns zero.\n" + ); + TOK_ADD(dirmtime,"x",tok_t::SYSONLY, + "%Return modification time of uri\n" + "%Syntax: \\dirmtime{uri}\n" + ); + TOK_ADD(diruid,"x",tok_t::SYSONLY, + "%Return UNIX uid of uri\n" + "%Syntax: \\diruid{uri}\n" + "%\n" + "%Note that the UNIX uid is different from the HTC one.\n" + ); + TOK_ADD(dirgid,"x",tok_t::SYSONLY, + "%Return UNIX gid of uri\n" + "%Syntax: \\dirgid{uri}\n" + "%\n" + "%Note that the UNIX gid is different from the HTC one.\n" + ); + TOK_ADD(filesize,"x",tok_t::SYSONLY, + "%Return filesize of uri\n" + "%Syntax: \\filesize{uri}\n" + ); + TOK_ADD(setperm,"xx",tok_t::SYSONLY, + "%Set file permissions of uri\n" + "%Syntax: \\setperm{uri}{mode}\n" + "%\n" + "%Mode is an integer bitmask compliant with fcntl.\n" + ); + +} -- cgit v1.2.3