summaryrefslogtreecommitdiff
path: root/htc
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 /htc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'htc')
-rw-r--r--htc/dml.htc382
-rw-r--r--htc/dmled.htc128
-rw-r--r--htc/help.htc31
-rw-r--r--htc/htcd.htc4
-rw-r--r--htc/html.htc152
-rw-r--r--htc/http.htc61
-rw-r--r--htc/latex.htc262
-rw-r--r--htc/layout.htc348
-rw-r--r--htc/mailer.htc53
-rw-r--r--htc/posit.htc23
-rw-r--r--htc/prefs.hdbbin0 -> 24576 bytes
-rw-r--r--htc/server.htc321
-rw-r--r--htc/system.htc35
-rw-r--r--htc/tree.htc21
-rw-r--r--htc/upload.htc26
-rw-r--r--htc/users.hdbbin0 -> 98304 bytes
16 files changed, 1847 insertions, 0 deletions
diff --git a/htc/dml.htc b/htc/dml.htc
new file mode 100644
index 0000000..9781952
--- /dev/null
+++ b/htc/dml.htc
@@ -0,0 +1,382 @@
1\include{system.htc}
2\include{html.htc}
3\const{dml.address}{nobody}
4\def{dml.init}{xxxx}{
5 %{listname}{group}{path}{http}
6 \global{dml.listname}{\1}
7 \global{dml.group}{\2}
8 \global{dml.path}{\3}
9 \global{dml.http}{\4}
10 \if(count \dml.group){\open{DML}{\dml.path/data/dml.hdb}{1}}
11}
12\def{dml.mailuser}{xx}{
13 \if{\user.id}{
14 \log{mail user: \1}
15 \mail{\dml.address}{}{\user.email}{DML Server}{\now}{\1}{text/plain}{\2}
16 }
17}
18\def{dml.dfs}{xr}{
19 \find.rec{\1}{
20 \2;
21 \query(PARENT==\1){
22 \dml.dfs(INDEX){\2}
23 }
24 }
25}
26\def{dml.bfs}{xr}{
27 [cur:="";bfs:=\1];
28 \while(count bfs){
29 [cur=first bfs];
30 \find.rec(cur){\2};
31 \query(PARENT==cur)(bfs=bfs+++INDEX);
32 [bfs=rest bfs];
33 }
34}
35\def{dml.ups}{xr}{
36 [cur:=\1];
37 \while(cur){
38 \find.rec(cur){\2;[cur=PARENT]}(cur=0)
39 }
40}
41\def{dml.watchers}{}{
42 \if(count \dml.group){
43 [
44 m.<-@;
45 break:=\dml.ups(m.INDEX){[BREAK] };
46 attime:=\if(m.PROTECT)(m.TIME){\now};
47 people:=\db{USERS}{\query(\allowed{\dml.group}(attime)){[UID] }}
48 ];
49 [people---break];
50 }
51}
52\def{dml.resubj}{x}{
53 [tmp:=first \1];\if(tmp nen "re" && tmp nen "re:"){Re: \1}{\1}
54}
55\def{dml.opennode}{x}{
56 \db{DML}{
57 \dml.ups{\1}(BREAK=BREAK---\user.id);
58 \dml.confirm{Opening \dml.listname\[\1\]};
59 }
60}
61\def{dml.closenode}{x}{
62 \db{DML}{
63 \find.rec{\1}{
64 [BREAK=BREAK|||\user.id];
65 \dml.confirm{Closing \dml.listname\[\1\]};
66 }
67 }
68}
69\def{dml.addnode}{x}{
70 %(node) - add to this node
71 %T.from - mail address
72 %T.reply - reply address
73 %T.name - user name
74 %T.subject - subject
75 %T.mime - MIME type
76 %T.body - message
77 %T.parts - attachments
78 %T.mime[i] - attachment MIME type
79 %T.body[i] - attachment body
80 %RETURN - node number
81 \db{DML}{
82 [
83 t.TIME:=\now;
84 t.PARENT:=\1;
85 t.AUTHOR:=\user.id;
86 t.MIME:=\T.mime;
87 t.SUBJECT:=\T.subject;
88 t.BODY:=\T.body;
89 t.INDEX:=\lastkey+1;
90 t.PROTECT:=1;
91 @<-t.;
92 ];
93 \log{dml: adding \dml.listname\[[INDEX]\]};
94 [t.INDEX];
95 \for(i:=0)(i<\T.parts)(i+=1){
96 [file:="A"++INDEX++"_"++\filesafe{\T.body[i]}];
97 \log{dml: uploading \dml.listname\[[file]\]};
98 \save{\dml.path/attach/[file]}{T.body[i]}{385};
99 [ATTACH=ATTACH|||file];
100 }
101 }
102}
103\def{dml.footer}{x}{
104 \if(\1 eq "text/html"){<hr>}{----------------------------------------------}
105 Help: send email to \dml.address with subject 'help \dml.listname'
106}
107\def{dml.quickguide}{}{
108 QUICK GUIDE
109
110 Mailing-lists on this server (\dml.address):
111
112 \getlists;[ex:=\dml.listname]
113
114 Mails received from the server ALWAYS starts with the listname
115 enclosed in stars (*). For example,
116
117 *[ex]\[7\]* hello world
118
119 means you've received a message from the list '[ex]' with
120 subject 'hello world'. The message is identified by its
121 message number, in this case 7.
122
123 EXAMPLES
124
125 To post a new message on '[ex]' with subject 'hello world',
126 mail to \dml.address with subject
127
128 new [ex] hello world
129
130 To post a new message on a particular message number, e.g. 7,
131 mail to \dml.address with subject
132
133 new [ex]\[7\] hello world
134
135 Note that message number 1 is the message root, and is the same
136 as issuing new without the \[\].
137
138 To reply to a message from the list, use 'reply' in your mailing program,
139 but DO NOT REMOVE anything before the subject. The server will
140 insert the appropriate 'Re:'. For instance, replying to the first example
141 above would normally give a reply-subject in your mailprogram like
142
143 Re: *[ex]\[7\]* hello world
144
145 which will be sent from the server as
146
147 *[ex]\[n\]* Re: hello world
148
149 where n is some new number assigned to your message.
150}
151\def{dml.message}{}{
152 HELP ON USAGE OF THE *\dml.listname* MAILING LIST AT \dml.address.
153
154 The address handles multiple mailinglists, and takes commands on the form:
155
156 <cmd> <list>\[<node>\] <subject>
157 or
158 <cmd> *<list>\[<node>\]* <subject>
159
160 where <cmd> is a command, <list> is a mailinglist,
161 <node> is a message number, and <subject> is the subject
162 line. The brackets \[\] should however be there as is.
163
164 Mailing-lists on this server (\dml.address):
165
166 \getlists
167
168 You are \user.name, and your user name at \dml.address
169 is \user.email. You may have clearance to several of
170 the lists above.
171 \if(\dml.listname eq "demo"){
172 \n;
173 This is a demo mailing list and will not work to send mails to.
174 You will need to know the name of a list to which you belong.
175 }
176 Commands are not case sensitive. Available commands <cmd> are:
177
178 HELP \dml.listname
179
180 Displays this message.
181
182 WHO \dml.listname\[<node>\]
183
184 Retrieve which people are registered at the list.
185 If a node number is given, it tells which people
186 will receive a new message from that node.
187 Note that this command may be restricted on some lists.
188
189 SILENT \dml.listname\[<node>\]
190
191 Adds a new message to message number <node> on \dml.listname,
192 without broadcasting.
193
194 NEW \dml.listname\[<node>\] <subject>
195
196 Adds a new message to message number <node> on \dml.listname,
197 and broadcasts to \dml.listname.
198
199 REPLY \dml.listname\[<node>\] <subject>
200
201 Replies to message number <node> on \dml.listname.
202 Possible acronyms are Re, Re:, Sv, Sv:.
203 Note that this command is issued when you do
204 a normal reply, whether it be on a swedish or
205 american mail program.
206
207 OPEN \dml.listname\[<node>\]
208
209 Opens a <node>. When a <node> is open, you recieve
210 broadcast messages descending from that <node>.
211
212 CLOSE \dml.listname\[<node>\]
213
214 Closes a <node>. When a <node> is closed, you do not
215 recieve the broadcast messages descending from that <node>.
216 The obvious usage of this command is to turn off
217 uninteresting of lengthy threads. Also, since everything
218 added to this node will pass unnoticed, it may be used
219 to structure e.q. news in topics, together with the
220 SILENT command.
221
222 MAIL \dml.listname\[<node>\]
223
224 Retrieve message number <node> from \dml.listname.
225 This command may not serve certain messages on the basis of your
226 clearance and when you first entered the list.
227
228 \if(\dml.listname ne "demo"){
229 To get additional help on how to use this system, how to
230 view or protect message trees, you may visit the
231 \dml.http/ web page. Of course the commands listed
232 above can be issued from there as well. You PIN code
233 at the server is \user.pin.
234 }
235}
236\def{dml.layout}{?xx}{
237 [mime:=\on.arg{0}{\0}(MIME)];
238 \2
239 \if(ATTACH ne ""){
240 \if(mime eq "text/html"){
241 <hr>
242 Attachments (PIN: \su{\1}{\user.pin})
243 \forall{i}(ATTACH){
244 \href{\dml.http/attach/[i]?alias=\su{\1}{\user.alias}}(i)\n;
245 }
246 }{
247 ----------------------------------------------
248 Attachments (PIN: \su{\1}{\user.pin})
249 \forall{i}(ATTACH){
250 \dml.http/attach/[i]?alias=\su{\1}{\user.alias}\n;
251 }
252 }
253 };
254 \dml.footer(mime)
255}
256\def{dml.error}{x}{
257 %T.cmd
258 %T.list
259 %T.node
260 %T.subject
261 \mail.root{mailer: \1}{
262 check <\T.cmd> \T.list\[\T.node\] \T.subject
263 };
264 \dml.mailuser{error}{
265 An error occurred while processing your command
266
267 \T.cmd \T.list\[\T.node\] \T.subject
268
269 \1
270 ----------------------------------------------
271 \dml.quickguide
272 \dml.footer(MIME)
273 }
274}
275\def{dml.help}{}{
276 \dml.mailuser{help \dml.listname}{
277 \dml.quickguide
278
279 ----------------------------------------------
280 \dml.message
281 }
282}
283\def{dml.who}{x}{
284 %(node) - mail this node to group
285 \db{DML}{
286 \find.rec{\1}{
287 \dml.mailuser{who \dml.listname}{
288 PEOPLE LISTENING TO \dml.listname;\[\1\] at \dml.address
289
290 \forall{i}{\dml.watchers}{
291 \su(i){\user.name <\user.email>}\n
292 }
293 }
294 }{
295 \dml.error{Could not find node \dml.listname;\[\1\]}
296 }
297 }
298}
299\def{dml.confirm}{x}{
300 %T.cmd
301 %T.list
302 %T.node
303 %T.subject
304 \dml.mailuser{\dml.listname: confirmation}{
305 Your command
306
307 \1
308
309 was processed sucessfully.
310 }
311}
312\def{dml.mail}{x}{
313 %(node) - mail this node to user
314 \db{DML}{
315 \find.rec{\1}{
316 [attime:=\if(PROTECT)(TIME){\now}];
317 \if{\user.allow{\dml.group}(attime)}{
318 \log{dml: mailing \dml.listname\[[INDEX]\] to (\user.id)};
319 \mail{\su(AUTHOR){\user.email}}{}{\user.email}{\su(AUTHOR){\user.name}}
320 (TIME){*\dml.listname\[[INDEX]\]* [SUBJECT]}(MIME){\dml.layout{\user.id}(BODY)};
321 }{
322 \log{dml: denying \dml.listname\[[INDEX]\] to (\user.id)};
323 \dml.mailuser{\dml.listname\[[INDEX]\]: not found}{
324 The node you requested could not be found
325
326 (or may be protected)
327 }
328 }
329 }{
330 \dml.error{Could not find node \dml.listname;\[\1\]}
331 }
332 }
333}
334\def{dml.broadcast}{x}{
335 %(node) - mail this node to group
336 \db{DML}{
337 \find.rec{\1}{
338 \if(!BROADCAST){
339 \log{dml: broadcasting \dml.listname\[[INDEX]\]}
340 [
341 femail:=\su(AUTHOR){\user.email};
342 fname:=\su(AUTHOR){\user.name};
343 fsubj:="*"++\dml.listname++"["++INDEX++"]* "++SUBJECT;
344 watchers:=\dml.watchers;
345 BROADCAST=count watchers;
346 ];
347 \forall{i}(watchers){
348 [
349 temail:=\su(i){\user.email};
350 talias:=\su(i){\user.alias};
351 tname:=\su(i){\user.name};
352 tpin:=\su(i){\user.pin};
353 tbody:=\replace(BODY){\recipient.email}(temail);
354 tbody=\replace(tbody){\recipient.alias}(talias);
355 tbody=\replace(tbody){\recipient.name}(tname);
356 tbody=\replace(tbody){\recipient.pin}(tpin);
357 tbody=\replace(tbody){\recipient.id}(i);
358 ];
359 \mail(femail){\dml.listname <\dml.address>}(temail)(fname)
360 (TIME)(fsubj)(MIME){\dml.layout(i)(tbody)};
361 \sleep(2);
362 }
363 }
364 }
365 }
366}
367\def{dml.addbroad}{x}{
368 [node:=\dml.addnode{\1}];
369 \if(node){
370 \dml.broadcast(node)
371 }{
372 \dml.error{Could not add to \dml.listname;\[\1\]}
373 }
374}
375\def{dml.addsilent}{x}{
376 [node:=\dml.addnode{\1}];
377 \if(node){
378 \dml.confirm{Added \dml.listname\[[node]\] to \dml.listname\[\1\]}
379 }{
380 \dml.error{Could not add to \dml.listname;\[\1\]}
381 }
382}
diff --git a/htc/dmled.htc b/htc/dmled.htc
new file mode 100644
index 0000000..61929fa
--- /dev/null
+++ b/htc/dmled.htc
@@ -0,0 +1,128 @@
1\include{dml.htc}
2\def{dmled.init}{xx}{
3 %{listname}{address}
4 \dml.init{\1}{\group}{\npwd}{\server\npwd};
5 \reconst{dml.address}{\2};
6 \sort{DML}{INDEX}{>}
7}
8\def{dmled.page}{}{
9 \cond{T.find}{}
10 \cond{T.msg}{0}
11 \title{Database Mailing List (\dml.listname)}
12 \db{DML}{
13 \form{
14 \table{width=100% bgcolor=#dddddd}{
15 \tr{valign=top}{
16 \td{
17 <select name=dummy size=6>
18 [tf:=\T.find];
19 \query(
20 (tf eq "" ||SUBJECT cntn tf||AUTHOR cntn tf||BODY cntn tf)&&
21 (!PROTECT||\user.allow(\dml.group)(TIME))
22 ){
23 \option{\if(INDEX==\T.msg){ selected }}(INDEX){
24 [INDEX] - \sub(SUBJECT){0}{30}
25 \su(AUTHOR){\[\user.name\]}; (\time2htc(TIME))
26 \if(count ATTACH){\[attach\]}
27 }
28 }
29 </select>
30 }
31 \td{
32 \button{View}<br>
33 \button{Reply}<br>
34 \button{New}
35 }
36 }
37 \tr{valign=top}{
38 \td{
39 \input{find}{60}{\T.find}
40 }
41 \td{
42 \button{Search}
43 }
44 }
45 }
46 }
47 \find.rec{\T.msg}{
48 \if(!PROTECT||\user.allow(\dml.group)(TIME)){
49 \table{width=100% bgcolor=#dddddd}{
50 \tr{
51 \th{align=left}{[INDEX] - [SUBJECT]}
52 \td{align=right}{
53 \find.rec(PARENT){
54 \if(!PROTECT||\user.allow(\dml.group)(TIME)){
55 \bf{Prev:}
56 \href{\this?msg=[INDEX]}{[INDEX] - \sub(SUBJECT){0}{30}}
57 \su(AUTHOR){\[\user.name\]}
58 }
59 }
60 }
61 }
62 \tr{
63 \td{align=left}{
64 \su(AUTHOR){
65 \user.name \lt;\href{mailto:\user.email}{\user.email};\gt
66 }
67 }
68 \td{align=right}{
69 \time2htc(TIME)
70 }
71 }
72 \tr{
73 \td{align=left colspan=2}{
74 \htmlize(BODY)
75 }
76 }
77 \if(count ATTACH){
78 \tr{
79 \td{align=left colspan=2}{
80 \forall{i}(ATTACH){
81 \href{\npwd/attach/[i]}(i)\n
82 }
83 }
84 }
85 }
86 \tr{
87 \td{align=left colspan=2}{
88 [idx:=INDEX];
89 \query(PARENT==idx&&(!PROTECT||\user.allow(\dml.group)(TIME))){
90 \bf{Next:}
91 \href{\this?msg=[INDEX]}{[INDEX] - [SUBJECT]}
92 \su(AUTHOR){\[\user.name\]}
93 <br>
94 }
95 }
96 }
97 }
98 }
99 }
100 }
101}
102\def{dmled.onpost}{}{
103 \switch{\T.cmd}
104 {View}{
105 \redirect{\server\this?msg=\T.dummy}
106 }
107 {Reply}{
108 \redirect{\server\this}
109 \db{DML}{
110 \find.rec{\T.dummy}{
111 \if(!PROTECT||\user.allow(\dml.group)(TIME)){
112 \redirect{
113 mailto:\dml.address?subject=Reply \dml.listname\[[INDEX]\] [SUBJECT]
114 }
115 }
116 }
117 }
118 }
119 {New}{
120 [node:=\on.glob{T.dummy}{\T.dummy}{1}];
121 \redirect{mailto:\dml.address?subject=New \dml.listname\[[node]\] (no subject)}
122 }
123 {
124 \on.glob{T.find}{
125 \redirect{\server\this?find=\encode{\T.find}}
126 }
127 }
128}
diff --git a/htc/help.htc b/htc/help.htc
new file mode 100644
index 0000000..d35d210
--- /dev/null
+++ b/htc/help.htc
@@ -0,0 +1,31 @@
1\throw{help: OBSOLETED}
2\def{list.unary}{}{
3 \ops.htc{
4 \order{PRE1}{>}
5 \query(PRE1){
6 \left(OP){10}[DESC]
7 }
8 }
9}
10\def{list.binary}{}{
11 \ops.htc{
12 \order{PRE2}{>}
13 \query(PRE2){
14 \left(OP){10}[DESC]
15 }
16 }
17}
18\def{list.mod}{x}{
19 \tokens{
20 \query(MOD==\1){
21 [TOK]
22 }
23 }
24}
25\def{list.users}{x}{
26 \users{\1}{
27 \query{1}{
28 \left(ID){4} \left(NAME){38} \left(GID){3} \sub{\time2htc(LAST)}{4}{12} [LASTIN]
29 }
30 }
31}
diff --git a/htc/htcd.htc b/htc/htcd.htc
new file mode 100644
index 0000000..038bf89
--- /dev/null
+++ b/htc/htcd.htc
@@ -0,0 +1,4 @@
1\include{latex.htc}
2\include{html.htc}
3\include{http.htc}
4\include{dmled.htc}
diff --git a/htc/html.htc b/htc/html.htc
new file mode 100644
index 0000000..bd96870
--- /dev/null
+++ b/htc/html.htc
@@ -0,0 +1,152 @@
1\const{icons}{/icons}
2\const{space}{&#160;}
3\const{lt}{&#60;}
4\const{gt}{&#62;}
5\def{indent}{x}{\for(i:=0)(i<\1)(i+=1){\space}}
6\def{option}{?xx}{
7 %<options>{value}{desc}
8 <option\on.arg{0}{ \0} value=\cdata{\1}>
9 \2
10}
11\def{select}{xx*}{
12 %{name}{selected}<optname><optval>..
13 <select name=\1>
14 \if(\args>2){
15 \for(i:=3)(i<=\args)(i+=2){
16 <option\if(\arg(i) eq \2){ selected} value=\cdata{\arg(i)}>
17 \arg(i+1)
18 }
19 }{
20 \2
21 }
22 </select>
23}
24\def{button}{?x}{
25 %[option]{value}
26 <input type=submit name=\on.arg{0}{\0}{cmd} value=\cdata{\1}>
27}
28\def{variable}{xx}{
29 %{name}{value}
30 <input type=hidden name=\1 value=\cdata{\2}>
31}
32\def{radio}{xx?}{
33 %{name}{value}[bool]
34 <input type=radio name=\1 value=\cdata{\2}\if{\0}{ checked}>
35}
36\def{target}{x}{}
37\def{href}{xx}{
38 %{uri}{name}
39 <a href=\cdata{\1}\target{\1}>\2</a>
40}
41\def{iref}{xx}{
42 %{uri}{image}
43 <a href=\cdata{\1}\target{\1}><img border=0 src=\cdata{\2}></a>
44}
45\def{form}{?x}{
46 %<uri>{body}
47 <form method=post action=/POST\on.arg{0}{\0}{\req.uri}\target{\0}>
48 \1
49 </form>
50}
51\def{form.multi}{?x}{
52 %{body}
53 <form method=post enctype=multipart/form-data action=/POST\on.arg{0}{\0}{\req.uri}\target{\0}>
54 \1
55 </form>
56}
57\def{input}{xx?}{
58 %{name}{size}[value]
59 <input type=text name=\1 size=\2\on.arg{0}{ value=\cdata{\0}}>
60}
61\def{passwd}{xx?}{
62 %{name}{size}[value]
63 <input type=password name=\1 size=\2\on.arg{0}{ value=\cdata{\0}}>
64}
65\def{check}{xx?}{
66 %{name}{value}[bool]
67 <input type=checkbox name=\1 value=\cdata{\2}\if{\0}{ checked}>
68}
69\def{file}{?xx}{
70 %{name}{size}[value]
71 <input type=file\on.arg{0}{ accept=\cdata{\0}} name=\1 size=\2>
72}
73\def{text}{xxx?}{
74 %{name}{row}{col}[value]
75 <textarea name=\1 rows=\2 cols=\3>
76 \mask.html{\4}
77 </textarea>
78}
79\def{image}{?x}{
80 %[options]{body}
81 <img\on.arg{0}{ \0} src=\cdata{\1}>
82}
83\def{table}{?x}{
84 %[options]{body}
85 <table\on.arg{0}{ \0}>
86 \1
87 </table>
88}
89\def{th}{?x}{
90 %[options]{body}
91 <th\on.arg{0}{ \0}>
92 \1
93 </th>
94}
95\def{tr}{?x}{
96 %[options]{body}
97 <tr\on.arg{0}{ \0}>
98 \1
99 </tr>
100}
101\def{td}{?x}{
102 %[options]{body}
103 <td\on.arg{0}{ \0}>\on.arg{1}{\1}{\space}</td>
104}
105\def{font}{?x}{
106 %[options]{body}
107 <font\on.arg{0}{ \0}>\1</font>
108}
109\def{ul}{?x}{
110 %[options]{body}
111 <ul\on.arg{0}{ \0}>
112 \1
113 </ul>
114}
115\def{li}{?x}{
116 %[options]{body}
117 <li\on.arg{0}{ \0}>\1</li>
118}
119\def{h1}{?x}{
120 %[options]{body}
121 <h1\on.arg{0}{ \0}>\1</h1>
122}
123\def{h2}{?x}{
124 %[options]{body}
125 <h2\on.arg{0}{ \0}>\1</h2>
126}
127\def{h3}{?x}{
128 %[options]{body}
129 <h3\on.arg{0}{ \0}>\1</h3>
130}
131\def{h4}{?x}{
132 %[options]{body}
133 <h4\on.arg{0}{ \0}>\1</h4>
134}
135\def{h5}{?x}{
136 %[options]{body}
137 <h5\on.arg{0}{ \0}>\1</h5>
138}
139\def{h6}{?x}{
140 %[options]{body}
141 <h6\on.arg{0}{ \0}>\1</h6>
142}
143\def{center}{?x}{
144 %[options]{body}
145 <center\on.arg{0}{ \0}>\1</center>
146}
147\def{body}{?x}{
148 %[options]{body}
149 <body\on.arg{0}{ \0}>
150 \1
151 </body>
152}
diff --git a/htc/http.htc b/htc/http.htc
new file mode 100644
index 0000000..c9a8557
--- /dev/null
+++ b/htc/http.htc
@@ -0,0 +1,61 @@
1\include{system.htc}
2\include{tree.htc}
3\include{layout.htc}
4\include{upload.htc}
5\include{posit.htc}
6\const{server}{http://\HOST\if(\port!=80){:\port}}
7\const{server.alias}(\HOST left ".")
8\const{server.admin}{\ADMIN}
9%
10% Some special stuff
11%
12\def{setcookie}{xx?}{
13 \resp.cookie{\1}{\2}{
14% domain=\HOST\; path=/\if(\0){; expires=\time2http{\0}}
15% the domain spec above does not work on modern browsers such as firefox
16% if host is not a fully qualified dns name
17 path=/\if(\0){; expires=\time2http{\0}}
18 }
19}
20\def{redirect}{x}{
21 \if(\req.version gt "HTTP/1.0"){
22 \resp.status{\HTTP.303}
23 }{
24 \resp.status{\HTTP.302}
25 }
26 \if(\1 cnt ":"){
27 \resp.location{\1}
28 }{
29 \resp.location{\server\1}
30 }
31}
32\def{onget}{r}{
33 \if("GET HEAD" which \req.method){
34 \1
35 }
36}
37\def{onpost}{r}{
38 \if(\req.method eq "POST"){
39 \1
40 }
41}
42%
43% Cookie allowance
44%
45\def{cookie.allow}{x}{
46 [ok:=1;name:=first \1;val:=rest \1];
47 \if(name ne ""){
48 [ok=0];
49 \for(i:=0)(i<\ncookie)(i+=1){
50 \if(\cookie[i].name eq name && \cookie[i].val eq val)(ok=1);
51 }
52 };
53 [ok]
54}
55%
56% CRONTAB
57%
58\cron(211){\sync}
59\cron(120){\tree.update}
60\cron(300){\tempfile.update}
61
diff --git a/htc/latex.htc b/htc/latex.htc
new file mode 100644
index 0000000..5b962bb
--- /dev/null
+++ b/htc/latex.htc
@@ -0,0 +1,262 @@
1\def{symbol}{x}{<font face=symbol>\1</font>}
2
3\const{alpha}{\symbol{a}}
4\const{beta}{\symbol{b}}
5\const{gamma}{\symbol{g}}
6\const{delta}{\symbol{d}}
7\const{epsilon}{\symbol{e}}
8\const{varepsilon}{\symbol{e}}
9\const{zeta}{\symbol{z}}
10\const{eta}{\symbol{h}}
11\const{theta}{\symbol{q}}
12\const{vartheta}{\symbol{J}}
13\const{iota}{\symbol{i}}
14\const{kappa}{\symbol{k}}
15\const{lambda}{\symbol{l}}
16\const{mu}{\symbol{m}}
17\const{nu}{\symbol{n}}
18\const{xi}{\symbol{x}}
19\const{omicron}{\symbol{o}}
20\const{pi}{\symbol{p}}
21\const{varpi}{\symbol{v}}
22\const{rho}{\symbol{r}}
23\const{varrho}{\symbol{r}}
24\const{sigma}{\symbol{s}}
25\const{varsigma}{\symbol{V}}
26\const{tau}{\symbol{t}}
27\const{upsilon}{\symbol{u}}
28\const{phi}{\symbol{f}}
29\const{varphi}{\symbol{j}}
30\const{chi}{\symbol{c}}
31\const{psi}{\symbol{y}}
32\const{omega}{\symbol{w}}
33\const{Gamma}{\symbol{G}}
34\const{Delta}{\symbol{D}}
35\const{Theta}{\symbol{Q}}
36\const{Lambda}{\symbol{L}}
37\const{Xi}{\symbol{X}}
38\const{Pi}{\symbol{P}}
39\const{Sigma}{\symbol{S}}
40\const{Upsilon}{\symbol{¡}}
41\const{Phi}{\symbol{F}}
42\const{Psi}{\symbol{Y}}
43\const{Omega}{\symbol{W}}
44\const{pm}{\symbol{±}}
45\const{times}{\symbol{´}}
46\const{div}{\symbol{¸}}
47\const{bullet}{\symbol{·}}
48\const{cdot}{\symbol{×}}
49\const{varplus}{\symbol{+}}
50\const{cap}{\symbol{Ç}}
51\const{cup}{\symbol{È}}
52\const{vee}{\symbol{Ù}}
53\const{wedge}{\symbol{Ú}}
54\const{varminus}{\symbol{-}}
55\const{diamond}{\symbol{à}}
56\const{oplus}{\symbol{Å}}
57\const{otimes}{\symbol{Ä}}
58\const{leq}{\symbol{£}}
59\const{subset}{\symbol{Ì}}
60\const{subseteq}{\symbol{Í}}
61\const{in}{\symbol{Î}}
62\const{notin}{\symbol{Ï}}
63\const{geq}{\symbol{³}}
64\const{supset}{\symbol{É}}
65\const{supseteq}{\symbol{Ê}}
66\const{equiv}{\symbol{º}}
67\const{sim}{\symbol{~}}
68\const{approx}{\symbol{»}}
69\const{cong}{\symbol{@}}
70\const{neq}{\symbol{¹}}
71\const{propto}{\symbol{µ}}
72\const{less}{\symbol{<}}
73\const{perp}{\symbol{^}}
74\const{mid}{\symbol{|}}
75\const{equal}{\symbol{=}}
76\const{greater}{\symbol{>}}
77\const{colon}{\symbol{:}}
78\const{semi}{\symbol{;}}
79\const{ldots}{\symbol{¼}}
80\const{leftarrow}{\symbol{¬}}
81\const{Leftarrow}{\symbol{Ü}}
82\const{rightarrow}{\symbol{®}}
83\const{Rightarrow}{\symbol{Þ}}
84\const{leftrightarrow}{\symbol{«}}
85\const{Leftrightarrow}{\symbol{Û}}
86\const{uparrow}{\symbol{¯}}
87\const{Uparrow}{\symbol{Ý}}
88\const{downarrow}{\symbol{­}}
89\const{Downarrow}{\symbol{ß}}
90\const{aleph}{\symbol{À}}
91\const{wp}{\symbol{Ã}}
92\const{Re}{\symbol{Â}}
93\const{Im}{\symbol{Á}}
94\const{prime}{\symbol{¢}}
95\const{doubleprime}{\symbol{²}}
96\const{emptyset}{\symbol{Æ}}
97\const{nabla}{\symbol{Ñ}}
98\const{surd}{\symbol{Ö}}
99\const{angle}{\symbol{Ð}}
100\const{deg}{\symbol{°}}
101\const{neg}{\symbol{Ø}}
102\const{partial}{\symbol{¶}}
103\const{infty}{\symbol{¥}}
104\const{clubsuit}{\symbol{§}}
105\const{diamondsuit}{\symbol{¨}}
106\const{heartsuit}{\symbol{©}}
107\const{spadesuit}{\symbol{ª}}
108\const{apple}{\symbol{ð}}
109\const{tm}{\symbol{Ô}}
110\const{vartm}{\symbol{ä}}
111\const{copyright}{\symbol{Ó}}
112\const{circledR}{\symbol{Ò}}
113\const{prod}{\symbol{Õ}}
114\const{int}{\symbol{ò}}
115\const{sum}{\symbol{å}}
116\const{ast}{*}
117\const{backslash}{
118 \
119}
120\const{setminus}{
121 \
122}
123
124\const{`A}{À}
125\const{'A}{Á}
126\const{^A}{Â}
127\const{~A}{Ã}
128\const{"A}{Ä}
129\const{AA}{Å}
130\const{AE}{Æ}
131\const{`E}{È}
132\const{'E}{É}
133\const{^E}{Ê}
134\const{"E}{Ë}
135\const{`I}{Ì}
136\const{'I}{Í}
137\const{^I}{Î}
138\const{"I}{Ï}
139\const{'N}{Ñ}
140\const{`O}{Ò}
141\const{'O}{Ó}
142\const{^O}{Ô}
143\const{~O}{Õ}
144\const{"O}{Ö}
145\const{OO}{Ø}
146\const{`U}{Ù}
147\const{'U}{Ú}
148\const{^U}{Û}
149\const{"U}{Ü}
150\const{'Y}{Ý}
151\const{`a}{à}
152\const{'a}{á}
153\const{^a}{â}
154\const{~a}{ã}
155\const{"a}{ä}
156\const{aa}{å}
157\const{ae}{æ}
158\const{cc}{ç}
159\const{`e}{è}
160\const{'e}{é}
161\const{^e}{ê}
162\const{"e}{ë}
163\const{`i}{ì}
164\const{'i}{í}
165\const{^i}{î}
166\const{"i}{ï}
167\const{~n}{ñ}
168\const{`o}{ò}
169\const{'o}{ó}
170\const{^o}{ô}
171\const{~o}{õ}
172\const{"o}{ö}
173\const{oo}{ø}
174\const{`u}{ù}
175\const{'u}{ú}
176\const{^u}{û}
177\const{"u}{ü}
178\const{'y}{ý}
179\const{"y}{ÿ}
180\const{
181 \
182}{
183 <br>
184}
185\const{,}{&#160;}
186\const{!}{}
187\const{para}{<p>\n}
188
189\const{newpage}{\n}
190\const{det}{det}
191\const{ln}{ln}
192\const{lim}{lim}
193%\const{tilde}{~}
194\const{tilde}{}
195\const{protect}{}
196
197\def{emph}{x}{<em>\1</em>}
198\def{title}{x}{<h1>\1</h1>}
199\def{chapter}{x}{<h2>\1</h2>}
200\def{section}{x}{<h3>\1</h3>}
201\def{subsection}{x}{<h4>\1</h4>}
202\def{subsubsection}{x}{<h5>\1</h5>}
203\def{itemize}{x}{
204 <ul>
205 \1
206 </ul>
207}
208\def{item}{x}{<li>\1</li>}
209\const{draft}{}
210\const{maketitle}{}
211
212\global{LATEX.CITEN}{1}
213\def{cite}{x}{
214 \global{LATEX.CITECUR}(
215 \forall{ii}{\1}{ ,}{
216 \LATEX.CITEN,\on.glob{LATEX.CITE[ii]}{}{
217 \global{LATEX.CITE[ii]}{\LATEX.CITEN}\global{LATEX.CITEN}(\LATEX.CITEN+1)
218 }
219 }
220 rleft ","
221 );
222 $^\LATEX.CITECUR$
223}
224\def{onlinecite}{x}{\cite{\1}}
225\def{bibitem}{x}{\[\LATEX.CITE[\1]\]}
226
227\def{author}{x}{}
228\def{address}{x}{}
229\def{pacs}{x}{}
230\def{ref}{x}{}
231\def{caption}{x}{}
232\def{abstract}{x}{\bf \1}
233\def{label}{x}{}
234\def{frac}{xx}{$\1/\2$}
235
236\def{document}{r}{
237 \page{
238 \1
239 }
240}
241\def{array}{x}{
242 \table{
243 \forall{ii}{\1}{<br>}{
244 \tr{
245 \forall{jj}(ii){&}{
246 \td(jj)
247 }
248 }
249 }
250 }
251}
252\def{ltable}{x}{
253 \table{
254 \forall{ii}{\1}{<br>}{
255 \tr{
256 \forall{jj}(ii){&}{
257 \td(jj)
258 }
259 }
260 }
261 }
262}
diff --git a/htc/layout.htc b/htc/layout.htc
new file mode 100644
index 0000000..b3e7b44
--- /dev/null
+++ b/htc/layout.htc
@@ -0,0 +1,348 @@
1\const{HEIGHT.head}{40}
2\const{HEIGHT.foot}{32}
3\const{COLOR.private}{#ffffcc}
4\const{COLOR.public}{#ffffff}
5\const{COLOR.special}{#cccccc}
6\const{COLOR.grayed}{#999999}
7\def{page}{r}{
8 \if("GET HEAD" which \req.method){
9 \output{
10 \body{bgcolor=\if(\group ne ""){\COLOR.private}{\COLOR.public}}{
11 \1
12 }
13 }
14 }
15}
16\def{show.head}{}{
17 <head>
18 <title>\server.alias\uri</title>
19 </head>
20}
21\def{show.page}{}{
22 \nif(\req.useragent cnt "Mozilla"){\resp.cont.type.charset{}};
23 \switch(stat.MIME)
24 {text/x-htc}{
25 \if(stat.MOD&1){
26 \parse.public(stat.REFER)
27 }{
28 \if(stat.MOD&8){
29 \parse.private(stat.REFER)
30 }{
31 \parse(stat.REFER)
32 }
33 }
34 }
35 {text/x-htx}{
36 \show.latex(stat.REFER)
37 }
38 {text/html}{
39 \resp.cont.type(stat.MIME);
40 \output{\minilang{\load(stat.REFER)}}
41 }
42}
43\def{show.rawpage}{}{
44 \resp.cont.type(stat.MIME);
45 \output{\load(stat.REFER)}
46}
47\def{show.srcpage}{}{
48 \resp.cont.type{text/plain}
49 \nif(\req.useragent cnt "Mozilla"){\resp.cont.type.charset{}};
50 \output{
51 \switch(stat.MIME)
52 {text/x-htc}{
53 \%/SRC\uri HTC/1.2 Last modified \time2http(stat.LASTMOD)
54 }
55 {text/html}{
56 \%/SRC\uri HTML Last modified \time2http(stat.LASTMOD)
57 }
58 {text/x-htx}{
59 \%/SRC\uri HTX/1.2 (LaTeX) Last modified \time2http(stat.LASTMOD)
60 }
61 \load(stat.REFER)
62 }
63}
64\def{show.banner}{}{
65 \ldef{shist}{x}{
66 \find.rec{\1}{
67 \if(count BANNER){
68 [ban:=rest BANNER]\run.local{ban}
69 }{
70 \if(count PARENT){\shist(PARENT)}
71 }
72 }
73 };
74 \db{TREE}{\shist(stat.URI rleftand "/")}
75}
76\def{calc.height}{}{
77 \ldef{chist}{x}{
78 \find.rec{\1}{
79 \if(count BANNER)(first BANNER){\if(count PARENT){\chist(PARENT)}{\HEIGHT.head}}
80 }{
81 \HEIGHT.head
82 }
83 };
84 \db{TREE}{\chist(stat.URI rleftand "/")}
85}
86\def{page.header}{}{
87 \ldef{hist}{x}{
88 \find.rec{\1}{
89 \if(count PARENT){\hist(PARENT)};
90 \if(URI eq uri){\run.local{ALIAS}}{\href{\andlang;[URI]}{\run.local{ALIAS}}}>
91 }
92 }
93 \page{
94 \show.banner
95 \table{width=100% border=0 cellspacing=0 cellpadding=0 bgcolor=\COLOR.special}{
96 \tr{valign=top align=left}{
97 \td{width=60%}{
98 \font{size=3}{
99 [uri:=stat.URI;dir:=uri rleftand "/";n:=0];
100 \db{TREE}{
101 \hist(dir);
102 \query(PARENT eq dir && URI ne "/"){
103 \if{\user.allow(X.CLEAR){\now}}{
104 \if(n){|}[n+=1]\if(URI eq uri){
105 \run.local{ALIAS}
106 }{
107 \href{\andlang;[URI]}{\run.local{ALIAS}}
108 }
109 }
110 }
111 }\space;
112 }
113 };
114 \td{width=40% align=right}{
115 \font{size=3}{
116 \if{\user.id}{\user.name}{\lang{Anonymous}{Anonym}}, \time2htc{\now}
117 }
118 }
119 }
120 }
121 }
122}
123\def{show.icons}{}{}
124\def{page.footer}{}{
125 \output{
126 \body{bgcolor=\COLOR.special}{
127 \table{width=100% border=0 cellspacing=0 cellpadding=0 bgcolor=\COLOR.special}{
128 \td{valign=top align=left}{
129 \iref{mailto:\server.admin}{\icons/mail.gif}
130 \if{\user.id}{
131 \iref{/LOGOUT\uri\andarg}{\icons/logout.gif}
132 }{
133 \iref{/LOGIN\uri\andarg}{\icons/login.gif}
134 }
135 \on.clear{ADM}{
136 \iref{\andlang/HTC/admin.htc}{\icons/adm.gif}
137 }
138 \iref{
139 \lang{/sv}{/en}[stat.URI]
140 }{
141 \icons/lang.gif
142 }
143 \if{\user.id}{
144 \iref{\andlang/HTC/prefs.htc}{\icons/prefs.gif}
145 }
146 \iref{/SRC[stat.URI]}{\icons/source.gif}
147 [acc:=\upload.clear(stat.URI)]\if((first acc) ne "ROOT"){
148 \on.clear(acc){
149 \iref{\server/RAW[stat.URI]}{\icons/transfer.gif}
150 }
151 }
152 \show.icons;
153 }
154 \td{valign=center align=right}{
155 HTCd/1.2 \[\lang{en}{sv}\] \time2htc(stat.LASTMOD)
156 }
157 }
158 }
159 }
160}
161\redef{show.register}{}{
162 \lang{
163 If your are not a registered user, register first.
164 }{
165 Om du inte {\"a}r en registrerad anv{\"a}ndare,
166 registrera dig f{\"o}rst.
167 }
168}
169\def{page.login}{}{
170 \cond{T.alias}{}
171 \page{
172 \h1{\server.alias Login}
173 \if{\user.id}{
174 \lang{
175 You are logged in as \user.name; (\user.alias).
176 }{
177 Du {\"a}r inloggad som \user.name; (\user.alias).
178 }
179 <p>
180 \href{\referer}{\lang{Continue}{Forts{\"a}tt}}
181 }{
182 \lang{
183 This server contains information only accessible to registered users.
184 Each registered user receives a user ID and a PIN code.
185 }{
186 Den h{\"a}r servern inneh{\aa}ller information som bara {\"a}r
187 tillg{\"a}nglig f{\"o}r registrerade anv{\"a}ndare.
188 Varje registrerad anv{\"a}ndare erh{\aa}ller ett anv{\"a}ndar-ID
189 och en PIN-kod.
190 };
191 <p>
192 \show.register;
193 <p>
194 \lang{
195 To login, enter your email address and PIN code below.
196 \it{DO NOT} enter your unix password!
197 }{
198 F{\"o}r att logga in, fyll i din epostadress och PIN kod nedan.
199 An{\"a}nd \it{EJ} ditt unix passord!
200 };
201 [remcookie:=0;email:=\T.alias];
202 \for(i:=0)(i<\ncookie)(i+=1){
203 \if(\cookie[i].name eq "RESEND"){
204 [remcookie=1;email=\cookie[i].val];
205 <p>
206 \font{color=red}{
207 \lang{E-mail has been sent to }{E-post har skickats till }[email]
208 (\lang{provided user exist}{f{\"o}rutsatt anv{\"a}ndaren existerar})
209 }
210 }
211 };
212 <p>
213 \form{
214 \variable{remcookie}(remcookie);
215 \variable{ref}{\referer};
216 \table{
217 \tr{
218 \td{\lang{E-mail (or alias)}{E-post (eller alias)}:}
219 \td{\input{email}{28}(email)}
220 };
221 \tr{
222 \td{PIN:}
223 \td{
224 \passwd{pin}{6}
225 }
226 };
227 \tr{
228 \td{colspan=2}{
229 \check{T.keep}{\endtime}
230 \lang{
231 Keep me logged in by storing to disk
232 }{
233 H{\aa}ll mig inloggad genom att spara till disk
234 };
235 }
236 };
237 \tr{
238 \td{colspan=2}{
239 \button{Login}
240 \button{Forgot my PIN code}
241 \button{Assign a new (4 digit) PIN code}
242 }
243 }
244 }
245 }
246 \h3{\lang{Nota bene}{Observera}}
247 <p>
248 \li{
249 \lang{
250 You must allow a COOKIE containing your user ID and
251 PIN code to be set. If you normally do not allow cookies,
252 you need to make an exception in this case, or by some other
253 means arrange for the cookie to be set.
254 If you don't know what a cookie is, you can probably ignore
255 this paragraph.
256 }{
257 Du m{\aa}ste till{\aa}ta s{\"a}ttning av en COOKIE med
258 ditt anv{\"a}ndar-ID och PIN-kod. Om du normalt inte till{\aa}ter
259 "kakor", m{\aa}ste du antingen g{\"o}ra ett undantag i det
260 h{\"a}r fallet, eller p{\aa} n{\aa}got annat s{\"a}tt
261 se till att kakan blir satt p{\aa} r{\"a}tt s{\"a}tt.
262 Vet du inte vad en kaka {\"a}r, kan du troligtvis bortse
263 fr{\aa}n denna paragraf.
264 }
265 };
266 <p>
267 \li{
268 \lang{
269 If logging in from a 'shared' browser, don't forget to logout
270 properly when you're done. Otherwise, the person after you may
271 enter the server as you.
272 }{
273 Om du loggar in fr{\aa}n en 'delad' webbl{\"a}sare, gl{\"o}m
274 inte att logga ut dig ordentligt. Annars kan n{\"a}sta person
275 komma in p{\aa} servern som dig.
276 }
277 }
278 }
279 };
280 \onpost{
281 \cond{T.keep}{0};
282 \cond{T.uid}{\getuser{\T.email}};
283 \switch(first \T.cmd)
284 {Login}{
285 \log{SetID \[\T.uid.\T.pin\] (\T.keep)};
286 \setcookie{ID}{\T.uid.\T.pin}{\T.keep};
287 \if{\T.remcookie}{\setcookie{RESEND}{deleted}{1}};
288 \redirect{\T.ref};
289 }
290 {Forgot}{
291 \su{\T.uid}{
292 \mail.user{PIN code}{
293 Your PIN code is \user.pin.
294
295 /Admin
296 }
297 };
298 \if(\T.email ne ""){\setcookie{RESEND}{\T.email}};
299 \redirect{\server\this\andarg};
300 }
301 {Assign}{
302 \su{\T.uid}{
303 \if(\user.pin eq \T.pin){
304 \user.pin.set{\random{4}}\user.update;
305 \mail.user{New PIN code}{
306 Your new PIN code is \user.pin.
307
308 /Admin
309 }
310 }
311 };
312 \if(\T.email ne ""){\setcookie{RESEND}{\T.email}};
313 \redirect{\server\this\andarg};
314 }{
315 Don't understand "\T.cmd"
316 }
317 }
318}
319\def{page.logout}{}{
320 \setcookie{ID}{deleted}{1};
321 \resp.cont.type.charset{};
322 \redirect{\server/}
323}
324\def{layout}{}{
325 \if{\FRAMES}{
326 [cacheok=1;stat.X.CACHE=\days{14}];
327 \output{
328 \show.head;
329 <frameset rows="\calc.height,*,\HEIGHT.foot" border=0 scrolling=no onload="\killframes">
330 <frame scrolling=no name=head align=top src="/HEAD\uri\andarg">
331 <frame scrolling=auto name=body align=left src="/BODY\uri\andarg">
332 <frame scrolling=no name=foot align=bottom src="/FOOT\uri\andarg">
333 </frameset>
334 }
335 }{
336 \resp.cont.type.charset{};
337 \output{\show.head};
338 \page.header;
339 \output{<br><br>};
340 \show.page;
341 \output{<br><br>};
342 \page.footer
343 }
344}
345\def{show.latex}{x}{
346 \parse.public{\1}
347}
348
diff --git a/htc/mailer.htc b/htc/mailer.htc
new file mode 100644
index 0000000..65f0d98
--- /dev/null
+++ b/htc/mailer.htc
@@ -0,0 +1,53 @@
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% maild Mailinglist
3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4\setuser{\getuser{\T.from}}
5\nif(count \T.node){\reconst{T.node}{1}}
6\dml.init{demo}{}{}{}
7\if{\user.id}{
8 \setlist{\T.list};
9 \if(count \dml.group){
10 \on.clear{\dml.group}{
11 \switch{\T.cmd}
12 {help}{
13 \dml.help
14 }
15 {who}{
16 \dml.who{\T.node}
17 }
18 {silent}{
19 \dml.addsilent{\T.node}
20 }
21 {new}{
22 \dml.addbroad{\T.node}
23 }
24 {reply}{
25 \reconst{T.subject}{\dml.resubj{\T.subject}}
26 \dml.addbroad{\T.node}
27 }
28 {open}{
29 \dml.opennode{\T.node}
30 }
31 {close}{
32 \dml.closenode{\T.node}
33 }
34 {mail}{
35 \dml.mail{\T.node}
36 }
37 {
38 \dml.error{\T.list: Bad command (\T.cmd)}
39 }
40 }{
41 \dml.error{\T.list: User denied (\T.from)}
42 }
43 }{
44 \if(\T.cmd eq "help"){
45 \dml.help
46 }{
47 \dml.error{\T.list: Not found}
48 }
49 }
50}{
51 \dml.error{\HOST: Could not find user \T.from}
52}
53
diff --git a/htc/posit.htc b/htc/posit.htc
new file mode 100644
index 0000000..af92038
--- /dev/null
+++ b/htc/posit.htc
@@ -0,0 +1,23 @@
1\def{select.posit}{xx}{
2 \select
3 {\1}{\2}
4 {Temp}{Temporary}
5 {ProfEmerit}{Professor Emeritus}
6 {Prof}{Professor}
7 {AssocProf}{Associate Professor}
8 {AssistProf}{Assistant Professor}
9 {ResAssoc}{Research Associate}
10 {Postdoc}{Post-doc}
11 {Doc}{Docent}
12 {PhD}{PhD}
13 {MD}{MD}
14 {Sec}{Secretary}
15 {Grad}{Graduate Student}
16 {Lic}{Licentiate}
17 {Master}{Master of Science}
18 {Diploma}{Diploma worker}
19 {Stud}{Student}
20 {Psi}{Psychologist}
21 {Prog}{Programmer}
22 {Other}{Other}
23}
diff --git a/htc/prefs.hdb b/htc/prefs.hdb
new file mode 100644
index 0000000..15cf68c
--- /dev/null
+++ b/htc/prefs.hdb
Binary files differ
diff --git a/htc/server.htc b/htc/server.htc
new file mode 100644
index 0000000..4060556
--- /dev/null
+++ b/htc/server.htc
@@ -0,0 +1,321 @@
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% HTCd/1.2 Server (H. Rydberg, 2001)
3% Supports methods HEAD, GET, PUT, POST, DELETE
4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5%
6% Useragent setting
7%
8\if(count \req.accept.lang){\setlang{\req.accept.lang}}
9\const{FRAMES}(int(\req.useragent past "Mozilla/")>=2);
10\if{\FRAMES}{
11 \redef{target}{x}{
12 \if(
13 (\1 cnt "//") ||
14 ( (\sub{\1}{0}{1} eq "/") && ("HEAD BODY FOOT" which (\1 past "/" left "/"))==0)
15 ){ target=_top}
16 }
17}
18\const{killframes}{
19 \if(int(\req.useragent past "Mozilla/")>2){
20 if(self!=top) top.location.replace(self.location)}{
21 if(self!=top) top.location=self.location}}
22%
23% Set userid and other cookies
24% Handle errors directly
25%
26[userok:=1;];
27\def{statlog}{x}{\resp.status{\HTTP.[\1]}}
28\for(i:=0)(i<\ncookie)(i+=1){
29 \switch{\cookie[i].name}
30 {LANG}{
31 \setlang{\cookie[i].val}
32 }
33 {FRAMES}{
34 \reconst{FRAMES}(int \cookie[i].val);
35 }
36 {AUTH}{
37 %MIGRATION to HTCd/1.1
38 %Just silently remove the cookie and continue
39 \resp.cookie{AUTH}{deleted}{path=/; expires=\time2http{1}}
40 }
41 {ID}{
42 [uid:=\cookie[i].val left ".";pin:=\cookie[i].val past "."];
43 \setuser(uid);
44 [MAXFAIL:=\on.clear{EXPERT}{1}{3}];
45 \if(\user.id && \user.pin eq pin){
46 \if(\user.fail>0){
47 \if(\user.fail>=MAXFAIL){
48 \statlog{409}[userok=0;];
49 \resp.cont.type.charset{};
50 \output{
51 \body{
52 \h3{Login \lang{Failure}{fel}}
53 \lang{
54 There has been too many bad logins.
55 Please contact the \href{mailto:\ADMIN}{Server Administrator}.
56 }{
57 F{\"o}r m{\aa}nga login-fel har gjorts.
58 Var v{\"a}nlig kontakta \href{mailto:\ADMIN}{Serveradministrat{\"o}ren}.
59 }
60 }
61 }
62 \setcookie{ID}{deleted}{1}
63 }{
64 \mail.user{LOGIN ALERT}{
65 \lang{
66 There has been (\user.fail) PIN failures
67 }{
68 Ett antal (\user.fail) PIN fel har gjorts.
69 }
70
71 \user.lastin; (\gethost{\user.lastin})
72 \time2htc{\user.last}
73 }
74 \user.fail.set{0}\user.update;
75 }
76 }{
77 \if(\user.lastin ne \remote.address){
78 \on.clear{EXPERT}{
79 \mail.user{HOST ALERT}{
80 \lang{
81 A change of access address has occured.
82 }{
83 Ett byte av access-adress har intr{\"a}ffat.
84 }
85
86 \lang{Current access:}{Nuvarande access:}
87 \remote.address; (\remote.name)
88 \time2htc{\now}
89
90 \lang{Last access:}{Senaste access:}
91 \user.lastin; (\gethost{\user.lastin})
92 \time2htc{\user.last}
93 }
94 }{
95 \log{HOST ALERT \user.lastin -> \remote.address}
96 }
97 }
98 }
99 }{
100 \if{\user.id}{
101 \user.fail.set(\user.fail+1)\user.update;
102 \if(\user.fail==MAXFAIL){
103 \mail.root{PIN failure}{
104 PIN failure (\user.fail) for \user.id: \user.name <\user.email>
105 From: \remote.address:\remote.port; (\remote.name)
106 }
107 }
108 }
109 \statlog{409}[userok=0;];
110 \resp.cont.type.charset{};
111 \output{
112 \body{
113 \h3{\lang{Bad User}{Felaktig anv{\"a}ndare}}
114 \lang{
115 Please check your user credentials and press the Back button.
116 }{
117 Var v{\"a}nlig kontrollera din anv{\"a}ndarinformation
118 och tryck p{\aa} Tillbaka-knappen.
119 }
120 }
121 }
122 \setcookie{ID}{deleted}{1}
123 }
124 }
125}
126%
127% At this point, user is set.
128%
129\if(\user.id){\user.last.set{\now}\user.lastin.set{\remote.address}\user.update}
130%
131% userok tells whether we should continue or not.
132%
133\if(userok){
134 %
135 % Start by checking special URIs
136 %
137 [muri:=\req.uri;sroute:=muri past "/" left "/"];
138 \if(sroute eq "POST")(muri=muri past "/" past sroute;sroute=muri past "/" left "/");
139 \const{this}(muri);
140 \if("LOGIN LOGOUT" which sroute)(muri=muri past "/" past sroute)(sroute="");
141 \const{referer}{\server;[muri]\andarg}
142 [route:=muri past "/" left "/";];
143 \if("SRC RAW HEAD FOOT BODY" which route)(muri=muri past "/" past route)(route="");
144 \seturi(muri);
145 [lroute:=muri past "/" left "/";];
146 \if("en sv" which lroute){[muri=muri past "/" past lroute]\setlang(lroute)}(lroute="");
147 \const{andlang}{/\lang{en}{sv}}
148 %
149 % sroute -> LOGIN|LOGOUT|none
150 % route -> SRC|RAW|HEAD|FOOT|BODY|none
151 % lroute -> en|sv|none
152 % this -> req.uri without POST
153 % referer -> complete URL (without POST|LOGIN|LOGOUT)
154 % uri -> directory URI (without SRC|RAW|HEAD|FOOT|BODY)
155 % andlang -> /[lang]
156 % muri -> mappable uri (without en|sv)
157 %
158 % Check method and dispatch
159 %
160 \if(\req.method eq "PUT" || \req.method eq "DELETE"){
161 %
162 % PUT and DELETE treated together
163 %
164 [wclear:=\upload.clear(muri)];
165 \if((count sroute)||(count lroute)|| !("SRC RAW" which route)||(wclear eq "ROOT")){
166 \statlog{405};
167 \resp.cont.type.charset{};
168 \output{
169 \body{
170 \h3{\lang{Method not allowed}{Metoden ej till{\aa}ten}}
171 \lang{
172 \req.method is not allowed here.
173 }{
174 \req.method; {\"a}r ej till{\aa}ten h{\"a}r.
175 }
176 <p>
177 \href{\server}{\lang{Home}{Hem}}
178 }
179 }
180 }{
181 \if{\user.allow(wclear){\now}}{
182 \statlog{200};
183 \if(\req.method eq "DELETE"){\upload.delete(muri)}{\upload.put(muri)}
184 }{
185 \statlog{409}
186 \resp.cont.type.charset{};
187 \output{
188 \body{
189 \h3{\lang{Conflict}{Konflikt}}
190 \lang{
191 The request could not be granted.
192 }{
193 Kommandot kunde ej utf{\"o}ras.
194 }
195 <p>
196 \href{\server}{\lang{Home}{Hem}}
197 }
198 }
199 }
200 }
201 }{
202 %
203 % HEAD, GET and POST treated together
204 %
205 [fallow:=0;uallow:=0;rallow:=0;callow:=0];
206 \switch(sroute){LOGIN}{\page.login}{LOGOUT}{\page.logout}{
207 \staturi(muri){
208 \if(stat.URI ne muri){
209 [canonized:={\server\andlang;[stat.URI]\andarg}];
210 \resp.status{\HTTP.301};
211 \resp.location(canonized);
212 \resp.cont.type.charset{};
213 \output{\href(canonized)(canonized)}
214 }{
215 \if(count stat.ALIAS){\db{TREE}(@<-stat.)};
216 \setgroup(first stat.X.CLEAR);
217 [
218 fallow=1;
219 ttime:=\if(stat.MOD&36){\now}(stat.LASTMOD);
220 uallow=\user.allow(stat.X.CLEAR)(ttime);
221 rallow=\remote.allow(stat.X.DOMAIN);
222 callow=\cookie.allow(stat.X.COOKIE);
223 ];
224 \nif((count stat.REFER) && uallow && rallow && callow)(userok=0){
225 \statlog{200}[cacheok:=0];
226 \if("text/x-htc text/x-htx text/html" which stat.MIME){
227 \if(\req.method eq "POST"){
228 \show.page;
229 }{
230 \switch(route)
231 {SRC}{
232 \show.srcpage
233 }
234 {RAW}{
235 \show.rawpage
236 }
237 {HEAD}{
238 \page.header
239 }
240 {FOOT}{
241 \page.footer
242 }
243 {BODY}{
244 \show.page;
245 [cacheok=(first \resp.getstatus == 200);]
246 }
247 {
248 \if(count lroute){\layout}{
249 [canonized:={\server\andlang\uri\andarg}];
250 \resp.status{\HTTP.301};
251 \resp.location(canonized);
252 \resp.cont.type.charset{};
253 \output{\href(canonized)(canonized)}
254 }
255 }
256 }
257 }{
258 \resp.cont.type(stat.MIME);
259 \output{\load(stat.REFER)}[cacheok=1;]
260 }
261 \if(cacheok&&(count stat.X.CACHE)){
262 \resp.pragma{}
263 \if(stat.X.CACHE){
264 \resp.lastmod{\time2http(stat.LASTMOD)}
265 [expire:=\now+stat.X.CACHE;
266 \if(expire<=stat.LASTMOD)(expire=stat.LASTMOD+1)];
267 \resp.expires{\time2http(expire)}
268 }
269 }
270 }
271 }
272 }(userok=0)
273 }
274 \nif(userok){
275 \statlog{404};
276 \resp.cont.type.charset{};
277 \output{
278 \body{
279 \h3{\lang{Not Found}{Ej hittad}}
280 \lang{
281 The requested uri (\req.uri) could not be found.
282 }{
283 Den beg{\"a}rda sidan (\req.uri) kunde inte hittas.
284 }
285 \nif{\user.id}{
286 \if(\req.useragent cnt "Mozilla"){
287 <p>
288 \lang
289 {The reason \it{may} be that you need need to }
290 {Andledningen \it{kan} vara att du beh{\"o}ver }
291 \href{/LOGIN\req.uri\andarg}{\lang{login}{logga in}} \lang{first}{f{\"o}rst}.
292 }{
293 <p>
294 \lang{
295 The reason \it{may} be that your user credentials were improperly set.
296 }{
297 Anledningen \it{kan} vara att din anv{\"a}ndar information {\"a}r felaktigt satt.
298 }
299 <p>
300 \lang{
301 Please go back try again.
302 }{
303 G{\aa} tillbaka och f{\"o}rs{\"o}k igen.
304 }
305 }
306 }{
307 \if(fallow){
308 <p>
309 \lang{Reason:}{Orsak:}
310 \nif(uallow){\lang{Bad clearance}{Fel r{\"a}ttigheter}}
311 \nif(rallow){\lang{Bad access address}{Felaktig access-adress}}
312 \nif(callow){\lang{Bad cookie}{Felaktig 'cookie'}}
313 }
314 }
315 <p>
316 \href{\server}{\lang{Home}{Hem}}
317 }
318 }
319 }
320 }
321}
diff --git a/htc/system.htc b/htc/system.htc
new file mode 100644
index 0000000..ecae08e
--- /dev/null
+++ b/htc/system.htc
@@ -0,0 +1,35 @@
1%
2% User stuff
3%
4\def{mail.root}{xx}{
5 \log{mail root: \1}
6 \mail{\ROOT}{}{\ROOT}{server root}{\now}{\1}{text/plain}{\2}
7}
8\def{mail.admin}{xx}{
9 \log{mail admin: \1}
10 \mail{\ADMIN}{}{\ADMIN}{server admin}{\now}{\1}{text/plain}{\2}
11}
12\def{mail.user}{xx}{
13 \if{\user.id}{
14 \log{mail user: \1}
15 \mail{\ADMIN}{}{\user.email}{\HOST}{\now}{\1}{text/plain}{\2}
16 }
17}
18%
19% Modification time handling
20%
21\def{statmod}{x}{
22 [mtime:=\dirmtime{\1}];
23 \if(mtime>stat.LASTMOD)(stat.LASTMOD=mtime);
24 \1
25}
26\def{statinclude}{x}{
27 \include{\statmod{\1}}
28}
29\def{statopen}{xx?}{
30 \open{\1}{\statmod{\2}}{\3}
31}
32\def{statdb}{x}{
33 [mtime:=\dbmod{\1}];
34 \if(mtime>stat.LASTMOD)(stat.LASTMOD=mtime);
35}
diff --git a/htc/tree.htc b/htc/tree.htc
new file mode 100644
index 0000000..8615108
--- /dev/null
+++ b/htc/tree.htc
@@ -0,0 +1,21 @@
1\const{HTCEXT}{htc htx html}
2\const{SKIPDIR}{sys htc SCCS}
3\def{tree.update}{}{
4 [xmod:=\now];
5 \ldef{trav}{x}{
6 \staturi{\1}{
7 \if(count stat.ALIAS)(@<-stat.);
8 \forall{it}{\dirent{\1}}{
9 \if(\dirmod(it)&24576){
10 \nif(\SKIPDIR which (it past \1)){\trav{[it]/}}
11 }{
12 \if(\HTCEXT which (it rpast ".")){
13 \staturi(it){\if(count stat.ALIAS)(@<-stat.)}
14 }
15 }
16 }
17 }
18 };
19 \db{TREE}{\trav{/}\query(XMOD<xmod){\rem.rec}}
20}
21
diff --git a/htc/upload.htc b/htc/upload.htc
new file mode 100644
index 0000000..ef3491e
--- /dev/null
+++ b/htc/upload.htc
@@ -0,0 +1,26 @@
1\def{upload.clear}{x}{
2 \if((\1 rpast "." eq "htc")||(\1 rleftand "/" eq \1)||(\1 cnt "WRITABLE")){
3 ROOT
4 }{
5 [path:=(\1 rleftand "/")++"WRITABLE"]\staturi(path)(\load(path) left \n){ROOT}
6 }
7}
8\def{upload.delete}{x}{
9 \log{upload: DELETING \1}
10 \remfile{\1}
11 \output{
12 \h3{\lang{File Deleted}{Filen raderad}}
13 \lang{
14 \1 was sucessfully deleted.
15 }{
16 \1 har raderats.
17 }
18 <p>
19 \href{\server}{\lang{Home}{Hem}}
20 }
21}
22\def{upload.put}{x}{
23 \log{upload: PUTTING \1}
24 \save{\1}{T.body}{417}
25}
26
diff --git a/htc/users.hdb b/htc/users.hdb
new file mode 100644
index 0000000..a55fc11
--- /dev/null
+++ b/htc/users.hdb
Binary files differ