summaryrefslogtreecommitdiff
path: root/src/sh/tree.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/sh/tree.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/sh/tree.cc')
-rw-r--r--src/sh/tree.cc304
1 files changed, 304 insertions, 0 deletions
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
27const mstring index_tag="index.htc";
28const mstring sindex_tag="/index.htc";
29const mstring htc_mime="text/x-htc";
30const mstring htx_mime="text/x-htx";
31const mstring html_mime="text/html";
32
33const mstring uri_tag="stat.URI";
34const mstring refer_tag="stat.REFER";
35const mstring parent_tag="stat.PARENT";
36const mstring mime_tag="stat.MIME";
37
38const mstring mod_tag="stat.MOD";
39const mstring mtime_tag="stat.LASTMOD";
40const mstring uid_tag="stat.UID";
41const mstring gid_tag="stat.GID";
42const mstring size_tag="stat.SIZE";
43
44const mstring alias_tag="stat.ALIAS";
45const mstring banner_tag="stat.BANNER";
46
47const mstring xclear_tag="stat.X.CLEAR";
48const mstring xcookie_tag="stat.X.COOKIE";
49const mstring domain_tag="stat.X.DOMAIN";
50const mstring user_tag="stat.X.USER";
51const mstring xcache_tag="stat.X.CACHE";
52
53const mstring xmod_tag="stat.XMOD";
54
55/////////////////////////////////////////////////////////////////
56
57TOK_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
64TOK_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
75TOK_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
86TOK_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
97TOK_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
105TOK_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
113TOK_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
123inline 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
139TOK_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
215void 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}