|
dbda8d6…
|
drh
|
1 |
/* |
|
c19f34c…
|
drh
|
2 |
** Copyright (c) 2007 D. Richard Hipp |
|
dbda8d6…
|
drh
|
3 |
** |
|
dbda8d6…
|
drh
|
4 |
** This program is free software; you can redistribute it and/or |
|
c06edd2…
|
drh
|
5 |
** modify it under the terms of the Simplified BSD License (also |
|
c06edd2…
|
drh
|
6 |
** known as the "2-Clause License" or "FreeBSD License".) |
|
ccf50f0…
|
drh
|
7 |
** |
|
dbda8d6…
|
drh
|
8 |
** This program is distributed in the hope that it will be useful, |
|
c06edd2…
|
drh
|
9 |
** but without any warranty; without even the implied warranty of |
|
c06edd2…
|
drh
|
10 |
** merchantability or fitness for a particular purpose. |
|
dbda8d6…
|
drh
|
11 |
** |
|
dbda8d6…
|
drh
|
12 |
** Author contact information: |
|
dbda8d6…
|
drh
|
13 |
** [email protected] |
|
dbda8d6…
|
drh
|
14 |
** http://www.hwaci.com/drh/ |
|
dbda8d6…
|
drh
|
15 |
** |
|
dbda8d6…
|
drh
|
16 |
******************************************************************************* |
|
dbda8d6…
|
drh
|
17 |
** |
|
dbda8d6…
|
drh
|
18 |
** Implementation of the Setup page |
|
dbda8d6…
|
drh
|
19 |
*/ |
|
dbda8d6…
|
drh
|
20 |
#include "config.h" |
|
c30cd93…
|
jan.nijtmans
|
21 |
#include <assert.h> |
|
dbda8d6…
|
drh
|
22 |
#include "setup.h" |
|
dbda8d6…
|
drh
|
23 |
|
|
3cb9ba4…
|
andygoth
|
24 |
/* |
|
7383450…
|
drh
|
25 |
** Increment the "cfgcnt" variable, so that ETags will know that |
|
7383450…
|
drh
|
26 |
** the configuration has changed. |
|
7383450…
|
drh
|
27 |
*/ |
|
7383450…
|
drh
|
28 |
void setup_incr_cfgcnt(void){ |
|
7383450…
|
drh
|
29 |
static int once = 1; |
|
7383450…
|
drh
|
30 |
if( once ){ |
|
7383450…
|
drh
|
31 |
once = 0; |
|
f741baa…
|
drh
|
32 |
db_unprotect(PROTECT_CONFIG); |
|
7383450…
|
drh
|
33 |
db_multi_exec("UPDATE config SET value=value+1 WHERE name='cfgcnt'"); |
|
7383450…
|
drh
|
34 |
if( db_changes()==0 ){ |
|
7383450…
|
drh
|
35 |
db_multi_exec("INSERT INTO config(name,value) VALUES('cfgcnt',1)"); |
|
7383450…
|
drh
|
36 |
} |
|
f741baa…
|
drh
|
37 |
db_protect_pop(); |
|
7383450…
|
drh
|
38 |
} |
|
7383450…
|
drh
|
39 |
} |
|
7383450…
|
drh
|
40 |
|
|
7383450…
|
drh
|
41 |
/* |
|
dbda8d6…
|
drh
|
42 |
** Output a single entry for a menu generated using an HTML table. |
|
b0feaa6…
|
drh
|
43 |
** If zLink is neither NULL nor an empty string, then it is the page that |
|
dbda8d6…
|
drh
|
44 |
** the menu entry will hyperlink to. If zLink is NULL or "", then |
|
dbda8d6…
|
drh
|
45 |
** the menu entry has no hyperlink - it is disabled. |
|
dbda8d6…
|
drh
|
46 |
*/ |
|
d0305b3…
|
aku
|
47 |
void setup_menu_entry( |
|
dbda8d6…
|
drh
|
48 |
const char *zTitle, |
|
dbda8d6…
|
drh
|
49 |
const char *zLink, |
|
b0feaa6…
|
drh
|
50 |
const char *zDesc /* Caution! Rendered using %s. May contain raw HTML. */ |
|
dbda8d6…
|
drh
|
51 |
){ |
|
d0305b3…
|
aku
|
52 |
@ <tr><td valign="top" align="right"> |
|
dbda8d6…
|
drh
|
53 |
if( zLink && zLink[0] ){ |
|
b28badb…
|
drh
|
54 |
@ <a href="%s(zLink)"><nobr>%h(zTitle)</nobr></a> |
|
dbda8d6…
|
drh
|
55 |
}else{ |
|
b0feaa6…
|
drh
|
56 |
@ <nobr>%h(zTitle)</nobr> |
|
dbda8d6…
|
drh
|
57 |
} |
|
b0feaa6…
|
drh
|
58 |
@ </td><td width="5"></td><td valign="top">%s(zDesc)</td></tr> |
|
dbda8d6…
|
drh
|
59 |
} |
|
dbda8d6…
|
drh
|
60 |
|
|
c6b2332…
|
drh
|
61 |
|
|
c6b2332…
|
drh
|
62 |
|
|
dbda8d6…
|
drh
|
63 |
/* |
|
7ab0328…
|
drh
|
64 |
** WEBPAGE: setup |
|
7ab0328…
|
drh
|
65 |
** |
|
7d034d3…
|
wyoung
|
66 |
** Main menu for the administrative pages. Requires Admin or Setup |
|
7d034d3…
|
wyoung
|
67 |
** privileges. Links to sub-pages only usable by Setup users are |
|
7d034d3…
|
wyoung
|
68 |
** shown only to Setup users. |
|
dbda8d6…
|
drh
|
69 |
*/ |
|
dbda8d6…
|
drh
|
70 |
void setup_page(void){ |
|
7d034d3…
|
wyoung
|
71 |
int setup_user = 0; |
|
d0305b3…
|
aku
|
72 |
login_check_credentials(); |
|
7d034d3…
|
wyoung
|
73 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
74 |
login_needed(0); |
|
766bec0…
|
drh
|
75 |
} |
|
7d034d3…
|
wyoung
|
76 |
setup_user = g.perm.Setup; |
|
766bec0…
|
drh
|
77 |
|
|
112c713…
|
drh
|
78 |
style_set_current_feature("setup"); |
|
766bec0…
|
drh
|
79 |
style_header("Server Administration"); |
|
65870e8…
|
drh
|
80 |
|
|
65870e8…
|
drh
|
81 |
/* Make sure the header contains <base href="...">. Issue a warning |
|
65870e8…
|
drh
|
82 |
** if it does not. */ |
|
65870e8…
|
drh
|
83 |
if( !cgi_header_contains("<base href=") ){ |
|
65870e8…
|
drh
|
84 |
@ <p class="generalError"><b>Configuration Error:</b> Please add |
|
a4e7b86…
|
drh
|
85 |
@ <tt><base href="$secureurl/$current_page"></tt> after |
|
7001228…
|
drh
|
86 |
@ <tt><head></tt> in the |
|
7001228…
|
drh
|
87 |
@ <a href="setup_skinedit?w=2">HTML header</a>!</p> |
|
65870e8…
|
drh
|
88 |
} |
|
c6b2332…
|
drh
|
89 |
|
|
c6b2332…
|
drh
|
90 |
#if !defined(_WIN32) |
|
c6b2332…
|
drh
|
91 |
/* Check for /dev/null and /dev/urandom. We want both devices to be present, |
|
c6b2332…
|
drh
|
92 |
** but they are sometimes omitted (by mistake) from chroot jails. */ |
|
c6b2332…
|
drh
|
93 |
if( access("/dev/null", R_OK|W_OK) ){ |
|
c6b2332…
|
drh
|
94 |
@ <p class="generalError">WARNING: Device "/dev/null" is not available |
|
c6b2332…
|
drh
|
95 |
@ for reading and writing.</p> |
|
c6b2332…
|
drh
|
96 |
} |
|
c6b2332…
|
drh
|
97 |
if( access("/dev/urandom", R_OK) ){ |
|
c6b2332…
|
drh
|
98 |
@ <p class="generalError">WARNING: Device "/dev/urandom" is not available |
|
c6b2332…
|
drh
|
99 |
@ for reading. This means that the pseudo-random number generator used |
|
c6b2332…
|
drh
|
100 |
@ by SQLite will be poorly seeded.</p> |
|
c6b2332…
|
drh
|
101 |
} |
|
c6b2332…
|
drh
|
102 |
#endif |
|
ca833ff…
|
drh
|
103 |
|
|
ca833ff…
|
drh
|
104 |
@ <table border="0" cellspacing="3"> |
|
d0305b3…
|
aku
|
105 |
setup_menu_entry("Users", "setup_ulist", |
|
d0305b3…
|
aku
|
106 |
"Grant privileges to individual users."); |
|
7d034d3…
|
wyoung
|
107 |
if( setup_user ){ |
|
7d034d3…
|
wyoung
|
108 |
setup_menu_entry("Access", "setup_access", |
|
7d034d3…
|
wyoung
|
109 |
"Control access settings."); |
|
7d034d3…
|
wyoung
|
110 |
setup_menu_entry("Configuration", "setup_config", |
|
7d034d3…
|
wyoung
|
111 |
"Configure the WWW components of the repository"); |
|
7d034d3…
|
wyoung
|
112 |
} |
|
0268307…
|
drh
|
113 |
setup_menu_entry("Security-Audit", "secaudit0", |
|
0268307…
|
drh
|
114 |
"Analyze the current configuration for security problems"); |
|
7d034d3…
|
wyoung
|
115 |
if( setup_user ){ |
|
df337eb…
|
drh
|
116 |
setup_menu_entry("Robot-Defense", "setup_robot", |
|
df337eb…
|
drh
|
117 |
"Settings for configure defense against robots"); |
|
7d034d3…
|
wyoung
|
118 |
setup_menu_entry("Settings", "setup_settings", |
|
7d034d3…
|
wyoung
|
119 |
"Web interface to the \"fossil settings\" command"); |
|
cd8c5df…
|
wyoung
|
120 |
} |
|
cd8c5df…
|
wyoung
|
121 |
setup_menu_entry("Timeline", "setup_timeline", |
|
cd8c5df…
|
wyoung
|
122 |
"Timeline display preferences"); |
|
6ce705b…
|
drh
|
123 |
setup_menu_entry("Tarballs and ZIPs", "setup_download", |
|
6ce705b…
|
drh
|
124 |
"Preferences for auto-generated tarballs and ZIP files"); |
|
cd8c5df…
|
wyoung
|
125 |
if( setup_user ){ |
|
7d034d3…
|
wyoung
|
126 |
setup_menu_entry("Login-Group", "setup_login_group", |
|
7d034d3…
|
wyoung
|
127 |
"Manage single sign-on between this repository and others" |
|
7d034d3…
|
wyoung
|
128 |
" on the same server"); |
|
7d034d3…
|
wyoung
|
129 |
setup_menu_entry("Tickets", "tktsetup", |
|
7d034d3…
|
wyoung
|
130 |
"Configure the trouble-ticketing system for this repository"); |
|
bf09c3b…
|
drh
|
131 |
setup_menu_entry("Wiki", "setup_wiki", |
|
bf09c3b…
|
drh
|
132 |
"Configure the wiki for this repository"); |
|
bb189a1…
|
drh
|
133 |
setup_menu_entry("Interwiki Map", "intermap", |
|
bb189a1…
|
drh
|
134 |
"Mapping keywords for interwiki links"); |
|
15bc20f…
|
drh
|
135 |
setup_menu_entry("Chat", "setup_chat", |
|
15bc20f…
|
drh
|
136 |
"Configure the chatroom"); |
|
673dc38…
|
stephan
|
137 |
setup_menu_entry("Forum", "setup_forum", |
|
673dc38…
|
stephan
|
138 |
"Forum config and metrics"); |
|
7d034d3…
|
wyoung
|
139 |
} |
|
ca833ff…
|
drh
|
140 |
setup_menu_entry("Search","srchsetup", |
|
ca833ff…
|
drh
|
141 |
"Configure the built-in search engine"); |
|
8131f1c…
|
drh
|
142 |
setup_menu_entry("URL Aliases", "waliassetup", |
|
8131f1c…
|
drh
|
143 |
"Configure URL aliases"); |
|
7d034d3…
|
wyoung
|
144 |
if( setup_user ){ |
|
7d034d3…
|
wyoung
|
145 |
setup_menu_entry("Notification", "setup_notification", |
|
7d034d3…
|
wyoung
|
146 |
"Automatic notifications of changes via outbound email"); |
|
6ce705b…
|
drh
|
147 |
#if 0 /* Disabled for now. Does this even work? */ |
|
7d034d3…
|
wyoung
|
148 |
setup_menu_entry("Transfers", "xfersetup", |
|
7d034d3…
|
wyoung
|
149 |
"Configure the transfer system for this repository"); |
|
6ce705b…
|
drh
|
150 |
#endif |
|
7d034d3…
|
wyoung
|
151 |
} |
|
33cc83f…
|
drh
|
152 |
setup_menu_entry("Skins", "setup_skin_admin", |
|
106c090…
|
drh
|
153 |
"Select and/or modify the web interface \"skins\""); |
|
ba418ee…
|
drh
|
154 |
setup_menu_entry("Moderation", "setup_modreq", |
|
ba418ee…
|
drh
|
155 |
"Enable/Disable requiring moderator approval of Wiki and/or Ticket" |
|
c89a694…
|
mistachkin
|
156 |
" changes and attachments."); |
|
257318c…
|
drh
|
157 |
setup_menu_entry("Ad-Unit", "setup_adunit", |
|
257318c…
|
drh
|
158 |
"Edit HTML text for an ad unit inserted after the menu bar"); |
|
a53beaa…
|
drh
|
159 |
setup_menu_entry("URLs & Checkouts", "urllist", |
|
a53beaa…
|
drh
|
160 |
"Show URLs used to access this repo and known check-outs"); |
|
7d034d3…
|
wyoung
|
161 |
if( setup_user ){ |
|
7d034d3…
|
wyoung
|
162 |
setup_menu_entry("Web-Cache", "cachestat", |
|
7d034d3…
|
wyoung
|
163 |
"View the status of the expensive-page cache"); |
|
7d034d3…
|
wyoung
|
164 |
} |
|
257318c…
|
drh
|
165 |
setup_menu_entry("Logo", "setup_logo", |
|
257318c…
|
drh
|
166 |
"Change the logo and background images for the server"); |
|
a48474b…
|
drh
|
167 |
setup_menu_entry("Shunned", "shun", |
|
a48474b…
|
drh
|
168 |
"Show artifacts that are shunned by this repository"); |
|
b28badb…
|
drh
|
169 |
setup_menu_entry("Log Files", "setup-logmenu", |
|
b28badb…
|
drh
|
170 |
"A menu of available log files"); |
|
ab4c1e2…
|
drh
|
171 |
setup_menu_entry("Unversioned Files", "uvlist?byage=1", |
|
ab4c1e2…
|
drh
|
172 |
"Show all unversioned files held"); |
|
3967d04…
|
drh
|
173 |
setup_menu_entry("Stats", "stat", |
|
3967d04…
|
drh
|
174 |
"Repository Status Reports"); |
|
9fa6808…
|
drh
|
175 |
setup_menu_entry("Sitemap", "sitemap", |
|
9fa6808…
|
drh
|
176 |
"Links to miscellaneous pages"); |
|
7d034d3…
|
wyoung
|
177 |
if( setup_user ){ |
|
7d034d3…
|
wyoung
|
178 |
setup_menu_entry("SQL", "admin_sql", |
|
7d034d3…
|
wyoung
|
179 |
"Enter raw SQL commands"); |
|
7d034d3…
|
wyoung
|
180 |
setup_menu_entry("TH1", "admin_th1", |
|
7d034d3…
|
wyoung
|
181 |
"Enter raw TH1 commands"); |
|
7d034d3…
|
wyoung
|
182 |
} |
|
7d034d3…
|
wyoung
|
183 |
@ </table> |
|
7d034d3…
|
wyoung
|
184 |
|
|
b28badb…
|
drh
|
185 |
style_finish_page(); |
|
b28badb…
|
drh
|
186 |
} |
|
b28badb…
|
drh
|
187 |
|
|
b28badb…
|
drh
|
188 |
|
|
b28badb…
|
drh
|
189 |
/* |
|
b28badb…
|
drh
|
190 |
** WEBPAGE: setup-logmenu |
|
b28badb…
|
drh
|
191 |
** |
|
25f43cc…
|
stephan
|
192 |
** Show a menu of available log renderings accessible to an administrator, |
|
b28badb…
|
drh
|
193 |
** together with a succinct explanation of each. |
|
b28badb…
|
drh
|
194 |
** |
|
b28badb…
|
drh
|
195 |
** This page is only accessible by administrators. |
|
b28badb…
|
drh
|
196 |
*/ |
|
b28badb…
|
drh
|
197 |
void setup_logmenu_page(void){ |
|
b28badb…
|
drh
|
198 |
Blob desc; |
|
b0feaa6…
|
drh
|
199 |
int bErrLog; /* True if Error Log enabled */ |
|
b28badb…
|
drh
|
200 |
blob_init(&desc, 0, 0); |
|
b28badb…
|
drh
|
201 |
|
|
b28badb…
|
drh
|
202 |
/* Administrator access only */ |
|
b28badb…
|
drh
|
203 |
login_check_credentials(); |
|
b28badb…
|
drh
|
204 |
if( !g.perm.Admin ){ |
|
b28badb…
|
drh
|
205 |
login_needed(0); |
|
b28badb…
|
drh
|
206 |
return; |
|
b28badb…
|
drh
|
207 |
} |
|
b28badb…
|
drh
|
208 |
style_header("Log Menu"); |
|
b28badb…
|
drh
|
209 |
@ <table border="0" cellspacing="3"> |
|
2771bea…
|
jkosche
|
210 |
|
|
bdf12f4…
|
drh
|
211 |
if( db_get_boolean("admin-log",1)==0 ){ |
|
767509f…
|
drh
|
212 |
blob_appendf(&desc, |
|
767509f…
|
drh
|
213 |
"The admin log records configuration changes to the repository.\n" |
|
767509f…
|
drh
|
214 |
"<b>Disabled</b>: Turn on the " |
|
767509f…
|
drh
|
215 |
" <a href='%R/setup_settings'>admin-log setting</a> to enable." |
|
767509f…
|
drh
|
216 |
); |
|
767509f…
|
drh
|
217 |
setup_menu_entry("Admin Log", 0, blob_str(&desc)); |
|
767509f…
|
drh
|
218 |
blob_reset(&desc); |
|
767509f…
|
drh
|
219 |
}else{ |
|
767509f…
|
drh
|
220 |
setup_menu_entry("Admin Log", "admin_log", |
|
767509f…
|
drh
|
221 |
"The admin log records configuration changes to the repository\n" |
|
767509f…
|
drh
|
222 |
"in the \"admin_log\" table.\n" |
|
767509f…
|
drh
|
223 |
); |
|
767509f…
|
drh
|
224 |
} |
|
c675484…
|
drh
|
225 |
setup_menu_entry("Xfer Log", "rcvfromlist", |
|
767509f…
|
drh
|
226 |
"The artifact log records when new content is added in the\n" |
|
767509f…
|
drh
|
227 |
"\"rcvfrom\" table.\n" |
|
767509f…
|
drh
|
228 |
); |
|
bdf12f4…
|
drh
|
229 |
if( db_get_boolean("access-log",1) ){ |
|
767509f…
|
drh
|
230 |
setup_menu_entry("User Log", "user_log", |
|
767509f…
|
drh
|
231 |
"Login attempts recorded in the \"accesslog\" table." |
|
767509f…
|
drh
|
232 |
); |
|
767509f…
|
drh
|
233 |
}else{ |
|
767509f…
|
drh
|
234 |
blob_appendf(&desc, |
|
767509f…
|
drh
|
235 |
"Login attempts recorded in the \"accesslog\" table.\n" |
|
767509f…
|
drh
|
236 |
"<b>Disabled</b>: Turn on the " |
|
767509f…
|
drh
|
237 |
"<a href='%R/setup_settings'>access-log setting</a> to enable." |
|
767509f…
|
drh
|
238 |
); |
|
767509f…
|
drh
|
239 |
setup_menu_entry("User Log", 0, blob_str(&desc)); |
|
767509f…
|
drh
|
240 |
blob_reset(&desc); |
|
767509f…
|
drh
|
241 |
} |
|
b28badb…
|
drh
|
242 |
|
|
b28badb…
|
drh
|
243 |
blob_appendf(&desc, |
|
767509f…
|
drh
|
244 |
"A separate text file to which warning and error\n" |
|
b28badb…
|
drh
|
245 |
"messages are appended. A single error log can and often is shared\n" |
|
b28badb…
|
drh
|
246 |
"across multiple repositories.\n" |
|
b28badb…
|
drh
|
247 |
); |
|
b28badb…
|
drh
|
248 |
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){ |
|
767509f…
|
drh
|
249 |
blob_appendf(&desc,"<b>Disabled</b>: " |
|
767509f…
|
drh
|
250 |
"To enable the error log "); |
|
b0feaa6…
|
drh
|
251 |
if( fossil_strcmp(g.zCmdName, "cgi")==0 ){ |
|
b0feaa6…
|
drh
|
252 |
blob_appendf(&desc, |
|
b0feaa6…
|
drh
|
253 |
"make an entry like \"errorlog: <i>FILENAME</i>\"" |
|
b0feaa6…
|
drh
|
254 |
" in the CGI script at %h", |
|
b0feaa6…
|
drh
|
255 |
P("SCRIPT_FILENAME") |
|
b0feaa6…
|
drh
|
256 |
); |
|
b0feaa6…
|
drh
|
257 |
}else{ |
|
b0feaa6…
|
drh
|
258 |
blob_appendf(&desc, |
|
bd0d442…
|
drh
|
259 |
" add the \"--errorlog <i>FILENAME</i>\" option to the\n" |
|
f38866e…
|
drh
|
260 |
"\"%h %h\" command that launched the server.", |
|
b0feaa6…
|
drh
|
261 |
g.argv[0], g.zCmdName |
|
b0feaa6…
|
drh
|
262 |
); |
|
b0feaa6…
|
drh
|
263 |
} |
|
b0feaa6…
|
drh
|
264 |
bErrLog = 0; |
|
b28badb…
|
drh
|
265 |
}else{ |
|
767509f…
|
drh
|
266 |
blob_appendf(&desc,"In this repository, the error log is the file " |
|
b28badb…
|
drh
|
267 |
"named \"%s\".", g.zErrlog); |
|
b0feaa6…
|
drh
|
268 |
bErrLog = 1; |
|
b0feaa6…
|
drh
|
269 |
} |
|
b0feaa6…
|
drh
|
270 |
setup_menu_entry("Error Log", bErrLog ? "errorlog" : 0, blob_str(&desc)); |
|
b0feaa6…
|
drh
|
271 |
blob_reset(&desc); |
|
b28badb…
|
drh
|
272 |
|
|
b28badb…
|
drh
|
273 |
@ </table> |
|
0a5d0e1…
|
drh
|
274 |
style_finish_page(); |
|
0a5d0e1…
|
drh
|
275 |
} |
|
0a5d0e1…
|
drh
|
276 |
|
|
dbda8d6…
|
drh
|
277 |
/* |
|
dbda8d6…
|
drh
|
278 |
** Generate a checkbox for an attribute. |
|
dbda8d6…
|
drh
|
279 |
*/ |
|
d4e9df1…
|
drh
|
280 |
void onoff_attribute( |
|
dbda8d6…
|
drh
|
281 |
const char *zLabel, /* The text label on the checkbox */ |
|
0a5d0e1…
|
drh
|
282 |
const char *zVar, /* The corresponding row in the CONFIG table */ |
|
dbda8d6…
|
drh
|
283 |
const char *zQParm, /* The query parameter */ |
|
0a5d0e1…
|
drh
|
284 |
int dfltVal, /* Default value if CONFIG table entry does not exist */ |
|
10d8abc…
|
jan.nijtmans
|
285 |
int disabled /* 1 if disabled */ |
|
dbda8d6…
|
drh
|
286 |
){ |
|
dbda8d6…
|
drh
|
287 |
const char *zQ = P(zQParm); |
|
671e7c3…
|
drh
|
288 |
int iVal = db_get_boolean(zVar, dfltVal); |
|
3cba68a…
|
jan.nijtmans
|
289 |
if( zQ==0 && !disabled && P("submit") ){ |
|
dbda8d6…
|
drh
|
290 |
zQ = "off"; |
|
dbda8d6…
|
drh
|
291 |
} |
|
dbda8d6…
|
drh
|
292 |
if( zQ ){ |
|
32ad9a1…
|
drh
|
293 |
int iQ = fossil_strcmp(zQ,"on")==0 || atoi(zQ); |
|
920ace1…
|
drh
|
294 |
if( iQ!=iVal && cgi_csrf_safe(2) ){ |
|
f741baa…
|
drh
|
295 |
db_protect_only(PROTECT_NONE); |
|
0a5d0e1…
|
drh
|
296 |
db_set(zVar/*works-like:"x"*/, iQ ? "1" : "0", 0); |
|
f741baa…
|
drh
|
297 |
db_protect_pop(); |
|
0ba0e5e…
|
drh
|
298 |
setup_incr_cfgcnt(); |
|
f3455a5…
|
drh
|
299 |
admin_log("Set option [%q] to [%q].", |
|
f3455a5…
|
drh
|
300 |
zVar, iQ ? "on" : "off"); |
|
dbda8d6…
|
drh
|
301 |
iVal = iQ; |
|
dbda8d6…
|
drh
|
302 |
} |
|
dbda8d6…
|
drh
|
303 |
} |
|
7dd07b2…
|
drh
|
304 |
@ <label><input type="checkbox" name="%s(zQParm)" \ |
|
ecab8f4…
|
drh
|
305 |
@ aria-label="%h(zLabel[0]?zLabel:zQParm)" \ |
|
dbda8d6…
|
drh
|
306 |
if( iVal ){ |
|
7dd07b2…
|
drh
|
307 |
@ checked="checked" \ |
|
10d8abc…
|
jan.nijtmans
|
308 |
} |
|
10d8abc…
|
jan.nijtmans
|
309 |
if( disabled ){ |
|
7dd07b2…
|
drh
|
310 |
@ disabled="disabled" \ |
|
dbda8d6…
|
drh
|
311 |
} |
|
f5482a0…
|
wyoung
|
312 |
@ > <b>%s(zLabel)</b></label> |
|
dbda8d6…
|
drh
|
313 |
} |
|
dbda8d6…
|
drh
|
314 |
|
|
dbda8d6…
|
drh
|
315 |
/* |
|
dbda8d6…
|
drh
|
316 |
** Generate an entry box for an attribute. |
|
dbda8d6…
|
drh
|
317 |
*/ |
|
ac3f1f2…
|
drh
|
318 |
void entry_attribute( |
|
dbda8d6…
|
drh
|
319 |
const char *zLabel, /* The text label on the entry box */ |
|
dbda8d6…
|
drh
|
320 |
int width, /* Width of the entry box */ |
|
0a5d0e1…
|
drh
|
321 |
const char *zVar, /* The corresponding row in the CONFIG table */ |
|
f3455a5…
|
drh
|
322 |
const char *zQParm, /* The query parameter */ |
|
0a5d0e1…
|
drh
|
323 |
const char *zDflt, /* Default value if CONFIG table entry does not exist */ |
|
f3455a5…
|
drh
|
324 |
int disabled /* 1 if disabled */ |
|
f3455a5…
|
drh
|
325 |
){ |
|
f3455a5…
|
drh
|
326 |
const char *zVal = db_get(zVar, zDflt); |
|
f3455a5…
|
drh
|
327 |
const char *zQ = P(zQParm); |
|
920ace1…
|
drh
|
328 |
if( zQ && fossil_strcmp(zQ,zVal)!=0 && cgi_csrf_safe(2) ){ |
|
f3455a5…
|
drh
|
329 |
const int nZQ = (int)strlen(zQ); |
|
0ba0e5e…
|
drh
|
330 |
setup_incr_cfgcnt(); |
|
f741baa…
|
drh
|
331 |
db_protect_only(PROTECT_NONE); |
|
0a5d0e1…
|
drh
|
332 |
db_set(zVar/*works-like:"x"*/, zQ, 0); |
|
f741baa…
|
drh
|
333 |
db_protect_pop(); |
|
f3455a5…
|
drh
|
334 |
admin_log("Set entry_attribute %Q to: %.*s%s", |
|
f3455a5…
|
drh
|
335 |
zVar, 20, zQ, (nZQ>20 ? "..." : "")); |
|
f3455a5…
|
drh
|
336 |
zVal = zQ; |
|
f3455a5…
|
drh
|
337 |
} |
|
7dd07b2…
|
drh
|
338 |
@ <input aria-label="%h(zLabel[0]?zLabel:zQParm)" type="text" \ |
|
7dd07b2…
|
drh
|
339 |
@ id="%s(zQParm)" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" \ |
|
f3455a5…
|
drh
|
340 |
if( disabled ){ |
|
b77f1aa…
|
drh
|
341 |
@ disabled="disabled" \ |
|
f3455a5…
|
drh
|
342 |
} |
|
f5482a0…
|
wyoung
|
343 |
@ > <b>%s(zLabel)</b> |
|
f3455a5…
|
drh
|
344 |
} |
|
f3455a5…
|
drh
|
345 |
|
|
f3455a5…
|
drh
|
346 |
/* |
|
f3455a5…
|
drh
|
347 |
** Generate a text box for an attribute. |
|
f3455a5…
|
drh
|
348 |
*/ |
|
106c090…
|
drh
|
349 |
const char *textarea_attribute( |
|
f3455a5…
|
drh
|
350 |
const char *zLabel, /* The text label on the textarea */ |
|
f3455a5…
|
drh
|
351 |
int rows, /* Rows in the textarea */ |
|
f3455a5…
|
drh
|
352 |
int cols, /* Columns in the textarea */ |
|
0a5d0e1…
|
drh
|
353 |
const char *zVar, /* The corresponding row in the CONFIG table */ |
|
f3455a5…
|
drh
|
354 |
const char *zQP, /* The query parameter */ |
|
0a5d0e1…
|
drh
|
355 |
const char *zDflt, /* Default value if CONFIG table entry does not exist */ |
|
f3455a5…
|
drh
|
356 |
int disabled /* 1 if the textarea should not be editable */ |
|
f3455a5…
|
drh
|
357 |
){ |
|
5b456cf…
|
jan.nijtmans
|
358 |
const char *z = db_get(zVar, zDflt); |
|
f3455a5…
|
drh
|
359 |
const char *zQ = P(zQP); |
|
920ace1…
|
drh
|
360 |
if( zQ && !disabled && fossil_strcmp(zQ,z)!=0 && cgi_csrf_safe(2) ){ |
|
f3455a5…
|
drh
|
361 |
const int nZQ = (int)strlen(zQ); |
|
f741baa…
|
drh
|
362 |
db_protect_only(PROTECT_NONE); |
|
0a5d0e1…
|
drh
|
363 |
db_set(zVar/*works-like:"x"*/, zQ, 0); |
|
f741baa…
|
drh
|
364 |
db_protect_pop(); |
|
0ba0e5e…
|
drh
|
365 |
setup_incr_cfgcnt(); |
|
f3455a5…
|
drh
|
366 |
admin_log("Set textarea_attribute %Q to: %.*s%s", |
|
f3455a5…
|
drh
|
367 |
zVar, 20, zQ, (nZQ>20 ? "..." : "")); |
|
f3455a5…
|
drh
|
368 |
z = zQ; |
|
f3455a5…
|
drh
|
369 |
} |
|
f3455a5…
|
drh
|
370 |
if( rows>0 && cols>0 ){ |
|
7dd07b2…
|
drh
|
371 |
@ <textarea id="id%s(zQP)" name="%s(zQP)" rows="%d(rows)" \ |
|
7dd07b2…
|
drh
|
372 |
@ aria-label="%h(zLabel[0]?zLabel:zQP)" \ |
|
f3455a5…
|
drh
|
373 |
if( disabled ){ |
|
7dd07b2…
|
drh
|
374 |
@ disabled="disabled" \ |
|
f3455a5…
|
drh
|
375 |
} |
|
f3455a5…
|
drh
|
376 |
@ cols="%d(cols)">%h(z)</textarea> |
|
7dd07b2…
|
drh
|
377 |
if( *zLabel ){ |
|
f3455a5…
|
drh
|
378 |
@ <span class="textareaLabel">%s(zLabel)</span> |
|
f3455a5…
|
drh
|
379 |
} |
|
f3455a5…
|
drh
|
380 |
} |
|
106c090…
|
drh
|
381 |
return z; |
|
f3455a5…
|
drh
|
382 |
} |
|
f3455a5…
|
drh
|
383 |
|
|
f3455a5…
|
drh
|
384 |
/* |
|
f3455a5…
|
drh
|
385 |
** Generate a text box for an attribute. |
|
f3455a5…
|
drh
|
386 |
*/ |
|
ccf50f0…
|
drh
|
387 |
void multiple_choice_attribute( |
|
f3455a5…
|
drh
|
388 |
const char *zLabel, /* The text label on the menu */ |
|
0a5d0e1…
|
drh
|
389 |
const char *zVar, /* The corresponding row in the CONFIG table */ |
|
f3455a5…
|
drh
|
390 |
const char *zQP, /* The query parameter */ |
|
0a5d0e1…
|
drh
|
391 |
const char *zDflt, /* Default value if CONFIG table entry does not exist */ |
|
f3455a5…
|
drh
|
392 |
int nChoice, /* Number of choices */ |
|
4aba9ea…
|
drh
|
393 |
const char *const *azChoice /* Choices in pairs (VAR value, Display) */ |
|
f3455a5…
|
drh
|
394 |
){ |
|
5b456cf…
|
jan.nijtmans
|
395 |
const char *z = db_get(zVar, zDflt); |
|
f3455a5…
|
drh
|
396 |
const char *zQ = P(zQP); |
|
f3455a5…
|
drh
|
397 |
int i; |
|
920ace1…
|
drh
|
398 |
if( zQ && fossil_strcmp(zQ,z)!=0 && cgi_csrf_safe(2) ){ |
|
f3455a5…
|
drh
|
399 |
const int nZQ = (int)strlen(zQ); |
|
95e7351…
|
drh
|
400 |
db_unprotect(PROTECT_ALL); |
|
0a5d0e1…
|
drh
|
401 |
db_set(zVar/*works-like:"x"*/, zQ, 0); |
|
0ba0e5e…
|
drh
|
402 |
setup_incr_cfgcnt(); |
|
95e7351…
|
drh
|
403 |
db_protect_pop(); |
|
f3455a5…
|
drh
|
404 |
admin_log("Set multiple_choice_attribute %Q to: %.*s%s", |
|
f3455a5…
|
drh
|
405 |
zVar, 20, zQ, (nZQ>20 ? "..." : "")); |
|
f3455a5…
|
drh
|
406 |
z = zQ; |
|
f3455a5…
|
drh
|
407 |
} |
|
7dd07b2…
|
drh
|
408 |
@ <select aria-label="%h(zLabel)" size="1" name="%s(zQP)" id="id%s(zQP)"> |
|
3587e45…
|
drh
|
409 |
for(i=0; i<nChoice*2; i+=2){ |
|
3587e45…
|
drh
|
410 |
const char *zSel = fossil_strcmp(azChoice[i],z)==0 ? " selected" : ""; |
|
3587e45…
|
drh
|
411 |
@ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option> |
|
3587e45…
|
drh
|
412 |
} |
|
3587e45…
|
drh
|
413 |
@ </select> <b>%h(zLabel)</b> |
|
3587e45…
|
drh
|
414 |
} |
|
3587e45…
|
drh
|
415 |
|
|
df337eb…
|
drh
|
416 |
/* |
|
df337eb…
|
drh
|
417 |
** Insert code into the current page that allows the user to configure |
|
df337eb…
|
drh
|
418 |
** auto-hyperlink related robot defense settings. |
|
df337eb…
|
drh
|
419 |
*/ |
|
df337eb…
|
drh
|
420 |
static void addAutoHyperlinkSettings(void){ |
|
df337eb…
|
drh
|
421 |
static const char *const azDefenseOpts[] = { |
|
df337eb…
|
drh
|
422 |
"0", "Off", |
|
df337eb…
|
drh
|
423 |
"2", "UserAgent only", |
|
df337eb…
|
drh
|
424 |
"1", "UserAgent and Javascript", |
|
df337eb…
|
drh
|
425 |
}; |
|
df337eb…
|
drh
|
426 |
multiple_choice_attribute( |
|
df337eb…
|
drh
|
427 |
"Enable hyperlinks base on User-Agent and/or Javascript", |
|
df337eb…
|
drh
|
428 |
"auto-hyperlink", "autohyperlink", "1", |
|
df337eb…
|
drh
|
429 |
count(azDefenseOpts)/2, azDefenseOpts); |
|
58a48e3…
|
drh
|
430 |
@ <br> |
|
f5482a0…
|
wyoung
|
431 |
entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, |
|
f5482a0…
|
wyoung
|
432 |
"auto-hyperlink-delay", "ah-delay", "50", 0); |
|
f5482a0…
|
wyoung
|
433 |
@ <br> |
|
f5482a0…
|
wyoung
|
434 |
onoff_attribute("Also require a mouse event before enabling hyperlinks", |
|
f5482a0…
|
wyoung
|
435 |
"auto-hyperlink-mouseover", "ahmo", 0, 0); |
|
58a48e3…
|
drh
|
436 |
@ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, |
|
58a48e3…
|
drh
|
437 |
@ including user "nobody" if the request appears to be from a human. |
|
58a48e3…
|
drh
|
438 |
@ Disabling hyperlinks helps prevent robots from walking your site and |
|
58a48e3…
|
drh
|
439 |
@ soaking up all your CPU and bandwidth. |
|
58a48e3…
|
drh
|
440 |
@ If this setting is "UserAgent only" (2) then the |
|
58a48e3…
|
drh
|
441 |
@ UserAgent string is the only factor considered. If the value of this |
|
58a48e3…
|
drh
|
442 |
@ setting is "UserAgent And Javascript" (1) then Javascript is added that |
|
58a48e3…
|
drh
|
443 |
@ runs after the page loads and fills in the href= values of <a> |
|
58a48e3…
|
drh
|
444 |
@ elements. In either case, <a> tags are not generated if the |
|
58a48e3…
|
drh
|
445 |
@ UserAgent string indicates that the client is a robot. |
|
58a48e3…
|
drh
|
446 |
@ (Property: "auto-hyperlink")</p> |
|
58a48e3…
|
drh
|
447 |
@ |
|
df337eb…
|
drh
|
448 |
@ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds |
|
df337eb…
|
drh
|
449 |
@ and "require a mouse event" should be turned on. These values only come |
|
df337eb…
|
drh
|
450 |
@ into play when the main auto-hyperlink settings is 2 ("UserAgent and |
|
58a48e3…
|
drh
|
451 |
@ Javascript"). |
|
58a48e3…
|
drh
|
452 |
@ (Properties: "auto-hyperlink-delay" and "auto-hyperlink-mouseover")</p> |
|
df337eb…
|
drh
|
453 |
@ |
|
df337eb…
|
drh
|
454 |
@ <p>To see if Javascript-base hyperlink enabling mechanism is working, |
|
58a48e3…
|
drh
|
455 |
@ visit the <a href="%R/test-env">/test-env</a> page from a separate |
|
58a48e3…
|
drh
|
456 |
@ web browser that is not logged in, even as "anonymous" and verify |
|
df337eb…
|
drh
|
457 |
@ that the "g.jsHref" value is "1".</p> |
|
df337eb…
|
drh
|
458 |
} |
|
df337eb…
|
drh
|
459 |
|
|
df337eb…
|
drh
|
460 |
/* |
|
df337eb…
|
drh
|
461 |
** WEBPAGE: setup_robot |
|
df337eb…
|
drh
|
462 |
** |
|
df337eb…
|
drh
|
463 |
** Settings associated with defense against robots. Requires setup privilege. |
|
df337eb…
|
drh
|
464 |
*/ |
|
df337eb…
|
drh
|
465 |
void setup_robots(void){ |
|
df337eb…
|
drh
|
466 |
login_check_credentials(); |
|
df337eb…
|
drh
|
467 |
if( !g.perm.Setup ){ |
|
df337eb…
|
drh
|
468 |
login_needed(0); |
|
df337eb…
|
drh
|
469 |
return; |
|
df337eb…
|
drh
|
470 |
} |
|
df337eb…
|
drh
|
471 |
style_set_current_feature("setup"); |
|
df337eb…
|
drh
|
472 |
style_header("Robot Defense Settings"); |
|
df337eb…
|
drh
|
473 |
db_begin_transaction(); |
|
df337eb…
|
drh
|
474 |
@ <p>A Fossil website can have billions of pages in its tree, even for a |
|
df337eb…
|
drh
|
475 |
@ modest project. Many of those pages (examples: diffs and tarballs) |
|
df337eb…
|
drh
|
476 |
@ might be expensive to compute. A robot that tries to walk the entire |
|
df337eb…
|
drh
|
477 |
@ website can present a crippling CPU and bandwidth load. |
|
df337eb…
|
drh
|
478 |
@ |
|
4d198d0…
|
drh
|
479 |
@ <p>The settings on this page are intended to help administrators |
|
4d198d0…
|
drh
|
480 |
@ defend against abusive robots. |
|
df337eb…
|
drh
|
481 |
@ |
|
df337eb…
|
drh
|
482 |
@ <form action="%R/setup_robot" method="post"><div> |
|
df337eb…
|
drh
|
483 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
484 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
485 |
@ <hr> |
|
86b6ef7…
|
drh
|
486 |
@ <p><b>Do not allow robots access to these pages.</b><br> |
|
86b6ef7…
|
drh
|
487 |
@ If the page name matches the GLOB pattern of this setting, and the |
|
16b3309…
|
drh
|
488 |
@ users is "nobody", and the client has not previously passed a captcha |
|
16b3309…
|
drh
|
489 |
@ test to show that it is not a robot, then the page is not displayed. |
|
33d3bf3…
|
km
|
490 |
@ A captcha test is rendered instead. |
|
4d198d0…
|
drh
|
491 |
@ The default value for this setting is: |
|
16b3309…
|
drh
|
492 |
@ <p> |
|
16b3309…
|
drh
|
493 |
@    <tt>%h(robot_restrict_default())</tt> |
|
16b3309…
|
drh
|
494 |
@ <p> |
|
4231598…
|
drh
|
495 |
@ Usually the tag should exactly match the page name. Exceptions: |
|
4231598…
|
drh
|
496 |
@ <ul> |
|
4231598…
|
drh
|
497 |
@ <li> The "diff" tag covers all diffing pages such as /vdiff, |
|
4231598…
|
drh
|
498 |
@ /fdiff, and /vpatch. |
|
4231598…
|
drh
|
499 |
@ <li> The "annotate" tag covers /annotate and also /blame and |
|
4231598…
|
drh
|
500 |
@ /praise. |
|
4231598…
|
drh
|
501 |
@ <li> The "zip" covers itself and also /tarball and /sqlar. |
|
4231598…
|
drh
|
502 |
@ <li> If a tag has an "X" character appended (ex: "timelineX") |
|
4231598…
|
drh
|
503 |
@ then it only applies if query parameters are such that |
|
4231598…
|
drh
|
504 |
@ the page is expensive and/or unusual. |
|
4231598…
|
drh
|
505 |
@ <li> The "ext" tag covers all extensions, but a tag like |
|
4231598…
|
drh
|
506 |
@ "ext/PATH" only covers the specific extension at PATH. |
|
4231598…
|
drh
|
507 |
@ </ul> |
|
db69c47…
|
drh
|
508 |
@ To disable robot restrictions, change this setting to "off". |
|
4231598…
|
drh
|
509 |
@ (Property: <a href="%R/help/robot-restrict">robot-restrict</a>) |
|
16b3309…
|
drh
|
510 |
@ <br> |
|
16b3309…
|
drh
|
511 |
textarea_attribute("", 2, 80, |
|
16b3309…
|
drh
|
512 |
"robot-restrict", "rbrestrict", robot_restrict_default(), 0); |
|
16b3309…
|
drh
|
513 |
|
|
4d198d0…
|
drh
|
514 |
@ <p><b>Exception #1</b><br> |
|
4d198d0…
|
drh
|
515 |
@ If "zipX" appears in the robot-restrict list above, then tarballs, |
|
4d198d0…
|
drh
|
516 |
@ ZIP-archives, and SQL-archives may be downloaded by robots if |
|
4d198d0…
|
drh
|
517 |
@ the check-in is a leaf (robot-zip-leaf):<br> |
|
4d198d0…
|
drh
|
518 |
onoff_attribute("Allow tarballs for leaf check-ins", |
|
4d198d0…
|
drh
|
519 |
"robot-zip-leaf", "rzleaf", 0, 0); |
|
4d198d0…
|
drh
|
520 |
|
|
4d198d0…
|
drh
|
521 |
@ <p><b>Exception #2</b><br> |
|
4d198d0…
|
drh
|
522 |
@ If "zipX" appears in the robot-restrict list above, then tarballs, |
|
4d198d0…
|
drh
|
523 |
@ ZIP-archives, and SQL-archives may be downloaded by robots if |
|
4d198d0…
|
drh
|
524 |
@ the check-in has one or more tags that match the following |
|
4d198d0…
|
drh
|
525 |
@ list of GLOB patterns: (robot-zip-tag)<br> |
|
4d198d0…
|
drh
|
526 |
textarea_attribute("", 2, 80, |
|
4d198d0…
|
drh
|
527 |
"robot-zip-tag", "rztag", "", 0); |
|
4d198d0…
|
drh
|
528 |
|
|
4d198d0…
|
drh
|
529 |
@ <p><b>Exception #3</b><br> |
|
4d198d0…
|
drh
|
530 |
@ If the request URI matches any of the following |
|
4d198d0…
|
drh
|
531 |
@ <a href="%R/re_rules">regular expressions</a> (one per line), then the |
|
4d198d0…
|
drh
|
532 |
@ request is exempt from anti-robot defenses. |
|
4d198d0…
|
drh
|
533 |
@ The regular expression is matched against the REQUEST_URI with the |
|
86b6ef7…
|
drh
|
534 |
@ SCRIPT_NAME prefix removed, and with QUERY_STRING appended following |
|
86b6ef7…
|
drh
|
535 |
@ a "?" if QUERY_STRING exists. (Property: robot-exception)<br> |
|
86b6ef7…
|
drh
|
536 |
textarea_attribute("", 3, 80, |
|
86b6ef7…
|
drh
|
537 |
"robot-exception", "rbexcept", "", 0); |
|
de66eea…
|
drh
|
538 |
@ <hr> |
|
df337eb…
|
drh
|
539 |
addAutoHyperlinkSettings(); |
|
7d2b47a…
|
drh
|
540 |
|
|
7d2b47a…
|
drh
|
541 |
@ <hr> |
|
7d2b47a…
|
drh
|
542 |
entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan", |
|
7d2b47a…
|
drh
|
543 |
"anoncookls", "840", 0); |
|
7d2b47a…
|
drh
|
544 |
@ <p>The number of minutes for which an anonymous login cookie is valid. |
|
7d2b47a…
|
drh
|
545 |
@ Set to zero to disable anonymous login. |
|
7d2b47a…
|
drh
|
546 |
@ (property: anon-cookie-lifespan) |
|
a72e9e1…
|
drh
|
547 |
|
|
a72e9e1…
|
drh
|
548 |
@ <hr> |
|
a72e9e1…
|
drh
|
549 |
entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg", |
|
a72e9e1…
|
drh
|
550 |
"0.0", 0); |
|
a72e9e1…
|
drh
|
551 |
@ <p>Some expensive operations (such as computing tarballs, zip archives, |
|
a72e9e1…
|
drh
|
552 |
@ or annotation/blame pages) are prohibited if the load average on the host |
|
a72e9e1…
|
drh
|
553 |
@ computer is too large. Set the threshold for disallowing expensive |
|
a72e9e1…
|
drh
|
554 |
@ computations here. Set this to 0.0 to disable the load average limit. |
|
a72e9e1…
|
drh
|
555 |
@ This limit is only enforced on Unix servers. On Linux systems, |
|
a72e9e1…
|
drh
|
556 |
@ access to the /proc virtual filesystem is required, which means this limit |
|
a72e9e1…
|
drh
|
557 |
@ might not work inside a chroot() jail. |
|
a72e9e1…
|
drh
|
558 |
@ (Property: "max-loadavg")</p> |
|
16b3309…
|
drh
|
559 |
@ |
|
f5482a0…
|
wyoung
|
560 |
@ <hr> |
|
f5482a0…
|
wyoung
|
561 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
df337eb…
|
drh
|
562 |
@ </div></form> |
|
df337eb…
|
drh
|
563 |
db_end_transaction(0); |
|
df337eb…
|
drh
|
564 |
style_finish_page(); |
|
df337eb…
|
drh
|
565 |
} |
|
3587e45…
|
drh
|
566 |
|
|
3587e45…
|
drh
|
567 |
/* |
|
3587e45…
|
drh
|
568 |
** WEBPAGE: setup_access |
|
7ab0328…
|
drh
|
569 |
** |
|
7d034d3…
|
wyoung
|
570 |
** The access-control settings page. Requires Setup privileges. |
|
3587e45…
|
drh
|
571 |
*/ |
|
3587e45…
|
drh
|
572 |
void setup_access(void){ |
|
70a94d0…
|
jan.nijtmans
|
573 |
static const char *const azRedirectOpts[] = { |
|
4aba9ea…
|
drh
|
574 |
"0", "Off", |
|
4aba9ea…
|
drh
|
575 |
"1", "Login Page Only", |
|
4aba9ea…
|
drh
|
576 |
"2", "All Pages" |
|
4aba9ea…
|
drh
|
577 |
}; |
|
3587e45…
|
drh
|
578 |
login_check_credentials(); |
|
3587e45…
|
drh
|
579 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
580 |
login_needed(0); |
|
653dd40…
|
drh
|
581 |
return; |
|
3587e45…
|
drh
|
582 |
} |
|
3587e45…
|
drh
|
583 |
|
|
112c713…
|
drh
|
584 |
style_set_current_feature("setup"); |
|
3587e45…
|
drh
|
585 |
style_header("Access Control Settings"); |
|
e1962ef…
|
drh
|
586 |
db_begin_transaction(); |
|
a40e8a0…
|
drh
|
587 |
@ <form action="%R/setup_access" method="post"><div> |
|
3587e45…
|
drh
|
588 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
589 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
590 |
@ <hr> |
|
4aba9ea…
|
drh
|
591 |
multiple_choice_attribute("Redirect to HTTPS", |
|
4aba9ea…
|
drh
|
592 |
"redirect-to-https", "redirhttps", "0", |
|
4aba9ea…
|
drh
|
593 |
count(azRedirectOpts)/2, azRedirectOpts); |
|
70a94d0…
|
jan.nijtmans
|
594 |
@ <p>Force the use of HTTPS by redirecting to HTTPS when an |
|
4aba9ea…
|
drh
|
595 |
@ unencrypted request is received. This feature can be enabled |
|
4aba9ea…
|
drh
|
596 |
@ for the Login page only, or for all pages. |
|
4aba9ea…
|
drh
|
597 |
@ <p>Further details: When enabled, this option causes the $secureurl TH1 |
|
a4e7b86…
|
drh
|
598 |
@ variable is set to an "https:" variant of $baseurl. Otherwise, |
|
4aba9ea…
|
drh
|
599 |
@ $secureurl is just an alias for $baseurl. |
|
4aba9ea…
|
drh
|
600 |
@ (Property: "redirect-to-https". "0" for off, "1" for Login page only, |
|
4aba9ea…
|
drh
|
601 |
@ "2" otherwise.) |
|
f5482a0…
|
wyoung
|
602 |
@ <hr> |
|
3587e45…
|
drh
|
603 |
onoff_attribute("Require password for local access", |
|
3587e45…
|
drh
|
604 |
"localauth", "localauth", 0, 0); |
|
3587e45…
|
drh
|
605 |
@ <p>When enabled, the password sign-in is always required for |
|
3587e45…
|
drh
|
606 |
@ web access. When disabled, unrestricted web access from 127.0.0.1 |
|
1fee037…
|
drh
|
607 |
@ is allowed for the <a href="%R/help/ui">fossil ui</a> command or |
|
1fee037…
|
drh
|
608 |
@ from the <a href="%R/help/server">fossil server</a>, |
|
1fee037…
|
drh
|
609 |
@ <a href="%R/help/http">fossil http</a> commands when the |
|
3587e45…
|
drh
|
610 |
@ "--localauth" command line options is used, or from the |
|
1fee037…
|
drh
|
611 |
@ <a href="%R/help/cgi">fossil cgi</a> if a line containing |
|
f7a3c6d…
|
drh
|
612 |
@ the word "localauth" appears in the CGI script. |
|
f7a3c6d…
|
drh
|
613 |
@ |
|
f7a3c6d…
|
drh
|
614 |
@ <p>A password is always required if any one or more |
|
f7a3c6d…
|
drh
|
615 |
@ of the following are true: |
|
f7a3c6d…
|
drh
|
616 |
@ <ol> |
|
f7a3c6d…
|
drh
|
617 |
@ <li> This button is checked |
|
f7a3c6d…
|
drh
|
618 |
@ <li> The inbound TCP/IP connection is not from 127.0.0.1 |
|
f7a3c6d…
|
drh
|
619 |
@ <li> The server is started using either of the |
|
1fee037…
|
drh
|
620 |
@ <a href="%R/help/server">fossil server</a> or |
|
1fee037…
|
drh
|
621 |
@ <a href="%R/help/server">fossil http</a> commands |
|
f7a3c6d…
|
drh
|
622 |
@ without the "--localauth" option. |
|
f7a3c6d…
|
drh
|
623 |
@ <li> The server is started from CGI without the "localauth" keyword |
|
f7a3c6d…
|
drh
|
624 |
@ in the CGI script. |
|
f7a3c6d…
|
drh
|
625 |
@ </ol> |
|
3ca935e…
|
drh
|
626 |
@ (Property: "localauth") |
|
4d32db8…
|
drh
|
627 |
@ |
|
f5482a0…
|
wyoung
|
628 |
@ <hr> |
|
caf286d…
|
drh
|
629 |
onoff_attribute("Enable /test-env", |
|
10d8abc…
|
jan.nijtmans
|
630 |
"test_env_enable", "test_env_enable", 0, 0); |
|
4d32db8…
|
drh
|
631 |
@ <p>When enabled, the %h(g.zBaseURL)/test_env URL is available to all |
|
4d32db8…
|
drh
|
632 |
@ users. When disabled (the default) only users Admin and Setup can visit |
|
4d32db8…
|
drh
|
633 |
@ the /test_env page. |
|
3ca935e…
|
drh
|
634 |
@ (Property: "test_env_enable") |
|
3ca935e…
|
drh
|
635 |
@ </p> |
|
3ca935e…
|
drh
|
636 |
@ |
|
f5482a0…
|
wyoung
|
637 |
@ <hr> |
|
86619b9…
|
drh
|
638 |
onoff_attribute("Enable /artifact_stats", |
|
86619b9…
|
drh
|
639 |
"artifact_stats_enable", "artifact_stats_enable", 0, 0); |
|
86619b9…
|
drh
|
640 |
@ <p>When enabled, the %h(g.zBaseURL)/artifact_stats URL is available to all |
|
86619b9…
|
drh
|
641 |
@ users. When disabled (the default) only users with check-in privilege may |
|
86619b9…
|
drh
|
642 |
@ access the /artifact_stats page. |
|
86619b9…
|
drh
|
643 |
@ (Property: "artifact_stats_enable") |
|
86619b9…
|
drh
|
644 |
@ </p> |
|
86619b9…
|
drh
|
645 |
@ |
|
f5482a0…
|
wyoung
|
646 |
@ <hr> |
|
6454153…
|
drh
|
647 |
onoff_attribute("Allow REMOTE_USER authentication", |
|
10d8abc…
|
jan.nijtmans
|
648 |
"remote_user_ok", "remote_user_ok", 0, 0); |
|
6454153…
|
drh
|
649 |
@ <p>When enabled, if the REMOTE_USER environment variable is set to the |
|
6454153…
|
drh
|
650 |
@ login name of a valid user and no other login credentials are available, |
|
6454153…
|
drh
|
651 |
@ then the REMOTE_USER is accepted as an authenticated user. |
|
3ca935e…
|
drh
|
652 |
@ (Property: "remote_user_ok") |
|
313ba5c…
|
drh
|
653 |
@ </p> |
|
313ba5c…
|
drh
|
654 |
@ |
|
f5482a0…
|
wyoung
|
655 |
@ <hr> |
|
315cf24…
|
drh
|
656 |
onoff_attribute("Allow HTTP_AUTHENTICATION authentication", |
|
315cf24…
|
drh
|
657 |
"http_authentication_ok", "http_authentication_ok", 0, 0); |
|
315cf24…
|
drh
|
658 |
@ <p>When enabled, allow the use of the HTTP_AUTHENTICATION environment |
|
315cf24…
|
drh
|
659 |
@ variable or the "Authentication:" HTTP header to find the username and |
|
7dd07b2…
|
drh
|
660 |
@ password. This is another way of supporting Basic Authentication. |
|
3ca935e…
|
drh
|
661 |
@ (Property: "http_authentication_ok") |
|
3243e63…
|
drh
|
662 |
@ </p> |
|
4d32db8…
|
drh
|
663 |
@ |
|
f5482a0…
|
wyoung
|
664 |
@ <hr> |
|
10d8abc…
|
jan.nijtmans
|
665 |
entry_attribute("Login expiration time", 6, "cookie-expire", "cex", |
|
10d8abc…
|
jan.nijtmans
|
666 |
"8766", 0); |
|
dbda8d6…
|
drh
|
667 |
@ <p>The number of hours for which a login is valid. This must be a |
|
97f68e6…
|
mistachkin
|
668 |
@ positive number. The default is 8766 hours which is approximately equal |
|
3ca935e…
|
drh
|
669 |
@ to a year. |
|
3ca935e…
|
drh
|
670 |
@ (Property: "cookie-expire")</p> |
|
dbdc160…
|
aku
|
671 |
|
|
f5482a0…
|
wyoung
|
672 |
@ <hr> |
|
dbdc160…
|
aku
|
673 |
entry_attribute("Download packet limit", 10, "max-download", "mxdwn", |
|
10d8abc…
|
jan.nijtmans
|
674 |
"5000000", 0); |
|
dbdc160…
|
aku
|
675 |
@ <p>Fossil tries to limit out-bound sync, clone, and pull packets |
|
dbdc160…
|
aku
|
676 |
@ to this many bytes, uncompressed. If the client requires more data |
|
dbdc160…
|
aku
|
677 |
@ than this, then the client will issue multiple HTTP requests. |
|
6454153…
|
drh
|
678 |
@ Values below 1 million are not recommended. 5 million is a |
|
3ca935e…
|
drh
|
679 |
@ reasonable number. (Property: "max-download")</p> |
|
769c90a…
|
drh
|
680 |
|
|
f5482a0…
|
wyoung
|
681 |
@ <hr> |
|
769c90a…
|
drh
|
682 |
entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt", |
|
10d8abc…
|
jan.nijtmans
|
683 |
"30", 0); |
|
769c90a…
|
drh
|
684 |
|
|
769c90a…
|
drh
|
685 |
@ <p>Fossil tries to spend less than this many seconds gathering |
|
769c90a…
|
drh
|
686 |
@ the out-bound data of sync, clone, and pull packets. |
|
769c90a…
|
drh
|
687 |
@ If the client request takes longer, a partial reply is given similar |
|
3ca935e…
|
drh
|
688 |
@ to the download packet limit. 30s is a reasonable default. |
|
3ca935e…
|
drh
|
689 |
@ (Property: "max-download-time")</p> |
|
5e26a1b…
|
drh
|
690 |
|
|
e5c0543…
|
drh
|
691 |
@ <a id="slal"></a> |
|
f5482a0…
|
wyoung
|
692 |
@ <hr> |
|
5e26a1b…
|
drh
|
693 |
entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg", |
|
5e26a1b…
|
drh
|
694 |
"0.0", 0); |
|
5e26a1b…
|
drh
|
695 |
@ <p>Some expensive operations (such as computing tarballs, zip archives, |
|
5e26a1b…
|
drh
|
696 |
@ or annotation/blame pages) are prohibited if the load average on the host |
|
5e26a1b…
|
drh
|
697 |
@ computer is too large. Set the threshold for disallowing expensive |
|
5e26a1b…
|
drh
|
698 |
@ computations here. Set this to 0.0 to disable the load average limit. |
|
5e26a1b…
|
drh
|
699 |
@ This limit is only enforced on Unix servers. On Linux systems, |
|
5e26a1b…
|
drh
|
700 |
@ access to the /proc virtual filesystem is required, which means this limit |
|
3ca935e…
|
drh
|
701 |
@ might not work inside a chroot() jail. |
|
3ca935e…
|
drh
|
702 |
@ (Property: "max-loadavg")</p> |
|
3ca935e…
|
drh
|
703 |
|
|
df337eb…
|
drh
|
704 |
/* Add the auto-hyperlink settings controls. These same controls |
|
df337eb…
|
drh
|
705 |
** are also accessible from the /setup_robot page. |
|
df337eb…
|
drh
|
706 |
*/ |
|
f5482a0…
|
wyoung
|
707 |
@ <hr> |
|
df337eb…
|
drh
|
708 |
addAutoHyperlinkSettings(); |
|
df337eb…
|
drh
|
709 |
|
|
f5482a0…
|
wyoung
|
710 |
@ <hr> |
|
82b8587…
|
drh
|
711 |
onoff_attribute("Require a CAPTCHA if not logged in", |
|
10d8abc…
|
jan.nijtmans
|
712 |
"require-captcha", "reqcapt", 1, 0); |
|
82b8587…
|
drh
|
713 |
@ <p>Require a CAPTCHA for edit operations (appending, creating, or |
|
82b8587…
|
drh
|
714 |
@ editing wiki or tickets or adding attachments to wiki or tickets) |
|
3ca935e…
|
drh
|
715 |
@ for users who are not logged in. (Property: "require-captcha")</p> |
|
82b8587…
|
drh
|
716 |
|
|
f5482a0…
|
wyoung
|
717 |
@ <hr> |
|
79ef961…
|
drh
|
718 |
entry_attribute("Public pages", 30, "public-pages", |
|
10d8abc…
|
jan.nijtmans
|
719 |
"pubpage", "", 0); |
|
79ef961…
|
drh
|
720 |
@ <p>A comma-separated list of glob patterns for pages that are accessible |
|
79ef961…
|
drh
|
721 |
@ without needing a login and using the privileges given by the |
|
275da70…
|
danield
|
722 |
@ "Default privileges" setting below. |
|
0c37445…
|
drh
|
723 |
@ |
|
0c37445…
|
drh
|
724 |
@ <p>Example use case: Set this field to "/doc/trunk/www/*" and set |
|
0c37445…
|
drh
|
725 |
@ the "Default privileges" to include the "o" privilege |
|
0c37445…
|
drh
|
726 |
@ to give anonymous users read-only permission to the |
|
79ef961…
|
drh
|
727 |
@ latest version of the embedded documentation in the www/ folder without |
|
79ef961…
|
drh
|
728 |
@ allowing them to see the rest of the source code. |
|
3ca935e…
|
drh
|
729 |
@ (Property: "public-pages") |
|
98cc520…
|
drh
|
730 |
@ </p> |
|
9039a6a…
|
drh
|
731 |
|
|
f5482a0…
|
wyoung
|
732 |
@ <hr> |
|
9039a6a…
|
drh
|
733 |
onoff_attribute("Allow users to register themselves", |
|
c00e912…
|
drh
|
734 |
"self-register", "selfreg", 0, 0); |
|
c00e912…
|
drh
|
735 |
@ <p>Allow users to register themselves on the /register webpage. |
|
c00e912…
|
drh
|
736 |
@ A self-registration creates a new entry in the USER table and |
|
c00e912…
|
drh
|
737 |
@ perhaps also in the SUBSCRIBER table if email notification is |
|
c00e912…
|
drh
|
738 |
@ enabled. |
|
c00e912…
|
drh
|
739 |
@ (Property: "self-register")</p> |
|
c00e912…
|
drh
|
740 |
|
|
f5482a0…
|
wyoung
|
741 |
@ <hr> |
|
07bfe3f…
|
drh
|
742 |
onoff_attribute("Allow users to reset their own passwords", |
|
07bfe3f…
|
drh
|
743 |
"self-pw-reset", "selfpw", 0, 0); |
|
07bfe3f…
|
drh
|
744 |
@ <p>Allow users to request that an email contains a hyperlink to a |
|
07bfe3f…
|
drh
|
745 |
@ password reset page be sent to their email address of record. This |
|
07bfe3f…
|
drh
|
746 |
@ enables forgetful users to recover their forgotten passwords without |
|
07bfe3f…
|
drh
|
747 |
@ administrator intervention. |
|
07bfe3f…
|
drh
|
748 |
@ (Property: "self-pw-reset")</p> |
|
07bfe3f…
|
drh
|
749 |
|
|
f5482a0…
|
wyoung
|
750 |
@ <hr> |
|
c00e912…
|
drh
|
751 |
onoff_attribute("Email verification required for self-registration", |
|
c00e912…
|
drh
|
752 |
"selfreg-verify", "sfverify", 0, 0); |
|
c00e912…
|
drh
|
753 |
@ <p>If enabled, self-registration creates a new entry in the USER table |
|
c00e912…
|
drh
|
754 |
@ with only capabilities "7". The default user capabilities are not |
|
c00e912…
|
drh
|
755 |
@ added until the email address associated with the self-registration |
|
c00e912…
|
drh
|
756 |
@ has been verified. This setting only makes sense if |
|
c00e912…
|
drh
|
757 |
@ email notifications are enabled. |
|
c00e912…
|
drh
|
758 |
@ (Property: "selfreg-verify")</p> |
|
c00e912…
|
drh
|
759 |
|
|
f5482a0…
|
wyoung
|
760 |
@ <hr> |
|
c00e912…
|
drh
|
761 |
onoff_attribute("Allow anonymous subscriptions", |
|
c00e912…
|
drh
|
762 |
"anon-subscribe", "anonsub", 1, 0); |
|
c00e912…
|
drh
|
763 |
@ <p>If disabled, email notification subscriptions are only allowed |
|
c00e912…
|
drh
|
764 |
@ for users with a login. If Nobody or Anonymous visit the /subscribe |
|
c00e912…
|
drh
|
765 |
@ page, they are redirected to /register or /login. |
|
c00e912…
|
drh
|
766 |
@ (Property: "anon-subscribe")</p> |
|
c00e912…
|
drh
|
767 |
|
|
f5482a0…
|
wyoung
|
768 |
@ <hr> |
|
c00e912…
|
drh
|
769 |
entry_attribute("Authorized subscription email addresses", 35, |
|
c00e912…
|
drh
|
770 |
"auth-sub-email", "asemail", "", 0); |
|
c00e912…
|
drh
|
771 |
@ <p>This is a comma-separated list of GLOB patterns that specify |
|
c00e912…
|
drh
|
772 |
@ email addresses that are authorized to subscriptions. If blank |
|
c00e912…
|
drh
|
773 |
@ (the usual case), then any email address can be used to self-register. |
|
c00e912…
|
drh
|
774 |
@ This setting is used to limit subscriptions to members of a particular |
|
c00e912…
|
drh
|
775 |
@ organization or group based on their email address. |
|
c00e912…
|
drh
|
776 |
@ (Property: "auth-sub-email")</p> |
|
c00e912…
|
drh
|
777 |
|
|
f5482a0…
|
wyoung
|
778 |
@ <hr> |
|
a257fde…
|
drh
|
779 |
entry_attribute("Default privileges", 10, "default-perms", |
|
10d8abc…
|
jan.nijtmans
|
780 |
"defaultperms", "u", 0); |
|
79ef961…
|
drh
|
781 |
@ <p>Permissions given to users that... <ul><li>register themselves using |
|
79ef961…
|
drh
|
782 |
@ the self-registration procedure (if enabled), or <li>access "public" |
|
79ef961…
|
drh
|
783 |
@ pages identified by the public-pages glob pattern above, or <li> |
|
79ef961…
|
drh
|
784 |
@ are users newly created by the administrator.</ul> |
|
99fcc43…
|
drh
|
785 |
@ <p>Recommended value: "u" for Reader. |
|
99fcc43…
|
drh
|
786 |
@ <a href="%R/setup_ucap_list">Capability Key</a>. |
|
3ca935e…
|
drh
|
787 |
@ (Property: "default-perms") |
|
9039a6a…
|
drh
|
788 |
@ </p> |
|
6454153…
|
drh
|
789 |
|
|
f5482a0…
|
wyoung
|
790 |
@ <hr> |
|
6454153…
|
drh
|
791 |
onoff_attribute("Show javascript button to fill in CAPTCHA", |
|
10d8abc…
|
jan.nijtmans
|
792 |
"auto-captcha", "autocaptcha", 0, 0); |
|
6454153…
|
drh
|
793 |
@ <p>When enabled, a button appears on the login screen for user |
|
6454153…
|
drh
|
794 |
@ "anonymous" that will automatically fill in the CAPTCHA password. |
|
13920cd…
|
drh
|
795 |
@ This is less secure than forcing the user to do it manually, but is |
|
6454153…
|
drh
|
796 |
@ probably secure enough and it is certainly more convenient for |
|
3ca935e…
|
drh
|
797 |
@ anonymous users. (Property: "auto-captcha")</p> |
|
caf286d…
|
drh
|
798 |
|
|
caf286d…
|
drh
|
799 |
@ <hr> |
|
7d2b47a…
|
drh
|
800 |
entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan", |
|
7d2b47a…
|
drh
|
801 |
"anoncookls", "840", 0); |
|
7d2b47a…
|
drh
|
802 |
@ <p>The number of minutes for which an anonymous login cookie is valid. |
|
7d2b47a…
|
drh
|
803 |
@ Set to zero to disable anonymous logins. |
|
7d2b47a…
|
drh
|
804 |
@ (property: anon-cookie-lifespan) |
|
7d2b47a…
|
drh
|
805 |
|
|
7d2b47a…
|
drh
|
806 |
@ <hr> |
|
f5482a0…
|
wyoung
|
807 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
3243e63…
|
drh
|
808 |
@ </div></form> |
|
d0305b3…
|
aku
|
809 |
db_end_transaction(0); |
|
112c713…
|
drh
|
810 |
style_finish_page(); |
|
a257fde…
|
drh
|
811 |
} |
|
a257fde…
|
drh
|
812 |
|
|
a257fde…
|
drh
|
813 |
/* |
|
a257fde…
|
drh
|
814 |
** WEBPAGE: setup_login_group |
|
7ab0328…
|
drh
|
815 |
** |
|
7ab0328…
|
drh
|
816 |
** Change how the current repository participates in a login |
|
7ab0328…
|
drh
|
817 |
** group. |
|
a257fde…
|
drh
|
818 |
*/ |
|
a257fde…
|
drh
|
819 |
void setup_login_group(void){ |
|
a257fde…
|
drh
|
820 |
const char *zGroup; |
|
a257fde…
|
drh
|
821 |
char *zErrMsg = 0; |
|
4420efd…
|
drh
|
822 |
Stmt q; |
|
a257fde…
|
drh
|
823 |
Blob fullName; |
|
a257fde…
|
drh
|
824 |
char *zSelfRepo; |
|
a257fde…
|
drh
|
825 |
const char *zRepo = PD("repo", ""); |
|
a257fde…
|
drh
|
826 |
const char *zLogin = PD("login", ""); |
|
a257fde…
|
drh
|
827 |
const char *zPw = PD("pw", ""); |
|
a257fde…
|
drh
|
828 |
const char *zNewName = PD("newname", "New Login Group"); |
|
a257fde…
|
drh
|
829 |
|
|
a257fde…
|
drh
|
830 |
login_check_credentials(); |
|
b344d3c…
|
drh
|
831 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
832 |
login_needed(0); |
|
653dd40…
|
drh
|
833 |
return; |
|
a257fde…
|
drh
|
834 |
} |
|
135ed93…
|
drh
|
835 |
file_canonical_name(g.zRepositoryName, &fullName, 0); |
|
49b0ff1…
|
drh
|
836 |
zSelfRepo = fossil_strdup(blob_str(&fullName)); |
|
a257fde…
|
drh
|
837 |
blob_reset(&fullName); |
|
a257fde…
|
drh
|
838 |
if( P("join")!=0 ){ |
|
c3ba504…
|
drh
|
839 |
login_group_join(zRepo, 1, zLogin, zPw, zNewName, &zErrMsg); |
|
a257fde…
|
drh
|
840 |
}else if( P("leave") ){ |
|
a257fde…
|
drh
|
841 |
login_group_leave(&zErrMsg); |
|
acfaf4e…
|
drh
|
842 |
}else if( P("rotate") ){ |
|
acfaf4e…
|
drh
|
843 |
captcha_secret_rotate(); |
|
a257fde…
|
drh
|
844 |
} |
|
112c713…
|
drh
|
845 |
style_set_current_feature("setup"); |
|
a257fde…
|
drh
|
846 |
style_header("Login Group Configuration"); |
|
a257fde…
|
drh
|
847 |
if( zErrMsg ){ |
|
a257fde…
|
drh
|
848 |
@ <p class="generalError">%s(zErrMsg)</p> |
|
a257fde…
|
drh
|
849 |
} |
|
a257fde…
|
drh
|
850 |
zGroup = login_group_name(); |
|
a257fde…
|
drh
|
851 |
if( zGroup==0 ){ |
|
a257fde…
|
drh
|
852 |
@ <p>This repository (in the file named "%h(zSelfRepo)") |
|
a257fde…
|
drh
|
853 |
@ is not currently part of any login-group. |
|
a257fde…
|
drh
|
854 |
@ To join a login group, fill out the form below.</p> |
|
a257fde…
|
drh
|
855 |
@ |
|
a40e8a0…
|
drh
|
856 |
@ <form action="%R/setup_login_group" method="post"><div> |
|
a257fde…
|
drh
|
857 |
login_insert_csrf_secret(); |
|
7a8938a…
|
drh
|
858 |
@ <blockquote><table border="0"> |
|
7a8938a…
|
drh
|
859 |
@ |
|
7dd07b2…
|
drh
|
860 |
@ <tr><th align="right" id="rfigtj">Repository filename \ |
|
7dd07b2…
|
drh
|
861 |
@ in group to join:</th> |
|
7dd07b2…
|
drh
|
862 |
@ <td width="5"></td><td> |
|
7dd07b2…
|
drh
|
863 |
@ <input aria-labelledby="rfigtj" type="text" size="50" \ |
|
7dd07b2…
|
drh
|
864 |
@ value="%h(zRepo)" name="repo"></td></tr> |
|
7dd07b2…
|
drh
|
865 |
@ |
|
7dd07b2…
|
drh
|
866 |
@ <tr><th align="right" id="lotar">Login on the above repo:</th> |
|
7dd07b2…
|
drh
|
867 |
@ <td width="5"></td><td> |
|
7dd07b2…
|
drh
|
868 |
@ <input aria-labelledby="lotar" type="text" size="20" \ |
|
7dd07b2…
|
drh
|
869 |
@ value="%h(zLogin)" name="login"></td></tr> |
|
7dd07b2…
|
drh
|
870 |
@ |
|
7dd07b2…
|
drh
|
871 |
@ <tr><th align="right" id="lgpw">Password:</th> |
|
7dd07b2…
|
drh
|
872 |
@ <td width="5"></td><td> |
|
7dd07b2…
|
drh
|
873 |
@ <input aria-labelledby="lgpw" type="password" size="20" name="pw">\ |
|
7dd07b2…
|
drh
|
874 |
@ </td></tr> |
|
7dd07b2…
|
drh
|
875 |
@ |
|
7dd07b2…
|
drh
|
876 |
@ <tr><th align="right" id="nolg">Name of login-group:</th> |
|
7dd07b2…
|
drh
|
877 |
@ <td width="5"></td><td> |
|
7dd07b2…
|
drh
|
878 |
@ <input aria-labelledby="nolg" type="text" size="30" \ |
|
7dd07b2…
|
drh
|
879 |
@ value="%h(zNewName)" name="newname"> |
|
a257fde…
|
drh
|
880 |
@ (only used if creating a new login-group).</td></tr> |
|
a257fde…
|
drh
|
881 |
@ |
|
a257fde…
|
drh
|
882 |
@ <tr><td colspan="3" align="center"> |
|
a257fde…
|
drh
|
883 |
@ <input type="submit" value="Join" name="join"></td></tr> |
|
7a8938a…
|
drh
|
884 |
@ </table></blockquote></div></form> |
|
a257fde…
|
drh
|
885 |
}else{ |
|
a257fde…
|
drh
|
886 |
int n = 0; |
|
a257fde…
|
drh
|
887 |
@ <p>This repository (in the file "%h(zSelfRepo)") |
|
a257fde…
|
drh
|
888 |
@ is currently part of the "<b>%h(zGroup)</b>" login group. |
|
a257fde…
|
drh
|
889 |
@ Other repositories in that group are:</p> |
|
a257fde…
|
drh
|
890 |
@ <table border="0" cellspacing="4"> |
|
a257fde…
|
drh
|
891 |
@ <tr><td colspan="2"><th align="left">Project Name<td> |
|
a257fde…
|
drh
|
892 |
@ <th align="left">Repository File</tr> |
|
a257fde…
|
drh
|
893 |
db_prepare(&q, |
|
a257fde…
|
drh
|
894 |
"SELECT value," |
|
a257fde…
|
drh
|
895 |
" (SELECT value FROM config" |
|
a257fde…
|
drh
|
896 |
" WHERE name=('peer-name-' || substr(x.name,11)))" |
|
a257fde…
|
drh
|
897 |
" FROM config AS x" |
|
a257fde…
|
drh
|
898 |
" WHERE name GLOB 'peer-repo-*'" |
|
a257fde…
|
drh
|
899 |
" ORDER BY value" |
|
a257fde…
|
drh
|
900 |
); |
|
a257fde…
|
drh
|
901 |
while( db_step(&q)==SQLITE_ROW ){ |
|
a257fde…
|
drh
|
902 |
const char *zRepo = db_column_text(&q, 0); |
|
a257fde…
|
drh
|
903 |
const char *zTitle = db_column_text(&q, 1); |
|
a257fde…
|
drh
|
904 |
n++; |
|
a257fde…
|
drh
|
905 |
@ <tr><td align="right">%d(n).</td><td width="4"> |
|
a257fde…
|
drh
|
906 |
@ <td>%h(zTitle)<td width="10"><td>%h(zRepo)</tr> |
|
a257fde…
|
drh
|
907 |
} |
|
a257fde…
|
drh
|
908 |
db_finalize(&q); |
|
a257fde…
|
drh
|
909 |
@ </table> |
|
a257fde…
|
drh
|
910 |
@ |
|
a40e8a0…
|
drh
|
911 |
@ <p><form action="%R/setup_login_group" method="post"><div> |
|
a257fde…
|
drh
|
912 |
login_insert_csrf_secret(); |
|
acfaf4e…
|
drh
|
913 |
@ <p>To leave this login group press: |
|
a257fde…
|
drh
|
914 |
@ <input type="submit" value="Leave Login Group" name="leave"> |
|
404f155…
|
drh
|
915 |
@ <p>Setting a common captcha-secret on all repositories in the login-group |
|
404f155…
|
drh
|
916 |
@ allows anonymous logins for one repository in the login group to be used |
|
404f155…
|
drh
|
917 |
@ by all other repositories of the group within the same domain. Warning: |
|
404f155…
|
drh
|
918 |
@ If a captcha dialog was painted before setting the common captcha-secret |
|
404f155…
|
drh
|
919 |
@ and the "Speak password for 'anonymous'" button is pressed afterwards, |
|
404f155…
|
drh
|
920 |
@ the spoken text will be incorrect. |
|
404f155…
|
drh
|
921 |
@ <input type="submit" name="rotate" value="Set common captcha-secret"> |
|
a257fde…
|
drh
|
922 |
@ </form></p> |
|
4420efd…
|
drh
|
923 |
} |
|
4420efd…
|
drh
|
924 |
@ <hr><h2>Implementation Details</h2> |
|
4420efd…
|
drh
|
925 |
@ <p>The following are fields from the CONFIG table related to login-groups. |
|
4420efd…
|
drh
|
926 |
@ </p> |
|
4420efd…
|
drh
|
927 |
@ <table border='1' cellspacing="0" cellpadding="4"\ |
|
4420efd…
|
drh
|
928 |
@ class='sortable' data-column-types='ttt' data-init-sort='1'> |
|
4420efd…
|
drh
|
929 |
@ <thead><tr> |
|
4420efd…
|
drh
|
930 |
@ <th>Config.Name<th>Config.Value<th>Config.mtime</tr> |
|
4420efd…
|
drh
|
931 |
@ </thead><tbody> |
|
4420efd…
|
drh
|
932 |
db_prepare(&q, "SELECT name, value, datetime(mtime,'unixepoch') FROM config" |
|
4420efd…
|
drh
|
933 |
" WHERE name GLOB 'peer-*'" |
|
4420efd…
|
drh
|
934 |
" OR name GLOB 'project-*'" |
|
4420efd…
|
drh
|
935 |
" OR name GLOB 'login-group-*'" |
|
4420efd…
|
drh
|
936 |
" ORDER BY name"); |
|
4420efd…
|
drh
|
937 |
while( db_step(&q)==SQLITE_ROW ){ |
|
4420efd…
|
drh
|
938 |
@ <tr><td>%h(db_column_text(&q,0))</td> |
|
4420efd…
|
drh
|
939 |
@ <td>%h(db_column_text(&q,1))</td> |
|
4420efd…
|
drh
|
940 |
@ <td>%h(db_column_text(&q,2))</td></tr> |
|
4420efd…
|
drh
|
941 |
} |
|
4420efd…
|
drh
|
942 |
db_finalize(&q); |
|
4420efd…
|
drh
|
943 |
@ </tbody></table> |
|
5bb4cee…
|
drh
|
944 |
@ <h2>Interpretation</h2> |
|
5bb4cee…
|
drh
|
945 |
@ <ul> |
|
5bb4cee…
|
drh
|
946 |
@ <li><p><b>login-group-code</b> → |
|
5bb4cee…
|
drh
|
947 |
@ A random code assigned to each login-group. The login-group-code is |
|
5bb4cee…
|
drh
|
948 |
@ a unique identifier for the login-group. |
|
5bb4cee…
|
drh
|
949 |
@ |
|
5bb4cee…
|
drh
|
950 |
@ <li><p><b>login-group-name</b> → |
|
5bb4cee…
|
drh
|
951 |
@ The human-readable name of the login-group. |
|
5bb4cee…
|
drh
|
952 |
@ |
|
5bb4cee…
|
drh
|
953 |
@ <li><p><b>project-code</b> → |
|
5bb4cee…
|
drh
|
954 |
@ A random code assigned to each project. The project-code is |
|
5bb4cee…
|
drh
|
955 |
@ a unique identifier for the project. Multiple repositories can share |
|
5bb4cee…
|
drh
|
956 |
@ the same project-code. When two or more repositories have the same |
|
5bb4cee…
|
drh
|
957 |
@ project code, that mean those repositories are clones of each other. |
|
5bb4cee…
|
drh
|
958 |
@ Repositories are only able to sync if they share the same project-code. |
|
5bb4cee…
|
drh
|
959 |
@ |
|
5bb4cee…
|
drh
|
960 |
@ <li><p><b>project-description</b> → |
|
5bb4cee…
|
drh
|
961 |
@ A description of project in this repository. This is a verbose form |
|
5bb4cee…
|
drh
|
962 |
@ of project-name. This description can be edited in the second entry |
|
5bb4cee…
|
drh
|
963 |
@ box on the <a href="./setup_config">Setup/Configuration page</a>. |
|
5bb4cee…
|
drh
|
964 |
@ |
|
5bb4cee…
|
drh
|
965 |
@ <li><p><b>project-name</b> → |
|
5bb4cee…
|
drh
|
966 |
@ The human-readable name for the project. The project-name can be |
|
25f43cc…
|
stephan
|
967 |
@ modified in the first entry on the |
|
5bb4cee…
|
drh
|
968 |
@ <a href="./setup_config">Setup/Configuration page</a>. |
|
5bb4cee…
|
drh
|
969 |
@ |
|
5bb4cee…
|
drh
|
970 |
@ <li><p><b>peer-repo-<i>CODE</i></b> → |
|
5bb4cee…
|
drh
|
971 |
@ <i>CODE</i> is 16-character prefix of the project-code for another |
|
5bb4cee…
|
drh
|
972 |
@ repository that is part of the same login-group. The value is the |
|
5bb4cee…
|
drh
|
973 |
@ filename for the peer repository. |
|
5bb4cee…
|
drh
|
974 |
@ |
|
5bb4cee…
|
drh
|
975 |
@ <li><p><b>peer-name-<i>CODE</i></b> → |
|
5bb4cee…
|
drh
|
976 |
@ <i>CODE</i> is 16-character prefix of the project-code for another |
|
5bb4cee…
|
drh
|
977 |
@ repository that is part of the same login-group. The value is |
|
5bb4cee…
|
drh
|
978 |
@ project-name value for the other repository. |
|
5bb4cee…
|
drh
|
979 |
@ </ul> |
|
4420efd…
|
drh
|
980 |
style_table_sorter(); |
|
112c713…
|
drh
|
981 |
style_finish_page(); |
|
d0305b3…
|
aku
|
982 |
} |
|
d0305b3…
|
aku
|
983 |
|
|
d0305b3…
|
aku
|
984 |
/* |
|
d0305b3…
|
aku
|
985 |
** WEBPAGE: setup_timeline |
|
7ab0328…
|
drh
|
986 |
** |
|
7ab0328…
|
drh
|
987 |
** Edit administrative settings controlling the display of |
|
7ab0328…
|
drh
|
988 |
** timelines. |
|
c7c81df…
|
drh
|
989 |
*/ |
|
c7c81df…
|
drh
|
990 |
void setup_timeline(void){ |
|
41c3c19…
|
drh
|
991 |
double tmDiff; |
|
41c3c19…
|
drh
|
992 |
char zTmDiff[20]; |
|
214899a…
|
jan.nijtmans
|
993 |
static const char *const azTimeFormats[] = { |
|
403d937…
|
drh
|
994 |
"0", "HH:MM", |
|
403d937…
|
drh
|
995 |
"1", "HH:MM:SS", |
|
feef2d1…
|
stephan
|
996 |
"2", "YYYY-MM-DD HH:MM", |
|
e5176d9…
|
drh
|
997 |
"3", "YYMMDD HH:MM", |
|
e5176d9…
|
drh
|
998 |
"4", "(off)" |
|
e5176d9…
|
drh
|
999 |
}; |
|
6ce705b…
|
drh
|
1000 |
static const char *const azLeafMark[] = { |
|
6ce705b…
|
drh
|
1001 |
"0", "No", |
|
6ce705b…
|
drh
|
1002 |
"1", "Yes", |
|
6ce705b…
|
drh
|
1003 |
"2", "Yes - with emphasis", |
|
6ce705b…
|
drh
|
1004 |
}; |
|
c7c81df…
|
drh
|
1005 |
login_check_credentials(); |
|
cd8c5df…
|
wyoung
|
1006 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
1007 |
login_needed(0); |
|
653dd40…
|
drh
|
1008 |
return; |
|
c7c81df…
|
drh
|
1009 |
} |
|
c7c81df…
|
drh
|
1010 |
|
|
112c713…
|
drh
|
1011 |
style_set_current_feature("setup"); |
|
c7c81df…
|
drh
|
1012 |
style_header("Timeline Display Preferences"); |
|
e1962ef…
|
drh
|
1013 |
db_begin_transaction(); |
|
a40e8a0…
|
drh
|
1014 |
@ <form action="%R/setup_timeline" method="post"><div> |
|
0be5482…
|
drh
|
1015 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1016 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
1017 |
|
|
f5482a0…
|
wyoung
|
1018 |
@ <hr> |
|
90e928d…
|
drh
|
1019 |
onoff_attribute("Plaintext comments on timelines", |
|
10d8abc…
|
jan.nijtmans
|
1020 |
"timeline-plaintext", "tpt", 0, 0); |
|
90e928d…
|
drh
|
1021 |
@ <p>In timeline displays, check-in comments are displayed literally, |
|
3ca935e…
|
drh
|
1022 |
@ without any wiki or HTML interpretation. Use CSS to change |
|
3ca935e…
|
drh
|
1023 |
@ display formatting features such as fonts and line-wrapping behavior. |
|
3ca935e…
|
drh
|
1024 |
@ (Property: "timeline-plaintext")</p> |
|
9610121…
|
drh
|
1025 |
|
|
f5482a0…
|
wyoung
|
1026 |
@ <hr> |
|
8af0255…
|
drh
|
1027 |
onoff_attribute("Truncate comment at first blank line (Git-style)", |
|
9610121…
|
drh
|
1028 |
"timeline-truncate-at-blank", "ttb", 0, 0); |
|
9610121…
|
drh
|
1029 |
@ <p>In timeline displays, check-in comments are displayed only through |
|
8af0255…
|
drh
|
1030 |
@ the first blank line. This is the traditional way to display comments |
|
8af0255…
|
drh
|
1031 |
@ in Git repositories (Property: "timeline-truncate-at-blank")</p> |
|
8af0255…
|
drh
|
1032 |
|
|
f5482a0…
|
wyoung
|
1033 |
@ <hr> |
|
8af0255…
|
drh
|
1034 |
onoff_attribute("Break comments at newline characters", |
|
8af0255…
|
drh
|
1035 |
"timeline-hard-newlines", "thnl", 0, 0); |
|
8af0255…
|
drh
|
1036 |
@ <p>In timeline displays, newline characters in check-in comments force |
|
8af0255…
|
drh
|
1037 |
@ a line break on the display. |
|
8af0255…
|
drh
|
1038 |
@ (Property: "timeline-hard-newlines")</p> |
|
620e1e0…
|
drh
|
1039 |
|
|
620e1e0…
|
drh
|
1040 |
@ <hr> |
|
620e1e0…
|
drh
|
1041 |
onoff_attribute("Do not adjust user-selected background colors", |
|
620e1e0…
|
drh
|
1042 |
"raw-bgcolor", "rbgc", 0, 0); |
|
620e1e0…
|
drh
|
1043 |
@ <p>Fossil normally attempts to adjust the saturation and intensity of |
|
620e1e0…
|
drh
|
1044 |
@ user-specified background colors on check-ins and branches so that the |
|
620e1e0…
|
drh
|
1045 |
@ foreground text is easily readable on all skins. Enable this setting |
|
620e1e0…
|
drh
|
1046 |
@ to omit that adjustment and use exactly the background color specified |
|
620e1e0…
|
drh
|
1047 |
@ by users. |
|
620e1e0…
|
drh
|
1048 |
@ (Property: "raw-bgcolor")</p> |
|
f5482a0…
|
wyoung
|
1049 |
|
|
f5482a0…
|
wyoung
|
1050 |
@ <hr> |
|
d23b8ba…
|
drh
|
1051 |
onoff_attribute("Use Universal Coordinated Time (UTC)", |
|
10d8abc…
|
jan.nijtmans
|
1052 |
"timeline-utc", "utc", 1, 0); |
|
d23b8ba…
|
drh
|
1053 |
@ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or |
|
41c3c19…
|
drh
|
1054 |
@ Zulu) instead of in local time. On this server, local time is currently |
|
41c3c19…
|
drh
|
1055 |
tmDiff = db_double(0.0, "SELECT julianday('now')"); |
|
3ba9a4d…
|
jan.nijtmans
|
1056 |
tmDiff = db_double(0.0, |
|
41c3c19…
|
drh
|
1057 |
"SELECT (julianday(%.17g,'localtime')-julianday(%.17g))*24.0", |
|
41c3c19…
|
drh
|
1058 |
tmDiff, tmDiff); |
|
41c3c19…
|
drh
|
1059 |
sqlite3_snprintf(sizeof(zTmDiff), zTmDiff, "%.1f", tmDiff); |
|
41c3c19…
|
drh
|
1060 |
if( strcmp(zTmDiff, "0.0")==0 ){ |
|
41c3c19…
|
drh
|
1061 |
@ the same as UTC and so this setting will make no difference in |
|
41c3c19…
|
drh
|
1062 |
@ the display.</p> |
|
41c3c19…
|
drh
|
1063 |
}else if( tmDiff<0.0 ){ |
|
41c3c19…
|
drh
|
1064 |
sqlite3_snprintf(sizeof(zTmDiff), zTmDiff, "%.1f", -tmDiff); |
|
41c3c19…
|
drh
|
1065 |
@ %s(zTmDiff) hours behind UTC.</p> |
|
41c3c19…
|
drh
|
1066 |
}else{ |
|
41c3c19…
|
drh
|
1067 |
@ %s(zTmDiff) hours ahead of UTC.</p> |
|
41c3c19…
|
drh
|
1068 |
} |
|
3ca935e…
|
drh
|
1069 |
@ <p>(Property: "timeline-utc") |
|
895eac4…
|
drh
|
1070 |
|
|
f5482a0…
|
wyoung
|
1071 |
@ <hr> |
|
895eac4…
|
drh
|
1072 |
multiple_choice_attribute("Style", "timeline-default-style", |
|
895eac4…
|
drh
|
1073 |
"tdss", "0", N_TIMELINE_VIEW_STYLE, timeline_view_styles); |
|
895eac4…
|
drh
|
1074 |
@ <p>The default timeline viewing style, for when the user has not |
|
895eac4…
|
drh
|
1075 |
@ specified an alternative. (Property: "timeline-default-style")</p> |
|
895eac4…
|
drh
|
1076 |
|
|
f5482a0…
|
wyoung
|
1077 |
@ <hr> |
|
8efc4d5…
|
drh
|
1078 |
entry_attribute("Default Number Of Rows", 6, "timeline-default-length", |
|
8efc4d5…
|
drh
|
1079 |
"tldl", "50", 0); |
|
8efc4d5…
|
drh
|
1080 |
@ <p>The maximum number of rows to show on a timeline in the absence |
|
8efc4d5…
|
drh
|
1081 |
@ of a user display preference cookie setting or an explicit n= query |
|
8efc4d5…
|
drh
|
1082 |
@ parameter. (Property: "timeline-default-length")</p> |
|
8efc4d5…
|
drh
|
1083 |
|
|
f5482a0…
|
wyoung
|
1084 |
@ <hr> |
|
e5176d9…
|
drh
|
1085 |
multiple_choice_attribute("Per-Item Time Format", "timeline-date-format", |
|
3cb9ba4…
|
andygoth
|
1086 |
"tdf", "0", count(azTimeFormats)/2, azTimeFormats); |
|
403d937…
|
drh
|
1087 |
@ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown |
|
7001228…
|
drh
|
1088 |
@ in a separate box (using CSS class "timelineDate") whenever the date |
|
7001228…
|
drh
|
1089 |
@ changes. With the "YYYY-MM-DD HH:MM" and "YYMMDD ..." formats, |
|
7001228…
|
drh
|
1090 |
@ the complete date and time is shown on every timeline entry using the |
|
ccf50f0…
|
drh
|
1091 |
@ CSS class "timelineTime". (Property: "timeline-date-format")</p> |
|
6ce705b…
|
drh
|
1092 |
|
|
6ce705b…
|
drh
|
1093 |
@ <hr> |
|
6ce705b…
|
drh
|
1094 |
multiple_choice_attribute("Leaf Markings", "timeline-mark-leaves", |
|
6ce705b…
|
drh
|
1095 |
"tml", "1", count(azLeafMark)/2, azLeafMark); |
|
6ce705b…
|
drh
|
1096 |
@ <p>Should timeline entries for leaf check-ins be identified in the |
|
6ce705b…
|
drh
|
1097 |
@ detail section. (Property: "timeline-mark-leaves")</p> |
|
f5482a0…
|
wyoung
|
1098 |
|
|
f5482a0…
|
wyoung
|
1099 |
@ <hr> |
|
6454153…
|
drh
|
1100 |
entry_attribute("Max timeline comment length", 6, |
|
10d8abc…
|
jan.nijtmans
|
1101 |
"timeline-max-comment", "tmc", "0", 0); |
|
c7c81df…
|
drh
|
1102 |
@ <p>The maximum length of a comment to be displayed in a timeline. |
|
3ca935e…
|
drh
|
1103 |
@ "0" there is no length limit. |
|
3ca935e…
|
drh
|
1104 |
@ (Property: "timeline-max-comment")</p> |
|
3ca935e…
|
drh
|
1105 |
|
|
f5482a0…
|
wyoung
|
1106 |
@ <hr> |
|
6908832…
|
drh
|
1107 |
entry_attribute("Tooltip dwell time (milliseconds)", 6, |
|
6908832…
|
drh
|
1108 |
"timeline-dwelltime", "tdt", "100", 0); |
|
6908832…
|
drh
|
1109 |
@ <br> |
|
6908832…
|
drh
|
1110 |
entry_attribute("Tooltip close time (milliseconds)", 6, |
|
6908832…
|
drh
|
1111 |
"timeline-closetime", "tct", "250", 0); |
|
6908832…
|
drh
|
1112 |
@ <p>The <strong>dwell time</strong> defines how long the mouse pointer |
|
6908832…
|
drh
|
1113 |
@ should be stationary above an object of the graph before a tooltip |
|
6908832…
|
drh
|
1114 |
@ appears.<br> |
|
6908832…
|
drh
|
1115 |
@ The <strong>close time</strong> defines how long the mouse pointer |
|
6908832…
|
drh
|
1116 |
@ can be away from an object before a tooltip is closed.</p> |
|
6908832…
|
drh
|
1117 |
@ <p>Set <strong>dwell time</strong> to "0" to disable tooltips.<br> |
|
6908832…
|
drh
|
1118 |
@ Set <strong>close time</strong> to "0" to keep tooltips visible until |
|
6908832…
|
drh
|
1119 |
@ the mouse is clicked elsewhere.<p> |
|
6908832…
|
drh
|
1120 |
@ <p>(Properties: "timeline-dwelltime", "timeline-closetime")</p> |
|
6908832…
|
drh
|
1121 |
|
|
f5482a0…
|
wyoung
|
1122 |
@ <hr> |
|
647424d…
|
drh
|
1123 |
onoff_attribute("Timestamp hyperlinks to /info", |
|
647424d…
|
drh
|
1124 |
"timeline-tslink-info", "ttlti", 0, 0); |
|
647424d…
|
drh
|
1125 |
@ <p>The hyperlink on the timestamp associated with each timeline entry, |
|
647424d…
|
drh
|
1126 |
@ on the far left-hand side of the screen, normally targets another |
|
647424d…
|
drh
|
1127 |
@ /timeline page that shows the entry in context. However, if this |
|
647424d…
|
drh
|
1128 |
@ option is turned on, that hyperlink targets the /info page showing |
|
647424d…
|
drh
|
1129 |
@ the details of the entry. |
|
647424d…
|
drh
|
1130 |
@ <p>The /timeline link is the default since it is often useful to |
|
647424d…
|
drh
|
1131 |
@ see an entry in context, and because that link is not otherwise |
|
647424d…
|
drh
|
1132 |
@ accessible on the timeline. The /info link is also accessible by |
|
647424d…
|
drh
|
1133 |
@ double-clicking the timeline node or by clicking on the hash that |
|
c8021e9…
|
stephan
|
1134 |
@ follows "check-in:" in the supplemental information section on the |
|
647424d…
|
drh
|
1135 |
@ right of the entry. |
|
647424d…
|
drh
|
1136 |
@ <p>(Properties: "timeline-tslink-info") |
|
647424d…
|
drh
|
1137 |
|
|
f5482a0…
|
wyoung
|
1138 |
@ <hr> |
|
f5482a0…
|
wyoung
|
1139 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
b48f789…
|
drh
|
1140 |
@ </div></form> |
|
b48f789…
|
drh
|
1141 |
db_end_transaction(0); |
|
112c713…
|
drh
|
1142 |
style_finish_page(); |
|
b48f789…
|
drh
|
1143 |
} |
|
b48f789…
|
drh
|
1144 |
|
|
b48f789…
|
drh
|
1145 |
/* |
|
b48f789…
|
drh
|
1146 |
** WEBPAGE: setup_settings |
|
7ab0328…
|
drh
|
1147 |
** |
|
26eef7f…
|
rberteig
|
1148 |
** Change or view miscellaneous settings. Part of the |
|
7d034d3…
|
wyoung
|
1149 |
** /setup pages requiring Setup privileges. |
|
b48f789…
|
drh
|
1150 |
*/ |
|
b48f789…
|
drh
|
1151 |
void setup_settings(void){ |
|
f74f701…
|
drh
|
1152 |
int nSetting; |
|
f74f701…
|
drh
|
1153 |
int i; |
|
32f8da0…
|
drh
|
1154 |
Setting const *pSet; |
|
74a5e10…
|
drh
|
1155 |
int bIfChng = P("all")==0; |
|
f74f701…
|
drh
|
1156 |
const Setting *aSetting = setting_info(&nSetting); |
|
b48f789…
|
drh
|
1157 |
|
|
b48f789…
|
drh
|
1158 |
login_check_credentials(); |
|
b344d3c…
|
drh
|
1159 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
1160 |
login_needed(0); |
|
653dd40…
|
drh
|
1161 |
return; |
|
b48f789…
|
drh
|
1162 |
} |
|
3243e63…
|
drh
|
1163 |
|
|
112c713…
|
drh
|
1164 |
style_set_current_feature("setup"); |
|
b48f789…
|
drh
|
1165 |
style_header("Settings"); |
|
0ab0079…
|
stephan
|
1166 |
if(!g.repositoryOpen){ |
|
0ab0079…
|
stephan
|
1167 |
/* Provide read-only access to versioned settings, |
|
0ab0079…
|
stephan
|
1168 |
but only if no repo file was explicitly provided. */ |
|
0ab0079…
|
stephan
|
1169 |
db_open_local(0); |
|
0ab0079…
|
stephan
|
1170 |
} |
|
e1962ef…
|
drh
|
1171 |
db_begin_transaction(); |
|
74a5e10…
|
drh
|
1172 |
if( bIfChng ){ |
|
74a5e10…
|
drh
|
1173 |
@ <p>Only settings whose value is different from the default are shown. |
|
74a5e10…
|
drh
|
1174 |
@ Click the "All" button above to set all settings. |
|
74a5e10…
|
drh
|
1175 |
} |
|
f74f701…
|
drh
|
1176 |
@ <p>Settings marked with (v) are "versionable" and will be overridden |
|
f74f701…
|
drh
|
1177 |
@ by the contents of managed files named |
|
f74f701…
|
drh
|
1178 |
@ "<tt>.fossil-settings/</tt><i>SETTING-NAME</i>". |
|
f74f701…
|
drh
|
1179 |
@ If the file for a versionable setting exists, the value cannot be |
|
f5482a0…
|
wyoung
|
1180 |
@ changed on this screen.</p><hr><p> |
|
f74f701…
|
drh
|
1181 |
@ |
|
a40e8a0…
|
drh
|
1182 |
@ <form action="%R/setup_settings" method="post"><div> |
|
74a5e10…
|
drh
|
1183 |
if( bIfChng ){ |
|
74a5e10…
|
drh
|
1184 |
style_submenu_element("All", "%R/setup_settings?all"); |
|
f60bd4a…
|
drh
|
1185 |
}else{ |
|
74a5e10…
|
drh
|
1186 |
@ <input type="hidden" name="all" value="1"> |
|
74a5e10…
|
drh
|
1187 |
style_submenu_element("Changes-Only", "%R/setup_settings"); |
|
f60bd4a…
|
drh
|
1188 |
} |
|
b48f789…
|
drh
|
1189 |
@ <table border="0"><tr><td valign="top"> |
|
b48f789…
|
drh
|
1190 |
login_insert_csrf_secret(); |
|
f74f701…
|
drh
|
1191 |
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ |
|
9b2d565…
|
mistachkin
|
1192 |
if( pSet->width==0 ){ |
|
9b2d565…
|
mistachkin
|
1193 |
int hasVersionableValue = pSet->versionable && |
|
dfc0f1b…
|
drh
|
1194 |
(db_get_versioned(pSet->name, NULL, NULL)!=0); |
|
bff93fc…
|
drh
|
1195 |
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){ |
|
bff93fc…
|
drh
|
1196 |
continue; |
|
3ba0763…
|
drh
|
1197 |
} |
|
45953a4…
|
stephan
|
1198 |
onoff_attribute("", pSet->name, |
|
0a5d0e1…
|
drh
|
1199 |
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/, |
|
45953a4…
|
stephan
|
1200 |
is_truth(pSet->def), hasVersionableValue); |
|
c64f28d…
|
drh
|
1201 |
@ <a href='%R/help/%s(pSet->name)'>%h(pSet->name)</a> |
|
45953a4…
|
stephan
|
1202 |
if( pSet->versionable ){ |
|
f5482a0…
|
wyoung
|
1203 |
@ (v)<br> |
|
45953a4…
|
stephan
|
1204 |
} else { |
|
f5482a0…
|
wyoung
|
1205 |
@ <br> |
|
45953a4…
|
stephan
|
1206 |
} |
|
45953a4…
|
stephan
|
1207 |
} |
|
45953a4…
|
stephan
|
1208 |
} |
|
f5482a0…
|
wyoung
|
1209 |
@ <br><input type="submit" name="submit" value="Apply Changes"> |
|
45953a4…
|
stephan
|
1210 |
@ </td><td style="width:50px;"></td><td valign="top"> |
|
c1ca100…
|
ashepilko
|
1211 |
@ <table> |
|
45953a4…
|
stephan
|
1212 |
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ |
|
45953a4…
|
stephan
|
1213 |
if( pSet->width>0 && !pSet->forceTextArea ){ |
|
45953a4…
|
stephan
|
1214 |
int hasVersionableValue = pSet->versionable && |
|
dfc0f1b…
|
drh
|
1215 |
(db_get_versioned(pSet->name, NULL, NULL)!=0); |
|
bff93fc…
|
drh
|
1216 |
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){ |
|
bff93fc…
|
drh
|
1217 |
continue; |
|
f60bd4a…
|
drh
|
1218 |
} |
|
c1ca100…
|
ashepilko
|
1219 |
@ <tr><td> |
|
c64f28d…
|
drh
|
1220 |
@ <a href='%R/help/%s(pSet->name)'>%h(pSet->name)</a> |
|
45953a4…
|
stephan
|
1221 |
if( pSet->versionable ){ |
|
c1ca100…
|
ashepilko
|
1222 |
@ (v) |
|
45953a4…
|
stephan
|
1223 |
} else { |
|
c1ca100…
|
ashepilko
|
1224 |
@ |
|
45953a4…
|
stephan
|
1225 |
} |
|
c1ca100…
|
ashepilko
|
1226 |
@</td><td> |
|
c1ca100…
|
ashepilko
|
1227 |
entry_attribute("", /*pSet->width*/ 25, pSet->name, |
|
0a5d0e1…
|
drh
|
1228 |
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/, |
|
c1ca100…
|
ashepilko
|
1229 |
(char*)pSet->def, hasVersionableValue); |
|
c1ca100…
|
ashepilko
|
1230 |
@</td></tr> |
|
45953a4…
|
stephan
|
1231 |
} |
|
45953a4…
|
stephan
|
1232 |
} |
|
c1ca100…
|
ashepilko
|
1233 |
@</table> |
|
45953a4…
|
stephan
|
1234 |
@ </td><td style="width:50px;"></td><td valign="top"> |
|
45953a4…
|
stephan
|
1235 |
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){ |
|
45953a4…
|
stephan
|
1236 |
if( pSet->width>0 && pSet->forceTextArea ){ |
|
dfc0f1b…
|
drh
|
1237 |
int hasVersionableValue = db_get_versioned(pSet->name, NULL, NULL)!=0; |
|
bff93fc…
|
drh
|
1238 |
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){ |
|
bff93fc…
|
drh
|
1239 |
continue; |
|
f60bd4a…
|
drh
|
1240 |
} |
|
c64f28d…
|
drh
|
1241 |
@ <a href='%R/help/%s(pSet->name)'>%s(pSet->name)</a> |
|
45953a4…
|
stephan
|
1242 |
if( pSet->versionable ){ |
|
f5482a0…
|
wyoung
|
1243 |
@ (v)<br> |
|
45953a4…
|
stephan
|
1244 |
} else { |
|
f5482a0…
|
wyoung
|
1245 |
@ <br> |
|
45953a4…
|
stephan
|
1246 |
} |
|
45953a4…
|
stephan
|
1247 |
textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name, |
|
0a5d0e1…
|
drh
|
1248 |
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/, |
|
45953a4…
|
stephan
|
1249 |
(char*)pSet->def, hasVersionableValue); |
|
f5482a0…
|
wyoung
|
1250 |
@<br> |
|
5a48a9b…
|
drh
|
1251 |
} |
|
5a48a9b…
|
drh
|
1252 |
} |
|
5a48a9b…
|
drh
|
1253 |
@ </td></tr></table> |
|
5a48a9b…
|
drh
|
1254 |
@ </div></form> |
|
5a48a9b…
|
drh
|
1255 |
db_end_transaction(0); |
|
112c713…
|
drh
|
1256 |
style_finish_page(); |
|
5a48a9b…
|
drh
|
1257 |
} |
|
aac9093…
|
drh
|
1258 |
|
|
aac9093…
|
drh
|
1259 |
/* |
|
1f6ae1e…
|
drh
|
1260 |
** SETTING: mainmenu width=70 block-text keep-empty |
|
aac9093…
|
drh
|
1261 |
** |
|
aac9093…
|
drh
|
1262 |
** The mainmenu setting specifies the entries on the main menu |
|
aac9093…
|
drh
|
1263 |
** for many skins. The mainmenu should be a TCL list. Each set |
|
aac9093…
|
drh
|
1264 |
** of four consecutive values defines a single main menu item: |
|
aac9093…
|
drh
|
1265 |
** |
|
aac9093…
|
drh
|
1266 |
** * The first term is text that appears on the menu. |
|
aac9093…
|
drh
|
1267 |
** |
|
aac9093…
|
drh
|
1268 |
** * The second term is a hyperlink to take when a user clicks on the |
|
aac9093…
|
drh
|
1269 |
** entry. Hyperlinks that start with "/" are relative to the |
|
aac9093…
|
drh
|
1270 |
** repository root. |
|
aac9093…
|
drh
|
1271 |
** |
|
aac9093…
|
drh
|
1272 |
** * The third term is an argument to the TH1 "capexpr" command. |
|
9993c43…
|
danshearer
|
1273 |
** If capexpr evaluates to true, then the entry is shown. If not, |
|
aac9093…
|
drh
|
1274 |
** the entry is omitted. "*" is always true. "{}" is never true. |
|
aac9093…
|
drh
|
1275 |
** |
|
2a88f7b…
|
stephan
|
1276 |
** * The fourth term is a list of extra class names to apply to the |
|
2a88f7b…
|
stephan
|
1277 |
** new menu entry. Some skins use classes "desktoponly" and |
|
2a88f7b…
|
stephan
|
1278 |
** "wideonly" to only show the entries when the web browser |
|
2a88f7b…
|
stephan
|
1279 |
** screen is wide or very wide, respectively. |
|
aac9093…
|
drh
|
1280 |
** |
|
aac9093…
|
drh
|
1281 |
** Some custom skins might not use this property. Whether the property |
|
aac9093…
|
drh
|
1282 |
** is used or not a choice made by the skin designer. Some skins may add |
|
aac9093…
|
drh
|
1283 |
** extra choices (such as the hamburger button) to the menu. |
|
aac9093…
|
drh
|
1284 |
*/ |
|
aac9093…
|
drh
|
1285 |
/* |
|
aac9093…
|
drh
|
1286 |
** SETTING: sitemap-extra width=70 block-text |
|
aac9093…
|
drh
|
1287 |
** |
|
aac9093…
|
drh
|
1288 |
** The sitemap-extra setting defines extra links to appear on the |
|
aac9093…
|
drh
|
1289 |
** /sitemap web page as sub-items of the "Home Page" entry before the |
|
aac9093…
|
drh
|
1290 |
** "Documentation Search" entry (if any). For skins that use the /sitemap |
|
aac9093…
|
drh
|
1291 |
** page to construct a hamburger menu dropdown, new entries added here |
|
aac9093…
|
drh
|
1292 |
** will appear on the hamburger menu. |
|
aac9093…
|
drh
|
1293 |
** |
|
aac9093…
|
drh
|
1294 |
** This setting should be a TCL list divided into triples. Each |
|
aac9093…
|
drh
|
1295 |
** triple defines a new entry: |
|
aac9093…
|
drh
|
1296 |
** |
|
aac9093…
|
drh
|
1297 |
** * The first term is the display name of the /sitemap entry |
|
aac9093…
|
drh
|
1298 |
** |
|
aac9093…
|
drh
|
1299 |
** * The second term is a hyperlink to take when a user clicks on the |
|
aac9093…
|
drh
|
1300 |
** entry. Hyperlinks that start with "/" are relative to the |
|
aac9093…
|
drh
|
1301 |
** repository root. |
|
aac9093…
|
drh
|
1302 |
** |
|
aac9093…
|
drh
|
1303 |
** * The third term is an argument to the TH1 "capexpr" command. |
|
9993c43…
|
danshearer
|
1304 |
** If capexpr evaluates to true, then the entry is shown. If not, |
|
aac9093…
|
drh
|
1305 |
** the entry is omitted. "*" is always true. |
|
aac9093…
|
drh
|
1306 |
** |
|
aac9093…
|
drh
|
1307 |
** The default value is blank, meaning no added entries. |
|
aac9093…
|
drh
|
1308 |
*/ |
|
aac9093…
|
drh
|
1309 |
|
|
c7c81df…
|
drh
|
1310 |
|
|
c7c81df…
|
drh
|
1311 |
/* |
|
c7c81df…
|
drh
|
1312 |
** WEBPAGE: setup_config |
|
7ab0328…
|
drh
|
1313 |
** |
|
7d034d3…
|
wyoung
|
1314 |
** The "Admin/Configuration" page. Requires Setup privilege. |
|
c7c81df…
|
drh
|
1315 |
*/ |
|
c7c81df…
|
drh
|
1316 |
void setup_config(void){ |
|
c7c81df…
|
drh
|
1317 |
login_check_credentials(); |
|
b344d3c…
|
drh
|
1318 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
1319 |
login_needed(0); |
|
653dd40…
|
drh
|
1320 |
return; |
|
c7c81df…
|
drh
|
1321 |
} |
|
c7c81df…
|
drh
|
1322 |
|
|
112c713…
|
drh
|
1323 |
style_set_current_feature("setup"); |
|
c7c81df…
|
drh
|
1324 |
style_header("WWW Configuration"); |
|
e1962ef…
|
drh
|
1325 |
db_begin_transaction(); |
|
a40e8a0…
|
drh
|
1326 |
@ <form action="%R/setup_config" method="post"><div> |
|
0be5482…
|
drh
|
1327 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1328 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
1329 |
@ <hr> |
|
10d8abc…
|
jan.nijtmans
|
1330 |
entry_attribute("Project Name", 60, "project-name", "pn", "", 0); |
|
3ca935e…
|
drh
|
1331 |
@ <p>A brief project name so visitors know what this site is about. |
|
49e112c…
|
drh
|
1332 |
@ The project name will also be used as the RSS feed title. |
|
3ca935e…
|
drh
|
1333 |
@ (Property: "project-name") |
|
fe76ad5…
|
drh
|
1334 |
@ </p> |
|
f5482a0…
|
wyoung
|
1335 |
@ <hr> |
|
65870e8…
|
drh
|
1336 |
textarea_attribute("Project Description", 3, 80, |
|
10d8abc…
|
jan.nijtmans
|
1337 |
"project-description", "pd", "", 0); |
|
c7c81df…
|
drh
|
1338 |
@ <p>Describe your project. This will be used in page headers for search |
|
2771bea…
|
jkosche
|
1339 |
@ engines, the repository listing and a short RSS description. |
|
3ca935e…
|
drh
|
1340 |
@ (Property: "project-description")</p> |
|
f5482a0…
|
wyoung
|
1341 |
@ <hr> |
|
7e993c7…
|
drh
|
1342 |
entry_attribute("Canonical Server URL", 40, "email-url", |
|
7e993c7…
|
drh
|
1343 |
"eurl", "", 0); |
|
6d5d5f0…
|
stephan
|
1344 |
@ <p>This is the URL used to access this repository as a server. |
|
7e993c7…
|
drh
|
1345 |
@ Other repositories use this URL to clone or sync against this repository. |
|
7e993c7…
|
drh
|
1346 |
@ This is also the basename for hyperlinks included in email alert text. |
|
7e993c7…
|
drh
|
1347 |
@ Omit the trailing "/". |
|
7e993c7…
|
drh
|
1348 |
@ If this repo will not be set up as a persistent server and will not |
|
7e993c7…
|
drh
|
1349 |
@ be sending email alerts, then leave this entry blank. |
|
7e993c7…
|
drh
|
1350 |
@ Suggested value: "%h(g.zBaseURL)" |
|
7e993c7…
|
drh
|
1351 |
@ (Property: "email-url")</p> |
|
7e993c7…
|
drh
|
1352 |
@ <hr> |
|
10d8abc…
|
jan.nijtmans
|
1353 |
entry_attribute("Index Page", 60, "index-page", "idxpg", "/home", 0); |
|
c7c81df…
|
drh
|
1354 |
@ <p>Enter the pathname of the page to display when the "Home" menu |
|
c7c81df…
|
drh
|
1355 |
@ option is selected and when no pathname is |
|
c7c81df…
|
drh
|
1356 |
@ specified in the URL. For example, if you visit the url:</p> |
|
c7c81df…
|
drh
|
1357 |
@ |
|
3243e63…
|
drh
|
1358 |
@ <blockquote><p>%h(g.zBaseURL)</p></blockquote> |
|
c7c81df…
|
drh
|
1359 |
@ |
|
c7c81df…
|
drh
|
1360 |
@ <p>And you have specified an index page of "/home" the above will |
|
c7c81df…
|
drh
|
1361 |
@ automatically redirect to:</p> |
|
c7c81df…
|
drh
|
1362 |
@ |
|
3243e63…
|
drh
|
1363 |
@ <blockquote><p>%h(g.zBaseURL)/home</p></blockquote> |
|
4348111…
|
drh
|
1364 |
@ |
|
4348111…
|
drh
|
1365 |
@ <p>The default "/home" page displays a Wiki page with the same name |
|
4348111…
|
drh
|
1366 |
@ as the Project Name specified above. Some sites prefer to redirect |
|
b32461f…
|
danshearer
|
1367 |
@ to a documentation page (ex: "/doc/trunk/index.wiki") or to "/timeline".</p> |
|
106c090…
|
drh
|
1368 |
@ |
|
106c090…
|
drh
|
1369 |
@ <p>Note: To avoid a redirect loop or other problems, this entry must |
|
106c090…
|
drh
|
1370 |
@ begin with "/" and it must specify a valid page. For example, |
|
106c090…
|
drh
|
1371 |
@ "<b>/home</b>" will work but "<b>home</b>" will not, since it omits the |
|
106c090…
|
drh
|
1372 |
@ leading "/".</p> |
|
3ca935e…
|
drh
|
1373 |
@ <p>(Property: "index-page") |
|
6898b3e…
|
drh
|
1374 |
@ <hr> |
|
5f22712…
|
drh
|
1375 |
@ <p>The main menu for the web interface |
|
5f22712…
|
drh
|
1376 |
@ <p> |
|
aac9093…
|
drh
|
1377 |
@ |
|
5f22712…
|
drh
|
1378 |
@ <p>This setting should be a TCL list. Each set of four consecutive |
|
5f22712…
|
drh
|
1379 |
@ values defines a single main menu item: |
|
5f22712…
|
drh
|
1380 |
@ <ol> |
|
5f22712…
|
drh
|
1381 |
@ <li> The first term is text that appears on the menu. |
|
5f22712…
|
drh
|
1382 |
@ <li> The second term is a hyperlink to take when a user clicks on the |
|
5f22712…
|
drh
|
1383 |
@ entry. Hyperlinks that start with "/" are relative to the |
|
5f22712…
|
drh
|
1384 |
@ repository root. |
|
5f22712…
|
drh
|
1385 |
@ <li> The third term is an argument to the TH1 "capexpr" command. |
|
9993c43…
|
danshearer
|
1386 |
@ If capexpr evaluates to true, then the entry is shown. If not, |
|
5f22712…
|
drh
|
1387 |
@ the entry is omitted. "*" is always true. "{}" is never true. |
|
f8c42ab…
|
stephan
|
1388 |
@ <li> The fourth term is a list of extra class names to apply to the new |
|
2a88f7b…
|
stephan
|
1389 |
@ menu entry. Some skins use classes "desktoponly" and "wideonly" |
|
5f22712…
|
drh
|
1390 |
@ to only show the entries when the web browser screen is wide or |
|
5f22712…
|
drh
|
1391 |
@ very wide, respectively. |
|
5f22712…
|
drh
|
1392 |
@ </ol> |
|
5f22712…
|
drh
|
1393 |
@ |
|
aac9093…
|
drh
|
1394 |
@ <p>Some custom skins might not use this property. Whether the property |
|
aac9093…
|
drh
|
1395 |
@ is used or not a choice made by the skin designer. Some skins may add extra |
|
5f22712…
|
drh
|
1396 |
@ choices (such as the hamburger button) to the menu that are not shown |
|
5f22712…
|
drh
|
1397 |
@ on this list. (Property: mainmenu) |
|
5f22712…
|
drh
|
1398 |
@ <p> |
|
8af3d42…
|
stephan
|
1399 |
if(P("resetMenu")!=0){ |
|
8af3d42…
|
stephan
|
1400 |
db_unset("mainmenu", 0); |
|
8af3d42…
|
stephan
|
1401 |
cgi_delete_parameter("mmenu"); |
|
8af3d42…
|
stephan
|
1402 |
} |
|
275da70…
|
danield
|
1403 |
textarea_attribute("Main Menu", 12, 80, |
|
5f22712…
|
drh
|
1404 |
"mainmenu", "mmenu", style_default_mainmenu(), 0); |
|
8af3d42…
|
stephan
|
1405 |
@ </p> |
|
8af3d42…
|
stephan
|
1406 |
@ <p><input type='checkbox' id='cbResetMenu' name='resetMenu' value='1'> |
|
8af3d42…
|
stephan
|
1407 |
@ <label for='cbResetMenu'>Reset menu to default value</label> |
|
8af3d42…
|
stephan
|
1408 |
@ </p> |
|
5f22712…
|
drh
|
1409 |
@ <hr> |
|
aa5beb8…
|
drh
|
1410 |
@ <p>Extra links to appear on the <a href="%R/sitemap">/sitemap</a> page, |
|
aa5beb8…
|
drh
|
1411 |
@ as sub-items of the "Home Page" entry, appearing before the |
|
aa5beb8…
|
drh
|
1412 |
@ "Documentation Search" entry (if any). In skins that use the /sitemap |
|
aa5beb8…
|
drh
|
1413 |
@ page to construct a hamburger menu dropdown, new entries added here |
|
aa5beb8…
|
drh
|
1414 |
@ will appear on the hamburger menu. |
|
aa5beb8…
|
drh
|
1415 |
@ |
|
aa5beb8…
|
drh
|
1416 |
@ <p>This setting should be a TCL list divided into triples. Each |
|
aa5beb8…
|
drh
|
1417 |
@ triple defines a new entry: |
|
aa5beb8…
|
drh
|
1418 |
@ <ol> |
|
aa5beb8…
|
drh
|
1419 |
@ <li> The first term is the display name of the /sitemap entry |
|
aa5beb8…
|
drh
|
1420 |
@ <li> The second term is a hyperlink to take when a user clicks on the |
|
aa5beb8…
|
drh
|
1421 |
@ entry. Hyperlinks that start with "/" are relative to the |
|
aa5beb8…
|
drh
|
1422 |
@ repository root. |
|
aa5beb8…
|
drh
|
1423 |
@ <li> The third term is an argument to the TH1 "capexpr" command. |
|
9993c43…
|
danshearer
|
1424 |
@ If capexpr evaluates to true, then the entry is shown. If not, |
|
aa5beb8…
|
drh
|
1425 |
@ the entry is omitted. "*" is always true. |
|
aa5beb8…
|
drh
|
1426 |
@ </ol> |
|
aa5beb8…
|
drh
|
1427 |
@ |
|
aa5beb8…
|
drh
|
1428 |
@ <p>The default value is blank, meaning no added entries. |
|
aa5beb8…
|
drh
|
1429 |
@ (Property: sitemap-extra) |
|
aa5beb8…
|
drh
|
1430 |
@ <p> |
|
275da70…
|
danield
|
1431 |
textarea_attribute("Custom Sitemap Entries", 8, 80, |
|
aa5beb8…
|
drh
|
1432 |
"sitemap-extra", "smextra", "", 0); |
|
9cc36d2…
|
drh
|
1433 |
@ <hr> |
|
6ce705b…
|
drh
|
1434 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
6ce705b…
|
drh
|
1435 |
@ </div></form> |
|
6ce705b…
|
drh
|
1436 |
db_end_transaction(0); |
|
6ce705b…
|
drh
|
1437 |
style_finish_page(); |
|
6ce705b…
|
drh
|
1438 |
} |
|
6ce705b…
|
drh
|
1439 |
|
|
6ce705b…
|
drh
|
1440 |
/* |
|
6ce705b…
|
drh
|
1441 |
** WEBPAGE: setup_download |
|
6ce705b…
|
drh
|
1442 |
** |
|
6ce705b…
|
drh
|
1443 |
** The "Admin/Download" page. Requires Setup privilege. |
|
6ce705b…
|
drh
|
1444 |
*/ |
|
6ce705b…
|
drh
|
1445 |
void setup_download(void){ |
|
6ce705b…
|
drh
|
1446 |
login_check_credentials(); |
|
6ce705b…
|
drh
|
1447 |
if( !g.perm.Setup ){ |
|
6ce705b…
|
drh
|
1448 |
login_needed(0); |
|
6ce705b…
|
drh
|
1449 |
return; |
|
6ce705b…
|
drh
|
1450 |
} |
|
6ce705b…
|
drh
|
1451 |
|
|
6ce705b…
|
drh
|
1452 |
style_set_current_feature("setup"); |
|
6ce705b…
|
drh
|
1453 |
style_header("Tarball and ZIP Downloads"); |
|
6ce705b…
|
drh
|
1454 |
db_begin_transaction(); |
|
6ce705b…
|
drh
|
1455 |
@ <form action="%R/setup_download" method="post"><div> |
|
6ce705b…
|
drh
|
1456 |
login_insert_csrf_secret(); |
|
6ce705b…
|
drh
|
1457 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
6ce705b…
|
drh
|
1458 |
@ <hr> |
|
6ce705b…
|
drh
|
1459 |
entry_attribute("Tarball and ZIP Name Prefix", 20, "short-project-name", |
|
6ce705b…
|
drh
|
1460 |
"spn", "", 0); |
|
6ce705b…
|
drh
|
1461 |
@ <p>This is used as a prefix for the names of generated tarballs and |
|
6ce705b…
|
drh
|
1462 |
@ ZIP archive. Keep this prefix brief and use only lower-case ASCII |
|
6ce705b…
|
drh
|
1463 |
@ characters, digits, "_", "-" in the name. If this setting is blank, |
|
6ce705b…
|
drh
|
1464 |
@ then the full <a href='%R/help/project-name'>project-name</a> setting |
|
6ce705b…
|
drh
|
1465 |
@ is used instead. |
|
6ce705b…
|
drh
|
1466 |
@ (Property: "short-project-name") |
|
6ce705b…
|
drh
|
1467 |
@ </p> |
|
6ce705b…
|
drh
|
1468 |
@ <hr> |
|
6ce705b…
|
drh
|
1469 |
@ <p><b>Configuration for the <a href="%R/download">/download</a> page.</b> |
|
6ce705b…
|
drh
|
1470 |
@ <p>The value is a TCL list divided into groups of four tokens: |
|
9cc36d2…
|
drh
|
1471 |
@ <ol> |
|
6ce705b…
|
drh
|
1472 |
@ <li> Maximum number of matches (COUNT). |
|
6ce705b…
|
drh
|
1473 |
@ <li> Tag to match using glob (TAG). |
|
6ce705b…
|
drh
|
1474 |
@ <li> Maximum age of check-ins to match (MAX_AGE). |
|
6ce705b…
|
drh
|
1475 |
@ <li> Comment to apply to matches (COMMENT). |
|
9cc36d2…
|
drh
|
1476 |
@ </ol> |
|
6ce705b…
|
drh
|
1477 |
@ Each 4-tuple will match zero or more check-ins. The /download page |
|
6ce705b…
|
drh
|
1478 |
@ displays the union of matches from all 4-tuples. |
|
6ce705b…
|
drh
|
1479 |
@ See the <a href="%R/help/suggested-downloads">suggested-downloads</a> |
|
6ce705b…
|
drh
|
1480 |
@ setting documentation for further detail. |
|
6ce705b…
|
drh
|
1481 |
@ <p> |
|
6ce705b…
|
drh
|
1482 |
@ The /download page is omitted from the <a href="%R/sitemap">/sitemap</a> |
|
6ce705b…
|
drh
|
1483 |
@ if the first token is "0" or "off" or "no". The default value |
|
6ce705b…
|
drh
|
1484 |
@ for this setting is "off". |
|
6ce705b…
|
drh
|
1485 |
@ (Property: <a href="%R/help/suggested-downloads">suggested-downloads</a>) |
|
6ce705b…
|
drh
|
1486 |
@ <p> |
|
6ce705b…
|
drh
|
1487 |
textarea_attribute("", 4, 80, |
|
6ce705b…
|
drh
|
1488 |
"suggested-downloads", "sgtrlst", "off", 0); |
|
25f43cc…
|
stephan
|
1489 |
@ <hr> |
|
25f43cc…
|
stephan
|
1490 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
25f43cc…
|
stephan
|
1491 |
@ </div></form> |
|
25f43cc…
|
stephan
|
1492 |
db_end_transaction(0); |
|
25f43cc…
|
stephan
|
1493 |
style_finish_page(); |
|
25f43cc…
|
stephan
|
1494 |
} |
|
25f43cc…
|
stephan
|
1495 |
|
|
25f43cc…
|
stephan
|
1496 |
/* |
|
bf09c3b…
|
drh
|
1497 |
** WEBPAGE: setup_wiki |
|
bf09c3b…
|
drh
|
1498 |
** |
|
bf09c3b…
|
drh
|
1499 |
** The "Admin/Wiki" page. Requires Setup privilege. |
|
bf09c3b…
|
drh
|
1500 |
*/ |
|
bf09c3b…
|
drh
|
1501 |
void setup_wiki(void){ |
|
bf09c3b…
|
drh
|
1502 |
login_check_credentials(); |
|
bf09c3b…
|
drh
|
1503 |
if( !g.perm.Setup ){ |
|
bf09c3b…
|
drh
|
1504 |
login_needed(0); |
|
bf09c3b…
|
drh
|
1505 |
return; |
|
bf09c3b…
|
drh
|
1506 |
} |
|
bf09c3b…
|
drh
|
1507 |
|
|
112c713…
|
drh
|
1508 |
style_set_current_feature("setup"); |
|
bf09c3b…
|
drh
|
1509 |
style_header("Wiki Configuration"); |
|
e1962ef…
|
drh
|
1510 |
db_begin_transaction(); |
|
a40e8a0…
|
drh
|
1511 |
@ <form action="%R/setup_wiki" method="post"><div> |
|
bf09c3b…
|
drh
|
1512 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1513 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
1514 |
@ <hr> |
|
25f43cc…
|
stephan
|
1515 |
onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins", |
|
5602385…
|
drh
|
1516 |
"wiki-about", "wiki-about", 1, 0); |
|
5602385…
|
drh
|
1517 |
@ <p> |
|
25f43cc…
|
stephan
|
1518 |
@ Associate wiki pages with branches, tags, tickets, or checkins, based on |
|
25f43cc…
|
stephan
|
1519 |
@ the wiki page name. Wiki pages that begin with "branch/", "checkin/", |
|
25f43cc…
|
stephan
|
1520 |
@ "tag/" or "ticket" and which continue with the name of an existing branch, |
|
25f43cc…
|
stephan
|
1521 |
@ check-in, tag or ticket are treated specially when this feature is enabled. |
|
5602385…
|
drh
|
1522 |
@ <ul> |
|
5602385…
|
drh
|
1523 |
@ <li> <b>branch/</b><i>branch-name</i> |
|
bc36fdc…
|
danield
|
1524 |
@ <li> <b>checkin/</b><i>full-check-in-hash</i> |
|
5602385…
|
drh
|
1525 |
@ <li> <b>tag/</b><i>tag-name</i> |
|
25f43cc…
|
stephan
|
1526 |
@ <li> <b>ticket/</b><i>full-ticket-hash</i> |
|
5602385…
|
drh
|
1527 |
@ </ul> |
|
5602385…
|
drh
|
1528 |
@ (Property: "wiki-about")</p> |
|
f5482a0…
|
wyoung
|
1529 |
@ <hr> |
|
89b6dda…
|
drh
|
1530 |
entry_attribute("Allow Unsafe HTML In Markdown", 6, |
|
89b6dda…
|
drh
|
1531 |
"safe-html", "safe-html", "", 0); |
|
89b6dda…
|
drh
|
1532 |
@ <p>Allow "unsafe" HTML (ex: <script>, <form>, etc) to be |
|
89b6dda…
|
drh
|
1533 |
@ generated by <a href="%R/md_rules">Markdown-formatted</a> documents. |
|
89b6dda…
|
drh
|
1534 |
@ This setting is a string where each character indicates a "type" of |
|
89b6dda…
|
drh
|
1535 |
@ document in which to allow unsafe HTML: |
|
89b6dda…
|
drh
|
1536 |
@ <ul> |
|
89b6dda…
|
drh
|
1537 |
@ <li> <b>b</b> → checked-in files, embedded documentation |
|
89b6dda…
|
drh
|
1538 |
@ <li> <b>f</b> → forum posts |
|
89b6dda…
|
drh
|
1539 |
@ <li> <b>t</b> → tickets |
|
89b6dda…
|
drh
|
1540 |
@ <li> <b>w</b> → wiki pages |
|
89b6dda…
|
drh
|
1541 |
@ </ul> |
|
89b6dda…
|
drh
|
1542 |
@ Include letters for each type of document for which unsafe HTML should |
|
89b6dda…
|
drh
|
1543 |
@ be allowed. For example, to allow unsafe HTML only for checked-in files, |
|
89b6dda…
|
drh
|
1544 |
@ make this setting be just "<b>b</b>". To allow unsafe HTML anywhere except |
|
89b6dda…
|
drh
|
1545 |
@ in forum posts, make this setting be "<b>btw</b>". The default is an |
|
89b6dda…
|
drh
|
1546 |
@ empty string which means that Fossil never allows Markdown documents |
|
89b6dda…
|
drh
|
1547 |
@ to generate unsafe HTML. |
|
89b6dda…
|
drh
|
1548 |
@ (Property: "safe-html")</p> |
|
f5482a0…
|
wyoung
|
1549 |
@ <hr> |
|
f4dc114…
|
drh
|
1550 |
@ The current interwiki tag map is as follows: |
|
f4dc114…
|
drh
|
1551 |
interwiki_append_map_table(cgi_output_blob()); |
|
f4dc114…
|
drh
|
1552 |
@ <p>Visit <a href="./intermap">%R/intermap</a> for details or to |
|
f4dc114…
|
drh
|
1553 |
@ modify the interwiki tag map. |
|
f5482a0…
|
wyoung
|
1554 |
@ <hr> |
|
106c090…
|
drh
|
1555 |
onoff_attribute("Use HTML as wiki markup language", |
|
106c090…
|
drh
|
1556 |
"wiki-use-html", "wiki-use-html", 0, 0); |
|
106c090…
|
drh
|
1557 |
@ <p>Use HTML as the wiki markup language. Wiki links will still be parsed |
|
19f2753…
|
stephan
|
1558 |
@ but all other wiki formatting will be ignored.</p> |
|
106c090…
|
drh
|
1559 |
@ <p><strong>CAUTION:</strong> when |
|
106c090…
|
drh
|
1560 |
@ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki. |
|
106c090…
|
drh
|
1561 |
@ No sanitization is done. This means that it is very possible for malicious |
|
106c090…
|
drh
|
1562 |
@ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p> |
|
106c090…
|
drh
|
1563 |
@ <p>This should <strong>only</strong> be enabled when wiki editing is limited |
|
4d1ac68…
|
drh
|
1564 |
@ to trusted users. It should <strong>not</strong> be used on a publicly |
|
106c090…
|
drh
|
1565 |
@ editable wiki.</p> |
|
3ca935e…
|
drh
|
1566 |
@ (Property: "wiki-use-html") |
|
f5482a0…
|
wyoung
|
1567 |
@ <hr> |
|
f5482a0…
|
wyoung
|
1568 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
15bc20f…
|
drh
|
1569 |
@ </div></form> |
|
15bc20f…
|
drh
|
1570 |
db_end_transaction(0); |
|
15bc20f…
|
drh
|
1571 |
style_finish_page(); |
|
15bc20f…
|
drh
|
1572 |
} |
|
15bc20f…
|
drh
|
1573 |
|
|
15bc20f…
|
drh
|
1574 |
/* |
|
15bc20f…
|
drh
|
1575 |
** WEBPAGE: setup_chat |
|
15bc20f…
|
drh
|
1576 |
** |
|
15bc20f…
|
drh
|
1577 |
** The "Admin/Chat" page. Requires Setup privilege. |
|
15bc20f…
|
drh
|
1578 |
*/ |
|
15bc20f…
|
drh
|
1579 |
void setup_chat(void){ |
|
d8e6994…
|
drh
|
1580 |
static const char *const azAlerts[] = { |
|
d8e6994…
|
drh
|
1581 |
"alerts/plunk.wav", "Plunk", |
|
d8e6994…
|
drh
|
1582 |
"alerts/bflat3.wav", "Tone-1", |
|
35b0781…
|
drh
|
1583 |
"alerts/bflat2.wav", "Tone-2", |
|
35b0781…
|
drh
|
1584 |
"alerts/bloop.wav", "Bloop", |
|
d8e6994…
|
drh
|
1585 |
}; |
|
d8e6994…
|
drh
|
1586 |
|
|
15bc20f…
|
drh
|
1587 |
login_check_credentials(); |
|
15bc20f…
|
drh
|
1588 |
if( !g.perm.Setup ){ |
|
15bc20f…
|
drh
|
1589 |
login_needed(0); |
|
15bc20f…
|
drh
|
1590 |
return; |
|
15bc20f…
|
drh
|
1591 |
} |
|
15bc20f…
|
drh
|
1592 |
|
|
15bc20f…
|
drh
|
1593 |
style_set_current_feature("setup"); |
|
15bc20f…
|
drh
|
1594 |
style_header("Chat Configuration"); |
|
15bc20f…
|
drh
|
1595 |
db_begin_transaction(); |
|
43af043…
|
drh
|
1596 |
if( P("rbldchatidx") && cgi_csrf_safe(2) ){ |
|
43af043…
|
drh
|
1597 |
chat_rebuild_index(1); |
|
43af043…
|
drh
|
1598 |
} |
|
15bc20f…
|
drh
|
1599 |
@ <form action="%R/setup_chat" method="post"><div> |
|
15bc20f…
|
drh
|
1600 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1601 |
@ <input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
1602 |
@ <hr> |
|
15bc20f…
|
drh
|
1603 |
entry_attribute("Initial Chat History Size", 10, |
|
15bc20f…
|
drh
|
1604 |
"chat-initial-history", "chatih", "50", 0); |
|
15bc20f…
|
drh
|
1605 |
@ <p>When /chat first starts up, it preloads up to this many historical |
|
15bc20f…
|
drh
|
1606 |
@ messages. |
|
15bc20f…
|
drh
|
1607 |
@ (Property: "chat-initial-history")</p> |
|
f5482a0…
|
wyoung
|
1608 |
@ <hr> |
|
15bc20f…
|
drh
|
1609 |
entry_attribute("Minimum Number Of Historical Messages To Retain", 10, |
|
15bc20f…
|
drh
|
1610 |
"chat-keep-count", "chatkc", "50", 0); |
|
15bc20f…
|
drh
|
1611 |
@ <p>The chat subsystem purges older messages. But it will always retain |
|
15bc20f…
|
drh
|
1612 |
@ the N most recent messages where N is the value of this setting. |
|
15bc20f…
|
drh
|
1613 |
@ (Property: "chat-keep-count")</p> |
|
f5482a0…
|
wyoung
|
1614 |
@ <hr> |
|
15bc20f…
|
drh
|
1615 |
entry_attribute("Maximum Message Age In Days", 10, |
|
15bc20f…
|
drh
|
1616 |
"chat-keep-days", "chatkd", "7", 0); |
|
15bc20f…
|
drh
|
1617 |
@ <p>Chat message are removed after N days, where N is the value of |
|
15bc20f…
|
drh
|
1618 |
@ this setting. N may be fractional. So, for example, to only keep |
|
15bc20f…
|
drh
|
1619 |
@ an historical record of chat messages for 12 hours, set this value |
|
15bc20f…
|
drh
|
1620 |
@ to 0.5. |
|
15bc20f…
|
drh
|
1621 |
@ (Property: "chat-keep-days")</p> |
|
f5482a0…
|
wyoung
|
1622 |
@ <hr> |
|
8363e7b…
|
drh
|
1623 |
entry_attribute("Chat Polling Timeout", 10, |
|
8363e7b…
|
drh
|
1624 |
"chat-poll-timeout", "chatpt", "420", 0); |
|
8363e7b…
|
drh
|
1625 |
@ <p>New chat content is downloaded using the "long poll" technique. |
|
8363e7b…
|
drh
|
1626 |
@ HTTP requests are made to /chat-poll which blocks waiting on new |
|
8363e7b…
|
drh
|
1627 |
@ content to arrive. But the /chat-poll cannot block forever. It |
|
8363e7b…
|
drh
|
1628 |
@ eventual must give up and return an empty message set. This setting |
|
8363e7b…
|
drh
|
1629 |
@ determines how long /chat-poll will wait before giving up. The |
|
8363e7b…
|
drh
|
1630 |
@ default setting of approximately 7 minutes works well on many systems. |
|
8363e7b…
|
drh
|
1631 |
@ Shorter delays might be required on installations that use proxies |
|
8363e7b…
|
drh
|
1632 |
@ or web-servers with short timeouts. For best efficiency, this value |
|
8363e7b…
|
drh
|
1633 |
@ should be larger rather than smaller. |
|
d8e6994…
|
drh
|
1634 |
@ (Property: "chat-poll-timeout")</p> |
|
f5482a0…
|
wyoung
|
1635 |
@ <hr> |
|
e9d7cf3…
|
drh
|
1636 |
entry_attribute("Chat Timeline Robot Username", 15, |
|
1f5474e…
|
drh
|
1637 |
"chat-timeline-user", "chatrobot", "", 0); |
|
1f5474e…
|
drh
|
1638 |
@ <p>If this setting is not an empty string, then any changes that appear |
|
1f5474e…
|
drh
|
1639 |
@ on the timeline are announced in the chatroom under the username |
|
c3ed243…
|
drh
|
1640 |
@ supplied. The username does not need to actually exist in the USER table. |
|
c3ed243…
|
drh
|
1641 |
@ Suggested username: "chat-robot". |
|
1f5474e…
|
drh
|
1642 |
@ (Property: "chat-timeline-user")</p> |
|
f5482a0…
|
wyoung
|
1643 |
@ <hr> |
|
d8e6994…
|
drh
|
1644 |
|
|
d8e6994…
|
drh
|
1645 |
multiple_choice_attribute("Alert sound", |
|
d8e6994…
|
drh
|
1646 |
"chat-alert-sound", "snd", azAlerts[0], |
|
d8e6994…
|
drh
|
1647 |
count(azAlerts)/2, azAlerts); |
|
d8e6994…
|
drh
|
1648 |
@ <p>The sound used in the client-side chat to indicate that a new |
|
d8e6994…
|
drh
|
1649 |
@ chat message has arrived. |
|
d8e6994…
|
drh
|
1650 |
@ (Property: "chat-alert-sound")</p> |
|
43af043…
|
drh
|
1651 |
|
|
d8e6994…
|
drh
|
1652 |
@ <hr/> |
|
43af043…
|
drh
|
1653 |
@ <p><input type="submit" name="submit" value="Apply Changes"> |
|
43af043…
|
drh
|
1654 |
@ <input type="submit" name="rbldchatidx"\ |
|
43af043…
|
drh
|
1655 |
@ value="Rebuild Full-Text Search Index"></p> |
|
7ab0328…
|
drh
|
1656 |
@ </div></form> |
|
d5504f9…
|
drh
|
1657 |
|
|
d5504f9…
|
drh
|
1658 |
/* Validate the chat FTS search index */ |
|
d5504f9…
|
drh
|
1659 |
if( db_table_exists("repository","chatfts1") ){ |
|
d5504f9…
|
drh
|
1660 |
char *zMissing; |
|
d5504f9…
|
drh
|
1661 |
zMissing = db_text(0, |
|
d5504f9…
|
drh
|
1662 |
"SELECT group_concat(rowid,', ') FROM chat" |
|
d5504f9…
|
drh
|
1663 |
" WHERE rowid NOT IN (SELECT rowid FROM chatfts1_docsize)" |
|
d5504f9…
|
drh
|
1664 |
); |
|
d5504f9…
|
drh
|
1665 |
if( zMissing && zMissing[0] ){ |
|
d5504f9…
|
drh
|
1666 |
@ <p><b>WARNING:</b> The following chat messages are missing |
|
d5504f9…
|
drh
|
1667 |
@ from the full-text index. Press the "Rebuild Full-Text Search Index" |
|
d5504f9…
|
drh
|
1668 |
@ button above to fix this.</p> |
|
d5504f9…
|
drh
|
1669 |
@ <p>%h(zMissing)</p> |
|
d5504f9…
|
drh
|
1670 |
} |
|
d5504f9…
|
drh
|
1671 |
fossil_free(zMissing); |
|
d5504f9…
|
drh
|
1672 |
} |
|
d5504f9…
|
drh
|
1673 |
|
|
7ab0328…
|
drh
|
1674 |
db_end_transaction(0); |
|
baa40a0…
|
drh
|
1675 |
@ <script nonce="%h(style_nonce())"> |
|
baa40a0…
|
drh
|
1676 |
@ (function(){ |
|
baa40a0…
|
drh
|
1677 |
@ var w = document.getElementById('idsnd'); |
|
baa40a0…
|
drh
|
1678 |
@ w.onchange = function(){ |
|
baa40a0…
|
drh
|
1679 |
@ var audio = new Audio('%s(g.zBaseURL)/builtin/' + w.value); |
|
baa40a0…
|
drh
|
1680 |
@ audio.currentTime = 0; |
|
baa40a0…
|
drh
|
1681 |
@ audio.play(); |
|
baa40a0…
|
drh
|
1682 |
@ } |
|
baa40a0…
|
drh
|
1683 |
@ })(); |
|
baa40a0…
|
drh
|
1684 |
@ </script> |
|
112c713…
|
drh
|
1685 |
style_finish_page(); |
|
7ab0328…
|
drh
|
1686 |
} |
|
7ab0328…
|
drh
|
1687 |
|
|
7ab0328…
|
drh
|
1688 |
/* |
|
7ab0328…
|
drh
|
1689 |
** WEBPAGE: setup_modreq |
|
7ab0328…
|
drh
|
1690 |
** |
|
7ab0328…
|
drh
|
1691 |
** Admin page for setting up moderation of tickets and wiki. |
|
7ab0328…
|
drh
|
1692 |
*/ |
|
7ab0328…
|
drh
|
1693 |
void setup_modreq(void){ |
|
7ab0328…
|
drh
|
1694 |
login_check_credentials(); |
|
6242e24…
|
wyoung
|
1695 |
if( !g.perm.Admin ){ |
|
7ab0328…
|
drh
|
1696 |
login_needed(0); |
|
7ab0328…
|
drh
|
1697 |
return; |
|
7ab0328…
|
drh
|
1698 |
} |
|
7ab0328…
|
drh
|
1699 |
|
|
112c713…
|
drh
|
1700 |
style_set_current_feature("setup"); |
|
ba418ee…
|
drh
|
1701 |
style_header("Moderator For Wiki And Tickets"); |
|
e1962ef…
|
drh
|
1702 |
db_begin_transaction(); |
|
ba418ee…
|
drh
|
1703 |
@ <form action="%R/setup_modreq" method="post"><div> |
|
ba418ee…
|
drh
|
1704 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1705 |
@ <hr> |
|
ba418ee…
|
drh
|
1706 |
onoff_attribute("Moderate ticket changes", |
|
10d8abc…
|
jan.nijtmans
|
1707 |
"modreq-tkt", "modreq-tkt", 0, 0); |
|
ba418ee…
|
drh
|
1708 |
@ <p>When enabled, any change to tickets is subject to the approval |
|
8fdb682…
|
drh
|
1709 |
@ by a ticket moderator - a user with the "q" or Mod-Tkt privilege. |
|
ba418ee…
|
drh
|
1710 |
@ Ticket changes enter the system and are shown locally, but are not |
|
3ba9a4d…
|
jan.nijtmans
|
1711 |
@ synced until they are approved. The moderator has the option to |
|
ba418ee…
|
drh
|
1712 |
@ delete the change rather than approve it. Ticket changes made by |
|
2530ee0…
|
stephan
|
1713 |
@ a user who has the Mod-Tkt privilege are never subject to |
|
3ca935e…
|
drh
|
1714 |
@ moderation. (Property: "modreq-tkt") |
|
ba418ee…
|
drh
|
1715 |
@ |
|
f5482a0…
|
wyoung
|
1716 |
@ <hr> |
|
ba418ee…
|
drh
|
1717 |
onoff_attribute("Moderate wiki changes", |
|
10d8abc…
|
jan.nijtmans
|
1718 |
"modreq-wiki", "modreq-wiki", 0, 0); |
|
ba418ee…
|
drh
|
1719 |
@ <p>When enabled, any change to wiki is subject to the approval |
|
8fdb682…
|
drh
|
1720 |
@ by a wiki moderator - a user with the "l" or Mod-Wiki privilege. |
|
ba418ee…
|
drh
|
1721 |
@ Wiki changes enter the system and are shown locally, but are not |
|
3ba9a4d…
|
jan.nijtmans
|
1722 |
@ synced until they are approved. The moderator has the option to |
|
ba418ee…
|
drh
|
1723 |
@ delete the change rather than approve it. Wiki changes made by |
|
ba418ee…
|
drh
|
1724 |
@ a user who has the Mod-Wiki privilege are never subject to |
|
3ca935e…
|
drh
|
1725 |
@ moderation. (Property: "modreq-wiki") |
|
ba418ee…
|
drh
|
1726 |
@ </p> |
|
3ba9a4d…
|
jan.nijtmans
|
1727 |
|
|
f5482a0…
|
wyoung
|
1728 |
@ <hr> |
|
f5482a0…
|
wyoung
|
1729 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
ba418ee…
|
drh
|
1730 |
@ </div></form> |
|
ba418ee…
|
drh
|
1731 |
db_end_transaction(0); |
|
112c713…
|
drh
|
1732 |
style_finish_page(); |
|
ba418ee…
|
drh
|
1733 |
|
|
e33fc88…
|
drh
|
1734 |
} |
|
e33fc88…
|
drh
|
1735 |
|
|
e33fc88…
|
drh
|
1736 |
/* |
|
e33fc88…
|
drh
|
1737 |
** WEBPAGE: setup_adunit |
|
7ab0328…
|
drh
|
1738 |
** |
|
7ab0328…
|
drh
|
1739 |
** Administrative page for configuring and controlling ad units |
|
7ab0328…
|
drh
|
1740 |
** and how they are displayed. |
|
e33fc88…
|
drh
|
1741 |
*/ |
|
e33fc88…
|
drh
|
1742 |
void setup_adunit(void){ |
|
e33fc88…
|
drh
|
1743 |
login_check_credentials(); |
|
257318c…
|
drh
|
1744 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
1745 |
login_needed(0); |
|
653dd40…
|
drh
|
1746 |
return; |
|
e33fc88…
|
drh
|
1747 |
} |
|
e1962ef…
|
drh
|
1748 |
db_begin_transaction(); |
|
920ace1…
|
drh
|
1749 |
if( P("clear")!=0 && cgi_csrf_safe(2) ){ |
|
f741baa…
|
drh
|
1750 |
db_unprotect(PROTECT_CONFIG); |
|
e33fc88…
|
drh
|
1751 |
db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'"); |
|
f741baa…
|
drh
|
1752 |
db_protect_pop(); |
|
869e27e…
|
drh
|
1753 |
cgi_replace_parameter("adunit",""); |
|
48dca1b…
|
drh
|
1754 |
cgi_replace_parameter("adright",""); |
|
0ba0e5e…
|
drh
|
1755 |
setup_incr_cfgcnt(); |
|
e33fc88…
|
drh
|
1756 |
} |
|
65870e8…
|
drh
|
1757 |
|
|
112c713…
|
drh
|
1758 |
style_set_current_feature("setup"); |
|
e33fc88…
|
drh
|
1759 |
style_header("Edit Ad Unit"); |
|
a40e8a0…
|
drh
|
1760 |
@ <form action="%R/setup_adunit" method="post"><div> |
|
e33fc88…
|
drh
|
1761 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
1762 |
@ <b>Banner Ad-Unit:</b><br> |
|
ff78d6d…
|
drh
|
1763 |
textarea_attribute("", 6, 80, "adunit", "adunit", "", 0); |
|
f5482a0…
|
wyoung
|
1764 |
@ <br> |
|
f5482a0…
|
wyoung
|
1765 |
@ <b>Right-Column Ad-Unit:</b><br> |
|
ff78d6d…
|
drh
|
1766 |
textarea_attribute("", 6, 80, "adunit-right", "adright", "", 0); |
|
f5482a0…
|
wyoung
|
1767 |
@ <br> |
|
e33fc88…
|
drh
|
1768 |
onoff_attribute("Omit ads to administrator", |
|
10d8abc…
|
jan.nijtmans
|
1769 |
"adunit-omit-if-admin", "oia", 0, 0); |
|
f5482a0…
|
wyoung
|
1770 |
@ <br> |
|
e33fc88…
|
drh
|
1771 |
onoff_attribute("Omit ads to logged-in users", |
|
10d8abc…
|
jan.nijtmans
|
1772 |
"adunit-omit-if-user", "oiu", 0, 0); |
|
f5482a0…
|
wyoung
|
1773 |
@ <br> |
|
48d8af2…
|
drh
|
1774 |
onoff_attribute("Temporarily disable all ads", |
|
48d8af2…
|
drh
|
1775 |
"adunit-disable", "oall", 0, 0); |
|
f5482a0…
|
wyoung
|
1776 |
@ <br> |
|
f5482a0…
|
wyoung
|
1777 |
@ <input type="submit" name="submit" value="Apply Changes"> |
|
f5482a0…
|
wyoung
|
1778 |
@ <input type="submit" name="clear" value="Delete Ad-Unit"> |
|
e33fc88…
|
drh
|
1779 |
@ </div></form> |
|
f5482a0…
|
wyoung
|
1780 |
@ <hr> |
|
ff78d6d…
|
drh
|
1781 |
@ <b>Ad-Unit Notes:</b><ul> |
|
ff78d6d…
|
drh
|
1782 |
@ <li>Leave both Ad-Units blank to disable all advertising. |
|
ff78d6d…
|
drh
|
1783 |
@ <li>The "Banner Ad-Unit" is used for wide pages. |
|
ff78d6d…
|
drh
|
1784 |
@ <li>The "Right-Column Ad-Unit" is used on pages with tall, narrow content. |
|
7001228…
|
drh
|
1785 |
@ <li>If the "Right-Column Ad-Unit" is blank, the "Banner Ad-Unit" is |
|
7001228…
|
drh
|
1786 |
@ used on all pages. |
|
23895c7…
|
jan.nijtmans
|
1787 |
@ <li>Properties: "adunit", "adunit-right", "adunit-omit-if-admin", and |
|
3ca935e…
|
drh
|
1788 |
@ "adunit-omit-if-user". |
|
106c090…
|
drh
|
1789 |
@ <li>Suggested <a href="setup_skinedit?w=0">CSS</a> changes: |
|
ff78d6d…
|
drh
|
1790 |
@ <blockquote><pre> |
|
ff78d6d…
|
drh
|
1791 |
@ div.adunit_banner { |
|
ff78d6d…
|
drh
|
1792 |
@ margin: auto; |
|
bc6355e…
|
drh
|
1793 |
@ width: 100%%; |
|
ff78d6d…
|
drh
|
1794 |
@ } |
|
ff78d6d…
|
drh
|
1795 |
@ div.adunit_right { |
|
ff78d6d…
|
drh
|
1796 |
@ float: right; |
|
ff78d6d…
|
drh
|
1797 |
@ } |
|
ff78d6d…
|
drh
|
1798 |
@ div.adunit_right_container { |
|
ff78d6d…
|
drh
|
1799 |
@ min-height: <i>height-of-right-column-ad-unit</i>; |
|
ff78d6d…
|
drh
|
1800 |
@ } |
|
ff78d6d…
|
drh
|
1801 |
@ </pre></blockquote> |
|
ff78d6d…
|
drh
|
1802 |
@ <li>For a place-holder Ad-Unit for testing, Copy/Paste the following |
|
ff78d6d…
|
drh
|
1803 |
@ with appropriate adjustments to "width:" and "height:". |
|
ff78d6d…
|
drh
|
1804 |
@ <blockquote><pre> |
|
ff78d6d…
|
drh
|
1805 |
@ <div style=' |
|
ff78d6d…
|
drh
|
1806 |
@ margin: 0 auto; |
|
ff78d6d…
|
drh
|
1807 |
@ width: 600px; |
|
ff78d6d…
|
drh
|
1808 |
@ height: 90px; |
|
ff78d6d…
|
drh
|
1809 |
@ border: 1px solid #f11; |
|
ff78d6d…
|
drh
|
1810 |
@ background-color: #fcc; |
|
ff78d6d…
|
drh
|
1811 |
@ '>Demo Ad</div> |
|
ff78d6d…
|
drh
|
1812 |
@ </pre></blockquote> |
|
ff78d6d…
|
drh
|
1813 |
@ </li> |
|
112c713…
|
drh
|
1814 |
style_finish_page(); |
|
4348111…
|
drh
|
1815 |
db_end_transaction(0); |
|
4348111…
|
drh
|
1816 |
} |
|
4348111…
|
drh
|
1817 |
|
|
4348111…
|
drh
|
1818 |
/* |
|
4348111…
|
drh
|
1819 |
** WEBPAGE: setup_logo |
|
7ab0328…
|
drh
|
1820 |
** |
|
37262b8…
|
mistachkin
|
1821 |
** Administrative page for changing the logo, background, and icon images. |
|
4348111…
|
drh
|
1822 |
*/ |
|
4348111…
|
drh
|
1823 |
void setup_logo(void){ |
|
daff9d2…
|
joel
|
1824 |
const char *zLogoMtime = db_get_mtime("logo-image", 0, 0); |
|
6239845…
|
drh
|
1825 |
const char *zLogoMime = db_get("logo-mimetype","image/gif"); |
|
6239845…
|
drh
|
1826 |
const char *aLogoImg = P("logoim"); |
|
6239845…
|
drh
|
1827 |
int szLogoImg = atoi(PD("logoim:bytes","0")); |
|
daff9d2…
|
joel
|
1828 |
const char *zBgMtime = db_get_mtime("background-image", 0, 0); |
|
6239845…
|
drh
|
1829 |
const char *zBgMime = db_get("background-mimetype","image/gif"); |
|
6239845…
|
drh
|
1830 |
const char *aBgImg = P("bgim"); |
|
6239845…
|
drh
|
1831 |
int szBgImg = atoi(PD("bgim:bytes","0")); |
|
37262b8…
|
mistachkin
|
1832 |
const char *zIconMtime = db_get_mtime("icon-image", 0, 0); |
|
37262b8…
|
mistachkin
|
1833 |
const char *zIconMime = db_get("icon-mimetype","image/gif"); |
|
37262b8…
|
mistachkin
|
1834 |
const char *aIconImg = P("iconim"); |
|
37262b8…
|
mistachkin
|
1835 |
int szIconImg = atoi(PD("iconim:bytes","0")); |
|
6239845…
|
drh
|
1836 |
if( szLogoImg>0 ){ |
|
6239845…
|
drh
|
1837 |
zLogoMime = PD("logoim:mimetype","image/gif"); |
|
6239845…
|
drh
|
1838 |
} |
|
6239845…
|
drh
|
1839 |
if( szBgImg>0 ){ |
|
6239845…
|
drh
|
1840 |
zBgMime = PD("bgim:mimetype","image/gif"); |
|
37262b8…
|
mistachkin
|
1841 |
} |
|
37262b8…
|
mistachkin
|
1842 |
if( szIconImg>0 ){ |
|
37262b8…
|
mistachkin
|
1843 |
zIconMime = PD("iconim:mimetype","image/gif"); |
|
257318c…
|
drh
|
1844 |
} |
|
4348111…
|
drh
|
1845 |
login_check_credentials(); |
|
257318c…
|
drh
|
1846 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
1847 |
login_needed(0); |
|
653dd40…
|
drh
|
1848 |
return; |
|
4348111…
|
drh
|
1849 |
} |
|
e1962ef…
|
drh
|
1850 |
db_begin_transaction(); |
|
920ace1…
|
drh
|
1851 |
if( !cgi_csrf_safe(2) ){ |
|
047802a…
|
drh
|
1852 |
/* Allow no state changes if not safe from CSRF */ |
|
047802a…
|
drh
|
1853 |
}else if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){ |
|
1654456…
|
drh
|
1854 |
Blob img; |
|
1654456…
|
drh
|
1855 |
Stmt ins; |
|
6239845…
|
drh
|
1856 |
blob_init(&img, aLogoImg, szLogoImg); |
|
f273832…
|
mistachkin
|
1857 |
db_unprotect(PROTECT_CONFIG); |
|
1654456…
|
drh
|
1858 |
db_prepare(&ins, |
|
1654456…
|
drh
|
1859 |
"REPLACE INTO config(name,value,mtime)" |
|
1654456…
|
drh
|
1860 |
" VALUES('logo-image',:bytes,now())" |
|
1654456…
|
drh
|
1861 |
); |
|
1654456…
|
drh
|
1862 |
db_bind_blob(&ins, ":bytes", &img); |
|
1654456…
|
drh
|
1863 |
db_step(&ins); |
|
1654456…
|
drh
|
1864 |
db_finalize(&ins); |
|
1654456…
|
drh
|
1865 |
db_multi_exec( |
|
1654456…
|
drh
|
1866 |
"REPLACE INTO config(name,value,mtime) VALUES('logo-mimetype',%Q,now())", |
|
6239845…
|
drh
|
1867 |
zLogoMime |
|
6239845…
|
drh
|
1868 |
); |
|
f273832…
|
mistachkin
|
1869 |
db_protect_pop(); |
|
6239845…
|
drh
|
1870 |
db_end_transaction(0); |
|
6239845…
|
drh
|
1871 |
cgi_redirect("setup_logo"); |
|
6239845…
|
drh
|
1872 |
}else if( P("clrlogo")!=0 ){ |
|
f273832…
|
mistachkin
|
1873 |
db_unprotect(PROTECT_CONFIG); |
|
6239845…
|
drh
|
1874 |
db_multi_exec( |
|
6239845…
|
drh
|
1875 |
"DELETE FROM config WHERE name IN " |
|
6239845…
|
drh
|
1876 |
"('logo-image','logo-mimetype')" |
|
6239845…
|
drh
|
1877 |
); |
|
f273832…
|
mistachkin
|
1878 |
db_protect_pop(); |
|
6239845…
|
drh
|
1879 |
db_end_transaction(0); |
|
6239845…
|
drh
|
1880 |
cgi_redirect("setup_logo"); |
|
6239845…
|
drh
|
1881 |
}else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){ |
|
6239845…
|
drh
|
1882 |
Blob img; |
|
6239845…
|
drh
|
1883 |
Stmt ins; |
|
6239845…
|
drh
|
1884 |
blob_init(&img, aBgImg, szBgImg); |
|
f741baa…
|
drh
|
1885 |
db_unprotect(PROTECT_CONFIG); |
|
6239845…
|
drh
|
1886 |
db_prepare(&ins, |
|
6239845…
|
drh
|
1887 |
"REPLACE INTO config(name,value,mtime)" |
|
6239845…
|
drh
|
1888 |
" VALUES('background-image',:bytes,now())" |
|
6239845…
|
drh
|
1889 |
); |
|
6239845…
|
drh
|
1890 |
db_bind_blob(&ins, ":bytes", &img); |
|
6239845…
|
drh
|
1891 |
db_step(&ins); |
|
6239845…
|
drh
|
1892 |
db_finalize(&ins); |
|
6239845…
|
drh
|
1893 |
db_multi_exec( |
|
6239845…
|
drh
|
1894 |
"REPLACE INTO config(name,value,mtime)" |
|
6239845…
|
drh
|
1895 |
" VALUES('background-mimetype',%Q,now())", |
|
6239845…
|
drh
|
1896 |
zBgMime |
|
6239845…
|
drh
|
1897 |
); |
|
f741baa…
|
drh
|
1898 |
db_protect_pop(); |
|
6239845…
|
drh
|
1899 |
db_end_transaction(0); |
|
6239845…
|
drh
|
1900 |
cgi_redirect("setup_logo"); |
|
6239845…
|
drh
|
1901 |
}else if( P("clrbg")!=0 ){ |
|
f741baa…
|
drh
|
1902 |
db_unprotect(PROTECT_CONFIG); |
|
6239845…
|
drh
|
1903 |
db_multi_exec( |
|
6239845…
|
drh
|
1904 |
"DELETE FROM config WHERE name IN " |
|
6239845…
|
drh
|
1905 |
"('background-image','background-mimetype')" |
|
6239845…
|
drh
|
1906 |
); |
|
f273832…
|
mistachkin
|
1907 |
db_protect_pop(); |
|
37262b8…
|
mistachkin
|
1908 |
db_end_transaction(0); |
|
37262b8…
|
mistachkin
|
1909 |
cgi_redirect("setup_logo"); |
|
37262b8…
|
mistachkin
|
1910 |
}else if( P("seticon")!=0 && zIconMime && zIconMime[0] && szIconImg>0 ){ |
|
37262b8…
|
mistachkin
|
1911 |
Blob img; |
|
37262b8…
|
mistachkin
|
1912 |
Stmt ins; |
|
37262b8…
|
mistachkin
|
1913 |
blob_init(&img, aIconImg, szIconImg); |
|
f741baa…
|
drh
|
1914 |
db_unprotect(PROTECT_CONFIG); |
|
37262b8…
|
mistachkin
|
1915 |
db_prepare(&ins, |
|
37262b8…
|
mistachkin
|
1916 |
"REPLACE INTO config(name,value,mtime)" |
|
37262b8…
|
mistachkin
|
1917 |
" VALUES('icon-image',:bytes,now())" |
|
37262b8…
|
mistachkin
|
1918 |
); |
|
37262b8…
|
mistachkin
|
1919 |
db_bind_blob(&ins, ":bytes", &img); |
|
37262b8…
|
mistachkin
|
1920 |
db_step(&ins); |
|
37262b8…
|
mistachkin
|
1921 |
db_finalize(&ins); |
|
37262b8…
|
mistachkin
|
1922 |
db_multi_exec( |
|
37262b8…
|
mistachkin
|
1923 |
"REPLACE INTO config(name,value,mtime)" |
|
37262b8…
|
mistachkin
|
1924 |
" VALUES('icon-mimetype',%Q,now())", |
|
37262b8…
|
mistachkin
|
1925 |
zIconMime |
|
37262b8…
|
mistachkin
|
1926 |
); |
|
f741baa…
|
drh
|
1927 |
db_protect_pop(); |
|
37262b8…
|
mistachkin
|
1928 |
db_end_transaction(0); |
|
37262b8…
|
mistachkin
|
1929 |
cgi_redirect("setup_logo"); |
|
37262b8…
|
mistachkin
|
1930 |
}else if( P("clricon")!=0 ){ |
|
f273832…
|
mistachkin
|
1931 |
db_unprotect(PROTECT_CONFIG); |
|
37262b8…
|
mistachkin
|
1932 |
db_multi_exec( |
|
37262b8…
|
mistachkin
|
1933 |
"DELETE FROM config WHERE name IN " |
|
37262b8…
|
mistachkin
|
1934 |
"('icon-image','icon-mimetype')" |
|
37262b8…
|
mistachkin
|
1935 |
); |
|
f273832…
|
mistachkin
|
1936 |
db_protect_pop(); |
|
1942d58…
|
drh
|
1937 |
db_end_transaction(0); |
|
1942d58…
|
drh
|
1938 |
cgi_redirect("setup_logo"); |
|
1942d58…
|
drh
|
1939 |
} |
|
112c713…
|
drh
|
1940 |
style_set_current_feature("setup"); |
|
6239845…
|
drh
|
1941 |
style_header("Edit Project Logo And Background"); |
|
6239845…
|
drh
|
1942 |
@ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b> |
|
6239845…
|
drh
|
1943 |
@ and looks like this:</p> |
|
f5482a0…
|
wyoung
|
1944 |
@ <blockquote><p> |
|
f5482a0…
|
wyoung
|
1945 |
@ <img src="%R/logo/%z(zLogoMtime)" alt="logo" border="1"> |
|
6239845…
|
drh
|
1946 |
@ </p></blockquote> |
|
6454153…
|
drh
|
1947 |
@ |
|
a40e8a0…
|
drh
|
1948 |
@ <form action="%R/setup_logo" method="post" |
|
6239845…
|
drh
|
1949 |
@ enctype="multipart/form-data"><div> |
|
4348111…
|
drh
|
1950 |
@ <p>The logo is accessible to all users at this URL: |
|
4348111…
|
drh
|
1951 |
@ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. |
|
007d0a9…
|
drh
|
1952 |
@ The logo may or may not appear on each |
|
106c090…
|
drh
|
1953 |
@ page depending on the <a href="setup_skinedit?w=0">CSS</a> and |
|
106c090…
|
drh
|
1954 |
@ <a href="setup_skinedit?w=2">header setup</a>. |
|
6239845…
|
drh
|
1955 |
@ To change the logo image, use the following form:</p> |
|
4348111…
|
drh
|
1956 |
login_insert_csrf_secret(); |
|
4348111…
|
drh
|
1957 |
@ Logo Image file: |
|
f5482a0…
|
wyoung
|
1958 |
@ <input type="file" name="logoim" size="60" accept="image/*"> |
|
6239845…
|
drh
|
1959 |
@ <p align="center"> |
|
f5482a0…
|
wyoung
|
1960 |
@ <input type="submit" name="setlogo" value="Change Logo"> |
|
f5482a0…
|
wyoung
|
1961 |
@ <input type="submit" name="clrlogo" value="Revert To Default"></p> |
|
3ca935e…
|
drh
|
1962 |
@ <p>(Properties: "logo-image" and "logo-mimetype") |
|
6239845…
|
drh
|
1963 |
@ </div></form> |
|
f5482a0…
|
wyoung
|
1964 |
@ <hr> |
|
6239845…
|
drh
|
1965 |
@ |
|
6239845…
|
drh
|
1966 |
@ <p>The current background image has a MIME-Type of <b>%h(zBgMime)</b> |
|
6239845…
|
drh
|
1967 |
@ and looks like this:</p> |
|
a40e8a0…
|
drh
|
1968 |
@ <blockquote><p><img src="%R/background/%z(zBgMtime)" \ |
|
f5482a0…
|
wyoung
|
1969 |
@ alt="background" border=1> |
|
6239845…
|
drh
|
1970 |
@ </p></blockquote> |
|
6239845…
|
drh
|
1971 |
@ |
|
a40e8a0…
|
drh
|
1972 |
@ <form action="%R/setup_logo" method="post" |
|
6239845…
|
drh
|
1973 |
@ enctype="multipart/form-data"><div> |
|
6239845…
|
drh
|
1974 |
@ <p>The background image is accessible to all users at this URL: |
|
6239845…
|
drh
|
1975 |
@ <a href="%s(g.zBaseURL)/background">%s(g.zBaseURL)/background</a>. |
|
6239845…
|
drh
|
1976 |
@ The background image may or may not appear on each |
|
106c090…
|
drh
|
1977 |
@ page depending on the <a href="setup_skinedit?w=0">CSS</a> and |
|
106c090…
|
drh
|
1978 |
@ <a href="setup_skinedit?w=2">header setup</a>. |
|
6239845…
|
drh
|
1979 |
@ To change the background image, use the following form:</p> |
|
6239845…
|
drh
|
1980 |
login_insert_csrf_secret(); |
|
6239845…
|
drh
|
1981 |
@ Background image file: |
|
f5482a0…
|
wyoung
|
1982 |
@ <input type="file" name="bgim" size="60" accept="image/*"> |
|
3ca935e…
|
drh
|
1983 |
@ <p align="center"> |
|
f5482a0…
|
wyoung
|
1984 |
@ <input type="submit" name="setbg" value="Change Background"> |
|
f5482a0…
|
wyoung
|
1985 |
@ <input type="submit" name="clrbg" value="Revert To Default"></p> |
|
3ca935e…
|
drh
|
1986 |
@ </div></form> |
|
3ca935e…
|
drh
|
1987 |
@ <p>(Properties: "background-image" and "background-mimetype") |
|
f5482a0…
|
wyoung
|
1988 |
@ <hr> |
|
37262b8…
|
mistachkin
|
1989 |
@ |
|
37262b8…
|
mistachkin
|
1990 |
@ <p>The current icon image has a MIME-Type of <b>%h(zIconMime)</b> |
|
37262b8…
|
mistachkin
|
1991 |
@ and looks like this:</p> |
|
a40e8a0…
|
drh
|
1992 |
@ <blockquote><p><img src="%R/favicon.ico/%z(zIconMtime)" \ |
|
f5482a0…
|
wyoung
|
1993 |
@ alt="icon" border=1> |
|
37262b8…
|
mistachkin
|
1994 |
@ </p></blockquote> |
|
37262b8…
|
mistachkin
|
1995 |
@ |
|
a40e8a0…
|
drh
|
1996 |
@ <form action="%R/setup_logo" method="post" |
|
37262b8…
|
mistachkin
|
1997 |
@ enctype="multipart/form-data"><div> |
|
37262b8…
|
mistachkin
|
1998 |
@ <p>The icon image is accessible to all users at this URL: |
|
37262b8…
|
mistachkin
|
1999 |
@ <a href="%s(g.zBaseURL)/favicon.ico">%s(g.zBaseURL)/favicon.ico</a>. |
|
37262b8…
|
mistachkin
|
2000 |
@ The icon image may or may not appear on each |
|
37262b8…
|
mistachkin
|
2001 |
@ page depending on the web browser in use and the MIME-Types that it |
|
37262b8…
|
mistachkin
|
2002 |
@ supports for icon images. |
|
37262b8…
|
mistachkin
|
2003 |
@ To change the icon image, use the following form:</p> |
|
37262b8…
|
mistachkin
|
2004 |
login_insert_csrf_secret(); |
|
37262b8…
|
mistachkin
|
2005 |
@ Icon image file: |
|
f5482a0…
|
wyoung
|
2006 |
@ <input type="file" name="iconim" size="60" accept="image/*"> |
|
37262b8…
|
mistachkin
|
2007 |
@ <p align="center"> |
|
f5482a0…
|
wyoung
|
2008 |
@ <input type="submit" name="seticon" value="Change Icon"> |
|
f5482a0…
|
wyoung
|
2009 |
@ <input type="submit" name="clricon" value="Revert To Default"></p> |
|
37262b8…
|
mistachkin
|
2010 |
@ </div></form> |
|
37262b8…
|
mistachkin
|
2011 |
@ <p>(Properties: "icon-image" and "icon-mimetype") |
|
f5482a0…
|
wyoung
|
2012 |
@ <hr> |
|
3243e63…
|
drh
|
2013 |
@ |
|
6239845…
|
drh
|
2014 |
@ <p><span class="note">Note:</span> Your browser has probably cached these |
|
6239845…
|
drh
|
2015 |
@ images, so you may need to press the Reload button before changes will |
|
6239845…
|
drh
|
2016 |
@ take effect. </p> |
|
112c713…
|
drh
|
2017 |
style_finish_page(); |
|
4348111…
|
drh
|
2018 |
db_end_transaction(0); |
|
98f29f2…
|
drh
|
2019 |
} |
|
98f29f2…
|
drh
|
2020 |
|
|
98f29f2…
|
drh
|
2021 |
/* |
|
98f29f2…
|
drh
|
2022 |
** Prevent the RAW SQL feature from being used to ATTACH a different |
|
98f29f2…
|
drh
|
2023 |
** database and query it. |
|
98f29f2…
|
drh
|
2024 |
** |
|
98f29f2…
|
drh
|
2025 |
** Actually, the RAW SQL feature only does a single statement per request. |
|
98f29f2…
|
drh
|
2026 |
** So it is not possible to ATTACH and then do a separate query. This |
|
98f29f2…
|
drh
|
2027 |
** routine is not strictly necessary, therefore. But it does not hurt |
|
98f29f2…
|
drh
|
2028 |
** to be paranoid. |
|
98f29f2…
|
drh
|
2029 |
*/ |
|
98f29f2…
|
drh
|
2030 |
int raw_sql_query_authorizer( |
|
98f29f2…
|
drh
|
2031 |
void *pError, |
|
98f29f2…
|
drh
|
2032 |
int code, |
|
98f29f2…
|
drh
|
2033 |
const char *zArg1, |
|
98f29f2…
|
drh
|
2034 |
const char *zArg2, |
|
98f29f2…
|
drh
|
2035 |
const char *zArg3, |
|
98f29f2…
|
drh
|
2036 |
const char *zArg4 |
|
98f29f2…
|
drh
|
2037 |
){ |
|
98f29f2…
|
drh
|
2038 |
if( code==SQLITE_ATTACH ){ |
|
98f29f2…
|
drh
|
2039 |
return SQLITE_DENY; |
|
98f29f2…
|
drh
|
2040 |
} |
|
98f29f2…
|
drh
|
2041 |
return SQLITE_OK; |
|
ca0faa8…
|
drh
|
2042 |
} |
|
ca0faa8…
|
drh
|
2043 |
|
|
ca0faa8…
|
drh
|
2044 |
|
|
ca0faa8…
|
drh
|
2045 |
/* |
|
ca0faa8…
|
drh
|
2046 |
** WEBPAGE: admin_sql |
|
ca0faa8…
|
drh
|
2047 |
** |
|
ca0faa8…
|
drh
|
2048 |
** Run raw SQL commands against the database file using the web interface. |
|
7d034d3…
|
wyoung
|
2049 |
** Requires Setup privileges. |
|
ca0faa8…
|
drh
|
2050 |
*/ |
|
ca0faa8…
|
drh
|
2051 |
void sql_page(void){ |
|
047802a…
|
drh
|
2052 |
const char *zQ; |
|
ca0faa8…
|
drh
|
2053 |
int go = P("go")!=0; |
|
ca0faa8…
|
drh
|
2054 |
login_check_credentials(); |
|
ca0faa8…
|
drh
|
2055 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
2056 |
login_needed(0); |
|
653dd40…
|
drh
|
2057 |
return; |
|
ca0faa8…
|
drh
|
2058 |
} |
|
93f514c…
|
stephan
|
2059 |
add_content_sql_commands(g.db); |
|
920ace1…
|
drh
|
2060 |
zQ = cgi_csrf_safe(2) ? P("q") : 0; |
|
112c713…
|
drh
|
2061 |
style_set_current_feature("setup"); |
|
ca0faa8…
|
drh
|
2062 |
style_header("Raw SQL Commands"); |
|
ca0faa8…
|
drh
|
2063 |
@ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
|
ca0faa8…
|
drh
|
2064 |
@ run by this page. You can do serious and irrepairable damage to the |
|
ca0faa8…
|
drh
|
2065 |
@ repository. Proceed with extreme caution.</p> |
|
ca0faa8…
|
drh
|
2066 |
@ |
|
6a67931…
|
drh
|
2067 |
#if 0 |
|
565d1b0…
|
m.ramakers
|
2068 |
@ <p>Only the first statement in the entry box will be run. |
|
98f29f2…
|
drh
|
2069 |
@ Any subsequent statements will be silently ignored.</p> |
|
98f29f2…
|
drh
|
2070 |
@ |
|
06aec61…
|
drh
|
2071 |
@ <p>Database names:<ul><li>repository |
|
a5dc533…
|
jan.nijtmans
|
2072 |
if( g.zConfigDbName ){ |
|
06aec61…
|
drh
|
2073 |
@ <li>configdb |
|
ca0faa8…
|
drh
|
2074 |
} |
|
ca0faa8…
|
drh
|
2075 |
if( g.localOpen ){ |
|
06aec61…
|
drh
|
2076 |
@ <li>localdb |
|
ca0faa8…
|
drh
|
2077 |
} |
|
ca0faa8…
|
drh
|
2078 |
@ </ul></p> |
|
6a67931…
|
drh
|
2079 |
#endif |
|
6a67931…
|
drh
|
2080 |
|
|
6a67931…
|
drh
|
2081 |
if( P("configtab") ){ |
|
6a67931…
|
drh
|
2082 |
/* If the user presses the "CONFIG Table Query" button, populate the |
|
6a67931…
|
drh
|
2083 |
** query text with a pre-packaged query against the CONFIG table */ |
|
6a67931…
|
drh
|
2084 |
zQ = "SELECT\n" |
|
7001228…
|
drh
|
2085 |
" CASE WHEN length(name)<50 THEN name ELSE printf('%.50s...',name)" |
|
7001228…
|
drh
|
2086 |
" END AS name,\n" |
|
6a67931…
|
drh
|
2087 |
" CASE WHEN typeof(value)<>'blob' AND length(value)<80 THEN value\n" |
|
6a67931…
|
drh
|
2088 |
" ELSE '...' END AS value,\n" |
|
6a67931…
|
drh
|
2089 |
" datetime(mtime, 'unixepoch') AS mtime\n" |
|
6a67931…
|
drh
|
2090 |
"FROM config\n" |
|
6a67931…
|
drh
|
2091 |
"-- ORDER BY mtime DESC; -- optional"; |
|
6a67931…
|
drh
|
2092 |
go = 1; |
|
6a67931…
|
drh
|
2093 |
} |
|
ca0faa8…
|
drh
|
2094 |
@ |
|
a40e8a0…
|
drh
|
2095 |
@ <form method="post" action="%R/admin_sql"> |
|
ca0faa8…
|
drh
|
2096 |
login_insert_csrf_secret(); |
|
f5482a0…
|
wyoung
|
2097 |
@ SQL:<br> |
|
f5482a0…
|
wyoung
|
2098 |
@ <textarea name="q" rows="8" cols="80">%h(zQ)</textarea><br> |
|
ca0faa8…
|
drh
|
2099 |
@ <input type="submit" name="go" value="Run SQL"> |
|
ca0faa8…
|
drh
|
2100 |
@ <input type="submit" name="schema" value="Show Schema"> |
|
ca0faa8…
|
drh
|
2101 |
@ <input type="submit" name="tablelist" value="List Tables"> |
|
6a67931…
|
drh
|
2102 |
@ <input type="submit" name="configtab" value="CONFIG Table Query"> |
|
ca0faa8…
|
drh
|
2103 |
@ </form> |
|
ca0faa8…
|
drh
|
2104 |
if( P("schema") ){ |
|
ca0faa8…
|
drh
|
2105 |
zQ = sqlite3_mprintf( |
|
e654b30…
|
mistachkin
|
2106 |
"SELECT sql FROM repository.sqlite_schema" |
|
7001228…
|
drh
|
2107 |
" WHERE sql IS NOT NULL ORDER BY name"); |
|
ca0faa8…
|
drh
|
2108 |
go = 1; |
|
ca0faa8…
|
drh
|
2109 |
}else if( P("tablelist") ){ |
|
6325f81…
|
drh
|
2110 |
zQ = sqlite3_mprintf("SELECT*FROM pragma_table_list ORDER BY schema, name"); |
|
ca0faa8…
|
drh
|
2111 |
go = 1; |
|
ca0faa8…
|
drh
|
2112 |
} |
|
920ace1…
|
drh
|
2113 |
if( go && cgi_csrf_safe(2) ){ |
|
ca0faa8…
|
drh
|
2114 |
sqlite3_stmt *pStmt; |
|
ca0faa8…
|
drh
|
2115 |
int rc; |
|
ca0faa8…
|
drh
|
2116 |
const char *zTail; |
|
ca0faa8…
|
drh
|
2117 |
int nCol; |
|
ca0faa8…
|
drh
|
2118 |
int nRow = 0; |
|
ca0faa8…
|
drh
|
2119 |
int i; |
|
f5482a0…
|
wyoung
|
2120 |
@ <hr> |
|
98f29f2…
|
drh
|
2121 |
sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0); |
|
6325f81…
|
drh
|
2122 |
search_sql_setup(g.db); |
|
ca0faa8…
|
drh
|
2123 |
rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail); |
|
ca0faa8…
|
drh
|
2124 |
if( rc!=SQLITE_OK ){ |
|
ca0faa8…
|
drh
|
2125 |
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> |
|
ca0faa8…
|
drh
|
2126 |
sqlite3_finalize(pStmt); |
|
ca0faa8…
|
drh
|
2127 |
}else if( pStmt==0 ){ |
|
ca0faa8…
|
drh
|
2128 |
/* No-op */ |
|
ca0faa8…
|
drh
|
2129 |
}else if( (nCol = sqlite3_column_count(pStmt))==0 ){ |
|
ca0faa8…
|
drh
|
2130 |
sqlite3_step(pStmt); |
|
ca0faa8…
|
drh
|
2131 |
rc = sqlite3_finalize(pStmt); |
|
ca0faa8…
|
drh
|
2132 |
if( rc ){ |
|
ca0faa8…
|
drh
|
2133 |
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> |
|
ca0faa8…
|
drh
|
2134 |
} |
|
ca0faa8…
|
drh
|
2135 |
}else{ |
|
6325f81…
|
drh
|
2136 |
@ <table border="1" cellpadding="4" cellspacing="0"> |
|
ca0faa8…
|
drh
|
2137 |
while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
|
ca0faa8…
|
drh
|
2138 |
if( nRow==0 ){ |
|
ca0faa8…
|
drh
|
2139 |
@ <tr> |
|
ca0faa8…
|
drh
|
2140 |
for(i=0; i<nCol; i++){ |
|
ca0faa8…
|
drh
|
2141 |
@ <th>%h(sqlite3_column_name(pStmt, i))</th> |
|
ca0faa8…
|
drh
|
2142 |
} |
|
ca0faa8…
|
drh
|
2143 |
@ </tr> |
|
ca0faa8…
|
drh
|
2144 |
} |
|
ca0faa8…
|
drh
|
2145 |
nRow++; |
|
ca0faa8…
|
drh
|
2146 |
@ <tr> |
|
ca0faa8…
|
drh
|
2147 |
for(i=0; i<nCol; i++){ |
|
ca0faa8…
|
drh
|
2148 |
switch( sqlite3_column_type(pStmt, i) ){ |
|
ca0faa8…
|
drh
|
2149 |
case SQLITE_INTEGER: |
|
ca0faa8…
|
drh
|
2150 |
case SQLITE_FLOAT: { |
|
ca0faa8…
|
drh
|
2151 |
@ <td align="right" valign="top"> |
|
ca0faa8…
|
drh
|
2152 |
@ %s(sqlite3_column_text(pStmt, i))</td> |
|
ca0faa8…
|
drh
|
2153 |
break; |
|
ca0faa8…
|
drh
|
2154 |
} |
|
ca0faa8…
|
drh
|
2155 |
case SQLITE_NULL: { |
|
ca0faa8…
|
drh
|
2156 |
@ <td valign="top" align="center"><i>NULL</i></td> |
|
ca0faa8…
|
drh
|
2157 |
break; |
|
ca0faa8…
|
drh
|
2158 |
} |
|
ca0faa8…
|
drh
|
2159 |
case SQLITE_TEXT: { |
|
ca0faa8…
|
drh
|
2160 |
const char *zText = (const char*)sqlite3_column_text(pStmt, i); |
|
ca0faa8…
|
drh
|
2161 |
@ <td align="left" valign="top" |
|
ca0faa8…
|
drh
|
2162 |
@ style="white-space:pre;">%h(zText)</td> |
|
ca0faa8…
|
drh
|
2163 |
break; |
|
ca0faa8…
|
drh
|
2164 |
} |
|
ca0faa8…
|
drh
|
2165 |
case SQLITE_BLOB: { |
|
ca0faa8…
|
drh
|
2166 |
@ <td valign="top" align="center"> |
|
ca0faa8…
|
drh
|
2167 |
@ <i>%d(sqlite3_column_bytes(pStmt, i))-byte BLOB</i></td> |
|
ca0faa8…
|
drh
|
2168 |
break; |
|
ca0faa8…
|
drh
|
2169 |
} |
|
ca0faa8…
|
drh
|
2170 |
} |
|
ca0faa8…
|
drh
|
2171 |
} |
|
ca0faa8…
|
drh
|
2172 |
@ </tr> |
|
ca0faa8…
|
drh
|
2173 |
} |
|
ca0faa8…
|
drh
|
2174 |
sqlite3_finalize(pStmt); |
|
ca0faa8…
|
drh
|
2175 |
@ </table> |
|
ca0faa8…
|
drh
|
2176 |
} |
|
ca0faa8…
|
drh
|
2177 |
} |
|
112c713…
|
drh
|
2178 |
style_finish_page(); |
|
e356f18…
|
drh
|
2179 |
} |
|
e356f18…
|
drh
|
2180 |
|
|
e356f18…
|
drh
|
2181 |
|
|
e356f18…
|
drh
|
2182 |
/* |
|
e356f18…
|
drh
|
2183 |
** WEBPAGE: admin_th1 |
|
e356f18…
|
drh
|
2184 |
** |
|
e356f18…
|
drh
|
2185 |
** Run raw TH1 commands using the web interface. If Tcl integration was |
|
e356f18…
|
drh
|
2186 |
** enabled at compile-time and the "tcl" setting is enabled, Tcl commands |
|
7ab0328…
|
drh
|
2187 |
** may be run as well. Requires Admin privilege. |
|
e356f18…
|
drh
|
2188 |
*/ |
|
e356f18…
|
drh
|
2189 |
void th1_page(void){ |
|
e356f18…
|
drh
|
2190 |
const char *zQ = P("q"); |
|
e356f18…
|
drh
|
2191 |
int go = P("go")!=0; |
|
e356f18…
|
drh
|
2192 |
login_check_credentials(); |
|
e356f18…
|
drh
|
2193 |
if( !g.perm.Setup ){ |
|
653dd40…
|
drh
|
2194 |
login_needed(0); |
|
653dd40…
|
drh
|
2195 |
return; |
|
e356f18…
|
drh
|
2196 |
} |
|
112c713…
|
drh
|
2197 |
style_set_current_feature("setup"); |
|
e356f18…
|
drh
|
2198 |
style_header("Raw TH1 Commands"); |
|
e356f18…
|
drh
|
2199 |
@ <p><b>Caution:</b> There are no restrictions on the TH1 that can be |
|
e356f18…
|
drh
|
2200 |
@ run by this page. If Tcl integration was enabled at compile-time and |
|
e356f18…
|
drh
|
2201 |
@ the "tcl" setting is enabled, Tcl commands may be run as well.</p> |
|
e356f18…
|
drh
|
2202 |
@ |
|
920ace1…
|
drh
|
2203 |
form_begin(0, "%R/admin_th1"); |
|
f5482a0…
|
wyoung
|
2204 |
@ TH1:<br> |
|
f5482a0…
|
wyoung
|
2205 |
@ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br> |
|
e356f18…
|
drh
|
2206 |
@ <input type="submit" name="go" value="Run TH1"> |
|
e356f18…
|
drh
|
2207 |
@ </form> |
|
920ace1…
|
drh
|
2208 |
if( go && cgi_csrf_safe(2) ){ |
|
e356f18…
|
drh
|
2209 |
const char *zR; |
|
e356f18…
|
drh
|
2210 |
int rc; |
|
e356f18…
|
drh
|
2211 |
int n; |
|
f5482a0…
|
wyoung
|
2212 |
@ <hr> |
|
e356f18…
|
drh
|
2213 |
rc = Th_Eval(g.interp, 0, zQ, -1); |
|
e356f18…
|
drh
|
2214 |
zR = Th_GetResult(g.interp, &n); |
|
e356f18…
|
drh
|
2215 |
if( rc==TH_OK ){ |
|
e356f18…
|
drh
|
2216 |
@ <pre class="th1result">%h(zR)</pre> |
|
e356f18…
|
drh
|
2217 |
}else{ |
|
e356f18…
|
drh
|
2218 |
@ <pre class="th1error">%h(zR)</pre> |
|
e356f18…
|
drh
|
2219 |
} |
|
e356f18…
|
drh
|
2220 |
} |
|
112c713…
|
drh
|
2221 |
style_finish_page(); |
|
f3455a5…
|
drh
|
2222 |
} |
|
f3455a5…
|
drh
|
2223 |
|
|
f3455a5…
|
drh
|
2224 |
/* |
|
f3455a5…
|
drh
|
2225 |
** WEBPAGE: admin_log |
|
f3455a5…
|
drh
|
2226 |
** |
|
f3455a5…
|
drh
|
2227 |
** Shows the contents of the admin_log table, which is only created if |
|
f3455a5…
|
drh
|
2228 |
** the admin-log setting is enabled. Requires Admin or Setup ('a' or |
|
f3455a5…
|
drh
|
2229 |
** 's') permissions. |
|
f3455a5…
|
drh
|
2230 |
*/ |
|
f3455a5…
|
drh
|
2231 |
void page_admin_log(){ |
|
703b57c…
|
drh
|
2232 |
Stmt stLog; |
|
703b57c…
|
drh
|
2233 |
int limit; /* How many entries to show */ |
|
703b57c…
|
drh
|
2234 |
int ofst; /* Offset to the first entry */ |
|
f3455a5…
|
drh
|
2235 |
int fLogEnabled; |
|
f3455a5…
|
drh
|
2236 |
int counter = 0; |
|
f3455a5…
|
drh
|
2237 |
login_check_credentials(); |
|
42c3364…
|
wyoung
|
2238 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
2239 |
login_needed(0); |
|
653dd40…
|
drh
|
2240 |
return; |
|
653dd40…
|
drh
|
2241 |
} |
|
112c713…
|
drh
|
2242 |
style_set_current_feature("setup"); |
|
3967d04…
|
drh
|
2243 |
style_header("Admin Log"); |
|
b28badb…
|
drh
|
2244 |
style_submenu_element("Log-Menu", "setup-logmenu"); |
|
3967d04…
|
drh
|
2245 |
create_admin_log_table(); |
|
703b57c…
|
drh
|
2246 |
limit = atoi(PD("n","200")); |
|
703b57c…
|
drh
|
2247 |
ofst = atoi(PD("x","0")); |
|
bdf12f4…
|
drh
|
2248 |
fLogEnabled = db_get_boolean("admin-log", 1); |
|
3967d04…
|
drh
|
2249 |
@ <div>Admin logging is %s(fLogEnabled?"on":"off"). |
|
3967d04…
|
drh
|
2250 |
@ (Change this on the <a href="setup_settings">settings</a> page.)</div> |
|
3967d04…
|
drh
|
2251 |
|
|
703b57c…
|
drh
|
2252 |
if( ofst>0 ){ |
|
703b57c…
|
drh
|
2253 |
int prevx = ofst - limit; |
|
703b57c…
|
drh
|
2254 |
if( prevx<0 ) prevx = 0; |
|
703b57c…
|
drh
|
2255 |
@ <p><a href="admin_log?n=%d(limit)&x=%d(prevx)">[Newer]</a></p> |
|
703b57c…
|
drh
|
2256 |
} |
|
703b57c…
|
drh
|
2257 |
db_prepare(&stLog, |
|
703b57c…
|
drh
|
2258 |
"SELECT datetime(time,'unixepoch'), who, page, what " |
|
703b57c…
|
drh
|
2259 |
"FROM admin_log " |
|
673dc38…
|
stephan
|
2260 |
"ORDER BY time DESC, rowid DESC"); |
|
6b645d6…
|
drh
|
2261 |
style_table_sorter(); |
|
6b645d6…
|
drh
|
2262 |
@ <table class="sortable adminLogTable" width="100%%" \ |
|
6b645d6…
|
drh
|
2263 |
@ data-column-types='Tttx' data-init-sort='1'> |
|
f3455a5…
|
drh
|
2264 |
@ <thead> |
|
f3455a5…
|
drh
|
2265 |
@ <th>Time</th> |
|
f3455a5…
|
drh
|
2266 |
@ <th>User</th> |
|
f3455a5…
|
drh
|
2267 |
@ <th>Page</th> |
|
f3455a5…
|
drh
|
2268 |
@ <th width="60%%">Message</th> |
|
f3455a5…
|
drh
|
2269 |
@ </thead><tbody> |
|
f3455a5…
|
drh
|
2270 |
while( SQLITE_ROW == db_step(&stLog) ){ |
|
5330d10…
|
jan.nijtmans
|
2271 |
const char *zTime = db_column_text(&stLog, 0); |
|
5330d10…
|
jan.nijtmans
|
2272 |
const char *zUser = db_column_text(&stLog, 1); |
|
5330d10…
|
jan.nijtmans
|
2273 |
const char *zPage = db_column_text(&stLog, 2); |
|
5330d10…
|
jan.nijtmans
|
2274 |
const char *zMessage = db_column_text(&stLog, 3); |
|
703b57c…
|
drh
|
2275 |
counter++; |
|
703b57c…
|
drh
|
2276 |
if( counter<ofst ) continue; |
|
703b57c…
|
drh
|
2277 |
if( counter>ofst+limit ) break; |
|
703b57c…
|
drh
|
2278 |
@ <tr class="row%d(counter%2)"> |
|
f3455a5…
|
drh
|
2279 |
@ <td class="adminTime">%s(zTime)</td> |
|
f3455a5…
|
drh
|
2280 |
@ <td>%s(zUser)</td> |
|
f3455a5…
|
drh
|
2281 |
@ <td>%s(zPage)</td> |
|
f3455a5…
|
drh
|
2282 |
@ <td>%h(zMessage)</td> |
|
f3455a5…
|
drh
|
2283 |
@ </tr> |
|
f3455a5…
|
drh
|
2284 |
} |
|
6022ad4…
|
drh
|
2285 |
db_finalize(&stLog); |
|
f3455a5…
|
drh
|
2286 |
@ </tbody></table> |
|
703b57c…
|
drh
|
2287 |
if( counter>ofst+limit ){ |
|
703b57c…
|
drh
|
2288 |
@ <p><a href="admin_log?n=%d(limit)&x=%d(limit+ofst)">[Older]</a></p> |
|
ca833ff…
|
drh
|
2289 |
} |
|
112c713…
|
drh
|
2290 |
style_finish_page(); |
|
112c713…
|
drh
|
2291 |
} |
|
112c713…
|
drh
|
2292 |
|
|
0e5d27f…
|
stephan
|
2293 |
|
|
0e5d27f…
|
stephan
|
2294 |
/* |
|
0e5d27f…
|
stephan
|
2295 |
** Renders a selection list of values for the search-tokenizer |
|
0e5d27f…
|
stephan
|
2296 |
** setting, using the form field name "ftstok". |
|
0e5d27f…
|
stephan
|
2297 |
*/ |
|
0e5d27f…
|
stephan
|
2298 |
static void select_fts_tokenizer(void){ |
|
0e5d27f…
|
stephan
|
2299 |
const char *const aTokenizer[] = { |
|
0e5d27f…
|
stephan
|
2300 |
"off", "None", |
|
0e5d27f…
|
stephan
|
2301 |
"porter", "Porter Stemmer", |
|
e180dbb…
|
stephan
|
2302 |
"unicode61", "Unicode without stemming", |
|
e180dbb…
|
stephan
|
2303 |
"trigram", "Trigram", |
|
0e5d27f…
|
stephan
|
2304 |
}; |
|
0e5d27f…
|
stephan
|
2305 |
multiple_choice_attribute("FTS Tokenizer", "search-tokenizer", |
|
e180dbb…
|
stephan
|
2306 |
"ftstok", "off", 4, aTokenizer); |
|
0e5d27f…
|
stephan
|
2307 |
} |
|
0e5d27f…
|
stephan
|
2308 |
|
|
ca833ff…
|
drh
|
2309 |
/* |
|
ca833ff…
|
drh
|
2310 |
** WEBPAGE: srchsetup |
|
ca833ff…
|
drh
|
2311 |
** |
|
7ab0328…
|
drh
|
2312 |
** Configure the search engine. Requires Admin privilege. |
|
ca833ff…
|
drh
|
2313 |
*/ |
|
ca833ff…
|
drh
|
2314 |
void page_srchsetup(){ |
|
ca0d66b…
|
danield
|
2315 |
const char *zMainBranch; |
|
ca833ff…
|
drh
|
2316 |
login_check_credentials(); |
|
42c3364…
|
wyoung
|
2317 |
if( !g.perm.Admin ){ |
|
653dd40…
|
drh
|
2318 |
login_needed(0); |
|
653dd40…
|
drh
|
2319 |
return; |
|
ca833ff…
|
drh
|
2320 |
} |
|
112c713…
|
drh
|
2321 |
style_set_current_feature("setup"); |
|
ca833ff…
|
drh
|
2322 |
style_header("Search Configuration"); |
|
a40e8a0…
|
drh
|
2323 |
@ <form action="%R/srchsetup" method="post"><div> |
|
ca833ff…
|
drh
|
2324 |
login_insert_csrf_secret(); |
|
ca833ff…
|
drh
|
2325 |
@ <div style="text-align:center;font-weight:bold;"> |
|
5260fbf…
|
jan.nijtmans
|
2326 |
@ Server-specific settings that affect the |
|
6714c94…
|
drh
|
2327 |
@ <a href="%R/search">/search</a> webpage. |
|
ca833ff…
|
drh
|
2328 |
@ </div> |
|
f5482a0…
|
wyoung
|
2329 |
@ <hr> |
|
ca833ff…
|
drh
|
2330 |
textarea_attribute("Document Glob List", 3, 35, "doc-glob", "dg", "", 0); |
|
5260fbf…
|
jan.nijtmans
|
2331 |
@ <p>The "Document Glob List" is a comma- or newline-separated list |
|
ca833ff…
|
drh
|
2332 |
@ of GLOB expressions that identify all documents within the source |
|
ca833ff…
|
drh
|
2333 |
@ tree that are to be searched when "Document Search" is enabled. |
|
ca833ff…
|
drh
|
2334 |
@ Some examples: |
|
ca833ff…
|
drh
|
2335 |
@ <table border=0 cellpadding=2 align=center> |
|
ca833ff…
|
drh
|
2336 |
@ <tr><td>*.wiki,*.html,*.md,*.txt<td style="width: 4x;"> |
|
ca833ff…
|
drh
|
2337 |
@ <td>Search all wiki, HTML, Markdown, and Text files</tr> |
|
ca833ff…
|
drh
|
2338 |
@ <tr><td>doc/*.md,*/README.txt,README.txt<td> |
|
ca833ff…
|
drh
|
2339 |
@ <td>Search all Markdown files in the doc/ subfolder and all README.txt |
|
ca833ff…
|
drh
|
2340 |
@ files.</tr> |
|
ca833ff…
|
drh
|
2341 |
@ <tr><td>*<td><td>Search all checked-in files</tr> |
|
ca833ff…
|
drh
|
2342 |
@ <tr><td><i>(blank)</i><td> |
|
ca833ff…
|
drh
|
2343 |
@ <td>Search nothing. (Disables document search).</tr> |
|
ca833ff…
|
drh
|
2344 |
@ </table> |
|
f5482a0…
|
wyoung
|
2345 |
@ <hr> |
|
ca0d66b…
|
danield
|
2346 |
zMainBranch = db_main_branch(); |
|
3a6dd83…
|
drh
|
2347 |
entry_attribute("Document Branches", 20, "doc-branch", "db", zMainBranch, 0); |
|
ca833ff…
|
drh
|
2348 |
@ <p>When searching documents, use the versions of the files found at the |
|
3a6dd83…
|
drh
|
2349 |
@ type of the "Document Branches" branch. Recommended value: the name of |
|
3a6dd83…
|
drh
|
2350 |
@ the main branch (usually "trunk"). |
|
40d0b36…
|
stephan
|
2351 |
@ Document search is disabled if blank. It may be a list of branch names |
|
40d0b36…
|
stephan
|
2352 |
@ separated by spaces and/or commas. |
|
f5482a0…
|
wyoung
|
2353 |
@ <hr> |
|
ca833ff…
|
drh
|
2354 |
onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0); |
|
f5482a0…
|
wyoung
|
2355 |
@ <br> |
|
ca833ff…
|
drh
|
2356 |
onoff_attribute("Search Documents", "search-doc", "sd", 0, 0); |
|
f5482a0…
|
wyoung
|
2357 |
@ <br> |
|
ca833ff…
|
drh
|
2358 |
onoff_attribute("Search Tickets", "search-tkt", "st", 0, 0); |
|
f5482a0…
|
wyoung
|
2359 |
@ <br> |
|
a551d50…
|
andygoth
|
2360 |
onoff_attribute("Search Wiki", "search-wiki", "sw", 0, 0); |
|
f5482a0…
|
wyoung
|
2361 |
@ <br> |
|
a551d50…
|
andygoth
|
2362 |
onoff_attribute("Search Tech Notes", "search-technote", "se", 0, 0); |
|
f5482a0…
|
wyoung
|
2363 |
@ <br> |
|
99fcc43…
|
drh
|
2364 |
onoff_attribute("Search Forum", "search-forum", "sf", 0, 0); |
|
6d9f0f5…
|
drh
|
2365 |
@ <br> |
|
6d9f0f5…
|
drh
|
2366 |
onoff_attribute("Search Built-in Help Text", "search-help", "sh", 0, 0); |
|
f5482a0…
|
wyoung
|
2367 |
@ <hr> |
|
f5482a0…
|
wyoung
|
2368 |
@ <p><input type="submit" name="submit" value="Apply Changes"></p> |
|
f5482a0…
|
wyoung
|
2369 |
@ <hr> |
|
43af043…
|
drh
|
2370 |
if( cgi_csrf_safe(2) ){ |
|
43af043…
|
drh
|
2371 |
if( P("fts0") ){ |
|
43af043…
|
drh
|
2372 |
search_drop_index(); |
|
43af043…
|
drh
|
2373 |
}else if( P("fts1") ){ |
|
43af043…
|
drh
|
2374 |
const char *zTokenizer = PD("ftstok","off"); |
|
43af043…
|
drh
|
2375 |
search_set_tokenizer(zTokenizer); |
|
43af043…
|
drh
|
2376 |
search_drop_index(); |
|
43af043…
|
drh
|
2377 |
search_create_index(); |
|
43af043…
|
drh
|
2378 |
search_fill_index(); |
|
43af043…
|
drh
|
2379 |
search_update_index(search_restrict(SRCH_ALL)); |
|
43af043…
|
drh
|
2380 |
} |
|
43af043…
|
drh
|
2381 |
if( P("rbldchatidx") ){ |
|
43af043…
|
drh
|
2382 |
chat_rebuild_index(1); |
|
43af043…
|
drh
|
2383 |
} |
|
a00a140…
|
drh
|
2384 |
} |
|
a00a140…
|
drh
|
2385 |
if( search_index_exists() ){ |
|
5c5e549…
|
drh
|
2386 |
int pgsz = db_int64(0, "PRAGMA repository.page_size;"); |
|
5c5e549…
|
drh
|
2387 |
i64 nTotal = db_int64(0, "PRAGMA repository.page_count;")*pgsz; |
|
5c5e549…
|
drh
|
2388 |
i64 nFts = db_int64(0, "SELECT count(*) FROM dbstat" |
|
5c5e549…
|
drh
|
2389 |
" WHERE schema='repository'" |
|
5c5e549…
|
drh
|
2390 |
" AND name LIKE 'fts%%'")*pgsz; |
|
5c5e549…
|
drh
|
2391 |
char zSize[30]; |
|
5c5e549…
|
drh
|
2392 |
approxSizeName(sizeof(zSize),zSize,nFts); |
|
c3c4ef1…
|
stephan
|
2393 |
@ <p>Currently using an SQLite FTS%d(search_index_type(0)) search index. |
|
c3c4ef1…
|
stephan
|
2394 |
@ The index helps search run faster, especially on large repositories, |
|
5c5e549…
|
drh
|
2395 |
@ but takes up space. The index is currently using about %s(zSize) |
|
5c5e549…
|
drh
|
2396 |
@ or %.1f(100.0*(double)nFts/(double)nTotal)%% of the repository.</p> |
|
0e5d27f…
|
stephan
|
2397 |
select_fts_tokenizer(); |
|
a00a140…
|
drh
|
2398 |
@ <p><input type="submit" name="fts0" value="Delete The Full-Text Index"> |
|
13d93e4…
|
drh
|
2399 |
@ <input type="submit" name="fts1" value="Rebuild The Full-Text Index"> |
|
43af043…
|
drh
|
2400 |
if( db_table_exists("repository","chat") ){ |
|
43af043…
|
drh
|
2401 |
@ <input type="submit" name="rbldchatidx" \ |
|
43af043…
|
drh
|
2402 |
@ value="Rebuild The Chat FTS Index"> |
|
43af043…
|
drh
|
2403 |
} |
|
53d1f05…
|
drh
|
2404 |
style_submenu_element("FTS Index Debugging","%R/test-ftsdocs"); |
|
a00a140…
|
drh
|
2405 |
}else{ |
|
c3c4ef1…
|
stephan
|
2406 |
@ <p>The SQLite search index is disabled. All searching will be |
|
a00a140…
|
drh
|
2407 |
@ a full-text scan. This usually works fine, but can be slow for |
|
a00a140…
|
drh
|
2408 |
@ larger repositories.</p> |
|
0e5d27f…
|
stephan
|
2409 |
select_fts_tokenizer(); |
|
a00a140…
|
drh
|
2410 |
@ <p><input type="submit" name="fts1" value="Create A Full-Text Index"> |
|
a00a140…
|
drh
|
2411 |
} |
|
ca833ff…
|
drh
|
2412 |
@ </div></form> |
|
112c713…
|
drh
|
2413 |
style_finish_page(); |
|
8131f1c…
|
drh
|
2414 |
} |
|
8131f1c…
|
drh
|
2415 |
|
|
8131f1c…
|
drh
|
2416 |
/* |
|
8131f1c…
|
drh
|
2417 |
** A URL Alias originally called zOldName is now zNewName/zValue. |
|
8131f1c…
|
drh
|
2418 |
** Write SQL to make this change into pSql. |
|
8131f1c…
|
drh
|
2419 |
** |
|
8131f1c…
|
drh
|
2420 |
** If zNewName or zValue is an empty string, then delete the entry. |
|
8131f1c…
|
drh
|
2421 |
** |
|
8131f1c…
|
drh
|
2422 |
** If zOldName is an empty string, create a new entry. |
|
8131f1c…
|
drh
|
2423 |
*/ |
|
8131f1c…
|
drh
|
2424 |
static void setup_update_url_alias( |
|
8131f1c…
|
drh
|
2425 |
Blob *pSql, |
|
8131f1c…
|
drh
|
2426 |
const char *zOldName, |
|
8131f1c…
|
drh
|
2427 |
const char *zNewName, |
|
8131f1c…
|
drh
|
2428 |
const char *zValue |
|
8131f1c…
|
drh
|
2429 |
){ |
|
920ace1…
|
drh
|
2430 |
if( !cgi_csrf_safe(2) ) return; |
|
8131f1c…
|
drh
|
2431 |
if( zNewName[0]==0 || zValue[0]==0 ){ |
|
8131f1c…
|
drh
|
2432 |
if( zOldName[0] ){ |
|
8131f1c…
|
drh
|
2433 |
blob_append_sql(pSql, |
|
8131f1c…
|
drh
|
2434 |
"DELETE FROM config WHERE name='walias:%q';\n", |
|
8131f1c…
|
drh
|
2435 |
zOldName); |
|
8131f1c…
|
drh
|
2436 |
} |
|
8131f1c…
|
drh
|
2437 |
return; |
|
8131f1c…
|
drh
|
2438 |
} |
|
8131f1c…
|
drh
|
2439 |
if( zOldName[0]==0 ){ |
|
8131f1c…
|
drh
|
2440 |
blob_append_sql(pSql, |
|
8131f1c…
|
drh
|
2441 |
"INSERT INTO config(name,value,mtime) VALUES('walias:%q',%Q,now());\n", |
|
8131f1c…
|
drh
|
2442 |
zNewName, zValue); |
|
8131f1c…
|
drh
|
2443 |
return; |
|
8131f1c…
|
drh
|
2444 |
} |
|
8131f1c…
|
drh
|
2445 |
if( strcmp(zOldName, zNewName)!=0 ){ |
|
8131f1c…
|
drh
|
2446 |
blob_append_sql(pSql, |
|
8131f1c…
|
drh
|
2447 |
"UPDATE config SET name='walias:%q', value=%Q, mtime=now()" |
|
8131f1c…
|
drh
|
2448 |
" WHERE name='walias:%q';\n", |
|
8131f1c…
|
drh
|
2449 |
zNewName, zValue, zOldName); |
|
8131f1c…
|
drh
|
2450 |
}else{ |
|
8131f1c…
|
drh
|
2451 |
blob_append_sql(pSql, |
|
8131f1c…
|
drh
|
2452 |
"UPDATE config SET value=%Q, mtime=now()" |
|
8131f1c…
|
drh
|
2453 |
" WHERE name='walias:%q' AND value<>%Q;\n", |
|
8131f1c…
|
drh
|
2454 |
zValue, zOldName, zValue); |
|
8131f1c…
|
drh
|
2455 |
} |
|
8131f1c…
|
drh
|
2456 |
} |
|
8131f1c…
|
drh
|
2457 |
|
|
8131f1c…
|
drh
|
2458 |
/* |
|
8131f1c…
|
drh
|
2459 |
** WEBPAGE: waliassetup |
|
8131f1c…
|
drh
|
2460 |
** |
|
8131f1c…
|
drh
|
2461 |
** Configure the URL aliases |
|
8131f1c…
|
drh
|
2462 |
*/ |
|
8131f1c…
|
drh
|
2463 |
void page_waliassetup(){ |
|
8131f1c…
|
drh
|
2464 |
Stmt q; |
|
8131f1c…
|
drh
|
2465 |
int cnt = 0; |
|
8131f1c…
|
drh
|
2466 |
Blob namelist; |
|
8131f1c…
|
drh
|
2467 |
login_check_credentials(); |
|
42c3364…
|
wyoung
|
2468 |
if( !g.perm.Admin ){ |
|
8131f1c…
|
drh
|
2469 |
login_needed(0); |
|
8131f1c…
|
drh
|
2470 |
return; |
|
8131f1c…
|
drh
|
2471 |
} |
|
112c713…
|
drh
|
2472 |
style_set_current_feature("setup"); |
|
a3e50c9…
|
andygoth
|
2473 |
style_header("URL Alias Configuration"); |
|
920ace1…
|
drh
|
2474 |
if( P("submit")!=0 && cgi_csrf_safe(2) ){ |
|
8131f1c…
|
drh
|
2475 |
Blob token; |
|
8131f1c…
|
drh
|
2476 |
Blob sql; |
|
8131f1c…
|
drh
|
2477 |
const char *zNewName; |
|
8131f1c…
|
drh
|
2478 |
const char *zValue; |
|
8131f1c…
|
drh
|
2479 |
char zCnt[10]; |
|
8131f1c…
|
drh
|
2480 |
blob_init(&namelist, PD("namelist",""), -1); |
|
8131f1c…
|
drh
|
2481 |
blob_init(&sql, 0, 0); |
|
8131f1c…
|
drh
|
2482 |
while( blob_token(&namelist, &token) ){ |
|
8131f1c…
|
drh
|
2483 |
const char *zOldName = blob_str(&token); |
|
8131f1c…
|
drh
|
2484 |
sqlite3_snprintf(sizeof(zCnt), zCnt, "n%d", cnt); |
|
8131f1c…
|
drh
|
2485 |
zNewName = PD(zCnt, ""); |
|
8131f1c…
|
drh
|
2486 |
sqlite3_snprintf(sizeof(zCnt), zCnt, "v%d", cnt); |
|
8131f1c…
|
drh
|
2487 |
zValue = PD(zCnt, ""); |
|
8131f1c…
|
drh
|
2488 |
setup_update_url_alias(&sql, zOldName, zNewName, zValue); |
|
8131f1c…
|
drh
|
2489 |
cnt++; |
|
8131f1c…
|
drh
|
2490 |
blob_reset(&token); |
|
8131f1c…
|
drh
|
2491 |
} |
|
8131f1c…
|
drh
|
2492 |
sqlite3_snprintf(sizeof(zCnt), zCnt, "n%d", cnt); |
|
8131f1c…
|
drh
|
2493 |
zNewName = PD(zCnt,""); |
|
8131f1c…
|
drh
|
2494 |
sqlite3_snprintf(sizeof(zCnt), zCnt, "v%d", cnt); |
|
8131f1c…
|
drh
|
2495 |
zValue = PD(zCnt,""); |
|
8131f1c…
|
drh
|
2496 |
setup_update_url_alias(&sql, "", zNewName, zValue); |
|
f273832…
|
mistachkin
|
2497 |
db_unprotect(PROTECT_CONFIG); |
|
8131f1c…
|
drh
|
2498 |
db_multi_exec("%s", blob_sql_text(&sql)); |
|
f273832…
|
mistachkin
|
2499 |
db_protect_pop(); |
|
8131f1c…
|
drh
|
2500 |
blob_reset(&sql); |
|
8131f1c…
|
drh
|
2501 |
blob_reset(&namelist); |
|
8131f1c…
|
drh
|
2502 |
cnt = 0; |
|
8131f1c…
|
drh
|
2503 |
} |
|
8131f1c…
|
drh
|
2504 |
db_prepare(&q, |
|
8131f1c…
|
drh
|
2505 |
"SELECT substr(name,8), value FROM config WHERE name GLOB 'walias:/*'" |
|
8131f1c…
|
drh
|
2506 |
" UNION ALL SELECT '', ''" |
|
8131f1c…
|
drh
|
2507 |
); |
|
a40e8a0…
|
drh
|
2508 |
@ <form action="%R/waliassetup" method="post"><div> |
|
8131f1c…
|
drh
|
2509 |
login_insert_csrf_secret(); |
|
8131f1c…
|
drh
|
2510 |
@ <table border=0 cellpadding=5> |
|
8131f1c…
|
drh
|
2511 |
@ <tr><th>Alias<th>URI That The Alias Maps Into |
|
8131f1c…
|
drh
|
2512 |
blob_init(&namelist, 0, 0); |
|
8131f1c…
|
drh
|
2513 |
while( db_step(&q)==SQLITE_ROW ){ |
|
8131f1c…
|
drh
|
2514 |
const char *zName = db_column_text(&q, 0); |
|
8131f1c…
|
drh
|
2515 |
const char *zValue = db_column_text(&q, 1); |
|
8131f1c…
|
drh
|
2516 |
@ <tr><td> |
|
8131f1c…
|
drh
|
2517 |
@ <input type='text' size='20' value='%h(zName)' name='n%d(cnt)'> |
|
8131f1c…
|
drh
|
2518 |
@ </td><td> |
|
8131f1c…
|
drh
|
2519 |
@ <input type='text' size='80' value='%h(zValue)' name='v%d(cnt)'> |
|
8131f1c…
|
drh
|
2520 |
@ </td></tr> |
|
8131f1c…
|
drh
|
2521 |
cnt++; |
|
8131f1c…
|
drh
|
2522 |
if( blob_size(&namelist)>0 ) blob_append(&namelist, " ", 1); |
|
8131f1c…
|
drh
|
2523 |
blob_append(&namelist, zName, -1); |
|
8131f1c…
|
drh
|
2524 |
} |
|
8131f1c…
|
drh
|
2525 |
db_finalize(&q); |
|
8131f1c…
|
drh
|
2526 |
@ <tr><td> |
|
8131f1c…
|
drh
|
2527 |
@ <input type='hidden' name='namelist' value='%h(blob_str(&namelist))'> |
|
8131f1c…
|
drh
|
2528 |
@ <input type='submit' name='submit' value="Apply Changes"> |
|
8131f1c…
|
drh
|
2529 |
@ </td><td></td></tr> |
|
8131f1c…
|
drh
|
2530 |
@ </table></form> |
|
a3b689b…
|
drh
|
2531 |
@ <hr> |
|
7001228…
|
drh
|
2532 |
@ <p>When the first term of an incoming URL exactly matches one of |
|
7001228…
|
drh
|
2533 |
@ the "Aliases" on the left-hand side (LHS) above, the URL is |
|
7001228…
|
drh
|
2534 |
@ converted into the corresponding form on the right-hand side (RHS). |
|
a3b689b…
|
drh
|
2535 |
@ <ul> |
|
a3b689b…
|
drh
|
2536 |
@ <li><p> |
|
a3b689b…
|
drh
|
2537 |
@ The LHS is compared against only the first term of the incoming URL. |
|
a3b689b…
|
drh
|
2538 |
@ All LHS entries in the alias table should therefore begin with a |
|
a3b689b…
|
drh
|
2539 |
@ single "/" followed by a single path element. |
|
a3b689b…
|
drh
|
2540 |
@ <li><p> |
|
7001228…
|
drh
|
2541 |
@ The RHS entries in the alias table should begin with a single "/" |
|
7001228…
|
drh
|
2542 |
@ followed by a path element, and optionally followed by "?" and a |
|
7001228…
|
drh
|
2543 |
@ list of query parameters. |
|
a3b689b…
|
drh
|
2544 |
@ <li><p> |
|
a3b689b…
|
drh
|
2545 |
@ Query parameters on the RHS are added to the set of query parameters |
|
a3b689b…
|
drh
|
2546 |
@ in the incoming URL. |
|
a3b689b…
|
drh
|
2547 |
@ <li><p> |
|
7001228…
|
drh
|
2548 |
@ If the same query parameter appears in both the incoming URL and |
|
7001228…
|
drh
|
2549 |
@ on the RHS of the alias, the RHS query parameter value overwrites |
|
7001228…
|
drh
|
2550 |
@ the value on the incoming URL. |
|
a3b689b…
|
drh
|
2551 |
@ <li><p> |
|
7001228…
|
drh
|
2552 |
@ If a query parameter on the RHS of the alias is of the form "X!" |
|
7001228…
|
drh
|
2553 |
@ (a name followed by "!") then the X query parameter is removed |
|
7001228…
|
drh
|
2554 |
@ from the incoming URL if |
|
7001228…
|
drh
|
2555 |
@ it exists. |
|
a3b689b…
|
drh
|
2556 |
@ <li><p> |
|
a3b689b…
|
drh
|
2557 |
@ Only a single alias operation occurs. It is not possible to nest aliases. |
|
a3b689b…
|
drh
|
2558 |
@ The RHS entries must be built-in webpage names. |
|
a3b689b…
|
drh
|
2559 |
@ <li><p> |
|
7001228…
|
drh
|
2560 |
@ The alias table is only checked if no built-in webpage matches |
|
7001228…
|
drh
|
2561 |
@ the incoming URL. |
|
7001228…
|
drh
|
2562 |
@ Hence, it is not possible to override a built-in webpage using aliases. |
|
7001228…
|
drh
|
2563 |
@ This is by design. |
|
a3b689b…
|
drh
|
2564 |
@ </ul> |
|
a3b689b…
|
drh
|
2565 |
@ |
|
aad384d…
|
andygoth
|
2566 |
@ <p>To delete an entry from the alias table, change its name or value to an |
|
a3b689b…
|
drh
|
2567 |
@ empty string and press "Apply Changes". |
|
a3b689b…
|
drh
|
2568 |
@ |
|
7001228…
|
drh
|
2569 |
@ <p>To add a new alias, fill in the name and value in the bottom row |
|
7001228…
|
drh
|
2570 |
@ of the table above and press "Apply Changes". |
|
112c713…
|
drh
|
2571 |
style_finish_page(); |
|
dbda8d6…
|
drh
|
2572 |
} |