Fossil SCM

Merge in latest from trunk.

andybradford 2018-03-08 04:03 pledge-additions merge
Commit 0d11ea056b0998b5fe9c337b68ec4a62ffa1e5ce03135ce53553564da006dc4c
+71 -125
--- src/cgi.c
+++ src/cgi.c
@@ -217,73 +217,20 @@
217217
}
218218
if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
219219
zSecure = " secure;";
220220
}
221221
if( lifetime>0 ){
222
- lifetime += (int)time(0);
223222
blob_appendf(&extraHeader,
224
- "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n",
225
- zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure);
223
+ "Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly;%s Version=1\r\n",
224
+ zName, zValue, zPath, lifetime, zSecure);
226225
}else{
227226
blob_appendf(&extraHeader,
228227
"Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n",
229228
zName, zValue, zPath, zSecure);
230229
}
231230
}
232231
233
-#if 0
234
-/*
235
-** Add an ETag header line
236
-*/
237
-static char *cgi_add_etag(char *zTxt, int nLen){
238
- MD5Context ctx;
239
- unsigned char digest[16];
240
- int i, j;
241
- char zETag[64];
242
-
243
- MD5Init(&ctx);
244
- MD5Update(&ctx,zTxt,nLen);
245
- MD5Final(digest,&ctx);
246
- for(j=i=0; i<16; i++,j+=2){
247
- bprintf(&zETag[j],sizeof(zETag)-j,"%02x",(int)digest[i]);
248
- }
249
- blob_appendf(&extraHeader, "ETag: %s\r\n", zETag);
250
- return fossil_strdup(zETag);
251
-}
252
-
253
-/*
254
-** Do some cache control stuff. First, we generate an ETag and include it in
255
-** the response headers. Second, we do whatever is necessary to determine if
256
-** the request was asking about caching and whether we need to send back the
257
-** response body. If we shouldn't send a body, return non-zero.
258
-**
259
-** Currently, we just check the ETag against any If-None-Match header.
260
-**
261
-** FIXME: In some cases (attachments, file contents) we could check
262
-** If-Modified-Since headers and always include Last-Modified in responses.
263
-*/
264
-static int check_cache_control(void){
265
- /* FIXME: there's some gotchas wth cookies and some headers. */
266
- char *zETag = cgi_add_etag(blob_buffer(&cgiContent),blob_size(&cgiContent));
267
- char *zMatch = P("HTTP_IF_NONE_MATCH");
268
-
269
- if( zETag!=0 && zMatch!=0 ) {
270
- char *zBuf = fossil_strdup(zMatch);
271
- if( zBuf!=0 ){
272
- char *zTok = 0;
273
- char *zPos;
274
- for( zTok = strtok_r(zBuf, ",\"",&zPos);
275
- zTok && fossil_stricmp(zTok,zETag);
276
- zTok = strtok_r(0, ",\"",&zPos)){}
277
- fossil_free(zBuf);
278
- if(zTok) return 1;
279
- }
280
- }
281
-
282
- return 0;
283
-}
284
-#endif
285232
286233
/*
287234
** Return true if the response should be sent with Content-Encoding: gzip.
288235
*/
289236
static int is_gzippable(void){
@@ -301,29 +248,32 @@
301248
if( iReplyStatus<=0 ){
302249
iReplyStatus = 200;
303250
zReplyStatus = "OK";
304251
}
305252
306
-#if 0
307
- if( iReplyStatus==200 && check_cache_control() ) {
308
- /* change the status to "unchanged" and we can skip sending the
309
- ** actual response body. Obviously we only do this when we _have_ a
310
- ** body (code 200).
311
- */
312
- iReplyStatus = 304;
313
- zReplyStatus = "Not Modified";
314
- }
315
-#endif
316
-
317253
if( g.fullHttpReply ){
318254
fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
319255
fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));
320256
fprintf(g.httpOut, "Connection: close\r\n");
321257
fprintf(g.httpOut, "X-UA-Compatible: IE=edge\r\n");
322258
}else{
323259
fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
324260
}
261
+ if( g.isConst ){
262
+ /* isConst means that the reply is guaranteed to be invariant, even
263
+ ** after configuration changes and/or Fossil binary recompiles. */
264
+ fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
265
+ }else if( etag_tag()!=0 ){
266
+ fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
267
+ fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
268
+ }else{
269
+ fprintf(g.httpOut, "Cache-control: no-cache\r\n");
270
+ }
271
+ if( etag_mtime()>0 ){
272
+ fprintf(g.httpOut, "Last-Modified: %s\r\n",
273
+ cgi_rfc822_datestamp(etag_mtime()));
274
+ }
325275
326276
if( blob_size(&extraHeader)>0 ){
327277
fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
328278
}
329279
@@ -343,24 +293,10 @@
343293
**
344294
** These headers are probably best added by the web server hosting fossil as
345295
** a CGI script.
346296
*/
347297
348
- if( g.isConst ){
349
- /* constant means that the input URL will _never_ generate anything
350
- ** else. In the case of attachments, the contents won't change because
351
- ** an attempt to change them generates a new attachment number. In the
352
- ** case of most /getfile calls for specific versions, the only way the
353
- ** content changes is if someone breaks the SCM. And if that happens, a
354
- ** stale cache is the least of the problem. So we provide an Expires
355
- ** header set to a reasonable period (default: one week).
356
- */
357
- fprintf(g.httpOut, "Cache-control: max-age=28800\r\n");
358
- }else{
359
- fprintf(g.httpOut, "Cache-control: no-cache\r\n");
360
- }
361
-
362298
/* Content intended for logged in users should only be cached in
363299
** the browser, not some shared location.
364300
*/
365301
fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
366302
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
@@ -456,10 +392,33 @@
456392
zRef = P("HTTP_REFERER");
457393
if( zRef==0 ) zRef = zDefault;
458394
}
459395
return zRef;
460396
}
397
+
398
+/*
399
+** Return true if the current request appears to be safe from a
400
+** Cross-Site Request Forgery (CSRF) attack. Conditions that must
401
+** be met:
402
+**
403
+** * The HTTP_REFERER must have the same origin
404
+** * The REQUEST_METHOD must be POST - or requirePost==0
405
+*/
406
+int cgi_csrf_safe(int requirePost){
407
+ const char *zRef = P("HTTP_REFERER");
408
+ int nBase;
409
+ if( zRef==0 ) return 0;
410
+ if( requirePost ){
411
+ const char *zMethod = P("REQUEST_METHOD");
412
+ if( zMethod==0 ) return 0;
413
+ if( strcmp(zMethod,"POST")!=0 ) return 0;
414
+ }
415
+ nBase = (int)strlen(g.zBaseURL);
416
+ if( strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
417
+ if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
418
+ return 1;
419
+}
461420
462421
/*
463422
** Information about all query parameters and cookies are stored
464423
** in these variables.
465424
*/
@@ -1954,55 +1913,42 @@
19541913
**
19551914
** Note that this won't handle all the _allowed_ HTTP formats, just the
19561915
** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
19571916
*/
19581917
time_t cgi_rfc822_parsedate(const char *zDate){
1959
- struct tm t;
1960
- char zIgnore[16];
1961
- char zMonth[16];
1962
-
1963
- memset(&t, 0, sizeof(t));
1964
- if( 7==sscanf(zDate, "%12[A-Za-z,] %d %12[A-Za-z] %d %d:%d:%d", zIgnore,
1965
- &t.tm_mday, zMonth, &t.tm_year, &t.tm_hour, &t.tm_min,
1966
- &t.tm_sec)){
1967
-
1968
- if( t.tm_year > 1900 ) t.tm_year -= 1900;
1969
- for(t.tm_mon=0; azMonths[t.tm_mon]; t.tm_mon++){
1970
- if( !fossil_strnicmp( azMonths[t.tm_mon], zMonth, 3 )){
1971
- return mkgmtime(&t);
1972
- }
1973
- }
1974
- }
1975
-
1976
- return 0;
1977
-}
1978
-
1979
-/*
1980
-** Convert a struct tm* that represents a moment in UTC into the number
1981
-** of seconds in 1970, UTC.
1982
-*/
1983
-time_t mkgmtime(struct tm *p){
1984
- time_t t;
1985
- int nDay;
1986
- int isLeapYr;
1987
- /* Days in each month: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 */
1988
- static int priorDays[] = { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
1989
- if( p->tm_mon<0 ){
1990
- int nYear = (11 - p->tm_mon)/12;
1991
- p->tm_year -= nYear;
1992
- p->tm_mon += nYear*12;
1993
- }else if( p->tm_mon>11 ){
1994
- p->tm_year += p->tm_mon/12;
1995
- p->tm_mon %= 12;
1996
- }
1997
- isLeapYr = p->tm_year%4==0 && (p->tm_year%100!=0 || (p->tm_year+300)%400==0);
1998
- p->tm_yday = priorDays[p->tm_mon] + p->tm_mday - 1;
1999
- if( isLeapYr && p->tm_mon>1 ) p->tm_yday++;
2000
- nDay = (p->tm_year-70)*365 + (p->tm_year-69)/4 -p->tm_year/100 +
2001
- (p->tm_year+300)/400 + p->tm_yday;
2002
- t = ((nDay*24 + p->tm_hour)*60 + p->tm_min)*60 + p->tm_sec;
2003
- return t;
1918
+ int mday, mon, year, yday, hour, min, sec;
1919
+ char zIgnore[4];
1920
+ char zMonth[4];
1921
+ static const char *const azMonths[] =
1922
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
1923
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};
1924
+ if( 7==sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
1925
+ &mday, zMonth, &year, &hour, &min, &sec)){
1926
+ if( year > 1900 ) year -= 1900;
1927
+ for(mon=0; azMonths[mon]; mon++){
1928
+ if( !strncmp( azMonths[mon], zMonth, 3 )){
1929
+ int nDay;
1930
+ int isLeapYr;
1931
+ static int priorDays[] =
1932
+ { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
1933
+ if( mon<0 ){
1934
+ int nYear = (11 - mon)/12;
1935
+ year -= nYear;
1936
+ mon += nYear*12;
1937
+ }else if( mon>11 ){
1938
+ year += mon/12;
1939
+ mon %= 12;
1940
+ }
1941
+ isLeapYr = year%4==0 && (year%100!=0 || (year+300)%400==0);
1942
+ yday = priorDays[mon] + mday - 1;
1943
+ if( isLeapYr && mon>1 ) yday++;
1944
+ nDay = (year-70)*365 + (year-69)/4 - year/100 + (year+300)/400 + yday;
1945
+ return ((time_t)(nDay*24 + hour)*60 + min)*60 + sec;
1946
+ }
1947
+ }
1948
+ }
1949
+ return 0;
20041950
}
20051951
20061952
/*
20071953
** Check the objectTime against the If-Modified-Since request header. If the
20081954
** object time isn't any newer than the header, we immediately send back
20091955
--- src/cgi.c
+++ src/cgi.c
@@ -217,73 +217,20 @@
217 }
218 if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
219 zSecure = " secure;";
220 }
221 if( lifetime>0 ){
222 lifetime += (int)time(0);
223 blob_appendf(&extraHeader,
224 "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n",
225 zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure);
226 }else{
227 blob_appendf(&extraHeader,
228 "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n",
229 zName, zValue, zPath, zSecure);
230 }
231 }
232
233 #if 0
234 /*
235 ** Add an ETag header line
236 */
237 static char *cgi_add_etag(char *zTxt, int nLen){
238 MD5Context ctx;
239 unsigned char digest[16];
240 int i, j;
241 char zETag[64];
242
243 MD5Init(&ctx);
244 MD5Update(&ctx,zTxt,nLen);
245 MD5Final(digest,&ctx);
246 for(j=i=0; i<16; i++,j+=2){
247 bprintf(&zETag[j],sizeof(zETag)-j,"%02x",(int)digest[i]);
248 }
249 blob_appendf(&extraHeader, "ETag: %s\r\n", zETag);
250 return fossil_strdup(zETag);
251 }
252
253 /*
254 ** Do some cache control stuff. First, we generate an ETag and include it in
255 ** the response headers. Second, we do whatever is necessary to determine if
256 ** the request was asking about caching and whether we need to send back the
257 ** response body. If we shouldn't send a body, return non-zero.
258 **
259 ** Currently, we just check the ETag against any If-None-Match header.
260 **
261 ** FIXME: In some cases (attachments, file contents) we could check
262 ** If-Modified-Since headers and always include Last-Modified in responses.
263 */
264 static int check_cache_control(void){
265 /* FIXME: there's some gotchas wth cookies and some headers. */
266 char *zETag = cgi_add_etag(blob_buffer(&cgiContent),blob_size(&cgiContent));
267 char *zMatch = P("HTTP_IF_NONE_MATCH");
268
269 if( zETag!=0 && zMatch!=0 ) {
270 char *zBuf = fossil_strdup(zMatch);
271 if( zBuf!=0 ){
272 char *zTok = 0;
273 char *zPos;
274 for( zTok = strtok_r(zBuf, ",\"",&zPos);
275 zTok && fossil_stricmp(zTok,zETag);
276 zTok = strtok_r(0, ",\"",&zPos)){}
277 fossil_free(zBuf);
278 if(zTok) return 1;
279 }
280 }
281
282 return 0;
283 }
284 #endif
285
286 /*
287 ** Return true if the response should be sent with Content-Encoding: gzip.
288 */
289 static int is_gzippable(void){
@@ -301,29 +248,32 @@
301 if( iReplyStatus<=0 ){
302 iReplyStatus = 200;
303 zReplyStatus = "OK";
304 }
305
306 #if 0
307 if( iReplyStatus==200 && check_cache_control() ) {
308 /* change the status to "unchanged" and we can skip sending the
309 ** actual response body. Obviously we only do this when we _have_ a
310 ** body (code 200).
311 */
312 iReplyStatus = 304;
313 zReplyStatus = "Not Modified";
314 }
315 #endif
316
317 if( g.fullHttpReply ){
318 fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
319 fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));
320 fprintf(g.httpOut, "Connection: close\r\n");
321 fprintf(g.httpOut, "X-UA-Compatible: IE=edge\r\n");
322 }else{
323 fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
324 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
326 if( blob_size(&extraHeader)>0 ){
327 fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
328 }
329
@@ -343,24 +293,10 @@
343 **
344 ** These headers are probably best added by the web server hosting fossil as
345 ** a CGI script.
346 */
347
348 if( g.isConst ){
349 /* constant means that the input URL will _never_ generate anything
350 ** else. In the case of attachments, the contents won't change because
351 ** an attempt to change them generates a new attachment number. In the
352 ** case of most /getfile calls for specific versions, the only way the
353 ** content changes is if someone breaks the SCM. And if that happens, a
354 ** stale cache is the least of the problem. So we provide an Expires
355 ** header set to a reasonable period (default: one week).
356 */
357 fprintf(g.httpOut, "Cache-control: max-age=28800\r\n");
358 }else{
359 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
360 }
361
362 /* Content intended for logged in users should only be cached in
363 ** the browser, not some shared location.
364 */
365 fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
366 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
@@ -456,10 +392,33 @@
456 zRef = P("HTTP_REFERER");
457 if( zRef==0 ) zRef = zDefault;
458 }
459 return zRef;
460 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
462 /*
463 ** Information about all query parameters and cookies are stored
464 ** in these variables.
465 */
@@ -1954,55 +1913,42 @@
1954 **
1955 ** Note that this won't handle all the _allowed_ HTTP formats, just the
1956 ** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
1957 */
1958 time_t cgi_rfc822_parsedate(const char *zDate){
1959 struct tm t;
1960 char zIgnore[16];
1961 char zMonth[16];
1962
1963 memset(&t, 0, sizeof(t));
1964 if( 7==sscanf(zDate, "%12[A-Za-z,] %d %12[A-Za-z] %d %d:%d:%d", zIgnore,
1965 &t.tm_mday, zMonth, &t.tm_year, &t.tm_hour, &t.tm_min,
1966 &t.tm_sec)){
1967
1968 if( t.tm_year > 1900 ) t.tm_year -= 1900;
1969 for(t.tm_mon=0; azMonths[t.tm_mon]; t.tm_mon++){
1970 if( !fossil_strnicmp( azMonths[t.tm_mon], zMonth, 3 )){
1971 return mkgmtime(&t);
1972 }
1973 }
1974 }
1975
1976 return 0;
1977 }
1978
1979 /*
1980 ** Convert a struct tm* that represents a moment in UTC into the number
1981 ** of seconds in 1970, UTC.
1982 */
1983 time_t mkgmtime(struct tm *p){
1984 time_t t;
1985 int nDay;
1986 int isLeapYr;
1987 /* Days in each month: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 */
1988 static int priorDays[] = { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
1989 if( p->tm_mon<0 ){
1990 int nYear = (11 - p->tm_mon)/12;
1991 p->tm_year -= nYear;
1992 p->tm_mon += nYear*12;
1993 }else if( p->tm_mon>11 ){
1994 p->tm_year += p->tm_mon/12;
1995 p->tm_mon %= 12;
1996 }
1997 isLeapYr = p->tm_year%4==0 && (p->tm_year%100!=0 || (p->tm_year+300)%400==0);
1998 p->tm_yday = priorDays[p->tm_mon] + p->tm_mday - 1;
1999 if( isLeapYr && p->tm_mon>1 ) p->tm_yday++;
2000 nDay = (p->tm_year-70)*365 + (p->tm_year-69)/4 -p->tm_year/100 +
2001 (p->tm_year+300)/400 + p->tm_yday;
2002 t = ((nDay*24 + p->tm_hour)*60 + p->tm_min)*60 + p->tm_sec;
2003 return t;
2004 }
2005
2006 /*
2007 ** Check the objectTime against the If-Modified-Since request header. If the
2008 ** object time isn't any newer than the header, we immediately send back
2009
--- src/cgi.c
+++ src/cgi.c
@@ -217,73 +217,20 @@
217 }
218 if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
219 zSecure = " secure;";
220 }
221 if( lifetime>0 ){
 
222 blob_appendf(&extraHeader,
223 "Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly;%s Version=1\r\n",
224 zName, zValue, zPath, lifetime, zSecure);
225 }else{
226 blob_appendf(&extraHeader,
227 "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n",
228 zName, zValue, zPath, zSecure);
229 }
230 }
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
233 /*
234 ** Return true if the response should be sent with Content-Encoding: gzip.
235 */
236 static int is_gzippable(void){
@@ -301,29 +248,32 @@
248 if( iReplyStatus<=0 ){
249 iReplyStatus = 200;
250 zReplyStatus = "OK";
251 }
252
 
 
 
 
 
 
 
 
 
 
 
253 if( g.fullHttpReply ){
254 fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
255 fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));
256 fprintf(g.httpOut, "Connection: close\r\n");
257 fprintf(g.httpOut, "X-UA-Compatible: IE=edge\r\n");
258 }else{
259 fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
260 }
261 if( g.isConst ){
262 /* isConst means that the reply is guaranteed to be invariant, even
263 ** after configuration changes and/or Fossil binary recompiles. */
264 fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
265 }else if( etag_tag()!=0 ){
266 fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
267 fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
268 }else{
269 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
270 }
271 if( etag_mtime()>0 ){
272 fprintf(g.httpOut, "Last-Modified: %s\r\n",
273 cgi_rfc822_datestamp(etag_mtime()));
274 }
275
276 if( blob_size(&extraHeader)>0 ){
277 fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
278 }
279
@@ -343,24 +293,10 @@
293 **
294 ** These headers are probably best added by the web server hosting fossil as
295 ** a CGI script.
296 */
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298 /* Content intended for logged in users should only be cached in
299 ** the browser, not some shared location.
300 */
301 fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
302 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
@@ -456,10 +392,33 @@
392 zRef = P("HTTP_REFERER");
393 if( zRef==0 ) zRef = zDefault;
394 }
395 return zRef;
396 }
397
398 /*
399 ** Return true if the current request appears to be safe from a
400 ** Cross-Site Request Forgery (CSRF) attack. Conditions that must
401 ** be met:
402 **
403 ** * The HTTP_REFERER must have the same origin
404 ** * The REQUEST_METHOD must be POST - or requirePost==0
405 */
406 int cgi_csrf_safe(int requirePost){
407 const char *zRef = P("HTTP_REFERER");
408 int nBase;
409 if( zRef==0 ) return 0;
410 if( requirePost ){
411 const char *zMethod = P("REQUEST_METHOD");
412 if( zMethod==0 ) return 0;
413 if( strcmp(zMethod,"POST")!=0 ) return 0;
414 }
415 nBase = (int)strlen(g.zBaseURL);
416 if( strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
417 if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
418 return 1;
419 }
420
421 /*
422 ** Information about all query parameters and cookies are stored
423 ** in these variables.
424 */
@@ -1954,55 +1913,42 @@
1913 **
1914 ** Note that this won't handle all the _allowed_ HTTP formats, just the
1915 ** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
1916 */
1917 time_t cgi_rfc822_parsedate(const char *zDate){
1918 int mday, mon, year, yday, hour, min, sec;
1919 char zIgnore[4];
1920 char zMonth[4];
1921 static const char *const azMonths[] =
1922 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
1923 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};
1924 if( 7==sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
1925 &mday, zMonth, &year, &hour, &min, &sec)){
1926 if( year > 1900 ) year -= 1900;
1927 for(mon=0; azMonths[mon]; mon++){
1928 if( !strncmp( azMonths[mon], zMonth, 3 )){
1929 int nDay;
1930 int isLeapYr;
1931 static int priorDays[] =
1932 { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
1933 if( mon<0 ){
1934 int nYear = (11 - mon)/12;
1935 year -= nYear;
1936 mon += nYear*12;
1937 }else if( mon>11 ){
1938 year += mon/12;
1939 mon %= 12;
1940 }
1941 isLeapYr = year%4==0 && (year%100!=0 || (year+300)%400==0);
1942 yday = priorDays[mon] + mday - 1;
1943 if( isLeapYr && mon>1 ) yday++;
1944 nDay = (year-70)*365 + (year-69)/4 - year/100 + (year+300)/400 + yday;
1945 return ((time_t)(nDay*24 + hour)*60 + min)*60 + sec;
1946 }
1947 }
1948 }
1949 return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
1950 }
1951
1952 /*
1953 ** Check the objectTime against the If-Modified-Since request header. If the
1954 ** object time isn't any newer than the header, we immediately send back
1955
+4 -3
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559559
/* Find and print all requested changes. */
560560
blob_zero(&report);
561561
status_report(&report, flags);
562562
if( blob_size(&report) ){
563563
if( showHdr ){
564
- fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
565
- g.zLocalRoot);
564
+ fossil_print(
565
+ "Changes for %s at %s:\n", db_get("project-name", "<unnamed>"),
566
+ g.zLocalRoot);
566567
}
567568
blob_write_to_file(&report, "-");
568569
}else if( verboseFlag ){
569570
fossil_print(" (none)\n");
570571
}
@@ -867,11 +868,11 @@
867868
868869
blob_zero(&report);
869870
status_report(&report, flags);
870871
if( blob_size(&report) ){
871872
if( showHdr ){
872
- fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
873
+ fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
873874
g.zLocalRoot);
874875
}
875876
blob_write_to_file(&report, "-");
876877
}
877878
blob_reset(&report);
878879
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559 /* Find and print all requested changes. */
560 blob_zero(&report);
561 status_report(&report, flags);
562 if( blob_size(&report) ){
563 if( showHdr ){
564 fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
565 g.zLocalRoot);
 
566 }
567 blob_write_to_file(&report, "-");
568 }else if( verboseFlag ){
569 fossil_print(" (none)\n");
570 }
@@ -867,11 +868,11 @@
867
868 blob_zero(&report);
869 status_report(&report, flags);
870 if( blob_size(&report) ){
871 if( showHdr ){
872 fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
873 g.zLocalRoot);
874 }
875 blob_write_to_file(&report, "-");
876 }
877 blob_reset(&report);
878
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559 /* Find and print all requested changes. */
560 blob_zero(&report);
561 status_report(&report, flags);
562 if( blob_size(&report) ){
563 if( showHdr ){
564 fossil_print(
565 "Changes for %s at %s:\n", db_get("project-name", "<unnamed>"),
566 g.zLocalRoot);
567 }
568 blob_write_to_file(&report, "-");
569 }else if( verboseFlag ){
570 fossil_print(" (none)\n");
571 }
@@ -867,11 +868,11 @@
868
869 blob_zero(&report);
870 status_report(&report, flags);
871 if( blob_size(&report) ){
872 if( showHdr ){
873 fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
874 g.zLocalRoot);
875 }
876 blob_write_to_file(&report, "-");
877 }
878 blob_reset(&report);
879
+4 -3
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559559
/* Find and print all requested changes. */
560560
blob_zero(&report);
561561
status_report(&report, flags);
562562
if( blob_size(&report) ){
563563
if( showHdr ){
564
- fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
565
- g.zLocalRoot);
564
+ fossil_print(
565
+ "Changes for %s at %s:\n", db_get("project-name", "<unnamed>"),
566
+ g.zLocalRoot);
566567
}
567568
blob_write_to_file(&report, "-");
568569
}else if( verboseFlag ){
569570
fossil_print(" (none)\n");
570571
}
@@ -867,11 +868,11 @@
867868
868869
blob_zero(&report);
869870
status_report(&report, flags);
870871
if( blob_size(&report) ){
871872
if( showHdr ){
872
- fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
873
+ fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
873874
g.zLocalRoot);
874875
}
875876
blob_write_to_file(&report, "-");
876877
}
877878
blob_reset(&report);
878879
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559 /* Find and print all requested changes. */
560 blob_zero(&report);
561 status_report(&report, flags);
562 if( blob_size(&report) ){
563 if( showHdr ){
564 fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
565 g.zLocalRoot);
 
566 }
567 blob_write_to_file(&report, "-");
568 }else if( verboseFlag ){
569 fossil_print(" (none)\n");
570 }
@@ -867,11 +868,11 @@
867
868 blob_zero(&report);
869 status_report(&report, flags);
870 if( blob_size(&report) ){
871 if( showHdr ){
872 fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
873 g.zLocalRoot);
874 }
875 blob_write_to_file(&report, "-");
876 }
877 blob_reset(&report);
878
--- src/checkin.c
+++ src/checkin.c
@@ -559,12 +559,13 @@
559 /* Find and print all requested changes. */
560 blob_zero(&report);
561 status_report(&report, flags);
562 if( blob_size(&report) ){
563 if( showHdr ){
564 fossil_print(
565 "Changes for %s at %s:\n", db_get("project-name", "<unnamed>"),
566 g.zLocalRoot);
567 }
568 blob_write_to_file(&report, "-");
569 }else if( verboseFlag ){
570 fossil_print(" (none)\n");
571 }
@@ -867,11 +868,11 @@
868
869 blob_zero(&report);
870 status_report(&report, flags);
871 if( blob_size(&report) ){
872 if( showHdr ){
873 fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
874 g.zLocalRoot);
875 }
876 blob_write_to_file(&report, "-");
877 }
878 blob_reset(&report);
879
+3 -1
--- src/dispatch.c
+++ src/dispatch.c
@@ -359,18 +359,20 @@
359359
@ <h1>Available commands:</h1>
360360
@ <table border="0"><tr>
361361
for(i=j=0; i<MX_COMMAND; i++){
362362
const char *z = aCommand[i].zName;
363363
if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
364
+ if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
364365
j++;
365366
}
366367
n = (j+5)/6;
367368
for(i=j=0; i<MX_COMMAND; i++){
368369
const char *z = aCommand[i].zName;
369370
const char *zBoldOn = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"<b>" :"";
370371
const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
371372
if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
373
+ if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
372374
if( j==0 ){
373375
@ <td valign="top"><ul>
374376
}
375377
@ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
376378
j++;
@@ -564,11 +566,11 @@
564566
** setting. Webpage names begin with "/". To display a list of available
565567
** topics, use one of:
566568
**
567569
** %fossil help Show common commands
568570
** %fossil help -a|--all Show both common and auxiliary commands
569
-** %fossil help -s|--settings Show setting names
571
+** %fossil help -s|--setting Show setting names
570572
** %fossil help -t|--test Show test commands only
571573
** %fossil help -x|--aux Show auxiliary commands only
572574
** %fossil help -w|--www Show list of webpages
573575
*/
574576
void help_cmd(void){
575577
--- src/dispatch.c
+++ src/dispatch.c
@@ -359,18 +359,20 @@
359 @ <h1>Available commands:</h1>
360 @ <table border="0"><tr>
361 for(i=j=0; i<MX_COMMAND; i++){
362 const char *z = aCommand[i].zName;
363 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
 
364 j++;
365 }
366 n = (j+5)/6;
367 for(i=j=0; i<MX_COMMAND; i++){
368 const char *z = aCommand[i].zName;
369 const char *zBoldOn = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"<b>" :"";
370 const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
371 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
 
372 if( j==0 ){
373 @ <td valign="top"><ul>
374 }
375 @ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
376 j++;
@@ -564,11 +566,11 @@
564 ** setting. Webpage names begin with "/". To display a list of available
565 ** topics, use one of:
566 **
567 ** %fossil help Show common commands
568 ** %fossil help -a|--all Show both common and auxiliary commands
569 ** %fossil help -s|--settings Show setting names
570 ** %fossil help -t|--test Show test commands only
571 ** %fossil help -x|--aux Show auxiliary commands only
572 ** %fossil help -w|--www Show list of webpages
573 */
574 void help_cmd(void){
575
--- src/dispatch.c
+++ src/dispatch.c
@@ -359,18 +359,20 @@
359 @ <h1>Available commands:</h1>
360 @ <table border="0"><tr>
361 for(i=j=0; i<MX_COMMAND; i++){
362 const char *z = aCommand[i].zName;
363 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
364 if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
365 j++;
366 }
367 n = (j+5)/6;
368 for(i=j=0; i<MX_COMMAND; i++){
369 const char *z = aCommand[i].zName;
370 const char *zBoldOn = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"<b>" :"";
371 const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
372 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
373 if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
374 if( j==0 ){
375 @ <td valign="top"><ul>
376 }
377 @ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
378 j++;
@@ -564,11 +566,11 @@
566 ** setting. Webpage names begin with "/". To display a list of available
567 ** topics, use one of:
568 **
569 ** %fossil help Show common commands
570 ** %fossil help -a|--all Show both common and auxiliary commands
571 ** %fossil help -s|--setting Show setting names
572 ** %fossil help -t|--test Show test commands only
573 ** %fossil help -x|--aux Show auxiliary commands only
574 ** %fossil help -w|--www Show list of webpages
575 */
576 void help_cmd(void){
577
+15 -7
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,23 @@
639639
}else{
640640
goto doc_not_found;
641641
}
642642
}
643643
if( isUV ){
644
- if( db_table_exists("repository","unversioned")
645
- && unversioned_content(zName, &filebody)==0
646
- ){
647
- rid = 1;
648
- zDfltTitle = zName;
644
+ if( db_table_exists("repository","unversioned") ){
645
+ Stmt q;
646
+ db_prepare(&q, "SELECT hash, mtime FROM unversioned"
647
+ " WHERE name=%Q", zName);
648
+ if( db_step(&q)==SQLITE_ROW ){
649
+ etag_check(ETAG_HASH, db_column_text(&q,0));
650
+ etag_last_modified(db_column_int64(&q,1));
651
+ }
652
+ db_finalize(&q);
653
+ if( unversioned_content(zName, &filebody)==0 ){
654
+ rid = 1;
655
+ zDfltTitle = zName;
656
+ }
649657
}
650658
}else if( fossil_strcmp(zCheckin,"ckout")==0 ){
651659
/* Read from the local checkout */
652660
char *zFullpath;
653661
db_must_be_within_tree();
@@ -839,19 +847,19 @@
839847
*/
840848
void logo_page(void){
841849
Blob logo;
842850
char *zMime;
843851
852
+ etag_check(ETAG_CONFIG, 0);
844853
zMime = db_get("logo-mimetype", "image/gif");
845854
blob_zero(&logo);
846855
db_blob(&logo, "SELECT value FROM config WHERE name='logo-image'");
847856
if( blob_size(&logo)==0 ){
848857
blob_init(&logo, (char*)aLogo, sizeof(aLogo));
849858
}
850859
cgi_set_content_type(zMime);
851860
cgi_set_content(&logo);
852
- g.isConst = 1;
853861
}
854862
855863
/*
856864
** The default background image: a 16x16 white GIF
857865
*/
@@ -873,19 +881,19 @@
873881
*/
874882
void background_page(void){
875883
Blob bgimg;
876884
char *zMime;
877885
886
+ etag_check(ETAG_CONFIG, 0);
878887
zMime = db_get("background-mimetype", "image/gif");
879888
blob_zero(&bgimg);
880889
db_blob(&bgimg, "SELECT value FROM config WHERE name='background-image'");
881890
if( blob_size(&bgimg)==0 ){
882891
blob_init(&bgimg, (char*)aBackground, sizeof(aBackground));
883892
}
884893
cgi_set_content_type(zMime);
885894
cgi_set_content(&bgimg);
886
- g.isConst = 1;
887895
}
888896
889897
890898
/*
891899
** WEBPAGE: docsrch
892900
893901
ADDED src/etag.c
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,23 @@
639 }else{
640 goto doc_not_found;
641 }
642 }
643 if( isUV ){
644 if( db_table_exists("repository","unversioned")
645 && unversioned_content(zName, &filebody)==0
646 ){
647 rid = 1;
648 zDfltTitle = zName;
 
 
 
 
 
 
 
 
649 }
650 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
651 /* Read from the local checkout */
652 char *zFullpath;
653 db_must_be_within_tree();
@@ -839,19 +847,19 @@
839 */
840 void logo_page(void){
841 Blob logo;
842 char *zMime;
843
 
844 zMime = db_get("logo-mimetype", "image/gif");
845 blob_zero(&logo);
846 db_blob(&logo, "SELECT value FROM config WHERE name='logo-image'");
847 if( blob_size(&logo)==0 ){
848 blob_init(&logo, (char*)aLogo, sizeof(aLogo));
849 }
850 cgi_set_content_type(zMime);
851 cgi_set_content(&logo);
852 g.isConst = 1;
853 }
854
855 /*
856 ** The default background image: a 16x16 white GIF
857 */
@@ -873,19 +881,19 @@
873 */
874 void background_page(void){
875 Blob bgimg;
876 char *zMime;
877
 
878 zMime = db_get("background-mimetype", "image/gif");
879 blob_zero(&bgimg);
880 db_blob(&bgimg, "SELECT value FROM config WHERE name='background-image'");
881 if( blob_size(&bgimg)==0 ){
882 blob_init(&bgimg, (char*)aBackground, sizeof(aBackground));
883 }
884 cgi_set_content_type(zMime);
885 cgi_set_content(&bgimg);
886 g.isConst = 1;
887 }
888
889
890 /*
891 ** WEBPAGE: docsrch
892
893 DDED src/etag.c
--- src/doc.c
+++ src/doc.c
@@ -639,15 +639,23 @@
639 }else{
640 goto doc_not_found;
641 }
642 }
643 if( isUV ){
644 if( db_table_exists("repository","unversioned") ){
645 Stmt q;
646 db_prepare(&q, "SELECT hash, mtime FROM unversioned"
647 " WHERE name=%Q", zName);
648 if( db_step(&q)==SQLITE_ROW ){
649 etag_check(ETAG_HASH, db_column_text(&q,0));
650 etag_last_modified(db_column_int64(&q,1));
651 }
652 db_finalize(&q);
653 if( unversioned_content(zName, &filebody)==0 ){
654 rid = 1;
655 zDfltTitle = zName;
656 }
657 }
658 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
659 /* Read from the local checkout */
660 char *zFullpath;
661 db_must_be_within_tree();
@@ -839,19 +847,19 @@
847 */
848 void logo_page(void){
849 Blob logo;
850 char *zMime;
851
852 etag_check(ETAG_CONFIG, 0);
853 zMime = db_get("logo-mimetype", "image/gif");
854 blob_zero(&logo);
855 db_blob(&logo, "SELECT value FROM config WHERE name='logo-image'");
856 if( blob_size(&logo)==0 ){
857 blob_init(&logo, (char*)aLogo, sizeof(aLogo));
858 }
859 cgi_set_content_type(zMime);
860 cgi_set_content(&logo);
 
861 }
862
863 /*
864 ** The default background image: a 16x16 white GIF
865 */
@@ -873,19 +881,19 @@
881 */
882 void background_page(void){
883 Blob bgimg;
884 char *zMime;
885
886 etag_check(ETAG_CONFIG, 0);
887 zMime = db_get("background-mimetype", "image/gif");
888 blob_zero(&bgimg);
889 db_blob(&bgimg, "SELECT value FROM config WHERE name='background-image'");
890 if( blob_size(&bgimg)==0 ){
891 blob_init(&bgimg, (char*)aBackground, sizeof(aBackground));
892 }
893 cgi_set_content_type(zMime);
894 cgi_set_content(&bgimg);
 
895 }
896
897
898 /*
899 ** WEBPAGE: docsrch
900
901 DDED src/etag.c
+71
--- a/src/etag.c
+++ b/src/etag.c
@@ -0,0 +1,71 @@
1
+/*
2
+** Copyright (c) 2018 iMaxAge = 86400;MATCH");
3
+ if( zIfNoneMatch==0 ) return;
4
+ *
5
+** Copyright (c) 2018 D. Richard Hipp
6
+**
7
+** This program is free software; you can redistribute it and/or
8
+** modif Simplified BSD License (also
9
+** known as the "2-Clause License" or "FreeBSD License".)
10
+**
11
+** This program is distributed in the hope that it will be useful,
12
+** but without any warranty; without even the implied warranty of
13
+** merchantability or fitness for a particular purpose.
14
+**
15
+** Author contact information:
16
+** [email protected]
17
+** http://www.hwaci.com/drh/
18
+**
19
+*******************************************************************************
20
+**
21
+** This file implements ETags: cache control for Fossil
22
+**
23
+** An ETag is a hash that encodes attributes which must be the same for
24
+** the page to continue to be valid. Attributes that might be contained
25
+** in the ETag include:
26
+**
27
+** (1) The mtime on the Fossil executable
28
+** (2) The last change to the CONFIG table
29
+** (
30
+** Item in the ETag. The other7) The name user as determined by the login cookie
31
+**
32
+** Item (1) is always included in the ETag. The other elements are
33
+** optional. Bec**************************************
34
+**
35
+** This file implements ETags: casqlite3_int64 mtime; cache control for Fossil
36
+**
37
+** An ETag is a hash that encodes attributes which must be the same for
38
+** the page to continue to be valid. Attmtime of the executable as pa;
39
+mtime: %lld\n", mtime);
40
+zBuf, -can redistribute it and/or
41
+** modif Simplified BSD License (also
42
+** known as the "2-Clause License" or "FreeBSD License".)
43
+**
44
+** This program is distributed in the hope thMaxAelse) 2018 iMaxAge = 86400;MATCH");
45
+ if( zIfNoneMatch==0 ) return;
46
+ *
47
+** Copyright (c) 2018 D. Richard Hipp
48
+**
49
+** This program is free software; you can redistribute it and/or
50
+** modif Simplified BSD License (also
51
+** known as the "2-Clause License" or "FreeBSD License".)
52
+**
53
+** This program is distributed in the hope that it will be useful,
54
+** but without any warranty; without even the implied warranty of
55
+** merchantability or fitness for a particular purpose.
56
+**
57
+** Author contact information:
58
+** [email protected]
59
+** http://www.hwaci.com/drh/
60
+**
61
+**********************data************************
62
+**
63
+** This file implements ETags: cache control for Fossil
64
+**
65
+** An ETag is a hash that encode/*
66
+** Copyright (c) 2018 iMaxAge = 86400;MATCH");
67
+ if( zIfNoneMatch==0 ) return;
68
+ *
69
+** Copyright (c) 2018 D. Richard Hipp
70
+**
71
+** This program is free software; you can redistrib=0 || x>, exeMtimeexeMlified BSD Licenif( exeMtime>x
--- a/src/etag.c
+++ b/src/etag.c
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/etag.c
+++ b/src/etag.c
@@ -0,0 +1,71 @@
1 /*
2 ** Copyright (c) 2018 iMaxAge = 86400;MATCH");
3 if( zIfNoneMatch==0 ) return;
4 *
5 ** Copyright (c) 2018 D. Richard Hipp
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modif Simplified BSD License (also
9 ** known as the "2-Clause License" or "FreeBSD License".)
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but without any warranty; without even the implied warranty of
13 ** merchantability or fitness for a particular purpose.
14 **
15 ** Author contact information:
16 ** [email protected]
17 ** http://www.hwaci.com/drh/
18 **
19 *******************************************************************************
20 **
21 ** This file implements ETags: cache control for Fossil
22 **
23 ** An ETag is a hash that encodes attributes which must be the same for
24 ** the page to continue to be valid. Attributes that might be contained
25 ** in the ETag include:
26 **
27 ** (1) The mtime on the Fossil executable
28 ** (2) The last change to the CONFIG table
29 ** (
30 ** Item in the ETag. The other7) The name user as determined by the login cookie
31 **
32 ** Item (1) is always included in the ETag. The other elements are
33 ** optional. Bec**************************************
34 **
35 ** This file implements ETags: casqlite3_int64 mtime; cache control for Fossil
36 **
37 ** An ETag is a hash that encodes attributes which must be the same for
38 ** the page to continue to be valid. Attmtime of the executable as pa;
39 mtime: %lld\n", mtime);
40 zBuf, -can redistribute it and/or
41 ** modif Simplified BSD License (also
42 ** known as the "2-Clause License" or "FreeBSD License".)
43 **
44 ** This program is distributed in the hope thMaxAelse) 2018 iMaxAge = 86400;MATCH");
45 if( zIfNoneMatch==0 ) return;
46 *
47 ** Copyright (c) 2018 D. Richard Hipp
48 **
49 ** This program is free software; you can redistribute it and/or
50 ** modif Simplified BSD License (also
51 ** known as the "2-Clause License" or "FreeBSD License".)
52 **
53 ** This program is distributed in the hope that it will be useful,
54 ** but without any warranty; without even the implied warranty of
55 ** merchantability or fitness for a particular purpose.
56 **
57 ** Author contact information:
58 ** [email protected]
59 ** http://www.hwaci.com/drh/
60 **
61 **********************data************************
62 **
63 ** This file implements ETags: cache control for Fossil
64 **
65 ** An ETag is a hash that encode/*
66 ** Copyright (c) 2018 iMaxAge = 86400;MATCH");
67 if( zIfNoneMatch==0 ) return;
68 *
69 ** Copyright (c) 2018 D. Richard Hipp
70 **
71 ** This program is free software; you can redistrib=0 || x>, exeMtimeexeMlified BSD Licenif( exeMtime>x
+11 -7
--- src/graph.c
+++ src/graph.c
@@ -27,18 +27,21 @@
2727
2828
/* The graph appears vertically beside a timeline. Each row in the
2929
** timeline corresponds to a row in the graph. GraphRow.idx is 0 for
3030
** the top-most row and increases moving down. Hence (in the absence of
3131
** time skew) parents have a larger index than their children.
32
+**
33
+** The nParent field is -1 for entires that do not participate in the graph
34
+** but which are included just so that we can capture their background color.
3235
*/
3336
struct GraphRow {
3437
int rid; /* The rid for the check-in */
35
- i8 nParent; /* Number of parents */
38
+ i8 nParent; /* Number of parents. -1 for technote lines */
3639
int *aParent; /* Array of parents. 0 element is primary .*/
3740
char *zBranch; /* Branch name */
3841
char *zBgClr; /* Background Color */
39
- char zUuid[41]; /* Check-in for file ID */
42
+ char zUuid[HNAME_MAX+1]; /* Check-in for file ID */
4043
4144
GraphRow *pNext; /* Next row down in the list of all rows */
4245
GraphRow *pPrev; /* Previous row */
4346
4447
int idx; /* Row index. First is 1. 0 used for "none" */
@@ -188,23 +191,23 @@
188191
int nByte;
189192
static int nRow = 0;
190193
191194
if( p->nErr ) return 0;
192195
nByte = sizeof(GraphRow);
193
- nByte += sizeof(pRow->aParent[0])*nParent;
196
+ if( nParent>0 ) nByte += sizeof(pRow->aParent[0])*nParent;
194197
pRow = (GraphRow*)safeMalloc( nByte );
195
- pRow->aParent = (int*)&pRow[1];
198
+ pRow->aParent = nParent>0 ? (int*)&pRow[1] : 0;
196199
pRow->rid = rid;
197200
pRow->nParent = nParent;
198201
pRow->zBranch = persistBranchName(p, zBranch);
199202
if( zUuid==0 ) zUuid = "";
200203
sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
201204
pRow->isLeaf = isLeaf;
202205
memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
203206
if( zBgClr==0 ) zBgClr = "";
204207
pRow->zBgClr = persistBranchName(p, zBgClr);
205
- memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
208
+ if( nParent>0 ) memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
206209
if( p->pFirst==0 ){
207210
p->pFirst = pRow;
208211
}else{
209212
p->pLast->pNext = pRow;
210213
}
@@ -432,11 +435,11 @@
432435
** In the case of a fork, choose the pChild that results in the
433436
** longest rail.
434437
*/
435438
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
436439
if( pRow->isDup ) continue;
437
- if( pRow->nParent==0 ) continue; /* Root node */
440
+ if( pRow->nParent<=0 ) continue; /* Root node */
438441
pParent = hashFind(p, pRow->aParent[0]);
439442
if( pParent==0 ) continue; /* Parent off-screen */
440443
if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
441444
if( pParent->idx <= pRow->idx ){
442445
pParent->timeWarp = 1;
@@ -455,10 +458,11 @@
455458
*/
456459
zTrunk = persistBranchName(p, "trunk");
457460
for(i=0; i<2; i++){
458461
for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
459462
if( pRow->isDup ) continue;
463
+ if( pRow->nParent<0 ) continue;
460464
if( i==0 ){
461465
if( pRow->zBranch!=zTrunk ) continue;
462466
}else {
463467
if( pRow->iRail>=0 ) continue;
464468
}
@@ -492,11 +496,11 @@
492496
riser_to_top(pRow);
493497
}
494498
}
495499
continue;
496500
}
497
- if( pRow->isDup ){
501
+ if( pRow->isDup || pRow->nParent<0 ){
498502
continue;
499503
}else{
500504
assert( pRow->nParent>0 );
501505
parentRid = pRow->aParent[0];
502506
pParent = hashFind(p, parentRid);
503507
--- src/graph.c
+++ src/graph.c
@@ -27,18 +27,21 @@
27
28 /* The graph appears vertically beside a timeline. Each row in the
29 ** timeline corresponds to a row in the graph. GraphRow.idx is 0 for
30 ** the top-most row and increases moving down. Hence (in the absence of
31 ** time skew) parents have a larger index than their children.
 
 
 
32 */
33 struct GraphRow {
34 int rid; /* The rid for the check-in */
35 i8 nParent; /* Number of parents */
36 int *aParent; /* Array of parents. 0 element is primary .*/
37 char *zBranch; /* Branch name */
38 char *zBgClr; /* Background Color */
39 char zUuid[41]; /* Check-in for file ID */
40
41 GraphRow *pNext; /* Next row down in the list of all rows */
42 GraphRow *pPrev; /* Previous row */
43
44 int idx; /* Row index. First is 1. 0 used for "none" */
@@ -188,23 +191,23 @@
188 int nByte;
189 static int nRow = 0;
190
191 if( p->nErr ) return 0;
192 nByte = sizeof(GraphRow);
193 nByte += sizeof(pRow->aParent[0])*nParent;
194 pRow = (GraphRow*)safeMalloc( nByte );
195 pRow->aParent = (int*)&pRow[1];
196 pRow->rid = rid;
197 pRow->nParent = nParent;
198 pRow->zBranch = persistBranchName(p, zBranch);
199 if( zUuid==0 ) zUuid = "";
200 sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
201 pRow->isLeaf = isLeaf;
202 memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
203 if( zBgClr==0 ) zBgClr = "";
204 pRow->zBgClr = persistBranchName(p, zBgClr);
205 memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
206 if( p->pFirst==0 ){
207 p->pFirst = pRow;
208 }else{
209 p->pLast->pNext = pRow;
210 }
@@ -432,11 +435,11 @@
432 ** In the case of a fork, choose the pChild that results in the
433 ** longest rail.
434 */
435 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
436 if( pRow->isDup ) continue;
437 if( pRow->nParent==0 ) continue; /* Root node */
438 pParent = hashFind(p, pRow->aParent[0]);
439 if( pParent==0 ) continue; /* Parent off-screen */
440 if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
441 if( pParent->idx <= pRow->idx ){
442 pParent->timeWarp = 1;
@@ -455,10 +458,11 @@
455 */
456 zTrunk = persistBranchName(p, "trunk");
457 for(i=0; i<2; i++){
458 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
459 if( pRow->isDup ) continue;
 
460 if( i==0 ){
461 if( pRow->zBranch!=zTrunk ) continue;
462 }else {
463 if( pRow->iRail>=0 ) continue;
464 }
@@ -492,11 +496,11 @@
492 riser_to_top(pRow);
493 }
494 }
495 continue;
496 }
497 if( pRow->isDup ){
498 continue;
499 }else{
500 assert( pRow->nParent>0 );
501 parentRid = pRow->aParent[0];
502 pParent = hashFind(p, parentRid);
503
--- src/graph.c
+++ src/graph.c
@@ -27,18 +27,21 @@
27
28 /* The graph appears vertically beside a timeline. Each row in the
29 ** timeline corresponds to a row in the graph. GraphRow.idx is 0 for
30 ** the top-most row and increases moving down. Hence (in the absence of
31 ** time skew) parents have a larger index than their children.
32 **
33 ** The nParent field is -1 for entires that do not participate in the graph
34 ** but which are included just so that we can capture their background color.
35 */
36 struct GraphRow {
37 int rid; /* The rid for the check-in */
38 i8 nParent; /* Number of parents. -1 for technote lines */
39 int *aParent; /* Array of parents. 0 element is primary .*/
40 char *zBranch; /* Branch name */
41 char *zBgClr; /* Background Color */
42 char zUuid[HNAME_MAX+1]; /* Check-in for file ID */
43
44 GraphRow *pNext; /* Next row down in the list of all rows */
45 GraphRow *pPrev; /* Previous row */
46
47 int idx; /* Row index. First is 1. 0 used for "none" */
@@ -188,23 +191,23 @@
191 int nByte;
192 static int nRow = 0;
193
194 if( p->nErr ) return 0;
195 nByte = sizeof(GraphRow);
196 if( nParent>0 ) nByte += sizeof(pRow->aParent[0])*nParent;
197 pRow = (GraphRow*)safeMalloc( nByte );
198 pRow->aParent = nParent>0 ? (int*)&pRow[1] : 0;
199 pRow->rid = rid;
200 pRow->nParent = nParent;
201 pRow->zBranch = persistBranchName(p, zBranch);
202 if( zUuid==0 ) zUuid = "";
203 sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
204 pRow->isLeaf = isLeaf;
205 memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
206 if( zBgClr==0 ) zBgClr = "";
207 pRow->zBgClr = persistBranchName(p, zBgClr);
208 if( nParent>0 ) memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
209 if( p->pFirst==0 ){
210 p->pFirst = pRow;
211 }else{
212 p->pLast->pNext = pRow;
213 }
@@ -432,11 +435,11 @@
435 ** In the case of a fork, choose the pChild that results in the
436 ** longest rail.
437 */
438 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
439 if( pRow->isDup ) continue;
440 if( pRow->nParent<=0 ) continue; /* Root node */
441 pParent = hashFind(p, pRow->aParent[0]);
442 if( pParent==0 ) continue; /* Parent off-screen */
443 if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
444 if( pParent->idx <= pRow->idx ){
445 pParent->timeWarp = 1;
@@ -455,10 +458,11 @@
458 */
459 zTrunk = persistBranchName(p, "trunk");
460 for(i=0; i<2; i++){
461 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
462 if( pRow->isDup ) continue;
463 if( pRow->nParent<0 ) continue;
464 if( i==0 ){
465 if( pRow->zBranch!=zTrunk ) continue;
466 }else {
467 if( pRow->iRail>=0 ) continue;
468 }
@@ -492,11 +496,11 @@
496 riser_to_top(pRow);
497 }
498 }
499 continue;
500 }
501 if( pRow->isDup || pRow->nParent<0 ){
502 continue;
503 }else{
504 assert( pRow->nParent>0 );
505 parentRid = pRow->aParent[0];
506 pParent = hashFind(p, parentRid);
507
+19 -13
--- src/graph.js
+++ src/graph.js
@@ -208,10 +208,11 @@
208208
var e = document.getElementById("mc"+p.id);
209209
if(e) e.style.backgroundColor = p.bg;
210210
e = document.getElementById("md"+p.id);
211211
if(e) e.style.backgroundColor = p.bg;
212212
}
213
+ if( p.r<0 ) return;
213214
if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
214215
var cls = node.cls;
215216
if( p.mi.length ) cls += " merge";
216217
if( p.f&1 ) cls += " leaf";
217218
var n = drawBox(cls,p.bg,p.x,p.y);
@@ -342,22 +343,27 @@
342343
var h = window.innerHeight;
343344
var y = absoluteY(x[0]) - h/2;
344345
if( y>0 ) window.scrollTo(0, y);
345346
}
346347
}
347
- var lastRow = document.getElementById("m"+tx.rowinfo[tx.rowinfo.length-1].id);
348
- var lastY = 0;
349
- function checkHeight(){
350
- var h = absoluteY(lastRow);
351
- if( h!=lastY ){
352
- renderGraph();
353
- lastY = h;
354
- }
355
- setTimeout(checkHeight, 1000);
356
- }
357
- initGraph();
358
- checkHeight();
348
+ if( tx.rowinfo ){
349
+ var lastRow =
350
+ document.getElementById("m"+tx.rowinfo[tx.rowinfo.length-1].id);
351
+ var lastY = 0;
352
+ function checkHeight(){
353
+ var h = absoluteY(lastRow);
354
+ if( h!=lastY ){
355
+ renderGraph();
356
+ lastY = h;
357
+ }
358
+ setTimeout(checkHeight, 1000);
359
+ }
360
+ initGraph();
361
+ checkHeight();
362
+ }else{
363
+ function checkHeight(){}
364
+ }
359365
if( tx.scrollToSelect ){
360366
scrollToSelected();
361367
}
362368
363369
/* Set the onclick= attributes for elements of the "Compact" display
@@ -382,8 +388,8 @@
382388
for(i=0; 1; i++){
383389
var dataObj = document.getElementById("timeline-data-"+i);
384390
if(!dataObj) break;
385391
var txJson = dataObj.textContent || dataObj.innerText;
386392
var tx = JSON.parse(txJson);
387
- if(tx.rowinfo) TimelineGraph(tx);
393
+ TimelineGraph(tx);
388394
}
389395
}())
390396
--- src/graph.js
+++ src/graph.js
@@ -208,10 +208,11 @@
208 var e = document.getElementById("mc"+p.id);
209 if(e) e.style.backgroundColor = p.bg;
210 e = document.getElementById("md"+p.id);
211 if(e) e.style.backgroundColor = p.bg;
212 }
 
213 if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
214 var cls = node.cls;
215 if( p.mi.length ) cls += " merge";
216 if( p.f&1 ) cls += " leaf";
217 var n = drawBox(cls,p.bg,p.x,p.y);
@@ -342,22 +343,27 @@
342 var h = window.innerHeight;
343 var y = absoluteY(x[0]) - h/2;
344 if( y>0 ) window.scrollTo(0, y);
345 }
346 }
347 var lastRow = document.getElementById("m"+tx.rowinfo[tx.rowinfo.length-1].id);
348 var lastY = 0;
349 function checkHeight(){
350 var h = absoluteY(lastRow);
351 if( h!=lastY ){
352 renderGraph();
353 lastY = h;
354 }
355 setTimeout(checkHeight, 1000);
356 }
357 initGraph();
358 checkHeight();
 
 
 
 
 
359 if( tx.scrollToSelect ){
360 scrollToSelected();
361 }
362
363 /* Set the onclick= attributes for elements of the "Compact" display
@@ -382,8 +388,8 @@
382 for(i=0; 1; i++){
383 var dataObj = document.getElementById("timeline-data-"+i);
384 if(!dataObj) break;
385 var txJson = dataObj.textContent || dataObj.innerText;
386 var tx = JSON.parse(txJson);
387 if(tx.rowinfo) TimelineGraph(tx);
388 }
389 }())
390
--- src/graph.js
+++ src/graph.js
@@ -208,10 +208,11 @@
208 var e = document.getElementById("mc"+p.id);
209 if(e) e.style.backgroundColor = p.bg;
210 e = document.getElementById("md"+p.id);
211 if(e) e.style.backgroundColor = p.bg;
212 }
213 if( p.r<0 ) return;
214 if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
215 var cls = node.cls;
216 if( p.mi.length ) cls += " merge";
217 if( p.f&1 ) cls += " leaf";
218 var n = drawBox(cls,p.bg,p.x,p.y);
@@ -342,22 +343,27 @@
343 var h = window.innerHeight;
344 var y = absoluteY(x[0]) - h/2;
345 if( y>0 ) window.scrollTo(0, y);
346 }
347 }
348 if( tx.rowinfo ){
349 var lastRow =
350 document.getElementById("m"+tx.rowinfo[tx.rowinfo.length-1].id);
351 var lastY = 0;
352 function checkHeight(){
353 var h = absoluteY(lastRow);
354 if( h!=lastY ){
355 renderGraph();
356 lastY = h;
357 }
358 setTimeout(checkHeight, 1000);
359 }
360 initGraph();
361 checkHeight();
362 }else{
363 function checkHeight(){}
364 }
365 if( tx.scrollToSelect ){
366 scrollToSelected();
367 }
368
369 /* Set the onclick= attributes for elements of the "Compact" display
@@ -382,8 +388,8 @@
388 for(i=0; 1; i++){
389 var dataObj = document.getElementById("timeline-data-"+i);
390 if(!dataObj) break;
391 var txJson = dataObj.textContent || dataObj.innerText;
392 var tx = JSON.parse(txJson);
393 TimelineGraph(tx);
394 }
395 }())
396
+9 -2
--- src/import.c
+++ src/import.c
@@ -517,10 +517,11 @@
517517
}
518518
519519
520520
static struct{
521521
const char *zMasterName; /* Name of master branch */
522
+ int authorFlag; /* Use author as checkin committer */
522523
} ggit;
523524
524525
/*
525526
** Read the git-fast-import format from pIn and insert the corresponding
526527
** content into the database.
@@ -619,19 +620,23 @@
619620
gg.aData = 0;
620621
gg.nData = 0;
621622
}
622623
}
623624
}else
624
- if( strncmp(zLine, "author ", 7)==0 ){
625
+ if( (!ggit.authorFlag && strncmp(zLine, "author ", 7)==0)
626
+ || (ggit.authorFlag && strncmp(zLine, "committer ",10)==0
627
+ && gg.zUser!=NULL) ){
625628
/* No-op */
626629
}else
627630
if( strncmp(zLine, "mark ", 5)==0 ){
628631
trim_newline(&zLine[5]);
629632
fossil_free(gg.zMark);
630633
gg.zMark = fossil_strdup(&zLine[5]);
631634
}else
632
- if( strncmp(zLine, "tagger ", 7)==0 || strncmp(zLine, "committer ",10)==0 ){
635
+ if( strncmp(zLine, "tagger ", 7)==0
636
+ || (ggit.authorFlag && strncmp(zLine, "author ", 7)==0)
637
+ || strncmp(zLine, "committer ",10)==0 ){
633638
sqlite3_int64 secSince1970;
634639
z = strchr(zLine, ' ');
635640
while( fossil_isspace(*z) ) z++;
636641
if( (zTo=strchr(z, '>'))==NULL ) goto malformed_line;
637642
*(++zTo) = '\0';
@@ -1603,10 +1608,11 @@
16031608
** --git Import from the git-fast-export file format (default)
16041609
** Options:
16051610
** --import-marks FILE Restore marks table from FILE
16061611
** --export-marks FILE Save marks table to FILE
16071612
** --rename-master NAME Renames the master branch to NAME
1613
+** --use-author Uses author as the committer
16081614
**
16091615
** --svn Import from the svnadmin-dump file format. The default
16101616
** behaviour (unless overridden by --flat) is to treat 3
16111617
** folders in the SVN root as special, following the
16121618
** common layout of SVN repositories. These are (by
@@ -1727,10 +1733,11 @@
17271733
markfile_in = find_option("import-marks", 0, 1);
17281734
markfile_out = find_option("export-marks", 0, 1);
17291735
if( !(ggit.zMasterName = find_option("rename-master", 0, 1)) ){
17301736
ggit.zMasterName = "master";
17311737
}
1738
+ ggit.authorFlag = find_option("use-author", 0, 0)!=0;
17321739
}
17331740
verify_all_options();
17341741
17351742
if( g.argc!=3 && g.argc!=4 ){
17361743
usage("--git|--svn ?OPTIONS? NEW-REPOSITORY ?INPUT-FILE?");
17371744
--- src/import.c
+++ src/import.c
@@ -517,10 +517,11 @@
517 }
518
519
520 static struct{
521 const char *zMasterName; /* Name of master branch */
 
522 } ggit;
523
524 /*
525 ** Read the git-fast-import format from pIn and insert the corresponding
526 ** content into the database.
@@ -619,19 +620,23 @@
619 gg.aData = 0;
620 gg.nData = 0;
621 }
622 }
623 }else
624 if( strncmp(zLine, "author ", 7)==0 ){
 
 
625 /* No-op */
626 }else
627 if( strncmp(zLine, "mark ", 5)==0 ){
628 trim_newline(&zLine[5]);
629 fossil_free(gg.zMark);
630 gg.zMark = fossil_strdup(&zLine[5]);
631 }else
632 if( strncmp(zLine, "tagger ", 7)==0 || strncmp(zLine, "committer ",10)==0 ){
 
 
633 sqlite3_int64 secSince1970;
634 z = strchr(zLine, ' ');
635 while( fossil_isspace(*z) ) z++;
636 if( (zTo=strchr(z, '>'))==NULL ) goto malformed_line;
637 *(++zTo) = '\0';
@@ -1603,10 +1608,11 @@
1603 ** --git Import from the git-fast-export file format (default)
1604 ** Options:
1605 ** --import-marks FILE Restore marks table from FILE
1606 ** --export-marks FILE Save marks table to FILE
1607 ** --rename-master NAME Renames the master branch to NAME
 
1608 **
1609 ** --svn Import from the svnadmin-dump file format. The default
1610 ** behaviour (unless overridden by --flat) is to treat 3
1611 ** folders in the SVN root as special, following the
1612 ** common layout of SVN repositories. These are (by
@@ -1727,10 +1733,11 @@
1727 markfile_in = find_option("import-marks", 0, 1);
1728 markfile_out = find_option("export-marks", 0, 1);
1729 if( !(ggit.zMasterName = find_option("rename-master", 0, 1)) ){
1730 ggit.zMasterName = "master";
1731 }
 
1732 }
1733 verify_all_options();
1734
1735 if( g.argc!=3 && g.argc!=4 ){
1736 usage("--git|--svn ?OPTIONS? NEW-REPOSITORY ?INPUT-FILE?");
1737
--- src/import.c
+++ src/import.c
@@ -517,10 +517,11 @@
517 }
518
519
520 static struct{
521 const char *zMasterName; /* Name of master branch */
522 int authorFlag; /* Use author as checkin committer */
523 } ggit;
524
525 /*
526 ** Read the git-fast-import format from pIn and insert the corresponding
527 ** content into the database.
@@ -619,19 +620,23 @@
620 gg.aData = 0;
621 gg.nData = 0;
622 }
623 }
624 }else
625 if( (!ggit.authorFlag && strncmp(zLine, "author ", 7)==0)
626 || (ggit.authorFlag && strncmp(zLine, "committer ",10)==0
627 && gg.zUser!=NULL) ){
628 /* No-op */
629 }else
630 if( strncmp(zLine, "mark ", 5)==0 ){
631 trim_newline(&zLine[5]);
632 fossil_free(gg.zMark);
633 gg.zMark = fossil_strdup(&zLine[5]);
634 }else
635 if( strncmp(zLine, "tagger ", 7)==0
636 || (ggit.authorFlag && strncmp(zLine, "author ", 7)==0)
637 || strncmp(zLine, "committer ",10)==0 ){
638 sqlite3_int64 secSince1970;
639 z = strchr(zLine, ' ');
640 while( fossil_isspace(*z) ) z++;
641 if( (zTo=strchr(z, '>'))==NULL ) goto malformed_line;
642 *(++zTo) = '\0';
@@ -1603,10 +1608,11 @@
1608 ** --git Import from the git-fast-export file format (default)
1609 ** Options:
1610 ** --import-marks FILE Restore marks table from FILE
1611 ** --export-marks FILE Save marks table to FILE
1612 ** --rename-master NAME Renames the master branch to NAME
1613 ** --use-author Uses author as the committer
1614 **
1615 ** --svn Import from the svnadmin-dump file format. The default
1616 ** behaviour (unless overridden by --flat) is to treat 3
1617 ** folders in the SVN root as special, following the
1618 ** common layout of SVN repositories. These are (by
@@ -1727,10 +1733,11 @@
1733 markfile_in = find_option("import-marks", 0, 1);
1734 markfile_out = find_option("export-marks", 0, 1);
1735 if( !(ggit.zMasterName = find_option("rename-master", 0, 1)) ){
1736 ggit.zMasterName = "master";
1737 }
1738 ggit.authorFlag = find_option("use-author", 0, 0)!=0;
1739 }
1740 verify_all_options();
1741
1742 if( g.argc!=3 && g.argc!=4 ){
1743 usage("--git|--svn ?OPTIONS? NEW-REPOSITORY ?INPUT-FILE?");
1744
+4 -5
--- src/info.c
+++ src/info.c
@@ -1464,11 +1464,10 @@
14641464
" ORDER BY mtime DESC /*sort*/",
14651465
rid
14661466
);
14671467
while( db_step(&q)==SQLITE_ROW ){
14681468
const char *zTarget = db_column_text(&q, 0);
1469
- int nTarget = db_column_bytes(&q, 0);
14701469
const char *zFilename = db_column_text(&q, 1);
14711470
const char *zDate = db_column_text(&q, 2);
14721471
const char *zUser = db_column_text(&q, 3);
14731472
/* const char *zSrc = db_column_text(&q, 4); */
14741473
if( cnt>0 ){
@@ -1475,11 +1474,11 @@
14751474
@ Also attachment "%h(zFilename)" to
14761475
}else{
14771476
@ Attachment "%h(zFilename)" to
14781477
}
14791478
objType |= OBJTYPE_ATTACHMENT;
1480
- if( nTarget==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
1479
+ if( fossil_is_uuid(zTarget) ){
14811480
if ( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
14821481
zTarget)
14831482
){
14841483
if( g.perm.Hyperlink && g.anon.RdTkt ){
14851484
@ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
@@ -2185,11 +2184,11 @@
21852184
*/
21862185
void tinfo_page(void){
21872186
int rid;
21882187
char *zDate;
21892188
const char *zUuid;
2190
- char zTktName[UUID_SIZE+1];
2189
+ char zTktName[HNAME_MAX+1];
21912190
Manifest *pTktChng;
21922191
int modPending;
21932192
const char *zModAction;
21942193
char *zTktTitle;
21952194
login_check_credentials();
@@ -2206,11 +2205,11 @@
22062205
}
22072206
}
22082207
pTktChng = manifest_get(rid, CFTYPE_TICKET, 0);
22092208
if( pTktChng==0 ) fossil_redirect_home();
22102209
zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
2211
- memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE+1);
2210
+ sqlite3_snprintf(sizeof(zTktName), zTktName, "%s", pTktChng->zTicketUuid);
22122211
if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
22132212
if( strcmp(zModAction,"delete")==0 ){
22142213
moderation_disapprove(rid);
22152214
/*
22162215
** Next, check if the ticket still exists; if not, we cannot
@@ -2618,11 +2617,11 @@
26182617
zNewTag = PDT("tagname","");
26192618
zNewBrFlag = P("newbr") ? " checked" : "";
26202619
zNewBranch = PDT("brname","");
26212620
zCloseFlag = P("close") ? " checked" : "";
26222621
zHideFlag = P("hide") ? " checked" : "";
2623
- if( P("apply") ){
2622
+ if( P("apply") && cgi_csrf_safe(1) ){
26242623
Blob ctrl;
26252624
char *zNow;
26262625
26272626
login_verify_csrf_secret();
26282627
blob_zero(&ctrl);
26292628
--- src/info.c
+++ src/info.c
@@ -1464,11 +1464,10 @@
1464 " ORDER BY mtime DESC /*sort*/",
1465 rid
1466 );
1467 while( db_step(&q)==SQLITE_ROW ){
1468 const char *zTarget = db_column_text(&q, 0);
1469 int nTarget = db_column_bytes(&q, 0);
1470 const char *zFilename = db_column_text(&q, 1);
1471 const char *zDate = db_column_text(&q, 2);
1472 const char *zUser = db_column_text(&q, 3);
1473 /* const char *zSrc = db_column_text(&q, 4); */
1474 if( cnt>0 ){
@@ -1475,11 +1474,11 @@
1475 @ Also attachment "%h(zFilename)" to
1476 }else{
1477 @ Attachment "%h(zFilename)" to
1478 }
1479 objType |= OBJTYPE_ATTACHMENT;
1480 if( nTarget==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
1481 if ( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
1482 zTarget)
1483 ){
1484 if( g.perm.Hyperlink && g.anon.RdTkt ){
1485 @ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
@@ -2185,11 +2184,11 @@
2185 */
2186 void tinfo_page(void){
2187 int rid;
2188 char *zDate;
2189 const char *zUuid;
2190 char zTktName[UUID_SIZE+1];
2191 Manifest *pTktChng;
2192 int modPending;
2193 const char *zModAction;
2194 char *zTktTitle;
2195 login_check_credentials();
@@ -2206,11 +2205,11 @@
2206 }
2207 }
2208 pTktChng = manifest_get(rid, CFTYPE_TICKET, 0);
2209 if( pTktChng==0 ) fossil_redirect_home();
2210 zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
2211 memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE+1);
2212 if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
2213 if( strcmp(zModAction,"delete")==0 ){
2214 moderation_disapprove(rid);
2215 /*
2216 ** Next, check if the ticket still exists; if not, we cannot
@@ -2618,11 +2617,11 @@
2618 zNewTag = PDT("tagname","");
2619 zNewBrFlag = P("newbr") ? " checked" : "";
2620 zNewBranch = PDT("brname","");
2621 zCloseFlag = P("close") ? " checked" : "";
2622 zHideFlag = P("hide") ? " checked" : "";
2623 if( P("apply") ){
2624 Blob ctrl;
2625 char *zNow;
2626
2627 login_verify_csrf_secret();
2628 blob_zero(&ctrl);
2629
--- src/info.c
+++ src/info.c
@@ -1464,11 +1464,10 @@
1464 " ORDER BY mtime DESC /*sort*/",
1465 rid
1466 );
1467 while( db_step(&q)==SQLITE_ROW ){
1468 const char *zTarget = db_column_text(&q, 0);
 
1469 const char *zFilename = db_column_text(&q, 1);
1470 const char *zDate = db_column_text(&q, 2);
1471 const char *zUser = db_column_text(&q, 3);
1472 /* const char *zSrc = db_column_text(&q, 4); */
1473 if( cnt>0 ){
@@ -1475,11 +1474,11 @@
1474 @ Also attachment "%h(zFilename)" to
1475 }else{
1476 @ Attachment "%h(zFilename)" to
1477 }
1478 objType |= OBJTYPE_ATTACHMENT;
1479 if( fossil_is_uuid(zTarget) ){
1480 if ( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
1481 zTarget)
1482 ){
1483 if( g.perm.Hyperlink && g.anon.RdTkt ){
1484 @ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
@@ -2185,11 +2184,11 @@
2184 */
2185 void tinfo_page(void){
2186 int rid;
2187 char *zDate;
2188 const char *zUuid;
2189 char zTktName[HNAME_MAX+1];
2190 Manifest *pTktChng;
2191 int modPending;
2192 const char *zModAction;
2193 char *zTktTitle;
2194 login_check_credentials();
@@ -2206,11 +2205,11 @@
2205 }
2206 }
2207 pTktChng = manifest_get(rid, CFTYPE_TICKET, 0);
2208 if( pTktChng==0 ) fossil_redirect_home();
2209 zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
2210 sqlite3_snprintf(sizeof(zTktName), zTktName, "%s", pTktChng->zTicketUuid);
2211 if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
2212 if( strcmp(zModAction,"delete")==0 ){
2213 moderation_disapprove(rid);
2214 /*
2215 ** Next, check if the ticket still exists; if not, we cannot
@@ -2618,11 +2617,11 @@
2617 zNewTag = PDT("tagname","");
2618 zNewBrFlag = P("newbr") ? " checked" : "";
2619 zNewBranch = PDT("brname","");
2620 zCloseFlag = P("close") ? " checked" : "";
2621 zHideFlag = P("hide") ? " checked" : "";
2622 if( P("apply") && cgi_csrf_safe(1) ){
2623 Blob ctrl;
2624 char *zNow;
2625
2626 login_verify_csrf_secret();
2627 blob_zero(&ctrl);
2628
+30 -3
--- src/login.c
+++ src/login.c
@@ -502,14 +502,28 @@
502502
const char *zReferer;
503503
504504
login_check_credentials();
505505
if( login_wants_https_redirect() ){
506506
const char *zQS = P("QUERY_STRING");
507
+ if( P("redir")!=0 ){
508
+ style_header("Insecure Connection");
509
+ @ <h1>Unable To Establish An Encrypted Connection</h1>
510
+ @ <p>This website requires that login credentials be sent over
511
+ @ an encrypted connection. The current connection is not encrypted
512
+ @ across the entire route between your browser and the server.
513
+ @ An attempt was made to redirect to %h(g.zHttpsURL) but
514
+ @ the connection is still insecure even after the redirect.</p>
515
+ @ <p>This is probably some kind of configuration problem. Please
516
+ @ contact your sysadmin.</p>
517
+ @ <p>Sorry it did not work out.</p>
518
+ style_footer();
519
+ return;
520
+ }
507521
if( zQS==0 ){
508
- zQS = "";
522
+ zQS = "?redir=1";
509523
}else if( zQS[0]!=0 ){
510
- zQS = mprintf("?%s", zQS);
524
+ zQS = mprintf("?%s&redir=1", zQS);
511525
}
512526
cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS);
513527
return;
514528
}
515529
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
@@ -661,10 +675,23 @@
661675
@ <td class="login_out_label">User ID:</td>
662676
if( anonFlag ){
663677
@ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
664678
}else{
665679
@ <td><input type="text" id="u" name="u" value="" size="30" /></td>
680
+ }
681
+ if( P("HTTPS")==0 ){
682
+ @ <td width="15"><td rowspan="3">
683
+ @ <p class='securityWarning'>
684
+ @ Warning: Your password will be sent in the clear over an
685
+ @ unencrypted connection.
686
+ if( g.sslNotAvailable ){
687
+ @ No encrypted connection is available on this server.
688
+ }else{
689
+ @ Consider logging in at
690
+ @ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead.
691
+ }
692
+ @ </p>
666693
}
667694
@ </tr>
668695
@ <tr>
669696
@ <td class="login_out_label">Password:</td>
670697
@ <td><input type="password" id="p" name="p" value="" size="30" /></td>
@@ -1337,11 +1364,11 @@
13371364
{
13381365
const char *zUrl = PD("REQUEST_URI", "index");
13391366
const char *zQS = P("QUERY_STRING");
13401367
Blob redir;
13411368
blob_init(&redir, 0, 0);
1342
- if( login_wants_https_redirect() ){
1369
+ if( login_wants_https_redirect() && !g.sslNotAvailable ){
13431370
blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
13441371
}else{
13451372
blob_appendf(&redir, "%R/login?g=%T", zUrl);
13461373
}
13471374
if( anonOk ) blob_append(&redir, "&anon", 5);
13481375
--- src/login.c
+++ src/login.c
@@ -502,14 +502,28 @@
502 const char *zReferer;
503
504 login_check_credentials();
505 if( login_wants_https_redirect() ){
506 const char *zQS = P("QUERY_STRING");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507 if( zQS==0 ){
508 zQS = "";
509 }else if( zQS[0]!=0 ){
510 zQS = mprintf("?%s", zQS);
511 }
512 cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS);
513 return;
514 }
515 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
@@ -661,10 +675,23 @@
661 @ <td class="login_out_label">User ID:</td>
662 if( anonFlag ){
663 @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
664 }else{
665 @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
666 }
667 @ </tr>
668 @ <tr>
669 @ <td class="login_out_label">Password:</td>
670 @ <td><input type="password" id="p" name="p" value="" size="30" /></td>
@@ -1337,11 +1364,11 @@
1337 {
1338 const char *zUrl = PD("REQUEST_URI", "index");
1339 const char *zQS = P("QUERY_STRING");
1340 Blob redir;
1341 blob_init(&redir, 0, 0);
1342 if( login_wants_https_redirect() ){
1343 blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1344 }else{
1345 blob_appendf(&redir, "%R/login?g=%T", zUrl);
1346 }
1347 if( anonOk ) blob_append(&redir, "&anon", 5);
1348
--- src/login.c
+++ src/login.c
@@ -502,14 +502,28 @@
502 const char *zReferer;
503
504 login_check_credentials();
505 if( login_wants_https_redirect() ){
506 const char *zQS = P("QUERY_STRING");
507 if( P("redir")!=0 ){
508 style_header("Insecure Connection");
509 @ <h1>Unable To Establish An Encrypted Connection</h1>
510 @ <p>This website requires that login credentials be sent over
511 @ an encrypted connection. The current connection is not encrypted
512 @ across the entire route between your browser and the server.
513 @ An attempt was made to redirect to %h(g.zHttpsURL) but
514 @ the connection is still insecure even after the redirect.</p>
515 @ <p>This is probably some kind of configuration problem. Please
516 @ contact your sysadmin.</p>
517 @ <p>Sorry it did not work out.</p>
518 style_footer();
519 return;
520 }
521 if( zQS==0 ){
522 zQS = "?redir=1";
523 }else if( zQS[0]!=0 ){
524 zQS = mprintf("?%s&redir=1", zQS);
525 }
526 cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS);
527 return;
528 }
529 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
@@ -661,10 +675,23 @@
675 @ <td class="login_out_label">User ID:</td>
676 if( anonFlag ){
677 @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
678 }else{
679 @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
680 }
681 if( P("HTTPS")==0 ){
682 @ <td width="15"><td rowspan="3">
683 @ <p class='securityWarning'>
684 @ Warning: Your password will be sent in the clear over an
685 @ unencrypted connection.
686 if( g.sslNotAvailable ){
687 @ No encrypted connection is available on this server.
688 }else{
689 @ Consider logging in at
690 @ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead.
691 }
692 @ </p>
693 }
694 @ </tr>
695 @ <tr>
696 @ <td class="login_out_label">Password:</td>
697 @ <td><input type="password" id="p" name="p" value="" size="30" /></td>
@@ -1337,11 +1364,11 @@
1364 {
1365 const char *zUrl = PD("REQUEST_URI", "index");
1366 const char *zQS = P("QUERY_STRING");
1367 Blob redir;
1368 blob_init(&redir, 0, 0);
1369 if( login_wants_https_redirect() && !g.sslNotAvailable ){
1370 blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1371 }else{
1372 blob_appendf(&redir, "%R/login?g=%T", zUrl);
1373 }
1374 if( anonOk ) blob_append(&redir, "&anon", 5);
1375
+53 -20
--- src/main.c
+++ src/main.c
@@ -49,20 +49,10 @@
4949
#ifdef FOSSIL_ENABLE_JSON
5050
# include "cson_amalgamation.h" /* JSON API. */
5151
# include "json_detail.h"
5252
#endif
5353
54
-/*
55
-** Size of a UUID in characters. A UUID is a randomly generated
56
-** lower-case hexadecimal number used to identify tickets.
57
-**
58
-** In Fossil 1.x, UUID also referred to a SHA1 artifact hash. But that
59
-** usage is now obsolete. The term UUID should now mean only a very large
60
-** random number used as a unique identifier for tickets or other objects.
61
-*/
62
-#define UUID_SIZE 40
63
-
6454
/*
6555
** Maximum number of auxiliary parameters on reports
6656
*/
6757
#define MX_AUX 5
6858
@@ -1284,46 +1274,92 @@
12841274
@ </head>
12851275
@ <body>
12861276
n = db_int(0, "SELECT count(*) FROM sfile");
12871277
if( n>0 ){
12881278
Stmt q;
1289
- @ <h1>Available Repositories:</h1>
1290
- @ <ol>
1279
+ sqlite3_int64 iNow, iMTime;
1280
+ @ <h1 align="center">Fossil Repositories</h1>
1281
+ @ <table border="0" class="sortable" data-init-sort="1" \
1282
+ @ data-column-types="tnk"><thead>
1283
+ @ <tr><th>Filename<th width="20"><th>Last Modified</tr>
1284
+ @ </thead><tbody>
12911285
db_prepare(&q, "SELECT pathname"
12921286
" FROM sfile ORDER BY pathname COLLATE nocase;");
1287
+ iNow = db_int64(0, "SELECT strftime('%%s','now')");
12931288
while( db_step(&q)==SQLITE_ROW ){
12941289
const char *zName = db_column_text(&q, 0);
12951290
int nName = (int)strlen(zName);
12961291
char *zUrl;
1292
+ char *zAge;
1293
+ char *zFull;
12971294
if( nName<7 ) continue;
12981295
zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
1296
+ if( zName[0]=='/'
1297
+#ifdef _WIN32
1298
+ || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
1299
+#endif
1300
+ ){
1301
+ zFull = mprintf("%s", zName);
1302
+ }else if ( allRepo ){
1303
+ zFull = mprintf("/%s", zName);
1304
+ }else{
1305
+ zFull = mprintf("%s/%s", g.zRepositoryName, zName);
1306
+ }
1307
+ iMTime = file_mtime(zFull, ExtFILE);
1308
+ fossil_free(zFull);
1309
+ if( iMTime<=0 ){
1310
+ zAge = mprintf("...");
1311
+ }else{
1312
+ zAge = human_readable_age((iNow - iMTime)/86400.0);
1313
+ }
12991314
if( sqlite3_strglob("*.fossil", zName)!=0 ){
13001315
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
13011316
** do not work for repositories whose names do not end in ".fossil".
13021317
** So do not hyperlink those cases. */
1303
- @ <li>%h(zName)</li>
1318
+ @ <tr><td>%h(zName)
13041319
} else if( sqlite3_strglob("*/.*", zName)==0 ){
13051320
/* Do not show hidden repos */
1306
- @ <li>%h(zName) (hidden)</li>
1321
+ @ <tr><td>%h(zName) (hidden)
13071322
} else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
1308
- @ <li><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a></li>
1323
+ @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
13091324
}else{
1310
- @ <li><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a></li>
1325
+ @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
13111326
}
1327
+ @ <td></td><td data-sortkey='%010llx(iNow - iMTime)'>%h(zAge)</tr>
1328
+ fossil_free(zAge);
13121329
sqlite3_free(zUrl);
13131330
}
1314
- @ </ol>
1331
+ @ </tbody></table>
13151332
}else{
13161333
@ <h1>No Repositories Found</h1>
13171334
}
1335
+ @ <script>%s(builtin_text("sorttable.js"))</script>
13181336
@ </body>
13191337
@ </html>
13201338
cgi_reply();
13211339
sqlite3_close(g.db);
13221340
g.db = 0;
13231341
return n;
13241342
}
1343
+
1344
+/*
1345
+** COMMAND: test-list-page
1346
+**
1347
+** Usage: %fossil test-list-page DIRECTORY
1348
+**
1349
+** Show all repositories underneath DIRECTORY. Or if DIRECTORY is "/"
1350
+** show all repositories in the ~/.fossil file.
1351
+*/
1352
+void test_list_page(void){
1353
+ if( g.argc<3 ){
1354
+ g.zRepositoryName = "/";
1355
+ }else{
1356
+ g.zRepositoryName = g.argv[2];
1357
+ }
1358
+ g.httpOut = stdout;
1359
+ repo_list_page();
1360
+}
13251361
13261362
/*
13271363
** Preconditions:
13281364
**
13291365
** * Environment variables are set up according to the CGI standard.
@@ -2460,13 +2496,10 @@
24602496
set_base_url(zAltBase);
24612497
}
24622498
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
24632499
if( find_option("https",0,0)!=0 ){
24642500
cgi_replace_parameter("HTTPS","on");
2465
- }else{
2466
- /* without --https, defaults to not available. */
2467
- g.sslNotAvailable = 1;
24682501
}
24692502
if( find_option("localhost", 0, 0)!=0 ){
24702503
flags |= HTTP_SERVER_LOCALHOST;
24712504
}
24722505
24732506
--- src/main.c
+++ src/main.c
@@ -49,20 +49,10 @@
49 #ifdef FOSSIL_ENABLE_JSON
50 # include "cson_amalgamation.h" /* JSON API. */
51 # include "json_detail.h"
52 #endif
53
54 /*
55 ** Size of a UUID in characters. A UUID is a randomly generated
56 ** lower-case hexadecimal number used to identify tickets.
57 **
58 ** In Fossil 1.x, UUID also referred to a SHA1 artifact hash. But that
59 ** usage is now obsolete. The term UUID should now mean only a very large
60 ** random number used as a unique identifier for tickets or other objects.
61 */
62 #define UUID_SIZE 40
63
64 /*
65 ** Maximum number of auxiliary parameters on reports
66 */
67 #define MX_AUX 5
68
@@ -1284,46 +1274,92 @@
1284 @ </head>
1285 @ <body>
1286 n = db_int(0, "SELECT count(*) FROM sfile");
1287 if( n>0 ){
1288 Stmt q;
1289 @ <h1>Available Repositories:</h1>
1290 @ <ol>
 
 
 
 
1291 db_prepare(&q, "SELECT pathname"
1292 " FROM sfile ORDER BY pathname COLLATE nocase;");
 
1293 while( db_step(&q)==SQLITE_ROW ){
1294 const char *zName = db_column_text(&q, 0);
1295 int nName = (int)strlen(zName);
1296 char *zUrl;
 
 
1297 if( nName<7 ) continue;
1298 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1299 if( sqlite3_strglob("*.fossil", zName)!=0 ){
1300 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
1301 ** do not work for repositories whose names do not end in ".fossil".
1302 ** So do not hyperlink those cases. */
1303 @ <li>%h(zName)</li>
1304 } else if( sqlite3_strglob("*/.*", zName)==0 ){
1305 /* Do not show hidden repos */
1306 @ <li>%h(zName) (hidden)</li>
1307 } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
1308 @ <li><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a></li>
1309 }else{
1310 @ <li><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a></li>
1311 }
 
 
1312 sqlite3_free(zUrl);
1313 }
1314 @ </ol>
1315 }else{
1316 @ <h1>No Repositories Found</h1>
1317 }
 
1318 @ </body>
1319 @ </html>
1320 cgi_reply();
1321 sqlite3_close(g.db);
1322 g.db = 0;
1323 return n;
1324 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1325
1326 /*
1327 ** Preconditions:
1328 **
1329 ** * Environment variables are set up according to the CGI standard.
@@ -2460,13 +2496,10 @@
2460 set_base_url(zAltBase);
2461 }
2462 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2463 if( find_option("https",0,0)!=0 ){
2464 cgi_replace_parameter("HTTPS","on");
2465 }else{
2466 /* without --https, defaults to not available. */
2467 g.sslNotAvailable = 1;
2468 }
2469 if( find_option("localhost", 0, 0)!=0 ){
2470 flags |= HTTP_SERVER_LOCALHOST;
2471 }
2472
2473
--- src/main.c
+++ src/main.c
@@ -49,20 +49,10 @@
49 #ifdef FOSSIL_ENABLE_JSON
50 # include "cson_amalgamation.h" /* JSON API. */
51 # include "json_detail.h"
52 #endif
53
 
 
 
 
 
 
 
 
 
 
54 /*
55 ** Maximum number of auxiliary parameters on reports
56 */
57 #define MX_AUX 5
58
@@ -1284,46 +1274,92 @@
1274 @ </head>
1275 @ <body>
1276 n = db_int(0, "SELECT count(*) FROM sfile");
1277 if( n>0 ){
1278 Stmt q;
1279 sqlite3_int64 iNow, iMTime;
1280 @ <h1 align="center">Fossil Repositories</h1>
1281 @ <table border="0" class="sortable" data-init-sort="1" \
1282 @ data-column-types="tnk"><thead>
1283 @ <tr><th>Filename<th width="20"><th>Last Modified</tr>
1284 @ </thead><tbody>
1285 db_prepare(&q, "SELECT pathname"
1286 " FROM sfile ORDER BY pathname COLLATE nocase;");
1287 iNow = db_int64(0, "SELECT strftime('%%s','now')");
1288 while( db_step(&q)==SQLITE_ROW ){
1289 const char *zName = db_column_text(&q, 0);
1290 int nName = (int)strlen(zName);
1291 char *zUrl;
1292 char *zAge;
1293 char *zFull;
1294 if( nName<7 ) continue;
1295 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
1296 if( zName[0]=='/'
1297 #ifdef _WIN32
1298 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
1299 #endif
1300 ){
1301 zFull = mprintf("%s", zName);
1302 }else if ( allRepo ){
1303 zFull = mprintf("/%s", zName);
1304 }else{
1305 zFull = mprintf("%s/%s", g.zRepositoryName, zName);
1306 }
1307 iMTime = file_mtime(zFull, ExtFILE);
1308 fossil_free(zFull);
1309 if( iMTime<=0 ){
1310 zAge = mprintf("...");
1311 }else{
1312 zAge = human_readable_age((iNow - iMTime)/86400.0);
1313 }
1314 if( sqlite3_strglob("*.fossil", zName)!=0 ){
1315 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
1316 ** do not work for repositories whose names do not end in ".fossil".
1317 ** So do not hyperlink those cases. */
1318 @ <tr><td>%h(zName)
1319 } else if( sqlite3_strglob("*/.*", zName)==0 ){
1320 /* Do not show hidden repos */
1321 @ <tr><td>%h(zName) (hidden)
1322 } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
1323 @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
1324 }else{
1325 @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
1326 }
1327 @ <td></td><td data-sortkey='%010llx(iNow - iMTime)'>%h(zAge)</tr>
1328 fossil_free(zAge);
1329 sqlite3_free(zUrl);
1330 }
1331 @ </tbody></table>
1332 }else{
1333 @ <h1>No Repositories Found</h1>
1334 }
1335 @ <script>%s(builtin_text("sorttable.js"))</script>
1336 @ </body>
1337 @ </html>
1338 cgi_reply();
1339 sqlite3_close(g.db);
1340 g.db = 0;
1341 return n;
1342 }
1343
1344 /*
1345 ** COMMAND: test-list-page
1346 **
1347 ** Usage: %fossil test-list-page DIRECTORY
1348 **
1349 ** Show all repositories underneath DIRECTORY. Or if DIRECTORY is "/"
1350 ** show all repositories in the ~/.fossil file.
1351 */
1352 void test_list_page(void){
1353 if( g.argc<3 ){
1354 g.zRepositoryName = "/";
1355 }else{
1356 g.zRepositoryName = g.argv[2];
1357 }
1358 g.httpOut = stdout;
1359 repo_list_page();
1360 }
1361
1362 /*
1363 ** Preconditions:
1364 **
1365 ** * Environment variables are set up according to the CGI standard.
@@ -2460,13 +2496,10 @@
2496 set_base_url(zAltBase);
2497 }
2498 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2499 if( find_option("https",0,0)!=0 ){
2500 cgi_replace_parameter("HTTPS","on");
 
 
 
2501 }
2502 if( find_option("localhost", 0, 0)!=0 ){
2503 flags |= HTTP_SERVER_LOCALHOST;
2504 }
2505
2506
+12
--- src/main.mk
+++ src/main.mk
@@ -43,10 +43,11 @@
4343
$(SRCDIR)/diff.c \
4444
$(SRCDIR)/diffcmd.c \
4545
$(SRCDIR)/dispatch.c \
4646
$(SRCDIR)/doc.c \
4747
$(SRCDIR)/encode.c \
48
+ $(SRCDIR)/etag.c \
4849
$(SRCDIR)/event.c \
4950
$(SRCDIR)/export.c \
5051
$(SRCDIR)/file.c \
5152
$(SRCDIR)/finfo.c \
5253
$(SRCDIR)/foci.c \
@@ -243,10 +244,11 @@
243244
$(OBJDIR)/diff_.c \
244245
$(OBJDIR)/diffcmd_.c \
245246
$(OBJDIR)/dispatch_.c \
246247
$(OBJDIR)/doc_.c \
247248
$(OBJDIR)/encode_.c \
249
+ $(OBJDIR)/etag_.c \
248250
$(OBJDIR)/event_.c \
249251
$(OBJDIR)/export_.c \
250252
$(OBJDIR)/file_.c \
251253
$(OBJDIR)/finfo_.c \
252254
$(OBJDIR)/foci_.c \
@@ -372,10 +374,11 @@
372374
$(OBJDIR)/diff.o \
373375
$(OBJDIR)/diffcmd.o \
374376
$(OBJDIR)/dispatch.o \
375377
$(OBJDIR)/doc.o \
376378
$(OBJDIR)/encode.o \
379
+ $(OBJDIR)/etag.o \
377380
$(OBJDIR)/event.o \
378381
$(OBJDIR)/export.o \
379382
$(OBJDIR)/file.o \
380383
$(OBJDIR)/finfo.o \
381384
$(OBJDIR)/foci.o \
@@ -673,10 +676,11 @@
673676
$(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
674677
$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
675678
$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
676679
$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
677680
$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
681
+ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
678682
$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
679683
$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
680684
$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
681685
$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
682686
$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1016,10 +1020,18 @@
10161020
10171021
$(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
10181022
$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
10191023
10201024
$(OBJDIR)/encode.h: $(OBJDIR)/headers
1025
+
1026
+$(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(OBJDIR)/translate
1027
+ $(OBJDIR)/translate $(SRCDIR)/etag.c >$@
1028
+
1029
+$(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1030
+ $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1031
+
1032
+$(OBJDIR)/etag.h: $(OBJDIR)/headers
10211033
10221034
$(OBJDIR)/event_.c: $(SRCDIR)/event.c $(OBJDIR)/translate
10231035
$(OBJDIR)/translate $(SRCDIR)/event.c >$@
10241036
10251037
$(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
10261038
--- src/main.mk
+++ src/main.mk
@@ -43,10 +43,11 @@
43 $(SRCDIR)/diff.c \
44 $(SRCDIR)/diffcmd.c \
45 $(SRCDIR)/dispatch.c \
46 $(SRCDIR)/doc.c \
47 $(SRCDIR)/encode.c \
 
48 $(SRCDIR)/event.c \
49 $(SRCDIR)/export.c \
50 $(SRCDIR)/file.c \
51 $(SRCDIR)/finfo.c \
52 $(SRCDIR)/foci.c \
@@ -243,10 +244,11 @@
243 $(OBJDIR)/diff_.c \
244 $(OBJDIR)/diffcmd_.c \
245 $(OBJDIR)/dispatch_.c \
246 $(OBJDIR)/doc_.c \
247 $(OBJDIR)/encode_.c \
 
248 $(OBJDIR)/event_.c \
249 $(OBJDIR)/export_.c \
250 $(OBJDIR)/file_.c \
251 $(OBJDIR)/finfo_.c \
252 $(OBJDIR)/foci_.c \
@@ -372,10 +374,11 @@
372 $(OBJDIR)/diff.o \
373 $(OBJDIR)/diffcmd.o \
374 $(OBJDIR)/dispatch.o \
375 $(OBJDIR)/doc.o \
376 $(OBJDIR)/encode.o \
 
377 $(OBJDIR)/event.o \
378 $(OBJDIR)/export.o \
379 $(OBJDIR)/file.o \
380 $(OBJDIR)/finfo.o \
381 $(OBJDIR)/foci.o \
@@ -673,10 +676,11 @@
673 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
674 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
675 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
676 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
677 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
 
678 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
679 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
680 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
681 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
682 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1016,10 +1020,18 @@
1016
1017 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1018 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1019
1020 $(OBJDIR)/encode.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1021
1022 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(OBJDIR)/translate
1023 $(OBJDIR)/translate $(SRCDIR)/event.c >$@
1024
1025 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
1026
--- src/main.mk
+++ src/main.mk
@@ -43,10 +43,11 @@
43 $(SRCDIR)/diff.c \
44 $(SRCDIR)/diffcmd.c \
45 $(SRCDIR)/dispatch.c \
46 $(SRCDIR)/doc.c \
47 $(SRCDIR)/encode.c \
48 $(SRCDIR)/etag.c \
49 $(SRCDIR)/event.c \
50 $(SRCDIR)/export.c \
51 $(SRCDIR)/file.c \
52 $(SRCDIR)/finfo.c \
53 $(SRCDIR)/foci.c \
@@ -243,10 +244,11 @@
244 $(OBJDIR)/diff_.c \
245 $(OBJDIR)/diffcmd_.c \
246 $(OBJDIR)/dispatch_.c \
247 $(OBJDIR)/doc_.c \
248 $(OBJDIR)/encode_.c \
249 $(OBJDIR)/etag_.c \
250 $(OBJDIR)/event_.c \
251 $(OBJDIR)/export_.c \
252 $(OBJDIR)/file_.c \
253 $(OBJDIR)/finfo_.c \
254 $(OBJDIR)/foci_.c \
@@ -372,10 +374,11 @@
374 $(OBJDIR)/diff.o \
375 $(OBJDIR)/diffcmd.o \
376 $(OBJDIR)/dispatch.o \
377 $(OBJDIR)/doc.o \
378 $(OBJDIR)/encode.o \
379 $(OBJDIR)/etag.o \
380 $(OBJDIR)/event.o \
381 $(OBJDIR)/export.o \
382 $(OBJDIR)/file.o \
383 $(OBJDIR)/finfo.o \
384 $(OBJDIR)/foci.o \
@@ -673,10 +676,11 @@
676 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
677 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
678 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
679 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
680 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
681 $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
682 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
683 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
684 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
685 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
686 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1016,10 +1020,18 @@
1020
1021 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1022 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1023
1024 $(OBJDIR)/encode.h: $(OBJDIR)/headers
1025
1026 $(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(OBJDIR)/translate
1027 $(OBJDIR)/translate $(SRCDIR)/etag.c >$@
1028
1029 $(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1030 $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1031
1032 $(OBJDIR)/etag.h: $(OBJDIR)/headers
1033
1034 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(OBJDIR)/translate
1035 $(OBJDIR)/translate $(SRCDIR)/event.c >$@
1036
1037 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
1038
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -55,10 +55,11 @@
5555
diff
5656
diffcmd
5757
dispatch
5858
doc
5959
encode
60
+ etag
6061
event
6162
export
6263
file
6364
finfo
6465
foci
6566
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -55,10 +55,11 @@
55 diff
56 diffcmd
57 dispatch
58 doc
59 encode
 
60 event
61 export
62 file
63 finfo
64 foci
65
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -55,10 +55,11 @@
55 diff
56 diffcmd
57 dispatch
58 doc
59 encode
60 etag
61 event
62 export
63 file
64 finfo
65 foci
66
+5 -2
--- src/manifest.c
+++ src/manifest.c
@@ -607,12 +607,12 @@
607607
** is amending.
608608
*/
609609
case 'K': {
610610
if( p->zTicketUuid!=0 ) SYNTAX("more than one K-card");
611611
p->zTicketUuid = next_token(&x, &sz);
612
- if( sz!=UUID_SIZE ) SYNTAX("K-card UUID is the wrong size");
613
- if( !validate16(p->zTicketUuid, UUID_SIZE) ){
612
+ if( sz!=HNAME_LEN_SHA1 ) SYNTAX("K-card UUID is the wrong size");
613
+ if( !validate16(p->zTicketUuid, sz) ){
614614
SYNTAX("invalid K-card UUID");
615615
}
616616
break;
617617
}
618618
@@ -1267,10 +1267,13 @@
12671267
int bBest /* 0: exact match only. 1: closest match */
12681268
){
12691269
int lwr, upr;
12701270
int c;
12711271
int i;
1272
+ if( p->aFile==0 ){
1273
+ return 0;
1274
+ }
12721275
lwr = 0;
12731276
upr = p->nFile - 1;
12741277
if( p->iFile>=lwr && p->iFile<upr ){
12751278
c = fossil_strcmp(p->aFile[p->iFile+1].zName, zName);
12761279
if( c==0 ){
12771280
--- src/manifest.c
+++ src/manifest.c
@@ -607,12 +607,12 @@
607 ** is amending.
608 */
609 case 'K': {
610 if( p->zTicketUuid!=0 ) SYNTAX("more than one K-card");
611 p->zTicketUuid = next_token(&x, &sz);
612 if( sz!=UUID_SIZE ) SYNTAX("K-card UUID is the wrong size");
613 if( !validate16(p->zTicketUuid, UUID_SIZE) ){
614 SYNTAX("invalid K-card UUID");
615 }
616 break;
617 }
618
@@ -1267,10 +1267,13 @@
1267 int bBest /* 0: exact match only. 1: closest match */
1268 ){
1269 int lwr, upr;
1270 int c;
1271 int i;
 
 
 
1272 lwr = 0;
1273 upr = p->nFile - 1;
1274 if( p->iFile>=lwr && p->iFile<upr ){
1275 c = fossil_strcmp(p->aFile[p->iFile+1].zName, zName);
1276 if( c==0 ){
1277
--- src/manifest.c
+++ src/manifest.c
@@ -607,12 +607,12 @@
607 ** is amending.
608 */
609 case 'K': {
610 if( p->zTicketUuid!=0 ) SYNTAX("more than one K-card");
611 p->zTicketUuid = next_token(&x, &sz);
612 if( sz!=HNAME_LEN_SHA1 ) SYNTAX("K-card UUID is the wrong size");
613 if( !validate16(p->zTicketUuid, sz) ){
614 SYNTAX("invalid K-card UUID");
615 }
616 break;
617 }
618
@@ -1267,10 +1267,13 @@
1267 int bBest /* 0: exact match only. 1: closest match */
1268 ){
1269 int lwr, upr;
1270 int c;
1271 int i;
1272 if( p->aFile==0 ){
1273 return 0;
1274 }
1275 lwr = 0;
1276 upr = p->nFile - 1;
1277 if( p->iFile>=lwr && p->iFile<upr ){
1278 c = fossil_strcmp(p->aFile[p->iFile+1].zName, zName);
1279 if( c==0 ){
1280
+1 -1
--- src/search.c
+++ src/search.c
@@ -1775,11 +1775,11 @@
17751775
{ 3, "disable" },
17761776
{ 4, "enable" },
17771777
{ 5, "stemmer" },
17781778
};
17791779
static const struct { char *zSetting; char *zName; char *zSw; } aSetng[] = {
1780
- { "search-ckin", "check-in search:", "c" },
1780
+ { "search-ci", "check-in search:", "c" },
17811781
{ "search-doc", "document search:", "d" },
17821782
{ "search-tkt", "ticket search:", "t" },
17831783
{ "search-wiki", "wiki search:", "w" },
17841784
{ "search-technote", "tech note search:", "e" },
17851785
};
17861786
--- src/search.c
+++ src/search.c
@@ -1775,11 +1775,11 @@
1775 { 3, "disable" },
1776 { 4, "enable" },
1777 { 5, "stemmer" },
1778 };
1779 static const struct { char *zSetting; char *zName; char *zSw; } aSetng[] = {
1780 { "search-ckin", "check-in search:", "c" },
1781 { "search-doc", "document search:", "d" },
1782 { "search-tkt", "ticket search:", "t" },
1783 { "search-wiki", "wiki search:", "w" },
1784 { "search-technote", "tech note search:", "e" },
1785 };
1786
--- src/search.c
+++ src/search.c
@@ -1775,11 +1775,11 @@
1775 { 3, "disable" },
1776 { 4, "enable" },
1777 { 5, "stemmer" },
1778 };
1779 static const struct { char *zSetting; char *zName; char *zSw; } aSetng[] = {
1780 { "search-ci", "check-in search:", "c" },
1781 { "search-doc", "document search:", "d" },
1782 { "search-tkt", "ticket search:", "t" },
1783 { "search-wiki", "wiki search:", "w" },
1784 { "search-technote", "tech note search:", "e" },
1785 };
1786
+24 -4
--- src/setup.c
+++ src/setup.c
@@ -18,10 +18,25 @@
1818
** Implementation of the Setup page
1919
*/
2020
#include "config.h"
2121
#include <assert.h>
2222
#include "setup.h"
23
+
24
+/*
25
+** Increment the "cfgcnt" variable, so that ETags will know that
26
+** the configuration has changed.
27
+*/
28
+void setup_incr_cfgcnt(void){
29
+ static int once = 1;
30
+ if( once ){
31
+ once = 0;
32
+ db_multi_exec("UPDATE config SET value=value+1 WHERE name='cfgcnt'");
33
+ if( db_changes()==0 ){
34
+ db_multi_exec("INSERT INTO config(name,value) VALUES('cfgcnt',1)");
35
+ }
36
+ }
37
+}
2338
2439
/*
2540
** Output a single entry for a menu generated using an HTML table.
2641
** If zLink is not NULL or an empty string, then it is the page that
2742
** the menu entry will hyperlink to. If zLink is NULL or "", then
@@ -450,11 +465,11 @@
450465
451466
/* If we have all the necessary information, write the new or
452467
** modified user record. After writing the user record, redirect
453468
** to the page that displays a list of users.
454469
*/
455
- doWrite = cgi_all("login","info","pw") && !higherUser;
470
+ doWrite = cgi_all("login","info","pw") && !higherUser && cgi_csrf_safe(1);
456471
if( doWrite ){
457472
char c;
458473
char zCap[50], zNm[4];
459474
zNm[0] = 'a';
460475
zNm[2] = 0;
@@ -496,10 +511,11 @@
496511
db_multi_exec(
497512
"REPLACE INTO user(uid,login,info,pw,cap,mtime) "
498513
"VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
499514
uid, zLogin, P("info"), zPw, zCap
500515
);
516
+ setup_incr_cfgcnt();
501517
admin_log( "Updated user [%q] with capabilities [%q].",
502518
zLogin, zCap );
503519
if( atoi(PD("all","0"))>0 ){
504520
Blob sql;
505521
char *zErr = 0;
@@ -1716,11 +1732,11 @@
17161732
if( !g.perm.Setup ){
17171733
login_needed(0);
17181734
return;
17191735
}
17201736
db_begin_transaction();
1721
- if( P("clear")!=0 ){
1737
+ if( P("clear")!=0 && cgi_csrf_safe(1) ){
17221738
db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
17231739
cgi_replace_parameter("adunit","");
17241740
}
17251741
17261742
style_header("Edit Ad Unit");
@@ -1805,11 +1821,13 @@
18051821
if( !g.perm.Setup ){
18061822
login_needed(0);
18071823
return;
18081824
}
18091825
db_begin_transaction();
1810
- if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
1826
+ if( !cgi_csrf_safe(1) ){
1827
+ /* Allow no state changes if not safe from CSRF */
1828
+ }else if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
18111829
Blob img;
18121830
Stmt ins;
18131831
blob_init(&img, aLogoImg, szLogoImg);
18141832
db_prepare(&ins,
18151833
"REPLACE INTO config(name,value,mtime)"
@@ -1940,19 +1958,20 @@
19401958
**
19411959
** Run raw SQL commands against the database file using the web interface.
19421960
** Requires Admin privileges.
19431961
*/
19441962
void sql_page(void){
1945
- const char *zQ = P("q");
1963
+ const char *zQ;
19461964
int go = P("go")!=0;
19471965
login_check_credentials();
19481966
if( !g.perm.Setup ){
19491967
login_needed(0);
19501968
return;
19511969
}
19521970
add_content_sql_commands(g.db);
19531971
db_begin_transaction();
1972
+ zQ = cgi_csrf_safe(1) ? P("q") : 0;
19541973
style_header("Raw SQL Commands");
19551974
@ <p><b>Caution:</b> There are no restrictions on the SQL that can be
19561975
@ run by this page. You can do serious and irrepairable damage to the
19571976
@ repository. Proceed with extreme caution.</p>
19581977
@
@@ -2270,10 +2289,11 @@
22702289
Blob *pSql,
22712290
const char *zOldName,
22722291
const char *zNewName,
22732292
const char *zValue
22742293
){
2294
+ if( !cgi_csrf_safe(1) ) return;
22752295
if( zNewName[0]==0 || zValue[0]==0 ){
22762296
if( zOldName[0] ){
22772297
blob_append_sql(pSql,
22782298
"DELETE FROM config WHERE name='walias:%q';\n",
22792299
zOldName);
22802300
--- src/setup.c
+++ src/setup.c
@@ -18,10 +18,25 @@
18 ** Implementation of the Setup page
19 */
20 #include "config.h"
21 #include <assert.h>
22 #include "setup.h"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24 /*
25 ** Output a single entry for a menu generated using an HTML table.
26 ** If zLink is not NULL or an empty string, then it is the page that
27 ** the menu entry will hyperlink to. If zLink is NULL or "", then
@@ -450,11 +465,11 @@
450
451 /* If we have all the necessary information, write the new or
452 ** modified user record. After writing the user record, redirect
453 ** to the page that displays a list of users.
454 */
455 doWrite = cgi_all("login","info","pw") && !higherUser;
456 if( doWrite ){
457 char c;
458 char zCap[50], zNm[4];
459 zNm[0] = 'a';
460 zNm[2] = 0;
@@ -496,10 +511,11 @@
496 db_multi_exec(
497 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
498 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
499 uid, zLogin, P("info"), zPw, zCap
500 );
 
501 admin_log( "Updated user [%q] with capabilities [%q].",
502 zLogin, zCap );
503 if( atoi(PD("all","0"))>0 ){
504 Blob sql;
505 char *zErr = 0;
@@ -1716,11 +1732,11 @@
1716 if( !g.perm.Setup ){
1717 login_needed(0);
1718 return;
1719 }
1720 db_begin_transaction();
1721 if( P("clear")!=0 ){
1722 db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
1723 cgi_replace_parameter("adunit","");
1724 }
1725
1726 style_header("Edit Ad Unit");
@@ -1805,11 +1821,13 @@
1805 if( !g.perm.Setup ){
1806 login_needed(0);
1807 return;
1808 }
1809 db_begin_transaction();
1810 if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
 
 
1811 Blob img;
1812 Stmt ins;
1813 blob_init(&img, aLogoImg, szLogoImg);
1814 db_prepare(&ins,
1815 "REPLACE INTO config(name,value,mtime)"
@@ -1940,19 +1958,20 @@
1940 **
1941 ** Run raw SQL commands against the database file using the web interface.
1942 ** Requires Admin privileges.
1943 */
1944 void sql_page(void){
1945 const char *zQ = P("q");
1946 int go = P("go")!=0;
1947 login_check_credentials();
1948 if( !g.perm.Setup ){
1949 login_needed(0);
1950 return;
1951 }
1952 add_content_sql_commands(g.db);
1953 db_begin_transaction();
 
1954 style_header("Raw SQL Commands");
1955 @ <p><b>Caution:</b> There are no restrictions on the SQL that can be
1956 @ run by this page. You can do serious and irrepairable damage to the
1957 @ repository. Proceed with extreme caution.</p>
1958 @
@@ -2270,10 +2289,11 @@
2270 Blob *pSql,
2271 const char *zOldName,
2272 const char *zNewName,
2273 const char *zValue
2274 ){
 
2275 if( zNewName[0]==0 || zValue[0]==0 ){
2276 if( zOldName[0] ){
2277 blob_append_sql(pSql,
2278 "DELETE FROM config WHERE name='walias:%q';\n",
2279 zOldName);
2280
--- src/setup.c
+++ src/setup.c
@@ -18,10 +18,25 @@
18 ** Implementation of the Setup page
19 */
20 #include "config.h"
21 #include <assert.h>
22 #include "setup.h"
23
24 /*
25 ** Increment the "cfgcnt" variable, so that ETags will know that
26 ** the configuration has changed.
27 */
28 void setup_incr_cfgcnt(void){
29 static int once = 1;
30 if( once ){
31 once = 0;
32 db_multi_exec("UPDATE config SET value=value+1 WHERE name='cfgcnt'");
33 if( db_changes()==0 ){
34 db_multi_exec("INSERT INTO config(name,value) VALUES('cfgcnt',1)");
35 }
36 }
37 }
38
39 /*
40 ** Output a single entry for a menu generated using an HTML table.
41 ** If zLink is not NULL or an empty string, then it is the page that
42 ** the menu entry will hyperlink to. If zLink is NULL or "", then
@@ -450,11 +465,11 @@
465
466 /* If we have all the necessary information, write the new or
467 ** modified user record. After writing the user record, redirect
468 ** to the page that displays a list of users.
469 */
470 doWrite = cgi_all("login","info","pw") && !higherUser && cgi_csrf_safe(1);
471 if( doWrite ){
472 char c;
473 char zCap[50], zNm[4];
474 zNm[0] = 'a';
475 zNm[2] = 0;
@@ -496,10 +511,11 @@
511 db_multi_exec(
512 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
513 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
514 uid, zLogin, P("info"), zPw, zCap
515 );
516 setup_incr_cfgcnt();
517 admin_log( "Updated user [%q] with capabilities [%q].",
518 zLogin, zCap );
519 if( atoi(PD("all","0"))>0 ){
520 Blob sql;
521 char *zErr = 0;
@@ -1716,11 +1732,11 @@
1732 if( !g.perm.Setup ){
1733 login_needed(0);
1734 return;
1735 }
1736 db_begin_transaction();
1737 if( P("clear")!=0 && cgi_csrf_safe(1) ){
1738 db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
1739 cgi_replace_parameter("adunit","");
1740 }
1741
1742 style_header("Edit Ad Unit");
@@ -1805,11 +1821,13 @@
1821 if( !g.perm.Setup ){
1822 login_needed(0);
1823 return;
1824 }
1825 db_begin_transaction();
1826 if( !cgi_csrf_safe(1) ){
1827 /* Allow no state changes if not safe from CSRF */
1828 }else if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
1829 Blob img;
1830 Stmt ins;
1831 blob_init(&img, aLogoImg, szLogoImg);
1832 db_prepare(&ins,
1833 "REPLACE INTO config(name,value,mtime)"
@@ -1940,19 +1958,20 @@
1958 **
1959 ** Run raw SQL commands against the database file using the web interface.
1960 ** Requires Admin privileges.
1961 */
1962 void sql_page(void){
1963 const char *zQ;
1964 int go = P("go")!=0;
1965 login_check_credentials();
1966 if( !g.perm.Setup ){
1967 login_needed(0);
1968 return;
1969 }
1970 add_content_sql_commands(g.db);
1971 db_begin_transaction();
1972 zQ = cgi_csrf_safe(1) ? P("q") : 0;
1973 style_header("Raw SQL Commands");
1974 @ <p><b>Caution:</b> There are no restrictions on the SQL that can be
1975 @ run by this page. You can do serious and irrepairable damage to the
1976 @ repository. Proceed with extreme caution.</p>
1977 @
@@ -2270,10 +2289,11 @@
2289 Blob *pSql,
2290 const char *zOldName,
2291 const char *zNewName,
2292 const char *zValue
2293 ){
2294 if( !cgi_csrf_safe(1) ) return;
2295 if( zNewName[0]==0 || zValue[0]==0 ){
2296 if( zOldName[0] ){
2297 blob_append_sql(pSql,
2298 "DELETE FROM config WHERE name='walias:%q';\n",
2299 zOldName);
2300
+68 -66
--- src/skins.c
+++ src/skins.c
@@ -467,76 +467,78 @@
467467
zCurrent = getSkin(0);
468468
for(i=0; i<count(aBuiltinSkin); i++){
469469
aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel);
470470
}
471471
472
- /* Process requests to delete a user-defined skin */
473
- if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
474
- style_header("Confirm Custom Skin Delete");
475
- @ <form action="%s(g.zTop)/setup_skin_admin" method="post"><div>
476
- @ <p>Deletion of a custom skin is a permanent action that cannot
477
- @ be undone. Please confirm that this is what you want to do:</p>
478
- @ <input type="hidden" name="sn" value="%h(P("sn"))" />
479
- @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
480
- @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
481
- login_insert_csrf_secret();
482
- @ </div></form>
483
- style_footer();
484
- return;
485
- }
486
- if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
487
- db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
488
- }
489
- if( P("draftdel")!=0 ){
490
- const char *zDraft = P("name");
491
- if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){
492
- db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft);
493
- }
494
- }
495
- if( skinRename() ) return;
496
- if( skinSave(zCurrent) ) return;
497
-
498
- /* The user pressed one of the "Install" buttons. */
499
- if( P("load") && (z = P("sn"))!=0 && z[0] ){
500
- int seen = 0;
501
-
502
- /* Check to see if the current skin is already saved. If it is, there
503
- ** is no need to create a backup */
504
- zCurrent = getSkin(0);
505
- for(i=0; i<count(aBuiltinSkin); i++){
506
- if( fossil_strcmp(aBuiltinSkin[i].zSQL, zCurrent)==0 ){
507
- seen = 1;
508
- break;
509
- }
510
- }
511
- if( !seen ){
512
- seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
513
- " AND value=%Q", zCurrent);
514
- if( !seen ){
515
- db_multi_exec(
516
- "INSERT INTO config(name,value,mtime) VALUES("
517
- " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
518
- " %Q,now())", zCurrent
519
- );
520
- }
521
- }
522
- seen = 0;
523
- for(i=0; i<count(aBuiltinSkin); i++){
524
- if( fossil_strcmp(aBuiltinSkin[i].zDesc, z)==0 ){
525
- seen = 1;
526
- zCurrent = aBuiltinSkin[i].zSQL;
527
- db_multi_exec("%s", zCurrent/*safe-for-%s*/);
528
- break;
529
- }
530
- }
531
- if( !seen ){
532
- zName = skinVarName(z,0);
533
- zCurrent = db_get(zName, 0);
534
- db_multi_exec("%s", zCurrent/*safe-for-%s*/);
535
- }
536
- }
537
-
472
+ if( cgi_csrf_safe(1) ){
473
+ /* Process requests to delete a user-defined skin */
474
+ if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
475
+ style_header("Confirm Custom Skin Delete");
476
+ @ <form action="%s(g.zTop)/setup_skin_admin" method="post"><div>
477
+ @ <p>Deletion of a custom skin is a permanent action that cannot
478
+ @ be undone. Please confirm that this is what you want to do:</p>
479
+ @ <input type="hidden" name="sn" value="%h(P("sn"))" />
480
+ @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
481
+ @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
482
+ login_insert_csrf_secret();
483
+ @ </div></form>
484
+ style_footer();
485
+ return;
486
+ }
487
+ if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
488
+ db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
489
+ }
490
+ if( P("draftdel")!=0 ){
491
+ const char *zDraft = P("name");
492
+ if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){
493
+ db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft);
494
+ }
495
+ }
496
+ if( skinRename() ) return;
497
+ if( skinSave(zCurrent) ) return;
498
+
499
+ /* The user pressed one of the "Install" buttons. */
500
+ if( P("load") && (z = P("sn"))!=0 && z[0] ){
501
+ int seen = 0;
502
+
503
+ /* Check to see if the current skin is already saved. If it is, there
504
+ ** is no need to create a backup */
505
+ zCurrent = getSkin(0);
506
+ for(i=0; i<count(aBuiltinSkin); i++){
507
+ if( fossil_strcmp(aBuiltinSkin[i].zSQL, zCurrent)==0 ){
508
+ seen = 1;
509
+ break;
510
+ }
511
+ }
512
+ if( !seen ){
513
+ seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
514
+ " AND value=%Q", zCurrent);
515
+ if( !seen ){
516
+ db_multi_exec(
517
+ "INSERT INTO config(name,value,mtime) VALUES("
518
+ " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
519
+ " %Q,now())", zCurrent
520
+ );
521
+ }
522
+ }
523
+ seen = 0;
524
+ for(i=0; i<count(aBuiltinSkin); i++){
525
+ if( fossil_strcmp(aBuiltinSkin[i].zDesc, z)==0 ){
526
+ seen = 1;
527
+ zCurrent = aBuiltinSkin[i].zSQL;
528
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
529
+ break;
530
+ }
531
+ }
532
+ if( !seen ){
533
+ zName = skinVarName(z,0);
534
+ zCurrent = db_get(zName, 0);
535
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
536
+ }
537
+ }
538
+ }
539
+
538540
style_header("Skins");
539541
if( zErr ){
540542
@ <p style="color:red">%h(zErr)</p>
541543
}
542544
@ <table border="0">
543545
--- src/skins.c
+++ src/skins.c
@@ -467,76 +467,78 @@
467 zCurrent = getSkin(0);
468 for(i=0; i<count(aBuiltinSkin); i++){
469 aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel);
470 }
471
472 /* Process requests to delete a user-defined skin */
473 if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
474 style_header("Confirm Custom Skin Delete");
475 @ <form action="%s(g.zTop)/setup_skin_admin" method="post"><div>
476 @ <p>Deletion of a custom skin is a permanent action that cannot
477 @ be undone. Please confirm that this is what you want to do:</p>
478 @ <input type="hidden" name="sn" value="%h(P("sn"))" />
479 @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
480 @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
481 login_insert_csrf_secret();
482 @ </div></form>
483 style_footer();
484 return;
485 }
486 if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
487 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
488 }
489 if( P("draftdel")!=0 ){
490 const char *zDraft = P("name");
491 if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){
492 db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft);
493 }
494 }
495 if( skinRename() ) return;
496 if( skinSave(zCurrent) ) return;
497
498 /* The user pressed one of the "Install" buttons. */
499 if( P("load") && (z = P("sn"))!=0 && z[0] ){
500 int seen = 0;
501
502 /* Check to see if the current skin is already saved. If it is, there
503 ** is no need to create a backup */
504 zCurrent = getSkin(0);
505 for(i=0; i<count(aBuiltinSkin); i++){
506 if( fossil_strcmp(aBuiltinSkin[i].zSQL, zCurrent)==0 ){
507 seen = 1;
508 break;
509 }
510 }
511 if( !seen ){
512 seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
513 " AND value=%Q", zCurrent);
514 if( !seen ){
515 db_multi_exec(
516 "INSERT INTO config(name,value,mtime) VALUES("
517 " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
518 " %Q,now())", zCurrent
519 );
520 }
521 }
522 seen = 0;
523 for(i=0; i<count(aBuiltinSkin); i++){
524 if( fossil_strcmp(aBuiltinSkin[i].zDesc, z)==0 ){
525 seen = 1;
526 zCurrent = aBuiltinSkin[i].zSQL;
527 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
528 break;
529 }
530 }
531 if( !seen ){
532 zName = skinVarName(z,0);
533 zCurrent = db_get(zName, 0);
534 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
535 }
536 }
537
 
 
538 style_header("Skins");
539 if( zErr ){
540 @ <p style="color:red">%h(zErr)</p>
541 }
542 @ <table border="0">
543
--- src/skins.c
+++ src/skins.c
@@ -467,76 +467,78 @@
467 zCurrent = getSkin(0);
468 for(i=0; i<count(aBuiltinSkin); i++){
469 aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel);
470 }
471
472 if( cgi_csrf_safe(1) ){
473 /* Process requests to delete a user-defined skin */
474 if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
475 style_header("Confirm Custom Skin Delete");
476 @ <form action="%s(g.zTop)/setup_skin_admin" method="post"><div>
477 @ <p>Deletion of a custom skin is a permanent action that cannot
478 @ be undone. Please confirm that this is what you want to do:</p>
479 @ <input type="hidden" name="sn" value="%h(P("sn"))" />
480 @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
481 @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
482 login_insert_csrf_secret();
483 @ </div></form>
484 style_footer();
485 return;
486 }
487 if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
488 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
489 }
490 if( P("draftdel")!=0 ){
491 const char *zDraft = P("name");
492 if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){
493 db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft);
494 }
495 }
496 if( skinRename() ) return;
497 if( skinSave(zCurrent) ) return;
498
499 /* The user pressed one of the "Install" buttons. */
500 if( P("load") && (z = P("sn"))!=0 && z[0] ){
501 int seen = 0;
502
503 /* Check to see if the current skin is already saved. If it is, there
504 ** is no need to create a backup */
505 zCurrent = getSkin(0);
506 for(i=0; i<count(aBuiltinSkin); i++){
507 if( fossil_strcmp(aBuiltinSkin[i].zSQL, zCurrent)==0 ){
508 seen = 1;
509 break;
510 }
511 }
512 if( !seen ){
513 seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
514 " AND value=%Q", zCurrent);
515 if( !seen ){
516 db_multi_exec(
517 "INSERT INTO config(name,value,mtime) VALUES("
518 " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
519 " %Q,now())", zCurrent
520 );
521 }
522 }
523 seen = 0;
524 for(i=0; i<count(aBuiltinSkin); i++){
525 if( fossil_strcmp(aBuiltinSkin[i].zDesc, z)==0 ){
526 seen = 1;
527 zCurrent = aBuiltinSkin[i].zSQL;
528 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
529 break;
530 }
531 }
532 if( !seen ){
533 zName = skinVarName(z,0);
534 zCurrent = db_get(zName, 0);
535 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
536 }
537 }
538 }
539
540 style_header("Skins");
541 if( zErr ){
542 @ <p style="color:red">%h(zErr)</p>
543 }
544 @ <table border="0">
545
+8 -5
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1147,11 +1147,11 @@
11471147
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
11481148
** [sqlite_version()] and [sqlite_source_id()].
11491149
*/
11501150
#define SQLITE_VERSION "3.22.0"
11511151
#define SQLITE_VERSION_NUMBER 3022000
1152
-#define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536"
1152
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
11531153
11541154
/*
11551155
** CAPI3REF: Run-Time Library Version Numbers
11561156
** KEYWORDS: sqlite3_version sqlite3_sourceid
11571157
**
@@ -60524,13 +60524,16 @@
6052460524
** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
6052560525
** with the page number and filename associated with the (MemPage*).
6052660526
*/
6052760527
#ifdef SQLITE_DEBUG
6052860528
int corruptPageError(int lineno, MemPage *p){
60529
- char *zMsg = sqlite3_mprintf("database corruption page %d of %s",
60529
+ char *zMsg;
60530
+ sqlite3BeginBenignMalloc();
60531
+ zMsg = sqlite3_mprintf("database corruption page %d of %s",
6053060532
(int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
6053160533
);
60534
+ sqlite3EndBenignMalloc();
6053260535
if( zMsg ){
6053360536
sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
6053460537
}
6053560538
sqlite3_free(zMsg);
6053660539
return SQLITE_CORRUPT_BKPT;
@@ -203328,11 +203331,11 @@
203328203331
int nArg, /* Number of args */
203329203332
sqlite3_value **apUnused /* Function arguments */
203330203333
){
203331203334
assert( nArg==0 );
203332203335
UNUSED_PARAM2(nArg, apUnused);
203333
- sqlite3_result_text(pCtx, "fts5: 2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536", -1, SQLITE_TRANSIENT);
203336
+ sqlite3_result_text(pCtx, "fts5: 2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d", -1, SQLITE_TRANSIENT);
203334203337
}
203335203338
203336203339
static int fts5Init(sqlite3 *db){
203337203340
static const sqlite3_module fts5Mod = {
203338203341
/* iVersion */ 2,
@@ -207596,12 +207599,12 @@
207596207599
}
207597207600
#endif /* SQLITE_CORE */
207598207601
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
207599207602
207600207603
/************** End of stmt.c ************************************************/
207601
-#if __LINE__!=207601
207604
+#if __LINE__!=207604
207602207605
#undef SQLITE_SOURCE_ID
207603
-#define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e255083alt2"
207606
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2alt2"
207604207607
#endif
207605207608
/* Return the source-id for this library */
207606207609
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
207607207610
/************************** End of sqlite3.c ******************************/
207608207611
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1147,11 +1147,11 @@
1147 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1148 ** [sqlite_version()] and [sqlite_source_id()].
1149 */
1150 #define SQLITE_VERSION "3.22.0"
1151 #define SQLITE_VERSION_NUMBER 3022000
1152 #define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536"
1153
1154 /*
1155 ** CAPI3REF: Run-Time Library Version Numbers
1156 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1157 **
@@ -60524,13 +60524,16 @@
60524 ** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
60525 ** with the page number and filename associated with the (MemPage*).
60526 */
60527 #ifdef SQLITE_DEBUG
60528 int corruptPageError(int lineno, MemPage *p){
60529 char *zMsg = sqlite3_mprintf("database corruption page %d of %s",
 
 
60530 (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
60531 );
 
60532 if( zMsg ){
60533 sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
60534 }
60535 sqlite3_free(zMsg);
60536 return SQLITE_CORRUPT_BKPT;
@@ -203328,11 +203331,11 @@
203328 int nArg, /* Number of args */
203329 sqlite3_value **apUnused /* Function arguments */
203330 ){
203331 assert( nArg==0 );
203332 UNUSED_PARAM2(nArg, apUnused);
203333 sqlite3_result_text(pCtx, "fts5: 2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536", -1, SQLITE_TRANSIENT);
203334 }
203335
203336 static int fts5Init(sqlite3 *db){
203337 static const sqlite3_module fts5Mod = {
203338 /* iVersion */ 2,
@@ -207596,12 +207599,12 @@
207596 }
207597 #endif /* SQLITE_CORE */
207598 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
207599
207600 /************** End of stmt.c ************************************************/
207601 #if __LINE__!=207601
207602 #undef SQLITE_SOURCE_ID
207603 #define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e255083alt2"
207604 #endif
207605 /* Return the source-id for this library */
207606 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
207607 /************************** End of sqlite3.c ******************************/
207608
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1147,11 +1147,11 @@
1147 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1148 ** [sqlite_version()] and [sqlite_source_id()].
1149 */
1150 #define SQLITE_VERSION "3.22.0"
1151 #define SQLITE_VERSION_NUMBER 3022000
1152 #define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
1153
1154 /*
1155 ** CAPI3REF: Run-Time Library Version Numbers
1156 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1157 **
@@ -60524,13 +60524,16 @@
60524 ** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
60525 ** with the page number and filename associated with the (MemPage*).
60526 */
60527 #ifdef SQLITE_DEBUG
60528 int corruptPageError(int lineno, MemPage *p){
60529 char *zMsg;
60530 sqlite3BeginBenignMalloc();
60531 zMsg = sqlite3_mprintf("database corruption page %d of %s",
60532 (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
60533 );
60534 sqlite3EndBenignMalloc();
60535 if( zMsg ){
60536 sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
60537 }
60538 sqlite3_free(zMsg);
60539 return SQLITE_CORRUPT_BKPT;
@@ -203328,11 +203331,11 @@
203331 int nArg, /* Number of args */
203332 sqlite3_value **apUnused /* Function arguments */
203333 ){
203334 assert( nArg==0 );
203335 UNUSED_PARAM2(nArg, apUnused);
203336 sqlite3_result_text(pCtx, "fts5: 2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d", -1, SQLITE_TRANSIENT);
203337 }
203338
203339 static int fts5Init(sqlite3 *db){
203340 static const sqlite3_module fts5Mod = {
203341 /* iVersion */ 2,
@@ -207596,12 +207599,12 @@
207599 }
207600 #endif /* SQLITE_CORE */
207601 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
207602
207603 /************** End of stmt.c ************************************************/
207604 #if __LINE__!=207604
207605 #undef SQLITE_SOURCE_ID
207606 #define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2alt2"
207607 #endif
207608 /* Return the source-id for this library */
207609 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
207610 /************************** End of sqlite3.c ******************************/
207611
+1 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123123
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124124
** [sqlite_version()] and [sqlite_source_id()].
125125
*/
126126
#define SQLITE_VERSION "3.22.0"
127127
#define SQLITE_VERSION_NUMBER 3022000
128
-#define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536"
128
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
129129
130130
/*
131131
** CAPI3REF: Run-Time Library Version Numbers
132132
** KEYWORDS: sqlite3_version sqlite3_sourceid
133133
**
134134
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.22.0"
127 #define SQLITE_VERSION_NUMBER 3022000
128 #define SQLITE_SOURCE_ID "2018-01-20 15:48:45 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
134
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.22.0"
127 #define SQLITE_VERSION_NUMBER 3022000
128 #define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
134
+11 -3
--- src/statrep.c
+++ src/statrep.c
@@ -58,10 +58,11 @@
5858
*/
5959
static int stats_report_init_view(){
6060
const char *zType = PD("type","*"); /* analog to /timeline?y=... */
6161
const char *zRealType = NULL; /* normalized form of zType */
6262
int rc = 0; /* result code */
63
+ char *zTimeSpan; /* Time span */
6364
assert( !statsReportType && "Must not be called more than once." );
6465
switch( (zType && *zType) ? *zType : 0 ){
6566
case 'c':
6667
case 'C':
6768
zRealType = "ci";
@@ -90,19 +91,26 @@
9091
default:
9192
rc = '*';
9293
break;
9394
}
9495
assert(0 != rc);
96
+ if( P("from")!=0 && P("to")!=0 ){
97
+ zTimeSpan = mprintf(
98
+ " (event.mtime BETWEEN julianday(%Q) AND julianday(%Q))",
99
+ P("from"), P("to"));
100
+ }else{
101
+ zTimeSpan = " 1";
102
+ }
95103
if(zRealType){
96104
statsReportTimelineYFlag = zRealType;
97105
db_multi_exec("CREATE TEMP VIEW v_reports AS "
98
- "SELECT * FROM event WHERE type GLOB %Q",
99
- zRealType);
106
+ "SELECT * FROM event WHERE (type GLOB %Q) AND %s",
107
+ zRealType, zTimeSpan/*safe-for-%s*/);
100108
}else{
101109
statsReportTimelineYFlag = "a";
102110
db_multi_exec("CREATE TEMP VIEW v_reports AS "
103
- "SELECT * FROM event");
111
+ "SELECT * FROM event WHERE %s", zTimeSpan/*safe-for-%s*/);
104112
}
105113
return statsReportType = rc;
106114
}
107115
108116
/*
109117
--- src/statrep.c
+++ src/statrep.c
@@ -58,10 +58,11 @@
58 */
59 static int stats_report_init_view(){
60 const char *zType = PD("type","*"); /* analog to /timeline?y=... */
61 const char *zRealType = NULL; /* normalized form of zType */
62 int rc = 0; /* result code */
 
63 assert( !statsReportType && "Must not be called more than once." );
64 switch( (zType && *zType) ? *zType : 0 ){
65 case 'c':
66 case 'C':
67 zRealType = "ci";
@@ -90,19 +91,26 @@
90 default:
91 rc = '*';
92 break;
93 }
94 assert(0 != rc);
 
 
 
 
 
 
 
95 if(zRealType){
96 statsReportTimelineYFlag = zRealType;
97 db_multi_exec("CREATE TEMP VIEW v_reports AS "
98 "SELECT * FROM event WHERE type GLOB %Q",
99 zRealType);
100 }else{
101 statsReportTimelineYFlag = "a";
102 db_multi_exec("CREATE TEMP VIEW v_reports AS "
103 "SELECT * FROM event");
104 }
105 return statsReportType = rc;
106 }
107
108 /*
109
--- src/statrep.c
+++ src/statrep.c
@@ -58,10 +58,11 @@
58 */
59 static int stats_report_init_view(){
60 const char *zType = PD("type","*"); /* analog to /timeline?y=... */
61 const char *zRealType = NULL; /* normalized form of zType */
62 int rc = 0; /* result code */
63 char *zTimeSpan; /* Time span */
64 assert( !statsReportType && "Must not be called more than once." );
65 switch( (zType && *zType) ? *zType : 0 ){
66 case 'c':
67 case 'C':
68 zRealType = "ci";
@@ -90,19 +91,26 @@
91 default:
92 rc = '*';
93 break;
94 }
95 assert(0 != rc);
96 if( P("from")!=0 && P("to")!=0 ){
97 zTimeSpan = mprintf(
98 " (event.mtime BETWEEN julianday(%Q) AND julianday(%Q))",
99 P("from"), P("to"));
100 }else{
101 zTimeSpan = " 1";
102 }
103 if(zRealType){
104 statsReportTimelineYFlag = zRealType;
105 db_multi_exec("CREATE TEMP VIEW v_reports AS "
106 "SELECT * FROM event WHERE (type GLOB %Q) AND %s",
107 zRealType, zTimeSpan/*safe-for-%s*/);
108 }else{
109 statsReportTimelineYFlag = "a";
110 db_multi_exec("CREATE TEMP VIEW v_reports AS "
111 "SELECT * FROM event WHERE %s", zTimeSpan/*safe-for-%s*/);
112 }
113 return statsReportType = rc;
114 }
115
116 /*
117
+13 -2
--- src/style.c
+++ src/style.c
@@ -833,15 +833,20 @@
833833
** WEBPAGE: builtin
834834
** URL: builtin/FILENAME
835835
**
836836
** Return the built-in text given by FILENAME. This is used internally
837837
** by many Fossil web pages to load built-in javascript files.
838
+**
839
+** If the id= query parameter is present, then Fossil assumes that the
840
+** result is immutable and sets a very large cache retention time (1 year).
838841
*/
839842
void page_builtin_text(void){
840843
Blob out;
841844
const char *zName = P("name");
842845
const char *zTxt = 0;
846
+ const char *zId = P("id");
847
+ int nId;
843848
if( zName ) zTxt = builtin_text(zName);
844849
if( zTxt==0 ){
845850
cgi_set_status(404, "Not Found");
846851
@ File "%h(zName)" not found
847852
return;
@@ -848,14 +853,18 @@
848853
}
849854
if( sqlite3_strglob("*.js", zName)==0 ){
850855
cgi_set_content_type("application/javascript");
851856
}else{
852857
cgi_set_content_type("text/plain");
858
+ }
859
+ if( zId && (nId = (int)strlen(zId))>=8 && strncmp(zId,MANIFEST_UUID,nId)==0 ){
860
+ g.isConst = 1;
861
+ }else{
862
+ etag_check(0,0);
853863
}
854864
blob_init(&out, zTxt, -1);
855865
cgi_set_content(&out);
856
- g.isConst = 1;
857866
}
858867
859868
860869
/*
861870
** WEBPAGE: test_env
@@ -870,11 +879,12 @@
870879
char zCap[30];
871880
static const char *const azCgiVars[] = {
872881
"COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
873882
"HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
874883
"HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
875
- "HTTP_CONNECTION", "HTTP_HOST", "HTTP_IF_NONE_MATCH",
884
+ "HTTP_CONNECTION", "HTTP_HOST",
885
+ "HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
876886
"HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
877887
"QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
878888
"REMOTE_USER", "REQUEST_METHOD",
879889
"REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
880890
"HOME", "FOSSIL_HOME", "USERNAME", "USER", "FOSSIL_USER",
@@ -925,10 +935,11 @@
925935
if( i>0 ){
926936
@ anonymous-adds = %s(zCap)<br />
927937
}
928938
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
929939
@ load_average() = %f(load_average())<br />
940
+ @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
930941
@ <hr />
931942
P("HTTP_USER_AGENT");
932943
cgi_print_all(showAll);
933944
if( showAll && blob_size(&g.httpHeader)>0 ){
934945
@ <hr />
935946
--- src/style.c
+++ src/style.c
@@ -833,15 +833,20 @@
833 ** WEBPAGE: builtin
834 ** URL: builtin/FILENAME
835 **
836 ** Return the built-in text given by FILENAME. This is used internally
837 ** by many Fossil web pages to load built-in javascript files.
 
 
 
838 */
839 void page_builtin_text(void){
840 Blob out;
841 const char *zName = P("name");
842 const char *zTxt = 0;
 
 
843 if( zName ) zTxt = builtin_text(zName);
844 if( zTxt==0 ){
845 cgi_set_status(404, "Not Found");
846 @ File "%h(zName)" not found
847 return;
@@ -848,14 +853,18 @@
848 }
849 if( sqlite3_strglob("*.js", zName)==0 ){
850 cgi_set_content_type("application/javascript");
851 }else{
852 cgi_set_content_type("text/plain");
 
 
 
 
 
853 }
854 blob_init(&out, zTxt, -1);
855 cgi_set_content(&out);
856 g.isConst = 1;
857 }
858
859
860 /*
861 ** WEBPAGE: test_env
@@ -870,11 +879,12 @@
870 char zCap[30];
871 static const char *const azCgiVars[] = {
872 "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
873 "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
874 "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
875 "HTTP_CONNECTION", "HTTP_HOST", "HTTP_IF_NONE_MATCH",
 
876 "HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
877 "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
878 "REMOTE_USER", "REQUEST_METHOD",
879 "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
880 "HOME", "FOSSIL_HOME", "USERNAME", "USER", "FOSSIL_USER",
@@ -925,10 +935,11 @@
925 if( i>0 ){
926 @ anonymous-adds = %s(zCap)<br />
927 }
928 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
929 @ load_average() = %f(load_average())<br />
 
930 @ <hr />
931 P("HTTP_USER_AGENT");
932 cgi_print_all(showAll);
933 if( showAll && blob_size(&g.httpHeader)>0 ){
934 @ <hr />
935
--- src/style.c
+++ src/style.c
@@ -833,15 +833,20 @@
833 ** WEBPAGE: builtin
834 ** URL: builtin/FILENAME
835 **
836 ** Return the built-in text given by FILENAME. This is used internally
837 ** by many Fossil web pages to load built-in javascript files.
838 **
839 ** If the id= query parameter is present, then Fossil assumes that the
840 ** result is immutable and sets a very large cache retention time (1 year).
841 */
842 void page_builtin_text(void){
843 Blob out;
844 const char *zName = P("name");
845 const char *zTxt = 0;
846 const char *zId = P("id");
847 int nId;
848 if( zName ) zTxt = builtin_text(zName);
849 if( zTxt==0 ){
850 cgi_set_status(404, "Not Found");
851 @ File "%h(zName)" not found
852 return;
@@ -848,14 +853,18 @@
853 }
854 if( sqlite3_strglob("*.js", zName)==0 ){
855 cgi_set_content_type("application/javascript");
856 }else{
857 cgi_set_content_type("text/plain");
858 }
859 if( zId && (nId = (int)strlen(zId))>=8 && strncmp(zId,MANIFEST_UUID,nId)==0 ){
860 g.isConst = 1;
861 }else{
862 etag_check(0,0);
863 }
864 blob_init(&out, zTxt, -1);
865 cgi_set_content(&out);
 
866 }
867
868
869 /*
870 ** WEBPAGE: test_env
@@ -870,11 +879,12 @@
879 char zCap[30];
880 static const char *const azCgiVars[] = {
881 "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
882 "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
883 "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
884 "HTTP_CONNECTION", "HTTP_HOST",
885 "HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
886 "HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
887 "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
888 "REMOTE_USER", "REQUEST_METHOD",
889 "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
890 "HOME", "FOSSIL_HOME", "USERNAME", "USER", "FOSSIL_USER",
@@ -925,10 +935,11 @@
935 if( i>0 ){
936 @ anonymous-adds = %s(zCap)<br />
937 }
938 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
939 @ load_average() = %f(load_average())<br />
940 @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
941 @ <hr />
942 P("HTTP_USER_AGENT");
943 cgi_print_all(showAll);
944 if( showAll && blob_size(&g.httpHeader)>0 ){
945 @ <hr />
946
+1
--- src/tar.c
+++ src/tar.c
@@ -731,10 +731,11 @@
731731
blob_appendf(&cacheKey, "/tarball/%z", rid_to_uuid(rid));
732732
blob_appendf(&cacheKey, "/%q", zName);
733733
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
734734
if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
735735
zKey = blob_str(&cacheKey);
736
+ etag_check(ETAG_HASH, zKey);
736737
737738
if( P("debug")!=0 ){
738739
style_header("Tarball Generator Debug Screen");
739740
@ zName = "%h(zName)"<br />
740741
@ rid = %d(rid)<br />
741742
--- src/tar.c
+++ src/tar.c
@@ -731,10 +731,11 @@
731 blob_appendf(&cacheKey, "/tarball/%z", rid_to_uuid(rid));
732 blob_appendf(&cacheKey, "/%q", zName);
733 if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
734 if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
735 zKey = blob_str(&cacheKey);
 
736
737 if( P("debug")!=0 ){
738 style_header("Tarball Generator Debug Screen");
739 @ zName = "%h(zName)"<br />
740 @ rid = %d(rid)<br />
741
--- src/tar.c
+++ src/tar.c
@@ -731,10 +731,11 @@
731 blob_appendf(&cacheKey, "/tarball/%z", rid_to_uuid(rid));
732 blob_appendf(&cacheKey, "/%q", zName);
733 if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
734 if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
735 zKey = blob_str(&cacheKey);
736 etag_check(ETAG_HASH, zKey);
737
738 if( P("debug")!=0 ){
739 style_header("Tarball Generator Debug Screen");
740 @ zName = "%h(zName)"<br />
741 @ rid = %d(rid)<br />
742
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -131,10 +131,17 @@
131131
# define TCL_LIBRARY_NAME "libtcl8.6.dylib\0"
132132
# endif
133133
# ifndef TCL_MINOR_OFFSET
134134
# define TCL_MINOR_OFFSET (8)
135135
# endif
136
+# elif defined(__FreeBSD__)
137
+# ifndef TCL_LIBRARY_NAME
138
+# define TCL_LIBRARY_NAME "libtcl86.so\0"
139
+# endif
140
+# ifndef TCL_MINOR_OFFSET
141
+# define TCL_MINOR_OFFSET (7)
142
+# endif
136143
# else
137144
# ifndef TCL_LIBRARY_NAME
138145
# define TCL_LIBRARY_NAME "libtcl8.6.so\0"
139146
# endif
140147
# ifndef TCL_MINOR_OFFSET
141148
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -131,10 +131,17 @@
131 # define TCL_LIBRARY_NAME "libtcl8.6.dylib\0"
132 # endif
133 # ifndef TCL_MINOR_OFFSET
134 # define TCL_MINOR_OFFSET (8)
135 # endif
 
 
 
 
 
 
 
136 # else
137 # ifndef TCL_LIBRARY_NAME
138 # define TCL_LIBRARY_NAME "libtcl8.6.so\0"
139 # endif
140 # ifndef TCL_MINOR_OFFSET
141
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -131,10 +131,17 @@
131 # define TCL_LIBRARY_NAME "libtcl8.6.dylib\0"
132 # endif
133 # ifndef TCL_MINOR_OFFSET
134 # define TCL_MINOR_OFFSET (8)
135 # endif
136 # elif defined(__FreeBSD__)
137 # ifndef TCL_LIBRARY_NAME
138 # define TCL_LIBRARY_NAME "libtcl86.so\0"
139 # endif
140 # ifndef TCL_MINOR_OFFSET
141 # define TCL_MINOR_OFFSET (7)
142 # endif
143 # else
144 # ifndef TCL_LIBRARY_NAME
145 # define TCL_LIBRARY_NAME "libtcl8.6.so\0"
146 # endif
147 # ifndef TCL_MINOR_OFFSET
148
+10 -2
--- src/timeline.c
+++ src/timeline.c
@@ -418,11 +418,11 @@
418418
}else{
419419
zBgClr = hash_color(zBr);
420420
}
421421
}
422422
}
423
- if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){
423
+ if( zType[0]=='c' && pGraph ){
424424
int nParent = 0;
425425
int aParent[GR_MAX_RAIL];
426426
static Stmt qparent;
427427
db_static_prepare(&qparent,
428428
"SELECT pid FROM plink"
@@ -436,10 +436,16 @@
436436
db_reset(&qparent);
437437
gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
438438
zUuid, isLeaf);
439439
db_reset(&qbranch);
440440
@ <div id="m%d(gidx)" class="tl-nodemark"></div>
441
+ }else if( zType[0]=='e' && pGraph && zBgClr && zBgClr[0] ){
442
+ /* For technotes, make a graph node with nParent==(-1). This will
443
+ ** not actually draw anything on the graph, but it will set the
444
+ ** background color of the timeline entry */
445
+ gidx = graph_add_row(pGraph, rid, -1, 0, zBr, zBgClr, zUuid, 0);
446
+ @ <div id="m%d(gidx)" class="tl-nodemark"></div>
441447
}
442448
@</td>
443449
if( !isSelectedOrCurrent ){
444450
@ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
445451
}else{
@@ -529,11 +535,11 @@
529535
530536
/* Generate extra information and hyperlinks to follow the comment.
531537
** Example: "(check-in: [abcdefg], user: drh, tags: trunk)"
532538
*/
533539
if( drawDetailEllipsis ){
534
- @ <span class='timelineEllipsis' id='ellipsis-%d(rid)'\
540
+ @ <span class='timelineEllipsis' id='ellipsis-%d(rid)' \
535541
@ data-id='%d(rid)'>...</span>
536542
}
537543
if( tmFlags & TIMELINE_COLUMNAR ){
538544
if( !isSelectedOrCurrent ){
539545
@ <td class="timelineDetailCell" id='md%d(gidx)'>
@@ -565,10 +571,12 @@
565571
cgi_printf("technote:&nbsp;");
566572
hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
567573
}else{
568574
cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
569575
}
576
+ }else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t' ){
577
+ cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
570578
}
571579
572580
if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
573581
char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
574582
cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
575583
--- src/timeline.c
+++ src/timeline.c
@@ -418,11 +418,11 @@
418 }else{
419 zBgClr = hash_color(zBr);
420 }
421 }
422 }
423 if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){
424 int nParent = 0;
425 int aParent[GR_MAX_RAIL];
426 static Stmt qparent;
427 db_static_prepare(&qparent,
428 "SELECT pid FROM plink"
@@ -436,10 +436,16 @@
436 db_reset(&qparent);
437 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
438 zUuid, isLeaf);
439 db_reset(&qbranch);
440 @ <div id="m%d(gidx)" class="tl-nodemark"></div>
 
 
 
 
 
 
441 }
442 @</td>
443 if( !isSelectedOrCurrent ){
444 @ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
445 }else{
@@ -529,11 +535,11 @@
529
530 /* Generate extra information and hyperlinks to follow the comment.
531 ** Example: "(check-in: [abcdefg], user: drh, tags: trunk)"
532 */
533 if( drawDetailEllipsis ){
534 @ <span class='timelineEllipsis' id='ellipsis-%d(rid)'\
535 @ data-id='%d(rid)'>...</span>
536 }
537 if( tmFlags & TIMELINE_COLUMNAR ){
538 if( !isSelectedOrCurrent ){
539 @ <td class="timelineDetailCell" id='md%d(gidx)'>
@@ -565,10 +571,12 @@
565 cgi_printf("technote:&nbsp;");
566 hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
567 }else{
568 cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
569 }
 
 
570 }
571
572 if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
573 char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
574 cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
575
--- src/timeline.c
+++ src/timeline.c
@@ -418,11 +418,11 @@
418 }else{
419 zBgClr = hash_color(zBr);
420 }
421 }
422 }
423 if( zType[0]=='c' && pGraph ){
424 int nParent = 0;
425 int aParent[GR_MAX_RAIL];
426 static Stmt qparent;
427 db_static_prepare(&qparent,
428 "SELECT pid FROM plink"
@@ -436,10 +436,16 @@
436 db_reset(&qparent);
437 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
438 zUuid, isLeaf);
439 db_reset(&qbranch);
440 @ <div id="m%d(gidx)" class="tl-nodemark"></div>
441 }else if( zType[0]=='e' && pGraph && zBgClr && zBgClr[0] ){
442 /* For technotes, make a graph node with nParent==(-1). This will
443 ** not actually draw anything on the graph, but it will set the
444 ** background color of the timeline entry */
445 gidx = graph_add_row(pGraph, rid, -1, 0, zBr, zBgClr, zUuid, 0);
446 @ <div id="m%d(gidx)" class="tl-nodemark"></div>
447 }
448 @</td>
449 if( !isSelectedOrCurrent ){
450 @ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
451 }else{
@@ -529,11 +535,11 @@
535
536 /* Generate extra information and hyperlinks to follow the comment.
537 ** Example: "(check-in: [abcdefg], user: drh, tags: trunk)"
538 */
539 if( drawDetailEllipsis ){
540 @ <span class='timelineEllipsis' id='ellipsis-%d(rid)' \
541 @ data-id='%d(rid)'>...</span>
542 }
543 if( tmFlags & TIMELINE_COLUMNAR ){
544 if( !isSelectedOrCurrent ){
545 @ <td class="timelineDetailCell" id='md%d(gidx)'>
@@ -565,10 +571,12 @@
571 cgi_printf("technote:&nbsp;");
572 hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
573 }else{
574 cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
575 }
576 }else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t' ){
577 cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
578 }
579
580 if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
581 char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
582 cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
583
+1 -1
--- src/tkt.c
+++ src/tkt.c
@@ -747,11 +747,11 @@
747747
zName = P("name");
748748
if( P("cancel") ){
749749
cgi_redirectf("tktview?name=%T", zName);
750750
}
751751
style_header("Edit Ticket");
752
- if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
752
+ if( zName==0 || (nName = strlen(zName))<4 || nName>HNAME_LEN_SHA1
753753
|| !validate16(zName,nName) ){
754754
@ <span class="tktError">Not a valid ticket id: "%h(zName)"</span>
755755
style_footer();
756756
return;
757757
}
758758
--- src/tkt.c
+++ src/tkt.c
@@ -747,11 +747,11 @@
747 zName = P("name");
748 if( P("cancel") ){
749 cgi_redirectf("tktview?name=%T", zName);
750 }
751 style_header("Edit Ticket");
752 if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
753 || !validate16(zName,nName) ){
754 @ <span class="tktError">Not a valid ticket id: "%h(zName)"</span>
755 style_footer();
756 return;
757 }
758
--- src/tkt.c
+++ src/tkt.c
@@ -747,11 +747,11 @@
747 zName = P("name");
748 if( P("cancel") ){
749 cgi_redirectf("tktview?name=%T", zName);
750 }
751 style_header("Edit Ticket");
752 if( zName==0 || (nName = strlen(zName))<4 || nName>HNAME_LEN_SHA1
753 || !validate16(zName,nName) ){
754 @ <span class="tktError">Not a valid ticket id: "%h(zName)"</span>
755 style_footer();
756 return;
757 }
758
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153153
** 2: zName exists and is the same as zHash but has a older mtime
154154
** 3: zName exists and is identical to mtime/zHash in all respects.
155155
** 4: zName exists and is the same as zHash but has a newer mtime.
156156
** 5: zName exists and should override the mtime/zHash remote.
157157
*/
158
-int unversioned_status(const char *zName, sqlite3_int64 mtime, const char *zHash){
158
+int unversioned_status(
159
+ const char *zName,
160
+ sqlite3_int64 mtime,
161
+ const char *zHash
162
+){
159163
int iStatus = 0;
160164
Stmt q;
161165
db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
162166
if( db_step(&q)==SQLITE_ROW ){
163167
const char *zLocalHash = db_column_text(&q, 1);
164168
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153 ** 2: zName exists and is the same as zHash but has a older mtime
154 ** 3: zName exists and is identical to mtime/zHash in all respects.
155 ** 4: zName exists and is the same as zHash but has a newer mtime.
156 ** 5: zName exists and should override the mtime/zHash remote.
157 */
158 int unversioned_status(const char *zName, sqlite3_int64 mtime, const char *zHash){
 
 
 
 
159 int iStatus = 0;
160 Stmt q;
161 db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
162 if( db_step(&q)==SQLITE_ROW ){
163 const char *zLocalHash = db_column_text(&q, 1);
164
--- src/unversioned.c
+++ src/unversioned.c
@@ -153,11 +153,15 @@
153 ** 2: zName exists and is the same as zHash but has a older mtime
154 ** 3: zName exists and is identical to mtime/zHash in all respects.
155 ** 4: zName exists and is the same as zHash but has a newer mtime.
156 ** 5: zName exists and should override the mtime/zHash remote.
157 */
158 int unversioned_status(
159 const char *zName,
160 sqlite3_int64 mtime,
161 const char *zHash
162 ){
163 int iStatus = 0;
164 Stmt q;
165 db_prepare(&q, "SELECT mtime, hash FROM unversioned WHERE name=%Q", zName);
166 if( db_step(&q)==SQLITE_ROW ){
167 const char *zLocalHash = db_column_text(&q, 1);
168
+4 -5
--- src/util.c
+++ src/util.c
@@ -376,17 +376,16 @@
376376
return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF;
377377
#endif
378378
}
379379
380380
/*
381
-** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains
382
-** only lower-case ASCII hexadecimal values.
381
+** Returns TRUE if zSym is exactly HNAME_LEN_SHA1 or HNAME_LEN_K256
382
+** bytes long and contains only lower-case ASCII hexadecimal values.
383383
*/
384384
int fossil_is_uuid(const char *zSym){
385
- return zSym
386
- && (UUID_SIZE==strlen(zSym))
387
- && validate16(zSym, UUID_SIZE);
385
+ int sz = zSym ? (int)strlen(zSym) : 0;
386
+ return (HNAME_LEN_SHA1==sz || HNAME_LEN_K256==sz) && validate16(zSym, sz);
388387
}
389388
390389
/*
391390
** Return true if the input string is NULL or all whitespace.
392391
** Return false if the input string contains text.
393392
--- src/util.c
+++ src/util.c
@@ -376,17 +376,16 @@
376 return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF;
377 #endif
378 }
379
380 /*
381 ** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains
382 ** only lower-case ASCII hexadecimal values.
383 */
384 int fossil_is_uuid(const char *zSym){
385 return zSym
386 && (UUID_SIZE==strlen(zSym))
387 && validate16(zSym, UUID_SIZE);
388 }
389
390 /*
391 ** Return true if the input string is NULL or all whitespace.
392 ** Return false if the input string contains text.
393
--- src/util.c
+++ src/util.c
@@ -376,17 +376,16 @@
376 return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF;
377 #endif
378 }
379
380 /*
381 ** Returns TRUE if zSym is exactly HNAME_LEN_SHA1 or HNAME_LEN_K256
382 ** bytes long and contains only lower-case ASCII hexadecimal values.
383 */
384 int fossil_is_uuid(const char *zSym){
385 int sz = zSym ? (int)strlen(zSym) : 0;
386 return (HNAME_LEN_SHA1==sz || HNAME_LEN_K256==sz) && validate16(zSym, sz);
 
387 }
388
389 /*
390 ** Return true if the input string is NULL or all whitespace.
391 ** Return false if the input string contains text.
392
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1110,12 +1110,12 @@
11101110
){
11111111
static Stmt q;
11121112
static int once = 1;
11131113
int n;
11141114
int rc;
1115
- char zLower[UUID_SIZE+1];
1116
- char zUpper[UUID_SIZE+1];
1115
+ char zLower[HNAME_MAX+1];
1116
+ char zUpper[HNAME_MAX+1];
11171117
n = strlen(zTarget);
11181118
memcpy(zLower, zTarget, n+1);
11191119
canonical16(zLower, n+1);
11201120
memcpy(zUpper, zLower, n+1);
11211121
zUpper[n-1]++;
@@ -1218,11 +1218,11 @@
12181218
blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
12191219
}else if( zTarget[0]=='#' ){
12201220
blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
12211221
}else if( is_valid_hname(zTarget) ){
12221222
int isClosed = 0;
1223
- if( strlen(zTarget)<=UUID_SIZE && is_ticket(zTarget, &isClosed) ){
1223
+ if( strlen(zTarget)<=HNAME_MAX && is_ticket(zTarget, &isClosed) ){
12241224
/* Special display processing for tickets. Display the hyperlink
12251225
** as crossed out if the ticket is closed.
12261226
*/
12271227
if( isClosed ){
12281228
if( g.perm.Hyperlink ){
@@ -1831,11 +1831,11 @@
18311831
}
18321832
switch( tokenType ){
18331833
case TOKEN_LINK: {
18341834
char *zTarget;
18351835
int i, c;
1836
- char zLink[42];
1836
+ char zLink[HNAME_MAX+4];
18371837
18381838
zTarget = &z[1];
18391839
for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
18401840
while(i>1 && zTarget[i-1]==' '){ i--; }
18411841
c = zTarget[i];
18421842
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1110,12 +1110,12 @@
1110 ){
1111 static Stmt q;
1112 static int once = 1;
1113 int n;
1114 int rc;
1115 char zLower[UUID_SIZE+1];
1116 char zUpper[UUID_SIZE+1];
1117 n = strlen(zTarget);
1118 memcpy(zLower, zTarget, n+1);
1119 canonical16(zLower, n+1);
1120 memcpy(zUpper, zLower, n+1);
1121 zUpper[n-1]++;
@@ -1218,11 +1218,11 @@
1218 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1219 }else if( zTarget[0]=='#' ){
1220 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1221 }else if( is_valid_hname(zTarget) ){
1222 int isClosed = 0;
1223 if( strlen(zTarget)<=UUID_SIZE && is_ticket(zTarget, &isClosed) ){
1224 /* Special display processing for tickets. Display the hyperlink
1225 ** as crossed out if the ticket is closed.
1226 */
1227 if( isClosed ){
1228 if( g.perm.Hyperlink ){
@@ -1831,11 +1831,11 @@
1831 }
1832 switch( tokenType ){
1833 case TOKEN_LINK: {
1834 char *zTarget;
1835 int i, c;
1836 char zLink[42];
1837
1838 zTarget = &z[1];
1839 for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
1840 while(i>1 && zTarget[i-1]==' '){ i--; }
1841 c = zTarget[i];
1842
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1110,12 +1110,12 @@
1110 ){
1111 static Stmt q;
1112 static int once = 1;
1113 int n;
1114 int rc;
1115 char zLower[HNAME_MAX+1];
1116 char zUpper[HNAME_MAX+1];
1117 n = strlen(zTarget);
1118 memcpy(zLower, zTarget, n+1);
1119 canonical16(zLower, n+1);
1120 memcpy(zUpper, zLower, n+1);
1121 zUpper[n-1]++;
@@ -1218,11 +1218,11 @@
1218 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1219 }else if( zTarget[0]=='#' ){
1220 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1221 }else if( is_valid_hname(zTarget) ){
1222 int isClosed = 0;
1223 if( strlen(zTarget)<=HNAME_MAX && is_ticket(zTarget, &isClosed) ){
1224 /* Special display processing for tickets. Display the hyperlink
1225 ** as crossed out if the ticket is closed.
1226 */
1227 if( isClosed ){
1228 if( g.perm.Hyperlink ){
@@ -1831,11 +1831,11 @@
1831 }
1832 switch( tokenType ){
1833 case TOKEN_LINK: {
1834 char *zTarget;
1835 int i, c;
1836 char zLink[HNAME_MAX+4];
1837
1838 zTarget = &z[1];
1839 for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
1840 while(i>1 && zTarget[i-1]==' '){ i--; }
1841 c = zTarget[i];
1842
+1
--- src/zip.c
+++ src/zip.c
@@ -932,10 +932,11 @@
932932
blob_appendf(&cacheKey, "/%s/%z", g.zPath, rid_to_uuid(rid));
933933
blob_appendf(&cacheKey, "/%q", zName);
934934
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
935935
if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
936936
zKey = blob_str(&cacheKey);
937
+ etag_check(ETAG_HASH, zKey);
937938
938939
if( P("debug")!=0 ){
939940
style_header("%s Archive Generator Debug Screen", zType);
940941
@ zName = "%h(zName)"<br />
941942
@ rid = %d(rid)<br />
942943
--- src/zip.c
+++ src/zip.c
@@ -932,10 +932,11 @@
932 blob_appendf(&cacheKey, "/%s/%z", g.zPath, rid_to_uuid(rid));
933 blob_appendf(&cacheKey, "/%q", zName);
934 if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
935 if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
936 zKey = blob_str(&cacheKey);
 
937
938 if( P("debug")!=0 ){
939 style_header("%s Archive Generator Debug Screen", zType);
940 @ zName = "%h(zName)"<br />
941 @ rid = %d(rid)<br />
942
--- src/zip.c
+++ src/zip.c
@@ -932,10 +932,11 @@
932 blob_appendf(&cacheKey, "/%s/%z", g.zPath, rid_to_uuid(rid));
933 blob_appendf(&cacheKey, "/%q", zName);
934 if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
935 if( zExclude ) blob_appendf(&cacheKey, ",ex=%Q", zExclude);
936 zKey = blob_str(&cacheKey);
937 etag_check(ETAG_HASH, zKey);
938
939 if( P("debug")!=0 ){
940 style_header("%s Archive Generator Debug Screen", zType);
941 @ zName = "%h(zName)"<br />
942 @ rid = %d(rid)<br />
943
+10 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
2828
2929
SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_USE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
3030
3131
SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
3232
33
-SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
33
+SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3434
35
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
35
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3636
3737
3838
RC=$(DMDIR)\bin\rcc
3939
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
4040
@@ -49,11 +49,11 @@
4949
5050
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5151
$(RC) $(RCFLAGS) -o$@ $**
5252
5353
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54
- +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode event export file finfo foci fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
54
+ +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5555
+echo fossil >> $@
5656
+echo fossil >> $@
5757
+echo $(LIBS) >> $@
5858
+echo. >> $@
5959
+echo fossil >> $@
@@ -308,10 +308,16 @@
308308
$(OBJDIR)\encode$O : encode_.c encode.h
309309
$(TCC) -o$@ -c encode_.c
310310
311311
encode_.c : $(SRCDIR)\encode.c
312312
+translate$E $** > $@
313
+
314
+$(OBJDIR)\etag$O : etag_.c etag.h
315
+ $(TCC) -o$@ -c etag_.c
316
+
317
+etag_.c : $(SRCDIR)\etag.c
318
+ +translate$E $** > $@
313319
314320
$(OBJDIR)\event$O : event_.c event.h
315321
$(TCC) -o$@ -c event_.c
316322
317323
event_.c : $(SRCDIR)\event.c
@@ -892,7 +898,7 @@
892898
893899
zip_.c : $(SRCDIR)\zip.c
894900
+translate$E $** > $@
895901
896902
headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
897
- +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
903
+ +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
898904
@copy /Y nul: headers
899905
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_USE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode event export file finfo foci fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -308,10 +308,16 @@
308 $(OBJDIR)\encode$O : encode_.c encode.h
309 $(TCC) -o$@ -c encode_.c
310
311 encode_.c : $(SRCDIR)\encode.c
312 +translate$E $** > $@
 
 
 
 
 
 
313
314 $(OBJDIR)\event$O : event_.c event.h
315 $(TCC) -o$@ -c event_.c
316
317 event_.c : $(SRCDIR)\event.c
@@ -892,7 +898,7 @@
892
893 zip_.c : $(SRCDIR)\zip.c
894 +translate$E $** > $@
895
896 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
897 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
898 @copy /Y nul: headers
899
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_USE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
30
31 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -308,10 +308,16 @@
308 $(OBJDIR)\encode$O : encode_.c encode.h
309 $(TCC) -o$@ -c encode_.c
310
311 encode_.c : $(SRCDIR)\encode.c
312 +translate$E $** > $@
313
314 $(OBJDIR)\etag$O : etag_.c etag.h
315 $(TCC) -o$@ -c etag_.c
316
317 etag_.c : $(SRCDIR)\etag.c
318 +translate$E $** > $@
319
320 $(OBJDIR)\event$O : event_.c event.h
321 $(TCC) -o$@ -c event_.c
322
323 event_.c : $(SRCDIR)\event.c
@@ -892,7 +898,7 @@
898
899 zip_.c : $(SRCDIR)\zip.c
900 +translate$E $** > $@
901
902 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
903 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
904 @copy /Y nul: headers
905
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -452,10 +452,11 @@
452452
$(SRCDIR)/diff.c \
453453
$(SRCDIR)/diffcmd.c \
454454
$(SRCDIR)/dispatch.c \
455455
$(SRCDIR)/doc.c \
456456
$(SRCDIR)/encode.c \
457
+ $(SRCDIR)/etag.c \
457458
$(SRCDIR)/event.c \
458459
$(SRCDIR)/export.c \
459460
$(SRCDIR)/file.c \
460461
$(SRCDIR)/finfo.c \
461462
$(SRCDIR)/foci.c \
@@ -652,10 +653,11 @@
652653
$(OBJDIR)/diff_.c \
653654
$(OBJDIR)/diffcmd_.c \
654655
$(OBJDIR)/dispatch_.c \
655656
$(OBJDIR)/doc_.c \
656657
$(OBJDIR)/encode_.c \
658
+ $(OBJDIR)/etag_.c \
657659
$(OBJDIR)/event_.c \
658660
$(OBJDIR)/export_.c \
659661
$(OBJDIR)/file_.c \
660662
$(OBJDIR)/finfo_.c \
661663
$(OBJDIR)/foci_.c \
@@ -781,10 +783,11 @@
781783
$(OBJDIR)/diff.o \
782784
$(OBJDIR)/diffcmd.o \
783785
$(OBJDIR)/dispatch.o \
784786
$(OBJDIR)/doc.o \
785787
$(OBJDIR)/encode.o \
788
+ $(OBJDIR)/etag.o \
786789
$(OBJDIR)/event.o \
787790
$(OBJDIR)/export.o \
788791
$(OBJDIR)/file.o \
789792
$(OBJDIR)/finfo.o \
790793
$(OBJDIR)/foci.o \
@@ -1129,10 +1132,11 @@
11291132
$(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
11301133
$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
11311134
$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
11321135
$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
11331136
$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
1137
+ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
11341138
$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
11351139
$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
11361140
$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
11371141
$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
11381142
$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1474,10 +1478,18 @@
14741478
14751479
$(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
14761480
$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
14771481
14781482
$(OBJDIR)/encode.h: $(OBJDIR)/headers
1483
+
1484
+$(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(TRANSLATE)
1485
+ $(TRANSLATE) $(SRCDIR)/etag.c >$@
1486
+
1487
+$(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1488
+ $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1489
+
1490
+$(OBJDIR)/etag.h: $(OBJDIR)/headers
14791491
14801492
$(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
14811493
$(TRANSLATE) $(SRCDIR)/event.c >$@
14821494
14831495
$(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
14841496
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -452,10 +452,11 @@
452 $(SRCDIR)/diff.c \
453 $(SRCDIR)/diffcmd.c \
454 $(SRCDIR)/dispatch.c \
455 $(SRCDIR)/doc.c \
456 $(SRCDIR)/encode.c \
 
457 $(SRCDIR)/event.c \
458 $(SRCDIR)/export.c \
459 $(SRCDIR)/file.c \
460 $(SRCDIR)/finfo.c \
461 $(SRCDIR)/foci.c \
@@ -652,10 +653,11 @@
652 $(OBJDIR)/diff_.c \
653 $(OBJDIR)/diffcmd_.c \
654 $(OBJDIR)/dispatch_.c \
655 $(OBJDIR)/doc_.c \
656 $(OBJDIR)/encode_.c \
 
657 $(OBJDIR)/event_.c \
658 $(OBJDIR)/export_.c \
659 $(OBJDIR)/file_.c \
660 $(OBJDIR)/finfo_.c \
661 $(OBJDIR)/foci_.c \
@@ -781,10 +783,11 @@
781 $(OBJDIR)/diff.o \
782 $(OBJDIR)/diffcmd.o \
783 $(OBJDIR)/dispatch.o \
784 $(OBJDIR)/doc.o \
785 $(OBJDIR)/encode.o \
 
786 $(OBJDIR)/event.o \
787 $(OBJDIR)/export.o \
788 $(OBJDIR)/file.o \
789 $(OBJDIR)/finfo.o \
790 $(OBJDIR)/foci.o \
@@ -1129,10 +1132,11 @@
1129 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
1130 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
1131 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
1132 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
1133 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
 
1134 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
1135 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
1136 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
1137 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
1138 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1474,10 +1478,18 @@
1474
1475 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1476 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1477
1478 $(OBJDIR)/encode.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1479
1480 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
1481 $(TRANSLATE) $(SRCDIR)/event.c >$@
1482
1483 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
1484
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -452,10 +452,11 @@
452 $(SRCDIR)/diff.c \
453 $(SRCDIR)/diffcmd.c \
454 $(SRCDIR)/dispatch.c \
455 $(SRCDIR)/doc.c \
456 $(SRCDIR)/encode.c \
457 $(SRCDIR)/etag.c \
458 $(SRCDIR)/event.c \
459 $(SRCDIR)/export.c \
460 $(SRCDIR)/file.c \
461 $(SRCDIR)/finfo.c \
462 $(SRCDIR)/foci.c \
@@ -652,10 +653,11 @@
653 $(OBJDIR)/diff_.c \
654 $(OBJDIR)/diffcmd_.c \
655 $(OBJDIR)/dispatch_.c \
656 $(OBJDIR)/doc_.c \
657 $(OBJDIR)/encode_.c \
658 $(OBJDIR)/etag_.c \
659 $(OBJDIR)/event_.c \
660 $(OBJDIR)/export_.c \
661 $(OBJDIR)/file_.c \
662 $(OBJDIR)/finfo_.c \
663 $(OBJDIR)/foci_.c \
@@ -781,10 +783,11 @@
783 $(OBJDIR)/diff.o \
784 $(OBJDIR)/diffcmd.o \
785 $(OBJDIR)/dispatch.o \
786 $(OBJDIR)/doc.o \
787 $(OBJDIR)/encode.o \
788 $(OBJDIR)/etag.o \
789 $(OBJDIR)/event.o \
790 $(OBJDIR)/export.o \
791 $(OBJDIR)/file.o \
792 $(OBJDIR)/finfo.o \
793 $(OBJDIR)/foci.o \
@@ -1129,10 +1132,11 @@
1132 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
1133 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
1134 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
1135 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
1136 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
1137 $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
1138 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
1139 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
1140 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
1141 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
1142 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1474,10 +1478,18 @@
1478
1479 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1480 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1481
1482 $(OBJDIR)/encode.h: $(OBJDIR)/headers
1483
1484 $(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(TRANSLATE)
1485 $(TRANSLATE) $(SRCDIR)/etag.c >$@
1486
1487 $(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1488 $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1489
1490 $(OBJDIR)/etag.h: $(OBJDIR)/headers
1491
1492 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
1493 $(TRANSLATE) $(SRCDIR)/event.c >$@
1494
1495 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
1496
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -452,10 +452,11 @@
452452
$(SRCDIR)/diff.c \
453453
$(SRCDIR)/diffcmd.c \
454454
$(SRCDIR)/dispatch.c \
455455
$(SRCDIR)/doc.c \
456456
$(SRCDIR)/encode.c \
457
+ $(SRCDIR)/etag.c \
457458
$(SRCDIR)/event.c \
458459
$(SRCDIR)/export.c \
459460
$(SRCDIR)/file.c \
460461
$(SRCDIR)/finfo.c \
461462
$(SRCDIR)/foci.c \
@@ -552,10 +553,14 @@
552553
$(SRCDIR)/xfersetup.c \
553554
$(SRCDIR)/zip.c
554555
555556
EXTRA_FILES = \
556557
$(SRCDIR)/../skins/aht/details.txt \
558
+ $(SRCDIR)/../skins/ardoise/css.txt \
559
+ $(SRCDIR)/../skins/ardoise/details.txt \
560
+ $(SRCDIR)/../skins/ardoise/footer.txt \
561
+ $(SRCDIR)/../skins/ardoise/header.txt \
557562
$(SRCDIR)/../skins/black_and_white/css.txt \
558563
$(SRCDIR)/../skins/black_and_white/details.txt \
559564
$(SRCDIR)/../skins/black_and_white/footer.txt \
560565
$(SRCDIR)/../skins/black_and_white/header.txt \
561566
$(SRCDIR)/../skins/blitz/css.txt \
@@ -648,10 +653,11 @@
648653
$(OBJDIR)/diff_.c \
649654
$(OBJDIR)/diffcmd_.c \
650655
$(OBJDIR)/dispatch_.c \
651656
$(OBJDIR)/doc_.c \
652657
$(OBJDIR)/encode_.c \
658
+ $(OBJDIR)/etag_.c \
653659
$(OBJDIR)/event_.c \
654660
$(OBJDIR)/export_.c \
655661
$(OBJDIR)/file_.c \
656662
$(OBJDIR)/finfo_.c \
657663
$(OBJDIR)/foci_.c \
@@ -777,10 +783,11 @@
777783
$(OBJDIR)/diff.o \
778784
$(OBJDIR)/diffcmd.o \
779785
$(OBJDIR)/dispatch.o \
780786
$(OBJDIR)/doc.o \
781787
$(OBJDIR)/encode.o \
788
+ $(OBJDIR)/etag.o \
782789
$(OBJDIR)/event.o \
783790
$(OBJDIR)/export.o \
784791
$(OBJDIR)/file.o \
785792
$(OBJDIR)/finfo.o \
786793
$(OBJDIR)/foci.o \
@@ -1125,10 +1132,11 @@
11251132
$(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
11261133
$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
11271134
$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
11281135
$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
11291136
$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
1137
+ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
11301138
$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
11311139
$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
11321140
$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
11331141
$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
11341142
$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1470,10 +1478,18 @@
14701478
14711479
$(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
14721480
$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
14731481
14741482
$(OBJDIR)/encode.h: $(OBJDIR)/headers
1483
+
1484
+$(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(TRANSLATE)
1485
+ $(TRANSLATE) $(SRCDIR)/etag.c >$@
1486
+
1487
+$(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1488
+ $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1489
+
1490
+$(OBJDIR)/etag.h: $(OBJDIR)/headers
14751491
14761492
$(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
14771493
$(TRANSLATE) $(SRCDIR)/event.c >$@
14781494
14791495
$(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
@@ -2271,10 +2287,13 @@
22712287
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
22722288
-DSQLITE_ENABLE_DBSTAT_VTAB \
22732289
-DSQLITE_ENABLE_JSON1 \
22742290
-DSQLITE_ENABLE_FTS5 \
22752291
-DSQLITE_ENABLE_STMTVTAB \
2292
+ -DSQLITE_USE_ZLIB \
2293
+ -DSQLITE_INTROSPECTION_PRAGMAS \
2294
+ -DSQLITE_ENABLE_DBPAGE_VTAB \
22762295
-DSQLITE_WIN32_NO_ANSI \
22772296
$(MINGW_OPTIONS) \
22782297
-DSQLITE_USE_MALLOC_H \
22792298
-DSQLITE_USE_MSIZE
22802299
22812300
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -452,10 +452,11 @@
452 $(SRCDIR)/diff.c \
453 $(SRCDIR)/diffcmd.c \
454 $(SRCDIR)/dispatch.c \
455 $(SRCDIR)/doc.c \
456 $(SRCDIR)/encode.c \
 
457 $(SRCDIR)/event.c \
458 $(SRCDIR)/export.c \
459 $(SRCDIR)/file.c \
460 $(SRCDIR)/finfo.c \
461 $(SRCDIR)/foci.c \
@@ -552,10 +553,14 @@
552 $(SRCDIR)/xfersetup.c \
553 $(SRCDIR)/zip.c
554
555 EXTRA_FILES = \
556 $(SRCDIR)/../skins/aht/details.txt \
 
 
 
 
557 $(SRCDIR)/../skins/black_and_white/css.txt \
558 $(SRCDIR)/../skins/black_and_white/details.txt \
559 $(SRCDIR)/../skins/black_and_white/footer.txt \
560 $(SRCDIR)/../skins/black_and_white/header.txt \
561 $(SRCDIR)/../skins/blitz/css.txt \
@@ -648,10 +653,11 @@
648 $(OBJDIR)/diff_.c \
649 $(OBJDIR)/diffcmd_.c \
650 $(OBJDIR)/dispatch_.c \
651 $(OBJDIR)/doc_.c \
652 $(OBJDIR)/encode_.c \
 
653 $(OBJDIR)/event_.c \
654 $(OBJDIR)/export_.c \
655 $(OBJDIR)/file_.c \
656 $(OBJDIR)/finfo_.c \
657 $(OBJDIR)/foci_.c \
@@ -777,10 +783,11 @@
777 $(OBJDIR)/diff.o \
778 $(OBJDIR)/diffcmd.o \
779 $(OBJDIR)/dispatch.o \
780 $(OBJDIR)/doc.o \
781 $(OBJDIR)/encode.o \
 
782 $(OBJDIR)/event.o \
783 $(OBJDIR)/export.o \
784 $(OBJDIR)/file.o \
785 $(OBJDIR)/finfo.o \
786 $(OBJDIR)/foci.o \
@@ -1125,10 +1132,11 @@
1125 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
1126 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
1127 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
1128 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
1129 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
 
1130 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
1131 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
1132 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
1133 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
1134 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1470,10 +1478,18 @@
1470
1471 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1472 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1473
1474 $(OBJDIR)/encode.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1475
1476 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
1477 $(TRANSLATE) $(SRCDIR)/event.c >$@
1478
1479 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
@@ -2271,10 +2287,13 @@
2271 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2272 -DSQLITE_ENABLE_DBSTAT_VTAB \
2273 -DSQLITE_ENABLE_JSON1 \
2274 -DSQLITE_ENABLE_FTS5 \
2275 -DSQLITE_ENABLE_STMTVTAB \
 
 
 
2276 -DSQLITE_WIN32_NO_ANSI \
2277 $(MINGW_OPTIONS) \
2278 -DSQLITE_USE_MALLOC_H \
2279 -DSQLITE_USE_MSIZE
2280
2281
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -452,10 +452,11 @@
452 $(SRCDIR)/diff.c \
453 $(SRCDIR)/diffcmd.c \
454 $(SRCDIR)/dispatch.c \
455 $(SRCDIR)/doc.c \
456 $(SRCDIR)/encode.c \
457 $(SRCDIR)/etag.c \
458 $(SRCDIR)/event.c \
459 $(SRCDIR)/export.c \
460 $(SRCDIR)/file.c \
461 $(SRCDIR)/finfo.c \
462 $(SRCDIR)/foci.c \
@@ -552,10 +553,14 @@
553 $(SRCDIR)/xfersetup.c \
554 $(SRCDIR)/zip.c
555
556 EXTRA_FILES = \
557 $(SRCDIR)/../skins/aht/details.txt \
558 $(SRCDIR)/../skins/ardoise/css.txt \
559 $(SRCDIR)/../skins/ardoise/details.txt \
560 $(SRCDIR)/../skins/ardoise/footer.txt \
561 $(SRCDIR)/../skins/ardoise/header.txt \
562 $(SRCDIR)/../skins/black_and_white/css.txt \
563 $(SRCDIR)/../skins/black_and_white/details.txt \
564 $(SRCDIR)/../skins/black_and_white/footer.txt \
565 $(SRCDIR)/../skins/black_and_white/header.txt \
566 $(SRCDIR)/../skins/blitz/css.txt \
@@ -648,10 +653,11 @@
653 $(OBJDIR)/diff_.c \
654 $(OBJDIR)/diffcmd_.c \
655 $(OBJDIR)/dispatch_.c \
656 $(OBJDIR)/doc_.c \
657 $(OBJDIR)/encode_.c \
658 $(OBJDIR)/etag_.c \
659 $(OBJDIR)/event_.c \
660 $(OBJDIR)/export_.c \
661 $(OBJDIR)/file_.c \
662 $(OBJDIR)/finfo_.c \
663 $(OBJDIR)/foci_.c \
@@ -777,10 +783,11 @@
783 $(OBJDIR)/diff.o \
784 $(OBJDIR)/diffcmd.o \
785 $(OBJDIR)/dispatch.o \
786 $(OBJDIR)/doc.o \
787 $(OBJDIR)/encode.o \
788 $(OBJDIR)/etag.o \
789 $(OBJDIR)/event.o \
790 $(OBJDIR)/export.o \
791 $(OBJDIR)/file.o \
792 $(OBJDIR)/finfo.o \
793 $(OBJDIR)/foci.o \
@@ -1125,10 +1132,11 @@
1132 $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \
1133 $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
1134 $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
1135 $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
1136 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
1137 $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
1138 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
1139 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
1140 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
1141 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
1142 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
@@ -1470,10 +1478,18 @@
1478
1479 $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h
1480 $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c
1481
1482 $(OBJDIR)/encode.h: $(OBJDIR)/headers
1483
1484 $(OBJDIR)/etag_.c: $(SRCDIR)/etag.c $(TRANSLATE)
1485 $(TRANSLATE) $(SRCDIR)/etag.c >$@
1486
1487 $(OBJDIR)/etag.o: $(OBJDIR)/etag_.c $(OBJDIR)/etag.h $(SRCDIR)/config.h
1488 $(XTCC) -o $(OBJDIR)/etag.o -c $(OBJDIR)/etag_.c
1489
1490 $(OBJDIR)/etag.h: $(OBJDIR)/headers
1491
1492 $(OBJDIR)/event_.c: $(SRCDIR)/event.c $(TRANSLATE)
1493 $(TRANSLATE) $(SRCDIR)/event.c >$@
1494
1495 $(OBJDIR)/event.o: $(OBJDIR)/event_.c $(OBJDIR)/event.h $(SRCDIR)/config.h
@@ -2271,10 +2287,13 @@
2287 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2288 -DSQLITE_ENABLE_DBSTAT_VTAB \
2289 -DSQLITE_ENABLE_JSON1 \
2290 -DSQLITE_ENABLE_FTS5 \
2291 -DSQLITE_ENABLE_STMTVTAB \
2292 -DSQLITE_USE_ZLIB \
2293 -DSQLITE_INTROSPECTION_PRAGMAS \
2294 -DSQLITE_ENABLE_DBPAGE_VTAB \
2295 -DSQLITE_WIN32_NO_ANSI \
2296 $(MINGW_OPTIONS) \
2297 -DSQLITE_USE_MALLOC_H \
2298 -DSQLITE_USE_MSIZE
2299
2300
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -382,10 +382,11 @@
382382
diff_.c \
383383
diffcmd_.c \
384384
dispatch_.c \
385385
doc_.c \
386386
encode_.c \
387
+ etag_.c \
387388
event_.c \
388389
export_.c \
389390
file_.c \
390391
finfo_.c \
391392
foci_.c \
@@ -581,10 +582,11 @@
581582
$(OX)\diff$O \
582583
$(OX)\diffcmd$O \
583584
$(OX)\dispatch$O \
584585
$(OX)\doc$O \
585586
$(OX)\encode$O \
587
+ $(OX)\etag$O \
586588
$(OX)\event$O \
587589
$(OX)\export$O \
588590
$(OX)\file$O \
589591
$(OX)\finfo$O \
590592
$(OX)\foci$O \
@@ -769,10 +771,11 @@
769771
echo $(OX)\diff.obj >> $@
770772
echo $(OX)\diffcmd.obj >> $@
771773
echo $(OX)\dispatch.obj >> $@
772774
echo $(OX)\doc.obj >> $@
773775
echo $(OX)\encode.obj >> $@
776
+ echo $(OX)\etag.obj >> $@
774777
echo $(OX)\event.obj >> $@
775778
echo $(OX)\export.obj >> $@
776779
echo $(OX)\file.obj >> $@
777780
echo $(OX)\finfo.obj >> $@
778781
echo $(OX)\foci.obj >> $@
@@ -1168,10 +1171,16 @@
11681171
$(OX)\encode$O : encode_.c encode.h
11691172
$(TCC) /Fo$@ -c encode_.c
11701173
11711174
encode_.c : $(SRCDIR)\encode.c
11721175
translate$E $** > $@
1176
+
1177
+$(OX)\etag$O : etag_.c etag.h
1178
+ $(TCC) /Fo$@ -c etag_.c
1179
+
1180
+etag_.c : $(SRCDIR)\etag.c
1181
+ translate$E $** > $@
11731182
11741183
$(OX)\event$O : event_.c event.h
11751184
$(TCC) /Fo$@ -c event_.c
11761185
11771186
event_.c : $(SRCDIR)\event.c
@@ -1785,10 +1794,11 @@
17851794
diff_.c:diff.h \
17861795
diffcmd_.c:diffcmd.h \
17871796
dispatch_.c:dispatch.h \
17881797
doc_.c:doc.h \
17891798
encode_.c:encode.h \
1799
+ etag_.c:etag.h \
17901800
event_.c:event.h \
17911801
export_.c:export.h \
17921802
file_.c:file.h \
17931803
finfo_.c:finfo.h \
17941804
foci_.c:foci.h \
17951805
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -382,10 +382,11 @@
382 diff_.c \
383 diffcmd_.c \
384 dispatch_.c \
385 doc_.c \
386 encode_.c \
 
387 event_.c \
388 export_.c \
389 file_.c \
390 finfo_.c \
391 foci_.c \
@@ -581,10 +582,11 @@
581 $(OX)\diff$O \
582 $(OX)\diffcmd$O \
583 $(OX)\dispatch$O \
584 $(OX)\doc$O \
585 $(OX)\encode$O \
 
586 $(OX)\event$O \
587 $(OX)\export$O \
588 $(OX)\file$O \
589 $(OX)\finfo$O \
590 $(OX)\foci$O \
@@ -769,10 +771,11 @@
769 echo $(OX)\diff.obj >> $@
770 echo $(OX)\diffcmd.obj >> $@
771 echo $(OX)\dispatch.obj >> $@
772 echo $(OX)\doc.obj >> $@
773 echo $(OX)\encode.obj >> $@
 
774 echo $(OX)\event.obj >> $@
775 echo $(OX)\export.obj >> $@
776 echo $(OX)\file.obj >> $@
777 echo $(OX)\finfo.obj >> $@
778 echo $(OX)\foci.obj >> $@
@@ -1168,10 +1171,16 @@
1168 $(OX)\encode$O : encode_.c encode.h
1169 $(TCC) /Fo$@ -c encode_.c
1170
1171 encode_.c : $(SRCDIR)\encode.c
1172 translate$E $** > $@
 
 
 
 
 
 
1173
1174 $(OX)\event$O : event_.c event.h
1175 $(TCC) /Fo$@ -c event_.c
1176
1177 event_.c : $(SRCDIR)\event.c
@@ -1785,10 +1794,11 @@
1785 diff_.c:diff.h \
1786 diffcmd_.c:diffcmd.h \
1787 dispatch_.c:dispatch.h \
1788 doc_.c:doc.h \
1789 encode_.c:encode.h \
 
1790 event_.c:event.h \
1791 export_.c:export.h \
1792 file_.c:file.h \
1793 finfo_.c:finfo.h \
1794 foci_.c:foci.h \
1795
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -382,10 +382,11 @@
382 diff_.c \
383 diffcmd_.c \
384 dispatch_.c \
385 doc_.c \
386 encode_.c \
387 etag_.c \
388 event_.c \
389 export_.c \
390 file_.c \
391 finfo_.c \
392 foci_.c \
@@ -581,10 +582,11 @@
582 $(OX)\diff$O \
583 $(OX)\diffcmd$O \
584 $(OX)\dispatch$O \
585 $(OX)\doc$O \
586 $(OX)\encode$O \
587 $(OX)\etag$O \
588 $(OX)\event$O \
589 $(OX)\export$O \
590 $(OX)\file$O \
591 $(OX)\finfo$O \
592 $(OX)\foci$O \
@@ -769,10 +771,11 @@
771 echo $(OX)\diff.obj >> $@
772 echo $(OX)\diffcmd.obj >> $@
773 echo $(OX)\dispatch.obj >> $@
774 echo $(OX)\doc.obj >> $@
775 echo $(OX)\encode.obj >> $@
776 echo $(OX)\etag.obj >> $@
777 echo $(OX)\event.obj >> $@
778 echo $(OX)\export.obj >> $@
779 echo $(OX)\file.obj >> $@
780 echo $(OX)\finfo.obj >> $@
781 echo $(OX)\foci.obj >> $@
@@ -1168,10 +1171,16 @@
1171 $(OX)\encode$O : encode_.c encode.h
1172 $(TCC) /Fo$@ -c encode_.c
1173
1174 encode_.c : $(SRCDIR)\encode.c
1175 translate$E $** > $@
1176
1177 $(OX)\etag$O : etag_.c etag.h
1178 $(TCC) /Fo$@ -c etag_.c
1179
1180 etag_.c : $(SRCDIR)\etag.c
1181 translate$E $** > $@
1182
1183 $(OX)\event$O : event_.c event.h
1184 $(TCC) /Fo$@ -c event_.c
1185
1186 event_.c : $(SRCDIR)\event.c
@@ -1785,10 +1794,11 @@
1794 diff_.c:diff.h \
1795 diffcmd_.c:diffcmd.h \
1796 dispatch_.c:dispatch.h \
1797 doc_.c:doc.h \
1798 encode_.c:encode.h \
1799 etag_.c:etag.h \
1800 event_.c:event.h \
1801 export_.c:export.h \
1802 file_.c:file.h \
1803 finfo_.c:finfo.h \
1804 foci_.c:foci.h \
1805
+28 -3
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,17 +1,42 @@
11
<title>Change Log</title>
22
33
<a name='v2_5'></a>
4
-<h2>Changes for Version 2.5 (pending)</h2>
4
+<h2>Changes for Version 2.5 (2018-02-07)</h2>
55
6
- * Numerous enhancements to the look and feel of the web interface
6
+ * Numerous enhancements to the look and feel of the web interface.
7
+ Especially: Added separate "Modern", "Compact", "Verbose", and
8
+ "Columnar" view options on timelines.
9
+ * Common display settings (such as the "view" option and the number
10
+ of rows in a timeline) are held in a cookie and thus persist
11
+ across multiple pages.
12
+ * Rework the skin editing process so that changes are implemented
13
+ on one of nine /draft pages, evaluated, then merged back to the
14
+ default.
15
+ * Added the [https://fossil-scm.org/skins/ardoise/timeline|Ardoise]
16
+ skin.
17
+ * Fix the "fossil server" command on Unix to be much more responsive
18
+ to multiple simultaneous web requests.
19
+ * Use the IPv6 stack for the "fossil ui" and "fossil server"
20
+ commands on Windows.
21
+ * Support for [https://sqlite.org/sqlar|SQL Archives] as a download
22
+ option.
723
* Fossil now automatically generates the
824
&lt;html&gt;&lt;head&gt;...&lt;/head&gt;&lt;body&gt;
925
at the beginning of each web page if the configurable header
1026
lacks a &lt;body&gt; tag.
27
+ * Added the /artifact_stats page, currently accessible only by
28
+ the administrator.
1129
* Upgrade to the latest versions of SQLite and OpenSSL.
12
- * Improved key bindings on the Tk diff screen generated by "fossil diff --tk".
30
+ * Improved key bindings on the Tk diff screen generated by
31
+ "fossil diff --tk".
32
+ * Begin factoring out in-line javascript into separately loaded
33
+ script files. This is a step along the
34
+ road toward supporting a strict Content Security Policy. More work
35
+ is to be done.
36
+ * Initial infrastructure is in place to make use of the pledge()
37
+ system call in OpenBSD. More work is to be done.
1338
1439
<a name='v2_4'></a>
1540
<h2>Changes for Version 2.4 (2017-11-03)</h2>
1641
1742
* New feature: URL Aliases. URL Aliases allow an administrator
1843
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,17 +1,42 @@
1 <title>Change Log</title>
2
3 <a name='v2_5'></a>
4 <h2>Changes for Version 2.5 (pending)</h2>
5
6 * Numerous enhancements to the look and feel of the web interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7 * Fossil now automatically generates the
8 &lt;html&gt;&lt;head&gt;...&lt;/head&gt;&lt;body&gt;
9 at the beginning of each web page if the configurable header
10 lacks a &lt;body&gt; tag.
 
 
11 * Upgrade to the latest versions of SQLite and OpenSSL.
12 * Improved key bindings on the Tk diff screen generated by "fossil diff --tk".
 
 
 
 
 
 
 
13
14 <a name='v2_4'></a>
15 <h2>Changes for Version 2.4 (2017-11-03)</h2>
16
17 * New feature: URL Aliases. URL Aliases allow an administrator
18
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,17 +1,42 @@
1 <title>Change Log</title>
2
3 <a name='v2_5'></a>
4 <h2>Changes for Version 2.5 (2018-02-07)</h2>
5
6 * Numerous enhancements to the look and feel of the web interface.
7 Especially: Added separate "Modern", "Compact", "Verbose", and
8 "Columnar" view options on timelines.
9 * Common display settings (such as the "view" option and the number
10 of rows in a timeline) are held in a cookie and thus persist
11 across multiple pages.
12 * Rework the skin editing process so that changes are implemented
13 on one of nine /draft pages, evaluated, then merged back to the
14 default.
15 * Added the [https://fossil-scm.org/skins/ardoise/timeline|Ardoise]
16 skin.
17 * Fix the "fossil server" command on Unix to be much more responsive
18 to multiple simultaneous web requests.
19 * Use the IPv6 stack for the "fossil ui" and "fossil server"
20 commands on Windows.
21 * Support for [https://sqlite.org/sqlar|SQL Archives] as a download
22 option.
23 * Fossil now automatically generates the
24 &lt;html&gt;&lt;head&gt;...&lt;/head&gt;&lt;body&gt;
25 at the beginning of each web page if the configurable header
26 lacks a &lt;body&gt; tag.
27 * Added the /artifact_stats page, currently accessible only by
28 the administrator.
29 * Upgrade to the latest versions of SQLite and OpenSSL.
30 * Improved key bindings on the Tk diff screen generated by
31 "fossil diff --tk".
32 * Begin factoring out in-line javascript into separately loaded
33 script files. This is a step along the
34 road toward supporting a strict Content Security Policy. More work
35 is to be done.
36 * Initial infrastructure is in place to make use of the pledge()
37 system call in OpenBSD. More work is to be done.
38
39 <a name='v2_4'></a>
40 <h2>Changes for Version 2.4 (2017-11-03)</h2>
41
42 * New feature: URL Aliases. URL Aliases allow an administrator
43
--- www/env-opts.md
+++ www/env-opts.md
@@ -73,13 +73,10 @@
7373
local time.
7474
7575
`--nocgi`: Prevent fossil from acting as a CGI by default even if the
7676
`GATEWAY_INTERFACE` environment variable is set.
7777
78
-`--no-dir-symlinks`: Disables support for directory symlinks, thus
79
-preventing them from being traversed into.
80
-
8178
`--no-th-hook`: (Sets `g.fNoThHook`.) Override the `th1-hooks` setting
8279
and prevent any TH1 hooks from being executed.
8380
8481
`--quiet`: (Sets `g.fQuiet`.) Cause fossil to suppress various messages and progress
8582
indicators that would otherwise be printed.
8683
--- www/env-opts.md
+++ www/env-opts.md
@@ -73,13 +73,10 @@
73 local time.
74
75 `--nocgi`: Prevent fossil from acting as a CGI by default even if the
76 `GATEWAY_INTERFACE` environment variable is set.
77
78 `--no-dir-symlinks`: Disables support for directory symlinks, thus
79 preventing them from being traversed into.
80
81 `--no-th-hook`: (Sets `g.fNoThHook`.) Override the `th1-hooks` setting
82 and prevent any TH1 hooks from being executed.
83
84 `--quiet`: (Sets `g.fQuiet`.) Cause fossil to suppress various messages and progress
85 indicators that would otherwise be printed.
86
--- www/env-opts.md
+++ www/env-opts.md
@@ -73,13 +73,10 @@
73 local time.
74
75 `--nocgi`: Prevent fossil from acting as a CGI by default even if the
76 `GATEWAY_INTERFACE` environment variable is set.
77
 
 
 
78 `--no-th-hook`: (Sets `g.fNoThHook`.) Override the `th1-hooks` setting
79 and prevent any TH1 hooks from being executed.
80
81 `--quiet`: (Sets `g.fQuiet`.) Cause fossil to suppress various messages and progress
82 indicators that would otherwise be printed.
83
+1 -1
--- www/index.wiki
+++ www/index.wiki
@@ -48,11 +48,11 @@
4848
4949
3. <b>Self-Contained</b> -
5050
Fossil is a single self-contained stand-alone executable.
5151
To install, simply download a
5252
[/uv/download.html | precompiled binary]
53
- for Linux, Mac, OpenBSD, or Windows and put it on your $PATH.
53
+ for Linux, Mac, or Windows and put it on your $PATH.
5454
[./build.wiki | Easy-to-compile source code] is also available.
5555
5656
4. <b>Simple Networking</b> -
5757
No custom protocols or TCP ports.
5858
Fossil uses ordinary HTTP (or HTTPS or SSH)
5959
6060
DELETED www/mkdownload.tcl
--- www/index.wiki
+++ www/index.wiki
@@ -48,11 +48,11 @@
48
49 3. <b>Self-Contained</b> -
50 Fossil is a single self-contained stand-alone executable.
51 To install, simply download a
52 [/uv/download.html | precompiled binary]
53 for Linux, Mac, OpenBSD, or Windows and put it on your $PATH.
54 [./build.wiki | Easy-to-compile source code] is also available.
55
56 4. <b>Simple Networking</b> -
57 No custom protocols or TCP ports.
58 Fossil uses ordinary HTTP (or HTTPS or SSH)
59
60 ELETED www/mkdownload.tcl
--- www/index.wiki
+++ www/index.wiki
@@ -48,11 +48,11 @@
48
49 3. <b>Self-Contained</b> -
50 Fossil is a single self-contained stand-alone executable.
51 To install, simply download a
52 [/uv/download.html | precompiled binary]
53 for Linux, Mac, or Windows and put it on your $PATH.
54 [./build.wiki | Easy-to-compile source code] is also available.
55
56 4. <b>Simple Networking</b> -
57 No custom protocols or TCP ports.
58 Fossil uses ordinary HTTP (or HTTPS or SSH)
59
60 ELETED www/mkdownload.tcl
D www/mkdownload.tcl
-125
--- a/www/mkdownload.tcl
+++ b/www/mkdownload.tcl
@@ -1,125 +0,0 @@
1
-#!/usr/bin/tclsh
2
-#
3
-# Run this script to build and install the "download.html" page of
4
-# unversioned comment.
5
-#
6
-# Also generate the fossil_download_checksums.html page.
7
-#
8
-#
9
-set out [open download.html w]
10
-fconfigure $out -encoding utf-8 -translation lf
11
-puts $out \
12
-{<div class='fossil-doc' data-title='Download Page'>
13
-
14
-<center><font size=4>}
15
-puts $out \
16
-"<b>To install Fossil &rarr;</b> download the stand-alone executable"
17
-puts $out \
18
-{and put it on your $PATH.
19
-</font><p><small>
20
-RPMs available
21
-<a href="http://download.opensuse.org/repositories/home:/rmax:/fossil/">
22
-here.</a>
23
-Cryptographic checksums for download files are
24
-<a href="http://www.hwaci.com/fossil_download_checksums.html">here</a>.
25
-</small></p>
26
-<table cellpadding="10">
27
-}
28
-
29
-# Find all unique timestamps.
30
-#
31
-set in [open {|fossil uv list} rb]
32
-while {[gets $in line]>0} {
33
- set fn [lindex $line 5]
34
- set filesize($fn) [lindex $line 3]
35
- if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
36
- set filehash($fn) [lindex $line 1]
37
- set avers($version) 1
38
- }
39
-}
40
-close $in
41
-
42
-set vdate(2.0) 2017-03-03
43
-set vdate(1.37) 2017-01-15
44
-
45
-# Do all versions from newest to oldest
46
-#
47
-foreach vers [lsort -decr -real [array names avers]] {
48
- # set hr "../timeline?c=version-$vers;y=ci"
49
- set v2 v[string map {. _} $vers]
50
- set hr "../doc/trunk/www/changes.wiki#$v2"
51
- puts $out "<tr><td colspan=6 align=left><hr>"
52
- puts $out "<center><b><a href=\"$hr\">Version $vers</a>"
53
- if {[info exists vdate($vers)]} {
54
- set hr2 "../timeline?c=version-$vers&amp;y=ci"
55
- puts $out " (<a href='$hr2'>$vdate($vers)</a>)"
56
- }
57
- puts $out "</b></center>"
58
- puts $out "</td></tr>"
59
- puts $out "<tr>"
60
-
61
- foreach {prefix img desc} {
62
- fossil-linux linux.gif {Linux 3.x x64}
63
- fossil-macosx mac.gif {Mac 10.x x86}
64
- fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
65
- fossil-w32 win32.gif {Windows}
66
- fossil-src src.gif {Source Tarball}
67
- } {
68
- set glob download/$prefix*-$vers*
69
- set filename [array names filesize $glob]
70
- if {[info exists filesize($filename)]} {
71
- set size [set filesize($filename)]
72
- set units bytes
73
- if {$size>1024*1024} {
74
- set size [format %.2f [expr {$size/(1024.0*1024.0)}]]
75
- set units MiB
76
- } elseif {$size>1024} {
77
- set size [format %.2f [expr {$size/(1024.0)}]]
78
- set units KiB
79
- }
80
- puts $out "<td align=center valign=bottom><a href=\"$filename\">"
81
- puts $out "<img src=\"build-icons/$img\" border=0><br>$desc</a><br>"
82
- puts $out "$size $units</td>"
83
- } else {
84
- puts $out "<td>&nbsp;</td>"
85
- }
86
- }
87
- puts $out "</tr>"
88
-#
89
-# if {[info exists filesize(download/releasenotes-$vers.html)]} {
90
-# puts $out "<tr><td colspan=6 align=left>"
91
-# set rn [|open uv cat download/releasenotes-$vers.html]
92
-# fconfigure $rn -encoding utf-8
93
-# puts $out "[read $rn]"
94
-# close $rn
95
-# puts $out "</td></tr>"
96
-# }
97
-}
98
-puts $out "<tr><td colspan=5><hr></td></tr>"
99
-
100
-puts $out {</table></center></div>}
101
-close $out
102
-
103
-# Generate the checksum page
104
-#
105
-set out [open fossil_download_checksums.html w]
106
-fconfigure $out -encoding utf-8 -translation lf
107
-puts $out {<html>
108
-<title>Fossil Download Checksums</title>
109
-<body>
110
-<h1 align="center">Checksums For Fossil Downloads</h1>
111
-<p>The following table shows the SHA1 checksums for the precompiled
112
-binaries available on the
113
-<a href="/uv/download.html">Fossil website</a>.</p>
114
-<pre>}
115
-
116
-foreach {line} [split [exec fossil sql "SELECT hash, name FROM unversioned\
117
- WHERE name GLOB '*.tar.gz' OR\
118
- name GLOB '*.zip'"] \n] {
119
- set x [split $line |]
120
- set hash [lindex $x 0]
121
- set nm [file tail [lindex $x 1]]
122
- puts $out "$hash $nm"
123
-}
124
-puts $out {</pre></body></html>}
125
-close $out
--- a/www/mkdownload.tcl
+++ b/www/mkdownload.tcl
@@ -1,125 +0,0 @@
1 #!/usr/bin/tclsh
2 #
3 # Run this script to build and install the "download.html" page of
4 # unversioned comment.
5 #
6 # Also generate the fossil_download_checksums.html page.
7 #
8 #
9 set out [open download.html w]
10 fconfigure $out -encoding utf-8 -translation lf
11 puts $out \
12 {<div class='fossil-doc' data-title='Download Page'>
13
14 <center><font size=4>}
15 puts $out \
16 "<b>To install Fossil &rarr;</b> download the stand-alone executable"
17 puts $out \
18 {and put it on your $PATH.
19 </font><p><small>
20 RPMs available
21 <a href="http://download.opensuse.org/repositories/home:/rmax:/fossil/">
22 here.</a>
23 Cryptographic checksums for download files are
24 <a href="http://www.hwaci.com/fossil_download_checksums.html">here</a>.
25 </small></p>
26 <table cellpadding="10">
27 }
28
29 # Find all unique timestamps.
30 #
31 set in [open {|fossil uv list} rb]
32 while {[gets $in line]>0} {
33 set fn [lindex $line 5]
34 set filesize($fn) [lindex $line 3]
35 if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
36 set filehash($fn) [lindex $line 1]
37 set avers($version) 1
38 }
39 }
40 close $in
41
42 set vdate(2.0) 2017-03-03
43 set vdate(1.37) 2017-01-15
44
45 # Do all versions from newest to oldest
46 #
47 foreach vers [lsort -decr -real [array names avers]] {
48 # set hr "../timeline?c=version-$vers;y=ci"
49 set v2 v[string map {. _} $vers]
50 set hr "../doc/trunk/www/changes.wiki#$v2"
51 puts $out "<tr><td colspan=6 align=left><hr>"
52 puts $out "<center><b><a href=\"$hr\">Version $vers</a>"
53 if {[info exists vdate($vers)]} {
54 set hr2 "../timeline?c=version-$vers&amp;y=ci"
55 puts $out " (<a href='$hr2'>$vdate($vers)</a>)"
56 }
57 puts $out "</b></center>"
58 puts $out "</td></tr>"
59 puts $out "<tr>"
60
61 foreach {prefix img desc} {
62 fossil-linux linux.gif {Linux 3.x x64}
63 fossil-macosx mac.gif {Mac 10.x x86}
64 fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
65 fossil-w32 win32.gif {Windows}
66 fossil-src src.gif {Source Tarball}
67 } {
68 set glob download/$prefix*-$vers*
69 set filename [array names filesize $glob]
70 if {[info exists filesize($filename)]} {
71 set size [set filesize($filename)]
72 set units bytes
73 if {$size>1024*1024} {
74 set size [format %.2f [expr {$size/(1024.0*1024.0)}]]
75 set units MiB
76 } elseif {$size>1024} {
77 set size [format %.2f [expr {$size/(1024.0)}]]
78 set units KiB
79 }
80 puts $out "<td align=center valign=bottom><a href=\"$filename\">"
81 puts $out "<img src=\"build-icons/$img\" border=0><br>$desc</a><br>"
82 puts $out "$size $units</td>"
83 } else {
84 puts $out "<td>&nbsp;</td>"
85 }
86 }
87 puts $out "</tr>"
88 #
89 # if {[info exists filesize(download/releasenotes-$vers.html)]} {
90 # puts $out "<tr><td colspan=6 align=left>"
91 # set rn [|open uv cat download/releasenotes-$vers.html]
92 # fconfigure $rn -encoding utf-8
93 # puts $out "[read $rn]"
94 # close $rn
95 # puts $out "</td></tr>"
96 # }
97 }
98 puts $out "<tr><td colspan=5><hr></td></tr>"
99
100 puts $out {</table></center></div>}
101 close $out
102
103 # Generate the checksum page
104 #
105 set out [open fossil_download_checksums.html w]
106 fconfigure $out -encoding utf-8 -translation lf
107 puts $out {<html>
108 <title>Fossil Download Checksums</title>
109 <body>
110 <h1 align="center">Checksums For Fossil Downloads</h1>
111 <p>The following table shows the SHA1 checksums for the precompiled
112 binaries available on the
113 <a href="/uv/download.html">Fossil website</a>.</p>
114 <pre>}
115
116 foreach {line} [split [exec fossil sql "SELECT hash, name FROM unversioned\
117 WHERE name GLOB '*.tar.gz' OR\
118 name GLOB '*.zip'"] \n] {
119 set x [split $line |]
120 set hash [lindex $x 0]
121 set nm [file tail [lindex $x 1]]
122 puts $out "$hash $nm"
123 }
124 puts $out {</pre></body></html>}
125 close $out
--- a/www/mkdownload.tcl
+++ b/www/mkdownload.tcl
@@ -1,125 +0,0 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
+1 -1
--- www/server.wiki
+++ www/server.wiki
@@ -317,11 +317,11 @@
317317
<ol>
318318
<li><p>An optional cache is available that remembers the 10 most recently
319319
requested /zip or /tarball pages and returns the precomputed answer
320320
if the same page is requested again.
321321
<li><p>Page requests can be configured to fail with a
322
- [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3 | "503 Server Overload"]
322
+ [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4 | "503 Server Overload"]
323323
HTTP error if an expensive request is received while the host load
324324
average is too high.
325325
</ol>
326326
Both of these load-control mechanisms are turned off by default, but they
327327
are recommended for high-traffic sites.
328328
--- www/server.wiki
+++ www/server.wiki
@@ -317,11 +317,11 @@
317 <ol>
318 <li><p>An optional cache is available that remembers the 10 most recently
319 requested /zip or /tarball pages and returns the precomputed answer
320 if the same page is requested again.
321 <li><p>Page requests can be configured to fail with a
322 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3 | "503 Server Overload"]
323 HTTP error if an expensive request is received while the host load
324 average is too high.
325 </ol>
326 Both of these load-control mechanisms are turned off by default, but they
327 are recommended for high-traffic sites.
328
--- www/server.wiki
+++ www/server.wiki
@@ -317,11 +317,11 @@
317 <ol>
318 <li><p>An optional cache is available that remembers the 10 most recently
319 requested /zip or /tarball pages and returns the precomputed answer
320 if the same page is requested again.
321 <li><p>Page requests can be configured to fail with a
322 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4 | "503 Server Overload"]
323 HTTP error if an expensive request is received while the host load
324 average is too high.
325 </ol>
326 Both of these load-control mechanisms are turned off by default, but they
327 are recommended for high-traffic sites.
328

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button