summaryrefslogtreecommitdiff
path: root/src/serv
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/serv
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/serv')
-rw-r--r--src/serv/auth.cc162
-rw-r--r--src/serv/const.cc69
-rw-r--r--src/serv/direct.cc73
-rw-r--r--src/serv/form.cc102
-rw-r--r--src/serv/htcd.h74
-rw-r--r--src/serv/htcs.cc92
-rw-r--r--src/serv/main.cc122
-rw-r--r--src/serv/request.cc279
-rw-r--r--src/serv/tempmap.cc82
-rw-r--r--src/serv/tempmap.h57
10 files changed, 1112 insertions, 0 deletions
diff --git a/src/serv/auth.cc b/src/serv/auth.cc
new file mode 100644
index 0000000..abf16b3
--- /dev/null
+++ b/src/serv/auth.cc
@@ -0,0 +1,162 @@
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 <serv/htcd.h>
21
22const mstring default_tag=".default";
23
24/////////////////////////////////////////////////////////////////
25
26TOK_IMPL(remote_name) { out<<Reqd(env)->tcp->node.name; }
27TOK_IMPL(remote_address) { out<<Reqd(env)->tcp->node.ip; }
28TOK_IMPL(remote_port) { out<<Reqd(env)->tcp->port; }
29
30/////////////////////////////////////////////////////////////////
31
32inline int match(const sref& rem,const sref& longrem,const sref& dom)
33{
34 if(rem==dom) return 1;
35 if(*dom!='.') return 0;
36 if(longrem.right_last(dom)==dom) return 1;
37 return 0;
38}
39
40inline int allow(const sref& uname,const sref& list)
41{
42 mstring remote=First(uname);
43 mstring longrem=remote; if(longrem.find('.')<0) longrem+=default_tag;
44 if(remote.empty()) return 0;
45 if(First(list).empty()) return 1;
46 sref first,rest=list;
47 while(Split(first,rest)) if(match(remote,longrem,first)) return 1;
48 return 0;
49}
50
51TOK_IMPL(remote_allow) { out<<allow(Reqd(env)->tcp->node.name,env[0]); }
52TOK_IMPL(bindroot) { Reqd(env)->htcd()->bindroot=env[0]; }
53
54/////////////////////////////////////////////////////////////////
55
56TOK_IMPL(user_allow) {
57 htcd_req* htcd=Reqd(env);
58 mstring opt=env.parg(-1);
59 int now=opt.empty()?time(0):atoi(opt);
60 out<<htcd->user.allow_list(env[0],now,htcd->RootAllowed());
61}
62
63TOK_IMPL(on_clear) {
64 htcd_req* htcd=Reqd(env);
65 if(htcd->user.allow_list(env[0],time(0),htcd->RootAllowed())) env.parg(out,1);
66 else env.parg(out,2);
67}
68
69/////////////////////////////////////////////////////////////////
70
71TOK_IMPL(allowed) {
72 int ok=0;
73 if(!env.db) THROW("htc: no open database");
74 if(env.dbat>=0&&env.dbat<env.db->size()) {
75 user_t user;
76 env.db->Get(env.dbat,user.list);
77 if(user.list.size()!=user_tabs)
78 THROW("htc: cannot test - probably not a users database");
79 mstring opt=env.parg(-1);
80 int now=opt.empty()?time(0):atoi(opt);
81 ok=user.allow_list(env[0],now,Reqd(env)->RootAllowed());
82 }
83 out<<ok;
84}
85
86TOK_IMPL(ingroups) {
87 int ok=0;
88 if(!env.db) THROW("htc: no open database");
89 if(env.dbat>=0&&env.dbat<env.db->size()) {
90 user_t user;
91 env.db->Get(env.dbat,user.list);
92 if(user.list.size()!=user_tabs)
93 THROW("htc: cannot test - probably not a users database");
94 mstring opt=env.parg(-1);
95 int now=opt.empty()?time(0):atoi(opt);
96 ok=user.allow_list(env[0],now,-1);
97 }
98 out<<ok;
99}
100
101/////////////////////////////////////////////////////////////////
102
103void envAddAuth(tokmap& T)
104{
105 TOK_ADD(remote_name,"",tok_t::PUBLIC,
106 "%Remote hostname\n"
107 "%Syntax: \\remote.name\n"
108 );
109 TOK_ADD(remote_address,"",tok_t::PUBLIC,
110 "%Remote address\n"
111 "%Syntax: \\remote.address\n"
112 );
113 TOK_ADD(remote_port,"",tok_t::PUBLIC,
114 "%Remote port\n"
115 "%Syntax: \\remote.port\n"
116 );
117
118 /////////////////////////////////////////////////////////////
119
120 TOK_ADD(remote_allow,"x",tok_t::PUBLIC,
121 "%True if remote hostname allowed by domain\n"
122 "%Syntax: \\remote.allow{domain list}\n"
123 "%\n"
124 "%May be used to restrict access without any group\n"
125 );
126 TOK_ADD(bindroot,"x",tok_t::SYSONLY,
127 "%Bind root access to explicit addresses\n"
128 "%Syntax: \\bindroot{address list}\n"
129 "%\n"
130 "%Note that domain syntax does not work here; you\n"
131 "%want to have total control over all root access.\n"
132 );
133
134 /////////////////////////////////////////////////////////////
135
136 TOK_ADD(user_allow,"x?",tok_t::SYSONLY,
137 "%Core test on user clearance\n"
138 "%Syntax: \\user.allow{groups}<time>\n"
139 "%\n"
140 "%In case of several groups, all must be allowed.\n"
141 );
142 TOK_ADD(on_clear,"xr?",tok_t::SYSONLY,
143 "%Do if user is allowed in all groups now\n"
144 "%Syntax: \\on.clear{groups}{body}<else>\n"
145 );
146
147 /////////////////////////////////////////////////////////////
148
149 TOK_ADD(allowed,"x?",tok_t::SYSONLY,
150 "%True if the current record is allowed in all groups now\n"
151 "%Syntax: \\allowed{groups}<time>\n"
152 "%\n"
153 "%Only used as a query function\n"
154 );
155
156 TOK_ADD(ingroups,"x?",tok_t::SYSONLY,
157 "%True if the current record is part of all groups now\n"
158 "%Syntax: \\ingroups{groups}<time>\n"
159 "%\n"
160 "%Only used as a query function\n"
161 );
162}
diff --git a/src/serv/const.cc b/src/serv/const.cc
new file mode 100644
index 0000000..f252a17
--- /dev/null
+++ b/src/serv/const.cc
@@ -0,0 +1,69 @@
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 <serv/htcd.h>
21
22inline tok_t* Const(tokmap& map,const char* s,const sref& b) throw(merror_t) {
23 return Const(map,sref(s),b,tok_t::PUBLIC);
24}
25
26void envAddConst(tokmap& T)
27{
28 Const(T,"HTTP.100",HTTP_100);
29 Const(T,"HTTP.101",HTTP_101);
30 Const(T,"HTTP.200",HTTP_200);
31 Const(T,"HTTP.201",HTTP_201);
32 Const(T,"HTTP.202",HTTP_202);
33 Const(T,"HTTP.203",HTTP_203);
34 Const(T,"HTTP.204",HTTP_204);
35 Const(T,"HTTP.205",HTTP_205);
36 Const(T,"HTTP.206",HTTP_206);
37 Const(T,"HTTP.300",HTTP_300);
38 Const(T,"HTTP.301",HTTP_301);
39 Const(T,"HTTP.302",HTTP_302);
40 Const(T,"HTTP.303",HTTP_303);
41 Const(T,"HTTP.304",HTTP_304);
42 Const(T,"HTTP.305",HTTP_305);
43 Const(T,"HTTP.306",HTTP_306);
44 Const(T,"HTTP.307",HTTP_307);
45 Const(T,"HTTP.400",HTTP_400);
46 Const(T,"HTTP.401",HTTP_401);
47 Const(T,"HTTP.402",HTTP_402);
48 Const(T,"HTTP.403",HTTP_403);
49 Const(T,"HTTP.404",HTTP_404);
50 Const(T,"HTTP.405",HTTP_405);
51 Const(T,"HTTP.406",HTTP_406);
52 Const(T,"HTTP.407",HTTP_407);
53 Const(T,"HTTP.408",HTTP_408);
54 Const(T,"HTTP.409",HTTP_409);
55 Const(T,"HTTP.410",HTTP_410);
56 Const(T,"HTTP.411",HTTP_411);
57 Const(T,"HTTP.412",HTTP_412);
58 Const(T,"HTTP.413",HTTP_413);
59 Const(T,"HTTP.414",HTTP_414);
60 Const(T,"HTTP.415",HTTP_415);
61 Const(T,"HTTP.416",HTTP_416);
62 Const(T,"HTTP.417",HTTP_417);
63 Const(T,"HTTP.500",HTTP_500);
64 Const(T,"HTTP.501",HTTP_501);
65 Const(T,"HTTP.502",HTTP_502);
66 Const(T,"HTTP.503",HTTP_503);
67 Const(T,"HTTP.504",HTTP_504);
68 Const(T,"HTTP.505",HTTP_505);
69}
diff --git a/src/serv/direct.cc b/src/serv/direct.cc
new file mode 100644
index 0000000..1e7c2d6
--- /dev/null
+++ b/src/serv/direct.cc
@@ -0,0 +1,73 @@
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 <serv/htcd.h>
21#include <mt/dates.h>
22
23const mstring log_cmd="\\group:\\user.id";
24
25TOK_IMPL(error) {
26 throw("htc: 'error' no longer supported");
27}
28
29TOK_IMPL(log) {
30 htcd_req* htc=Reqd(env);
31 MLOCK(htc->htcd()->mutex);
32 fp_stream& tlog=htc->htcd()->errlog;
33 tlog<<"["<<time(0)<<"]["<<htc->tcp->node.ip<<"]["
34 <<htc->tcp->node.name<<":"<<htc->tcp->port<<"]["
35 <<htc->group<<":"<<htc->user.uid()<<"] ";
36 env.parg(tlog,0);
37 tlog<<"\n";
38 tlog.flush();
39}
40
41TOK_IMPL(output) {
42 env.parg(*Reqd(env)->output,0);
43}
44
45void envAddDirect(tokmap& T)
46{
47 TOK_ADD(output,"r",tok_t::PUBLIC,
48 "%Redirect to output stream\n"
49 "%Syntax: \\output{body}\n"
50 "%\n"
51 "%Normally used on server-level, when output refers\n"
52 "%to a socket.\n"
53 );
54
55 TOK_ADD(error,"r",tok_t::SYSONLY,
56 "%Redirect to error stream\n"
57 "%Syntax: \\error{body}\n"
58 "%\n"
59 "%Normally used for debugging and loggin of errors.\n"
60 );
61
62 TOK_ADD(log,"r",tok_t::SYSONLY,
63 "%Message log\n"
64 "%Syntax: \\log{msg}\n"
65 "%\n"
66 "%Outputs to log stream a single line with pre-set information:\n"
67 "%\n"
68 "%IP address\n"
69 "%Time\n"
70 "%Request\n"
71 "%Response\n"
72 );
73}
diff --git a/src/serv/form.cc b/src/serv/form.cc
new file mode 100644
index 0000000..815f9c4
--- /dev/null
+++ b/src/serv/form.cc
@@ -0,0 +1,102 @@
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 <serv/htcd.h>
21
22const mstring tag="T.";
23const mstring ncookie_tag="ncookie";
24const mstring multipart_tag="multipart";
25const mstring body_tag="T.body";
26
27static mstring Tag(const sref& in)
28{
29 mstring name=in;
30 for(int i=0;i<name.size();i++) if(name[i]=='_') name[i]='.';
31 if(tag.empty()||tag==name.left(tag.size())) return name;
32 name.insert(0,tag);
33 return name;
34}
35
36static void AddConst(tokmap& map,const sref& s,const sref& b) throw(merror_t)
37{
38 tok_t* p=map.get_this(s);
39 if(p) {
40 mstring nb=p->body; nb.append(1,' '); nb+=b;
41 Const(map,s,nb,tok_t::PUBLIC,1);
42 }
43 else Const(map,s,b,tok_t::PUBLIC);
44}
45
46static void PushMultipart(tokmap& map,const Mime& root) throw(merror_t)
47{
48 rpile part;
49 if(root.Multipart(part)) {
50 for(int i=0;i<part.size();i++) {
51 Mime msg(part[i]);
52 if(msg.cont_disp_name.nempty()) {
53 mstring name=Tag(msg.cont_disp_name);
54 if(msg.cont_disp_file.nempty()) {
55 reference_t* tok=Reference(map,name,msg.cont_disp_file,tok_t::PUBLIC);
56 swrite via;
57 if(eqn(msg.cont_trans_enc,trans_base64))
58 decode64(via(tok->data),msg.body);
59 else if(eqn(msg.cont_trans_enc,trans_quote))
60 decodeQP(via(tok->data),msg.body);
61 else
62 via(tok->data)<<msg.body;
63 }
64 else AddConst(map,name,msg.body);
65 }
66 }
67 }
68}
69
70static void PushWWWForm(tokmap& map,const sref& in) throw(merror_t)
71{
72 sspile tmp;
73 Unpack(tmp,in);
74 for(int i=0;i<tmp.size();i++)
75 AddConst(map,Tag(tmp[i].first),tmp[i].second);
76}
77
78void SetCookies(tokmap& map,const httpReq& req)
79{
80 Const(map,ncookie_tag,itoa(req.cookies.size()),tok_t::PUBLIC);
81 int n=0;
82 for(sspile::const_iterator p=req.cookies.begin();p!=req.cookies.end();p++) {
83 mstring name,val;
84 name.convert("cookie%d.name",n);
85 val.convert("cookie%d.val",n);
86 Const(map,name,p->first,tok_t::PUBLIC);
87 Const(map,val,p->second,tok_t::PUBLIC);
88 n++;
89 }
90 if(req.arg.nempty()) PushWWWForm(map,req.arg);
91}
92
93void envAddForm(tokmap& map,const httpReq& req)
94{
95 if(req.method==HTTP_POST) {
96 if(req.cont_type.find(multipart_tag,cset_lcase)>=0) PushMultipart(map,req);
97 else PushWWWForm(map,req.body);
98 }
99 else if(req.method==HTTP_PUT) {
100 Const(map,body_tag,req.body,tok_t::PUBLIC);
101 }
102}
diff --git a/src/serv/htcd.h b/src/serv/htcd.h
new file mode 100644
index 0000000..7eaa8dc
--- /dev/null
+++ b/src/serv/htcd.h
@@ -0,0 +1,74 @@
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 HTCdH
21#define HTCdH
22
23#include <serv/tempmap.h>
24#include <sh/htc.h>
25#include <http/http.h>
26
27///////////////////////////////////////////////////
28
29struct HTCd : public HTC {
30 fp_stream logger,errlog;
31 mstring bindroot;
32 mutex_t mutex;
33
34 HTCd(const mstring& path);
35 ~HTCd();
36};
37
38///////////////////////////////////////////////////
39
40struct htcd_user : public htc_user {
41 htcd_user(tokmap& p,const mstring& path);
42};
43
44///////////////////////////////////////////////////
45
46struct tcpReq {
47 IPnode node;
48 int port;
49};
50
51///////////////////////////////////////////////////
52
53struct htcd_req : public htc_req {
54 mstream* output;
55 tcpReq* tcp;
56 httpReq* req;
57 httpResp resp;
58
59 HTCd* htcd() { return (HTCd*)glob; }
60
61 void AddBody(const sref& body);
62 int RootAllowed();
63
64 htcd_req(HTCd& g,tokmap& p,mstream& out,tcpReq& trec,httpReq& hrec);
65};
66
67inline htcd_req* Reqd(Env& env) throw(merror_t) { return (htcd_req*)env.req; }
68
69///////////////////////////////////////////////////
70
71void Setup(tokmap& user,HTCd& htcd);
72
73#endif
74
diff --git a/src/serv/htcs.cc b/src/serv/htcs.cc
new file mode 100644
index 0000000..42ac8e3
--- /dev/null
+++ b/src/serv/htcs.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 <serv/htcd.h>
21#include <hdb/buffer.h>
22#include <mt/lock.h>
23
24static fp_stream mout(stdout),merr(stderr);
25const mstring left="{",right="}";
26
27static int unbalanced(const sref& in)
28{
29 static const charset tag("{[(");
30 if(in.empty()) return 1;
31 sref s=in.right_first_of(tag);
32 while(s.nempty()) {
33 int p=-1;
34 switch(*s) {
35 case '{': p=s.skip(cset_braces); break;
36 case '[': p=s.skip(cset_indices); break;
37 case '(': p=s.skip(cset_para); break;
38 }
39 if(p<0) return 1;
40 s=s.adv(p).right_first_of(tag);
41 }
42 return 0;
43}
44
45main(int argc,char* argv[]) try
46{
47 NODELOCK(USERMAP);
48 if(argc<2) THROW("Usage: "<<argv[0]<<" <docroot>");
49 mstring path=argv[1];
50 if(path.back()=='/') path=path.popb();
51 HTCd htcd(path);
52 tokmap user(htcd.toks);
53 Setup(user,htcd);
54 htcd_user thr(user,path);
55 tcpReq tcp; tcp.port=0;
56 httpReq hreq; hreq.method="GET";
57 htcd_req req(htcd,thr.toks,mout,tcp,hreq);
58 Env env(htcd.ops,req,XSYSTEM);
59 if(argc>2) {
60 for(int i=3;i<argc;i++) env.xpush(left+sref(argv[i])+right);
61 mstring buffer; LoadBuffer(buffer,argv[2]);
62 if(*buffer=='#') buffer.erase(0,buffer.find('\n')+1);
63 mstream m;
64 env.eval(m,buffer,1);
65 }
66 else {
67 mstring buffer,line;
68 while(!feof(stdin)) {
69 merr<<"htcd>";
70 buffer.clear();
71 while(!feof(stdin)&&unbalanced(buffer)) {
72 getline(line,stdin);
73 buffer.append(sref(line));
74 buffer+='\n';
75 }
76 try {
77 env.parse(mout,buffer);
78 mout<<"\n";
79 }
80 catch(const merror_t& e) {
81 merr<<e.desc<<"\n";
82 }
83 }
84 }
85 return 0;
86}
87catch(const merror_t& e) {
88 merr<<"ERROR: ["<<e.desc<<"]\n";
89 return -1;
90}
91
92
diff --git a/src/serv/main.cc b/src/serv/main.cc
new file mode 100644
index 0000000..f02f10c
--- /dev/null
+++ b/src/serv/main.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 <serv/htcd.h>
21#include <hdb/buffer.h>
22
23const mstring RCURI="/sys/htcd.rc";
24const mstring TREEURI="/sys/sitemap.hdb";
25const mstring TEMPURI="/sys/temp.hdb";
26
27const mstring LOGURI="/sys/htcd.log";
28const mstring ERRURI="/sys/htcd.err";
29
30///////////////////////////////////////////////////
31
32static void OpenTREE(dbmap& db,const sref& path)
33{
34 mstring TREEMAP=path+TREEURI;
35 db.Open(TREEMAP,1);
36 if(db.Tables()==0) for(int i=0;i<tree_tabs;i++) db.InsertTable(i,tree_tab[i]);
37}
38
39static void OpenTEMP(dbmap& db,const sref& path)
40{
41 mstring TEMPMAP=path+TEMPURI;
42 db.Open(TEMPMAP,1);
43 if(db.Tables()==0) for(int i=0;i<temp_tabs;i++) db.InsertTable(i,temp_tab[i]);
44}
45
46htcd_user::htcd_user(tokmap& p,const mstring& path) : htc_user(p)
47{
48 OpenTREE(DBRef(toks,TREE_tag,ms_empty,tok_t::SYSONLY)->db,path);
49 OpenTEMP(DBRef(toks,TEMP_tag,ms_empty,tok_t::SYSONLY)->db,path);
50}
51
52///////////////////////////////////////////////////
53
54void SetCookies(tokmap& map,const httpReq& req);
55void envAddForm(tokmap& map,const httpReq& req);
56
57int htcd_req::RootAllowed()
58{
59 if(htcd()->bindroot.empty()) return 1;
60 sref first,rest=htcd()->bindroot;
61 while(Split(first,rest)) if(first==tcp->node.name) return 1;
62 return 0;
63}
64
65htcd_req::htcd_req(HTCd& g,tokmap& p,mstream& out,
66 tcpReq& trec,httpReq& hrec) : htc_req(g,p)
67{
68 output=&out;
69 tcp=&trec;
70 req=&hrec;
71 SetCookies(toks,hrec);
72}
73
74void htcd_req::AddBody(const sref& body)
75{
76 req->body=body;
77 envAddForm(toks,*req);
78}
79
80///////////////////////////////////////////////////
81
82void envAddDirect(tokmap& map);
83void envAddReq(tokmap& map);
84void envAddConst(tokmap& map);
85void envAddAuth(tokmap& map);
86void envAddTemp(tokmap& map);
87
88HTCd::HTCd(const mstring& path):
89 logger(fopen((path+LOGURI).c_str(),"a+")),
90 errlog(fopen((path+ERRURI).c_str(),"a+")),
91 HTC(path)
92{
93 envAddDirect(toks);
94 envAddReq(toks);
95 envAddConst(toks);
96 envAddAuth(toks);
97 envAddTemp(toks);
98
99 memset(&mutex,0,sizeof(mutex));
100 errlog<<"["<<time(0)<<"][MAIN][HTCd started]\n";
101 errlog.flush();
102}
103
104HTCd::~HTCd()
105{
106 fclose(errlog.fp);
107 fclose(logger.fp);
108}
109
110void Setup(tokmap& user,HTCd& htcd)
111{
112 tcpReq tcp; tcp.port=0;
113 httpReq hreq; hreq.method="GET";
114 mstream m1;
115 htcd_req req(htcd,htcd.toks,m1,tcp,hreq);
116 Env env(htcd.ops,req,XSYSTEM);
117 mstring buffer;
118 LoadBuffer(buffer,htcd.docroot+RCURI);
119 Env e(env,user,htcd.docroot+RCURI);
120 mstream m2;
121 e.parse(m2,buffer);
122}
diff --git a/src/serv/request.cc b/src/serv/request.cc
new file mode 100644
index 0000000..163797f
--- /dev/null
+++ b/src/serv/request.cc
@@ -0,0 +1,279 @@
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 <serv/htcd.h>
21
22TOK_IMPL(req_mime_version) { out<<Reqd(env)->req->mime_version; }
23TOK_IMPL(req_cont_type) { out<<Reqd(env)->req->cont_type; }
24TOK_IMPL(req_cont_type_charset) { out<<Reqd(env)->req->cont_type_charset; }
25TOK_IMPL(req_cont_type_name) { out<<Reqd(env)->req->cont_type_name; }
26TOK_IMPL(req_cont_type_boundary) { out<<Reqd(env)->req->cont_type_boundary; }
27TOK_IMPL(req_cont_id) { out<<Reqd(env)->req->cont_id; }
28TOK_IMPL(req_cont_desc) { out<<Reqd(env)->req->cont_desc; }
29TOK_IMPL(req_cont_disp) { out<<Reqd(env)->req->cont_disp; }
30TOK_IMPL(req_cont_disp_name) { out<<Reqd(env)->req->cont_disp_name; }
31TOK_IMPL(req_cont_disp_file) { out<<Reqd(env)->req->cont_disp_file; }
32TOK_IMPL(req_cont_trans_enc) { out<<Reqd(env)->req->cont_trans_enc; }
33TOK_IMPL(req_cont_length) { out<<Reqd(env)->req->cont_length; }
34
35TOK_IMPL(req_cache) { out<<Reqd(env)->req->cache; }
36TOK_IMPL(req_connect) { out<<Reqd(env)->req->connect; }
37TOK_IMPL(req_date) { out<<Reqd(env)->req->date; }
38TOK_IMPL(req_pragma) { out<<Reqd(env)->req->pragma; }
39TOK_IMPL(req_trailer) { out<<Reqd(env)->req->trailer; }
40TOK_IMPL(req_trans_enc) { out<<Reqd(env)->req->trans_enc; }
41TOK_IMPL(req_upgrade) { out<<Reqd(env)->req->upgrade; }
42TOK_IMPL(req_via) { out<<Reqd(env)->req->via; }
43TOK_IMPL(req_warning) { out<<Reqd(env)->req->warning; }
44TOK_IMPL(req_allow) { out<<Reqd(env)->req->allow; }
45TOK_IMPL(req_cont_enc) { out<<Reqd(env)->req->cont_enc; }
46TOK_IMPL(req_cont_lang) { out<<Reqd(env)->req->cont_lang; }
47TOK_IMPL(req_cont_location) { out<<Reqd(env)->req->cont_location; }
48TOK_IMPL(req_cont_md5) { out<<Reqd(env)->req->cont_md5; }
49TOK_IMPL(req_cont_range) { out<<Reqd(env)->req->cont_range; }
50TOK_IMPL(req_expires) { out<<Reqd(env)->req->expires; }
51TOK_IMPL(req_lastmod) { out<<Reqd(env)->req->lastmod; }
52
53TOK_IMPL(req_method) { out<<Reqd(env)->req->method; }
54TOK_IMPL(req_uri) { out<<Reqd(env)->req->uri; }
55TOK_IMPL(req_arg) { out<<Reqd(env)->req->arg; }
56TOK_IMPL(req_version) { out<<Reqd(env)->req->version; }
57TOK_IMPL(req_accept) { out<<Reqd(env)->req->accept; }
58TOK_IMPL(req_accept_charset) { out<<Reqd(env)->req->accept_charset; }
59TOK_IMPL(req_accept_enc) { out<<Reqd(env)->req->accept_enc; }
60TOK_IMPL(req_accept_lang) { out<<Reqd(env)->req->accept_lang; }
61TOK_IMPL(req_accept_range) { out<<Reqd(env)->req->accept_range; }
62TOK_IMPL(req_auth) { out<<Reqd(env)->req->auth; }
63TOK_IMPL(req_expect) { out<<Reqd(env)->req->expect; }
64TOK_IMPL(req_from) { out<<Reqd(env)->req->from; }
65TOK_IMPL(req_host) { out<<Reqd(env)->req->host; }
66TOK_IMPL(req_if_match) { out<<Reqd(env)->req->if_match; }
67TOK_IMPL(req_if_mod) { out<<Reqd(env)->req->if_mod; }
68TOK_IMPL(req_if_none) { out<<Reqd(env)->req->if_none; }
69TOK_IMPL(req_if_range) { out<<Reqd(env)->req->if_range; }
70TOK_IMPL(req_if_unmod) { out<<Reqd(env)->req->if_unmod; }
71TOK_IMPL(req_max_forwards) { out<<Reqd(env)->req->max_forwards; }
72TOK_IMPL(req_proxy) { out<<Reqd(env)->req->proxy; }
73TOK_IMPL(req_range) { out<<Reqd(env)->req->range; }
74TOK_IMPL(req_referer) { out<<Reqd(env)->req->referer; }
75TOK_IMPL(req_te) { out<<Reqd(env)->req->te; }
76TOK_IMPL(req_useragent) { out<<Reqd(env)->req->user_agent; }
77
78///////////////////////////////////////////////////////////////////
79
80TOK_IMPL(resp_cookie) {
81 Reqd(env)->resp.set_cookies.push_back(cookie_t(env[0],env[1],env.parg(2)));
82}
83TOK_IMPL(resp_mime_version) { Reqd(env)->resp.mime_version=env[0]; }
84TOK_IMPL(resp_cont_type) { Reqd(env)->resp.cont_type=env[0]; }
85TOK_IMPL(resp_cont_type_charset) { Reqd(env)->resp.cont_type_charset=env[0]; }
86TOK_IMPL(resp_cont_type_name) { Reqd(env)->resp.cont_type_name=env[0]; }
87TOK_IMPL(resp_cont_type_boundary) { Reqd(env)->resp.cont_type_boundary=env[0]; }
88TOK_IMPL(resp_cont_id) { Reqd(env)->resp.cont_id=env[0]; }
89TOK_IMPL(resp_cont_desc) { Reqd(env)->resp.cont_desc=env[0]; }
90TOK_IMPL(resp_cont_disp) { Reqd(env)->resp.cont_disp=env[0]; }
91TOK_IMPL(resp_cont_disp_name) { Reqd(env)->resp.cont_disp_name=env[0]; }
92TOK_IMPL(resp_cont_disp_file) { Reqd(env)->resp.cont_disp_file=env[0]; }
93TOK_IMPL(resp_cont_trans_enc) { Reqd(env)->resp.cont_trans_enc=env[0]; }
94TOK_IMPL(resp_cont_length) { Reqd(env)->resp.cont_length=env[0]; }
95
96TOK_IMPL(resp_cache) { Reqd(env)->resp.cache=env[0]; }
97TOK_IMPL(resp_connect) { Reqd(env)->resp.connect=env[0]; }
98TOK_IMPL(resp_date) { Reqd(env)->resp.date=env[0]; }
99TOK_IMPL(resp_pragma) { Reqd(env)->resp.pragma=env[0]; }
100TOK_IMPL(resp_trailer) { Reqd(env)->resp.trailer=env[0]; }
101TOK_IMPL(resp_trans_enc) { Reqd(env)->resp.trans_enc=env[0]; }
102TOK_IMPL(resp_upgrade) { Reqd(env)->resp.upgrade=env[0]; }
103TOK_IMPL(resp_via) { Reqd(env)->resp.via=env[0]; }
104TOK_IMPL(resp_warning) { Reqd(env)->resp.warning=env[0]; }
105TOK_IMPL(resp_allow) { Reqd(env)->resp.allow=env[0]; }
106TOK_IMPL(resp_cont_enc) { Reqd(env)->resp.cont_enc=env[0]; }
107TOK_IMPL(resp_cont_lang) { Reqd(env)->resp.cont_lang=env[0]; }
108TOK_IMPL(resp_cont_location) { Reqd(env)->resp.cont_location=env[0]; }
109TOK_IMPL(resp_cont_md5) { Reqd(env)->resp.cont_md5=env[0]; }
110TOK_IMPL(resp_cont_range) { Reqd(env)->resp.cont_range=env[0]; }
111TOK_IMPL(resp_expires) { Reqd(env)->resp.expires=env[0]; }
112TOK_IMPL(resp_lastmod) { Reqd(env)->resp.lastmod=env[0]; }
113
114TOK_IMPL(resp_version) { Reqd(env)->resp.version=env[0]; }
115TOK_IMPL(resp_status) { Reqd(env)->resp.status=env[0]; }
116TOK_IMPL(resp_age) { Reqd(env)->resp.age=env[0]; }
117TOK_IMPL(resp_etag) { Reqd(env)->resp.etag=env[0]; }
118TOK_IMPL(resp_location) { Reqd(env)->resp.location=env[0]; }
119TOK_IMPL(resp_proxy_auth) { Reqd(env)->resp.proxy_authent=env[0]; }
120TOK_IMPL(resp_retry) { Reqd(env)->resp.retry=env[0]; }
121TOK_IMPL(resp_server) { Reqd(env)->resp.server=env[0]; }
122TOK_IMPL(resp_vary) { Reqd(env)->resp.vary=env[0]; }
123TOK_IMPL(resp_auth) { Reqd(env)->resp.authent=env[0]; }
124
125TOK_IMPL(resp_accept) { Reqd(env)->resp.accept=env[0]; }
126TOK_IMPL(resp_accept_charset) { Reqd(env)->resp.accept_charset=env[0]; }
127TOK_IMPL(resp_accept_enc) { Reqd(env)->resp.accept_enc=env[0]; }
128TOK_IMPL(resp_accept_lang) { Reqd(env)->resp.accept_lang=env[0]; }
129TOK_IMPL(resp_accept_range) { Reqd(env)->resp.accept_range=env[0]; }
130
131///////////////////////////////////////////////////////////////////
132
133TOK_IMPL(resp_getstatus) { out<<Reqd(env)->resp.status; }
134
135///////////////////////////////////////////////////////////////////
136
137TOK_IMPL(andarg) { sref s=Reqd(env)->req->arg; if(s.nempty()) out.put('?')<<s; }
138
139///////////////////////////////////////////////////////////////////
140
141const mstring reqhelp="%Request header entry\n";
142const mstring resphelp="%Response header entry; takes one argument\n";
143const mstring respgethelp="%Get response header entry\n";
144const mstring x_tag="x";
145
146void envAddReq(tokmap& T)
147{
148 TOK_ADD(req_mime_version,ms_empty,tok_t::PUBLIC,reqhelp);
149 TOK_ADD(req_cont_type,ms_empty,tok_t::PUBLIC,reqhelp);
150 TOK_ADD(req_cont_type_charset,ms_empty,tok_t::PUBLIC,reqhelp);
151 TOK_ADD(req_cont_type_name,ms_empty,tok_t::PUBLIC,reqhelp);
152 TOK_ADD(req_cont_type_boundary,ms_empty,tok_t::PUBLIC,reqhelp);
153 TOK_ADD(req_cont_id,ms_empty,tok_t::PUBLIC,reqhelp);
154 TOK_ADD(req_cont_desc,ms_empty,tok_t::PUBLIC,reqhelp);
155 TOK_ADD(req_cont_disp,ms_empty,tok_t::PUBLIC,reqhelp);
156 TOK_ADD(req_cont_disp_name,ms_empty,tok_t::PUBLIC,reqhelp);
157 TOK_ADD(req_cont_disp_file,ms_empty,tok_t::PUBLIC,reqhelp);
158 TOK_ADD(req_cont_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp);
159 TOK_ADD(req_cont_length,ms_empty,tok_t::PUBLIC,reqhelp);
160
161 TOK_ADD(req_cache,ms_empty,tok_t::PUBLIC,reqhelp);
162 TOK_ADD(req_connect,ms_empty,tok_t::PUBLIC,reqhelp);
163 TOK_ADD(req_date,ms_empty,tok_t::PUBLIC,reqhelp);
164 TOK_ADD(req_pragma,ms_empty,tok_t::PUBLIC,reqhelp);
165 TOK_ADD(req_trailer,ms_empty,tok_t::PUBLIC,reqhelp);
166 TOK_ADD(req_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp);
167 TOK_ADD(req_upgrade,ms_empty,tok_t::PUBLIC,reqhelp);
168 TOK_ADD(req_via,ms_empty,tok_t::PUBLIC,reqhelp);
169 TOK_ADD(req_warning,ms_empty,tok_t::PUBLIC,reqhelp);
170 TOK_ADD(req_allow,ms_empty,tok_t::PUBLIC,reqhelp);
171 TOK_ADD(req_cont_enc,ms_empty,tok_t::PUBLIC,reqhelp);
172 TOK_ADD(req_cont_lang,ms_empty,tok_t::PUBLIC,reqhelp);
173 TOK_ADD(req_cont_location,ms_empty,tok_t::PUBLIC,reqhelp);
174 TOK_ADD(req_cont_md5,ms_empty,tok_t::PUBLIC,reqhelp);
175 TOK_ADD(req_cont_range,ms_empty,tok_t::PUBLIC,reqhelp);
176 TOK_ADD(req_expires,ms_empty,tok_t::PUBLIC,reqhelp);
177 TOK_ADD(req_lastmod,ms_empty,tok_t::PUBLIC,reqhelp);
178
179 TOK_ADD(req_method,ms_empty,tok_t::PUBLIC,reqhelp);
180 TOK_ADD(req_uri,ms_empty,tok_t::PUBLIC,reqhelp);
181 TOK_ADD(req_arg,ms_empty,tok_t::PUBLIC,reqhelp);
182 TOK_ADD(req_version,ms_empty,tok_t::PUBLIC,reqhelp);
183 TOK_ADD(req_accept,ms_empty,tok_t::PUBLIC,reqhelp);
184 TOK_ADD(req_accept_charset,ms_empty,tok_t::PUBLIC,reqhelp);
185 TOK_ADD(req_accept_enc,ms_empty,tok_t::PUBLIC,reqhelp);
186 TOK_ADD(req_accept_lang,ms_empty,tok_t::PUBLIC,reqhelp);
187 TOK_ADD(req_accept_range,ms_empty,tok_t::PUBLIC,reqhelp);
188 TOK_ADD(req_auth,ms_empty,tok_t::PUBLIC,reqhelp);
189 TOK_ADD(req_expect,ms_empty,tok_t::PUBLIC,reqhelp);
190 TOK_ADD(req_from,ms_empty,tok_t::PUBLIC,reqhelp);
191 TOK_ADD(req_host,ms_empty,tok_t::PUBLIC,reqhelp);
192 TOK_ADD(req_if_match,ms_empty,tok_t::PUBLIC,reqhelp);
193 TOK_ADD(req_if_mod,ms_empty,tok_t::PUBLIC,reqhelp);
194 TOK_ADD(req_if_none,ms_empty,tok_t::PUBLIC,reqhelp);
195 TOK_ADD(req_if_range,ms_empty,tok_t::PUBLIC,reqhelp);
196 TOK_ADD(req_if_unmod,ms_empty,tok_t::PUBLIC,reqhelp);
197 TOK_ADD(req_max_forwards,ms_empty,tok_t::PUBLIC,reqhelp);
198 TOK_ADD(req_proxy,ms_empty,tok_t::PUBLIC,reqhelp);
199 TOK_ADD(req_range,ms_empty,tok_t::PUBLIC,reqhelp);
200 TOK_ADD(req_referer,ms_empty,tok_t::PUBLIC,reqhelp);
201 TOK_ADD(req_te,ms_empty,tok_t::PUBLIC,reqhelp);
202 TOK_ADD(req_useragent,ms_empty,tok_t::PUBLIC,reqhelp);
203
204 ///////////////////////////////////////////////////////////////
205
206 TOK_ADD(andarg,ms_empty,tok_t::PUBLIC,
207 "%Conditional output of argument string\n"
208 "%Syntax: \\andarg\n"
209 "%\n"
210 "%Outputs ?\\req.arg if \\req.arg is non-empty.\n"
211 );
212
213 TOK_ADD(resp_cookie,"xx?",tok_t::SYSONLY,
214 "%Set cookie\n"
215 "%Syntax: \\resp.cookie{name}{val}<options>\n"
216 "%\n"
217 "%Sets the cookie name to value val\n"
218 "%The options field should be on the form expected\n"
219 "%in the HTTP header, for instance\n"
220 "%domain=something; path=/; expires=http-data\n"
221 "%\n"
222 "%No newlines should be added, and remember that ; needs\n"
223 "%to be escaped.\n"
224 );
225
226 ///////////////////////////////////////////////////////////////
227
228 TOK_ADD(resp_mime_version,x_tag,tok_t::SYSONLY,resphelp);
229 TOK_ADD(resp_cont_type,x_tag,tok_t::SYSONLY,resphelp);
230 TOK_ADD(resp_cont_type_charset,x_tag,tok_t::SYSONLY,resphelp);
231 TOK_ADD(resp_cont_type_name,x_tag,tok_t::SYSONLY,resphelp);
232 TOK_ADD(resp_cont_type_boundary,x_tag,tok_t::SYSONLY,resphelp);
233 TOK_ADD(resp_cont_id,x_tag,tok_t::SYSONLY,resphelp);
234 TOK_ADD(resp_cont_desc,x_tag,tok_t::SYSONLY,resphelp);
235 TOK_ADD(resp_cont_disp,x_tag,tok_t::SYSONLY,resphelp);
236 TOK_ADD(resp_cont_disp_name,x_tag,tok_t::SYSONLY,resphelp);
237 TOK_ADD(resp_cont_disp_file,x_tag,tok_t::SYSONLY,resphelp);
238 TOK_ADD(resp_cont_trans_enc,x_tag,tok_t::SYSONLY,resphelp);
239 TOK_ADD(resp_cont_length,x_tag,tok_t::SYSONLY,resphelp);
240
241 TOK_ADD(resp_cache,x_tag,tok_t::SYSONLY,resphelp);
242 TOK_ADD(resp_connect,x_tag,tok_t::SYSONLY,resphelp);
243 TOK_ADD(resp_date,x_tag,tok_t::SYSONLY,resphelp);
244 TOK_ADD(resp_pragma,x_tag,tok_t::SYSONLY,resphelp);
245 TOK_ADD(resp_trailer,x_tag,tok_t::SYSONLY,resphelp);
246 TOK_ADD(resp_trans_enc,x_tag,tok_t::SYSONLY,resphelp);
247 TOK_ADD(resp_upgrade,x_tag,tok_t::SYSONLY,resphelp);
248 TOK_ADD(resp_via,x_tag,tok_t::SYSONLY,resphelp);
249 TOK_ADD(resp_warning,x_tag,tok_t::SYSONLY,resphelp);
250 TOK_ADD(resp_allow,x_tag,tok_t::SYSONLY,resphelp);
251 TOK_ADD(resp_cont_enc,x_tag,tok_t::SYSONLY,resphelp);
252 TOK_ADD(resp_cont_lang,x_tag,tok_t::SYSONLY,resphelp);
253 TOK_ADD(resp_cont_location,x_tag,tok_t::SYSONLY,resphelp);
254 TOK_ADD(resp_cont_md5,x_tag,tok_t::SYSONLY,resphelp);
255 TOK_ADD(resp_cont_range,x_tag,tok_t::SYSONLY,resphelp);
256 TOK_ADD(resp_expires,x_tag,tok_t::SYSONLY,resphelp);
257 TOK_ADD(resp_lastmod,x_tag,tok_t::SYSONLY,resphelp);
258
259 TOK_ADD(resp_version,x_tag,tok_t::SYSONLY,resphelp);
260 TOK_ADD(resp_status,x_tag,tok_t::SYSONLY,resphelp);
261 TOK_ADD(resp_age,x_tag,tok_t::SYSONLY,resphelp);
262 TOK_ADD(resp_etag,x_tag,tok_t::SYSONLY,resphelp);
263 TOK_ADD(resp_location,x_tag,tok_t::SYSONLY,resphelp);
264 TOK_ADD(resp_proxy_auth,x_tag,tok_t::SYSONLY,resphelp);
265 TOK_ADD(resp_retry,x_tag,tok_t::SYSONLY,resphelp);
266 TOK_ADD(resp_server,x_tag,tok_t::SYSONLY,resphelp);
267 TOK_ADD(resp_vary,x_tag,tok_t::SYSONLY,resphelp);
268 TOK_ADD(resp_auth,x_tag,tok_t::SYSONLY,resphelp);
269
270 TOK_ADD(resp_accept,x_tag,tok_t::SYSONLY,resphelp);
271 TOK_ADD(resp_accept_charset,x_tag,tok_t::SYSONLY,resphelp);
272 TOK_ADD(resp_accept_enc,x_tag,tok_t::SYSONLY,resphelp);
273 TOK_ADD(resp_accept_lang,x_tag,tok_t::SYSONLY,resphelp);
274 TOK_ADD(resp_accept_range,x_tag,tok_t::SYSONLY,resphelp);
275
276 ///////////////////////////////////////////////////////////////
277
278 TOK_ADD(resp_getstatus,ms_empty,tok_t::PUBLIC,respgethelp);
279}
diff --git a/src/serv/tempmap.cc b/src/serv/tempmap.cc
new file mode 100644
index 0000000..43b8732
--- /dev/null
+++ b/src/serv/tempmap.cc
@@ -0,0 +1,82 @@
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 <serv/htcd.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <sys/stat.h>
24
25const mstring TEMPDIR="/tmp/";
26
27inline dbmap* GetDB(Env& env)
28{
29 dbref_t* p=(dbref_t*)env.toks->get(TEMP_tag);
30 if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find tempfile db");
31 p->db.remap();
32 return &p->db;
33}
34
35TOK_IMPL(tempfile)
36{
37 mstring path=Reqd(env)->htcd()->docroot+TEMPDIR;
38 mstring file=Random(8),ext=env[1];
39 int fd;
40 while((fd=open((path+file+ext).c_str(),O_CREAT|O_EXCL|O_WRONLY|O_TRUNC,0600))==-1)
41 file=Random(8);
42 close(fd);
43 tempmap_t temp;
44 temp.name()=file+ext;
45 temp.start()=itoa(time(0));
46 temp.stop()=itoa(time(0)+atoi(env[0]));
47 temp.refer()=Reqd(env)->user.uid();
48 dbmap* db=GetDB(env);
49 if(db->empty()) temp.id()=itoa(1);
50 else temp.id()=itoa(atoi(db->at(db->size()-1,temp_id))+1);
51 int row=db->Insert(temp.list,1);
52 if(row<0) THROW("htc: could not add tempfile - record not unique");
53 out<<temp.name();
54}
55
56TOK_IMPL(tempfile_update)
57{
58 mstring path=Reqd(env)->htcd()->docroot+TEMPDIR;
59 time_t now=time(0);
60 dbmap* db=GetDB(env);
61 int n=0;
62 while(n<db->size()) {
63 if(now>atoi(db->at(n,temp_stop))) {
64 remove((path+db->at(n,temp_name)).c_str());
65 db->Rem(n);
66 }
67 else n++;
68 }
69}
70
71void envAddTemp(tokmap& T)
72{
73 TOK_ADD(tempfile,"xx",tok_t::SYSONLY,
74 "%Create a temporary file"
75 "%Syntax: \\tempfile{duration}{.ext}\n"
76 );
77 TOK_ADD(tempfile_update,"",tok_t::SYSONLY,
78 "%Update tempfile database\n"
79 "%Syntax: \\tempfile_update\n"
80 );
81}
82
diff --git a/src/serv/tempmap.h b/src/serv/tempmap.h
new file mode 100644
index 0000000..0b9cf5a
--- /dev/null
+++ b/src/serv/tempmap.h
@@ -0,0 +1,57 @@
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 TEMPMAPH
21#define TEMPMAPH
22
23#include <sh/htc.h>
24
25const mstring TEMP_tag="TEMP";
26
27const int temp_tabs=5,temp_id=0,temp_name=1,temp_start=2,temp_stop=3;
28const mstring temp_tab[temp_tabs]={
29 "ID","NAME","START","STOP","REFER"
30};
31
32struct tempmap_t {
33 spile list;
34
35 tempmap_t() : list(temp_tabs) { reset(); }
36
37 mstring& id() { return list[0]; }
38 mstring& name() { return list[1]; }
39 mstring& start() { return list[2]; }
40 mstring& stop() { return list[3]; }
41 mstring& refer() { return list[4]; }
42
43 void reset() {
44 list.resize(temp_tabs);
45 id()=itoa(0);
46 name().clear();
47 start()=itoa(0);
48 stop()=itoa(0);
49 refer()=itoa(0);
50 }
51};
52
53/////////////////////////////////////////////////////////
54
55void envAddTemp(tokmap& T);
56
57#endif