/************************************************************************* * * 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" ); }