|
1
|
/* |
|
2
|
** Copyright (c) 2014 D. Richard Hipp |
|
3
|
** |
|
4
|
** This program is free software; you can redistribute it and/or |
|
5
|
** modify it under the terms of the Simplified BSD License (also |
|
6
|
** known as the "2-Clause License" or "FreeBSD License".) |
|
7
|
|
|
8
|
** This program is distributed in the hope that it will be useful, |
|
9
|
** but without any warranty; without even the implied warranty of |
|
10
|
** merchantability or fitness for a particular purpose. |
|
11
|
** |
|
12
|
** Author contact information: |
|
13
|
** [email protected] |
|
14
|
** http://www.hwaci.com/drh/ |
|
15
|
** |
|
16
|
******************************************************************************* |
|
17
|
** |
|
18
|
** This file contains code to implement the sitemap webpage. |
|
19
|
*/ |
|
20
|
#include "config.h" |
|
21
|
#include "sitemap.h" |
|
22
|
#include <assert.h> |
|
23
|
|
|
24
|
/* |
|
25
|
** WEBPAGE: sitemap |
|
26
|
** |
|
27
|
** List some of the web pages offered by the Fossil web engine. This |
|
28
|
** page is intended as a supplement to the menu bar on the main screen. |
|
29
|
** That is, this page is designed to hold links that are omitted from |
|
30
|
** the main menu due to lack of space. |
|
31
|
** |
|
32
|
** Additional entries defined by the "sitemap-extra" setting are included |
|
33
|
** in the sitemap. "sitemap-extra" should be a TCL script with three |
|
34
|
** values per entry: |
|
35
|
** |
|
36
|
** * The displayed text |
|
37
|
** |
|
38
|
** * The URL |
|
39
|
** |
|
40
|
** * A "capexpr" expression that determines whether or not to include |
|
41
|
** the entry based on user capabilities. "*" means always include |
|
42
|
** the entry and "{}" means never. |
|
43
|
** |
|
44
|
** If the "e=1" query parameter is present, then the standard content |
|
45
|
** is omitted and only the sitemap-extra content is shown. If "e=2" is |
|
46
|
** present, then only the standard content is shown and sitemap-extra |
|
47
|
** content is omitted. |
|
48
|
** |
|
49
|
** If the "popup" query parameter is present and this is a POST request |
|
50
|
** from the same origin, then the normal HTML header and footer information |
|
51
|
** is omitted and the HTML text returned is just a raw "<ul>...</ul>". |
|
52
|
*/ |
|
53
|
void sitemap_page(void){ |
|
54
|
int srchFlags; |
|
55
|
int inSublist = 0; |
|
56
|
int i; |
|
57
|
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */ |
|
58
|
int e = atoi(PD("e","0")); |
|
59
|
const char *zExtra; |
|
60
|
|
|
61
|
login_check_credentials(); |
|
62
|
if( P("popup")!=0 ){ |
|
63
|
/* The "popup" query parameter |
|
64
|
** then disable anti-robot defenses */ |
|
65
|
isPopup = 1; |
|
66
|
g.perm.Hyperlink = 1; |
|
67
|
g.jsHref = 0; |
|
68
|
} |
|
69
|
srchFlags = search_restrict(SRCH_ALL); |
|
70
|
if( !isPopup ){ |
|
71
|
style_header("Site Map"); |
|
72
|
style_adunit_config(ADUNIT_RIGHT_OK); |
|
73
|
} |
|
74
|
|
|
75
|
@ <ul id="sitemap" class="columns" style="column-width:20em"> |
|
76
|
if( (e&1)==0 ){ |
|
77
|
@ <li>%z(href("%R/home"))Home Page</a> |
|
78
|
} |
|
79
|
|
|
80
|
zExtra = db_get("sitemap-extra",0); |
|
81
|
if( zExtra && (e&2)==0 ){ |
|
82
|
int rc; |
|
83
|
char **azExtra = 0; |
|
84
|
int *anExtra; |
|
85
|
int nExtra = 0; |
|
86
|
if( isPopup ) Th_FossilInit(0); |
|
87
|
if( (e&1)!=0 ) inSublist = 1; |
|
88
|
rc = Th_SplitList(g.interp, zExtra, (int)strlen(zExtra), |
|
89
|
&azExtra, &anExtra, &nExtra); |
|
90
|
if( rc==TH_OK && nExtra ){ |
|
91
|
for(i=0; i+2<nExtra; i+=3){ |
|
92
|
int nResult = 0; |
|
93
|
const char *zResult; |
|
94
|
int iCond = 0; |
|
95
|
rc = capexprCmd(g.interp, 0, 2, |
|
96
|
(const char**)&azExtra[i+1], (int*)&anExtra[i+1]); |
|
97
|
if( rc!=TH_OK ) continue; |
|
98
|
zResult = Th_GetResult(g.interp, &nResult); |
|
99
|
Th_ToInt(g.interp, zResult, nResult, &iCond); |
|
100
|
if( iCond==0 ) continue; |
|
101
|
if( !inSublist ){ |
|
102
|
@ <ul> |
|
103
|
inSublist = 1; |
|
104
|
} |
|
105
|
if( azExtra[i+1][0]=='/' ){ |
|
106
|
@ <li>%z(href("%R%s",azExtra[i+1]))%h(azExtra[i])</a></li> |
|
107
|
}else{ |
|
108
|
@ <li>%z(href("%s",azExtra[i+1]))%s(azExtra[i])</a></li> |
|
109
|
} |
|
110
|
} |
|
111
|
} |
|
112
|
Th_Free(g.interp, azExtra); |
|
113
|
} |
|
114
|
if( (e&1)!=0 ) goto end_of_sitemap; |
|
115
|
|
|
116
|
if( inSublist ){ |
|
117
|
@ </ul> |
|
118
|
inSublist = 0; |
|
119
|
} |
|
120
|
@ </li> |
|
121
|
if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){ |
|
122
|
@ <li>%z(href("%R/ckout"))Checkout Status</a></li> |
|
123
|
} |
|
124
|
if( g.perm.Read ){ |
|
125
|
const char *zEditGlob = db_get("fileedit-glob",""); |
|
126
|
@ <li>%z(href("%R/tree"))File Browser</a> |
|
127
|
@ <ul> |
|
128
|
@ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view, |
|
129
|
@ Trunk Check-in</a></li> |
|
130
|
@ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li> |
|
131
|
@ <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li> |
|
132
|
@ <li>%z(href("%R/uvlist"))Unversioned Files</a> |
|
133
|
if( g.perm.Write && zEditGlob[0]!=0 ){ |
|
134
|
@ <li>%z(href("%R/fileedit"))On-line File Editor</li> |
|
135
|
} |
|
136
|
@ </ul> |
|
137
|
} |
|
138
|
if( g.perm.Zip && db_get_boolean("suggested-downloads",0)!=0 ){ |
|
139
|
@ <li>%z(href("%R/download"))Tarballs and ZIPs</a> |
|
140
|
} |
|
141
|
if( g.perm.Read ){ |
|
142
|
@ <li>%z(href("%R/timeline"))Project Timeline</a> |
|
143
|
@ <ul> |
|
144
|
@ <li>%z(href("%R/reports"))Activity Reports</a></li> |
|
145
|
@ <li>%z(href("%R/sitemap-timeline"))Other timelines</a></li> |
|
146
|
@ </ul> |
|
147
|
@ </li> |
|
148
|
} |
|
149
|
if( g.perm.Read ){ |
|
150
|
@ <li>%z(href("%R/brlist"))Branches</a> |
|
151
|
@ <ul> |
|
152
|
@ <li>%z(href("%R/taglist"))Tags</a></li> |
|
153
|
@ <li>%z(href("%R/leaves"))Leaf Check-ins</a></li> |
|
154
|
@ </ul> |
|
155
|
@ </li> |
|
156
|
} |
|
157
|
if( srchFlags ){ |
|
158
|
@ <li>%z(href("%R/search"))Search</a></li> |
|
159
|
} |
|
160
|
if( g.perm.Chat ){ |
|
161
|
@ <li>%z(href("%R/chat"))Chat</a></li> |
|
162
|
} |
|
163
|
if( g.perm.RdForum ){ |
|
164
|
const char *zTitle = db_get("forum-title","Forum"); |
|
165
|
@ <li>%z(href("%R/forum"))%h(zTitle)</a> |
|
166
|
@ <ul> |
|
167
|
@ <li>%z(href("%R/timeline?y=f"))Recent activity</a></li> |
|
168
|
@ </ul> |
|
169
|
@ </li> |
|
170
|
} |
|
171
|
if( g.perm.RdTkt ){ |
|
172
|
@ <li>%z(href("%R/reportlist"))Tickets/Bug Reports</a> |
|
173
|
@ <ul> |
|
174
|
if( srchFlags & SRCH_TKT ){ |
|
175
|
@ <li>%z(href("%R/tktsrch"))Ticket Search</a></li> |
|
176
|
} |
|
177
|
@ <li>%z(href("%R/timeline?y=t"))Recent activity</a></li> |
|
178
|
@ <li>%z(href("%R/attachlist"))List of Attachments</a></li> |
|
179
|
@ </ul> |
|
180
|
@ </li> |
|
181
|
} |
|
182
|
if( g.perm.RdWiki ){ |
|
183
|
@ <li>%z(href("%R/wikihelp"))Wiki</a> |
|
184
|
@ <ul> |
|
185
|
if( srchFlags & SRCH_WIKI ){ |
|
186
|
@ <li>%z(href("%R/wikisrch"))Wiki Search</a></li> |
|
187
|
} |
|
188
|
@ <li>%z(href("%R/wcontent"))List of Wiki Pages</a></li> |
|
189
|
@ <li>%z(href("%R/timeline?y=w"))Recent activity</a></li> |
|
190
|
@ <li>%z(href("%R/wikiedit?name=Sandbox"))Wiki Sandbox</a></li> |
|
191
|
@ <li>%z(href("%R/attachlist"))List of Attachments</a></li> |
|
192
|
@ <li>%z(href("%R/pikchrshow"))Pikchr Sandbox</a></li> |
|
193
|
@ </ul> |
|
194
|
@ </li> |
|
195
|
} |
|
196
|
|
|
197
|
if( !g.zLogin ){ |
|
198
|
@ <li>%z(href("%R/login"))Login</a> |
|
199
|
@ <ul> |
|
200
|
if( login_self_register_available(0) ){ |
|
201
|
@ <li>%z(href("%R/register"))Create a new account</a></li> |
|
202
|
} |
|
203
|
}else { |
|
204
|
@ <li>%z(href("%R/logout"))Logout from %h(g.zLogin)</a> |
|
205
|
@ <ul> |
|
206
|
if( g.perm.Password ){ |
|
207
|
@ <li>%z(href("%R/logout"))Change Password for %h(g.zLogin)</a></li> |
|
208
|
} |
|
209
|
} |
|
210
|
if( alert_enabled() && g.perm.EmailAlert ){ |
|
211
|
if( login_is_individual() ){ |
|
212
|
@ <li>%z(href("%R/alerts"))Email Alerts for %h(g.zLogin)</a></li> |
|
213
|
}else{ |
|
214
|
@ <li>%z(href("%R/subscribe"))Subscribe to Email Alerts</a></li> |
|
215
|
} |
|
216
|
} |
|
217
|
@ <li>%z(href("%R/cookies"))Cookies</a></li> |
|
218
|
@ </ul> |
|
219
|
@ </li> |
|
220
|
|
|
221
|
if( g.perm.Read ){ |
|
222
|
@ <li>%z(href("%R/stat"))Repository Status</a> |
|
223
|
@ <ul> |
|
224
|
@ <li>%z(href("%R/hash-collisions"))Collisions on hash prefixes</a></li> |
|
225
|
if( g.perm.Admin ){ |
|
226
|
@ <li>%z(href("%R/urllist"))List of URLs used to access |
|
227
|
@ this repository</a></li> |
|
228
|
} |
|
229
|
@ <li>%z(href("%R/bloblist"))List of Artifacts</a></li> |
|
230
|
@ </ul> |
|
231
|
@ </li> |
|
232
|
} |
|
233
|
@ <li>%z(href("%R/help"))Help</a> |
|
234
|
@ <ul> |
|
235
|
if( g.perm.Admin || g.perm.Write || |
|
236
|
g.perm.WrForum || g.perm.WrTForum || |
|
237
|
g.perm.NewWiki || g.perm.ApndWiki || g.perm.WrWiki || g.perm.ModWiki || |
|
238
|
g.perm.NewTkt || g.perm.ApndTkt || g.perm.WrTkt || g.perm.ModTkt ){ |
|
239
|
@ <li>%z(href("%R/wiki_rules"))Wiki Formatting Rules</a></li> |
|
240
|
@ <li>%z(href("%R/md_rules"))Markdown Formatting Rules</a></li> |
|
241
|
} |
|
242
|
@ <li>%z(href("%R/test-all-help"))All "help" text on a single page</a></li> |
|
243
|
if( g.perm.Admin || g.perm.Write || g.perm.WrUnver ){ |
|
244
|
@ <li>%z(href("%R/mimetype_list"))\ |
|
245
|
@ Filename suffix to MIME type map</a></li> |
|
246
|
} |
|
247
|
@ </ul></li> |
|
248
|
if( g.perm.Admin ){ |
|
249
|
@ <li><a href="%R/setup">Administration Pages</a> |
|
250
|
@ <ul> |
|
251
|
@ <li><a href="%R/secaudit0">Security Audit</a></li> |
|
252
|
@ <li><a href="%R/modreq">Pending Moderation Requests</a></li> |
|
253
|
@ </ul></li> |
|
254
|
} |
|
255
|
@ <li>%z(href("%R/skins"))Skins</a></li> |
|
256
|
@ <li>%z(href("%R/sitemap-test"))Test Pages</a></li> |
|
257
|
if( isPopup ){ |
|
258
|
@ <li>%z(href("%R/sitemap"))Site Map</a></li> |
|
259
|
} |
|
260
|
|
|
261
|
end_of_sitemap: |
|
262
|
@ </ul> |
|
263
|
if( !isPopup ){ |
|
264
|
style_finish_page(); |
|
265
|
} |
|
266
|
} |
|
267
|
|
|
268
|
/* |
|
269
|
** WEBPAGE: sitemap-test |
|
270
|
** |
|
271
|
** List some of the web pages offered by the Fossil web engine for testing |
|
272
|
** purposes. This is similar to /sitemap, but is focused only on showing |
|
273
|
** pages associated with testing. |
|
274
|
*/ |
|
275
|
void sitemap_test_page(void){ |
|
276
|
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */ |
|
277
|
|
|
278
|
login_check_credentials(); |
|
279
|
style_set_current_feature("sitemap"); |
|
280
|
if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
|
281
|
/* If this is a POST from the same origin with the popup=1 parameter, |
|
282
|
** then disable anti-robot defenses */ |
|
283
|
isPopup = 1; |
|
284
|
g.perm.Hyperlink = 1; |
|
285
|
g.jsHref = 0; |
|
286
|
} |
|
287
|
if( !isPopup ){ |
|
288
|
style_header("Test Page Map"); |
|
289
|
style_adunit_config(ADUNIT_RIGHT_OK); |
|
290
|
} |
|
291
|
@ <ul id="sitemap" class="columns" style="column-width:20em"> |
|
292
|
if( g.perm.Admin || db_get_boolean("test_env_enable",0) ){ |
|
293
|
@ <li>%z(href("%R/test-env"))CGI Environment Test</a></li> |
|
294
|
} |
|
295
|
if( g.perm.Read ){ |
|
296
|
@ <li>%z(href("%R/test-rename-list"))List of file renames</a></li> |
|
297
|
} |
|
298
|
@ <li>%z(href("%R/test-builtin-files"))List of built-in files</a></li> |
|
299
|
@ <li>%z(href("%R/mimetype_list"))List of MIME types</a></li> |
|
300
|
@ <li>%z(href("%R/hash-color-test"))Hash color test</a> |
|
301
|
@ <li>%z(href("%R/test-bgcolor"))Background color test</a> |
|
302
|
if( g.perm.Admin ){ |
|
303
|
@ <li>%z(href("%R/test-backlinks"))List of backlinks</a></li> |
|
304
|
@ <li>%z(href("%R/test-backlink-timeline"))Backlink timeline</a></li> |
|
305
|
@ <li>%z(href("%R/phantoms"))List of phantom artifacts</a></li> |
|
306
|
@ <li>%z(href("%R/test-warning"))Error Log test page</a></li> |
|
307
|
@ <li>%z(href("%R/repo_stat1"))Repository <tt>sqlite_stat1</tt> table</a> |
|
308
|
@ <li>%z(href("%R/repo_schema"))Repository schema</a></li> |
|
309
|
} |
|
310
|
if( g.perm.Read && g.perm.Hyperlink ){ |
|
311
|
@ <li>%z(href("%R/timewarps"))Timeline of timewarps</a></li> |
|
312
|
} |
|
313
|
@ <li>%z(href("%R/cookies"))Content of display preference cookie</a></li> |
|
314
|
@ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</a></li> |
|
315
|
@ <li>%z(href("%R/test-piechart"))Pie-Chart generator test</a></li> |
|
316
|
if( !isPopup ){ |
|
317
|
style_finish_page(); |
|
318
|
} |
|
319
|
} |
|
320
|
|
|
321
|
/* |
|
322
|
** WEBPAGE: sitemap-timeline |
|
323
|
** |
|
324
|
** Generate a list of hyperlinks to various (obscure) variations on |
|
325
|
** the /timeline page. |
|
326
|
*/ |
|
327
|
void sitemap_timeline_page(void){ |
|
328
|
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */ |
|
329
|
|
|
330
|
login_check_credentials(); |
|
331
|
style_set_current_feature("sitemap"); |
|
332
|
if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
|
333
|
/* If this is a POST from the same origin with the popup=1 parameter, |
|
334
|
** then disable anti-robot defenses */ |
|
335
|
isPopup = 1; |
|
336
|
g.perm.Hyperlink = 1; |
|
337
|
g.jsHref = 0; |
|
338
|
} |
|
339
|
if( !isPopup ){ |
|
340
|
style_header("Timeline Examples"); |
|
341
|
style_adunit_config(ADUNIT_RIGHT_OK); |
|
342
|
} |
|
343
|
@ <ul id="sitemap" class="columns" style="column-width:20em"> |
|
344
|
@ <li>%z(href("%R/timeline?ymd"))Current day</a></li> |
|
345
|
@ <li>%z(href("%R/timeline?yw"))Current week</a></li> |
|
346
|
@ <li>%z(href("%R/timeline?ym"))Current month</a></li> |
|
347
|
@ <li>%z(href("%R/thisdayinhistory"))Today in history</a></li> |
|
348
|
@ <li>%z(href("%R/timeline?a=1970-01-01&y=ci&n=10"))First 10 |
|
349
|
@ check-ins</a></li> |
|
350
|
@ <li>%z(href("%R/timeline?namechng"))File name changes</a></li> |
|
351
|
@ <li>%z(href("%R/timeline?forks"))Forks</a></li> |
|
352
|
@ <li>%z(href("%R/timeline?cherrypicks"))Cherrypick merges</a></li> |
|
353
|
@ <li>%z(href("%R/timewarps"))Timewarps</a></li> |
|
354
|
@ <li>%z(href("%R/timeline?ubg"))Color-coded by user</a></li> |
|
355
|
@ <li>%z(href("%R/timeline?deltabg"))Delta vs. baseline manifests</a></li> |
|
356
|
@ </ul> |
|
357
|
if( !isPopup ){ |
|
358
|
style_finish_page(); |
|
359
|
} |
|
360
|
} |
|
361
|
|