Fossil SCM

Add the ability to bring up a web server that uses a different skin from the default, and have multiple servers going at the same time, each using a different skin. Currently enabled for unix only.

drh 2015-01-22 15:23 UTC trunk
Commit b36e24110009ef9d80e32591a6cbeef9632ddced
+3 -3
--- src/configure.c
+++ src/configure.c
@@ -83,13 +83,13 @@
8383
*/
8484
static struct {
8585
const char *zName; /* Name of the configuration parameter */
8686
int groupMask; /* Which config groups is it part of */
8787
} aConfig[] = {
88
- { "css", CONFIGSET_CSS },
89
- { "header", CONFIGSET_SKIN },
90
- { "footer", CONFIGSET_SKIN },
88
+ { "css", CONFIGSET_CSS }, /* Keep all CSS and SKIN in */
89
+ { "header", CONFIGSET_SKIN }, /* in sync with db_skin_name() */
90
+ { "footer", CONFIGSET_SKIN }, /* in db.c */
9191
{ "logo-mimetype", CONFIGSET_SKIN },
9292
{ "logo-image", CONFIGSET_SKIN },
9393
{ "background-mimetype", CONFIGSET_SKIN },
9494
{ "background-image", CONFIGSET_SKIN },
9595
{ "index-page", CONFIGSET_SKIN },
9696
--- src/configure.c
+++ src/configure.c
@@ -83,13 +83,13 @@
83 */
84 static struct {
85 const char *zName; /* Name of the configuration parameter */
86 int groupMask; /* Which config groups is it part of */
87 } aConfig[] = {
88 { "css", CONFIGSET_CSS },
89 { "header", CONFIGSET_SKIN },
90 { "footer", CONFIGSET_SKIN },
91 { "logo-mimetype", CONFIGSET_SKIN },
92 { "logo-image", CONFIGSET_SKIN },
93 { "background-mimetype", CONFIGSET_SKIN },
94 { "background-image", CONFIGSET_SKIN },
95 { "index-page", CONFIGSET_SKIN },
96
--- src/configure.c
+++ src/configure.c
@@ -83,13 +83,13 @@
83 */
84 static struct {
85 const char *zName; /* Name of the configuration parameter */
86 int groupMask; /* Which config groups is it part of */
87 } aConfig[] = {
88 { "css", CONFIGSET_CSS }, /* Keep all CSS and SKIN in */
89 { "header", CONFIGSET_SKIN }, /* in sync with db_skin_name() */
90 { "footer", CONFIGSET_SKIN }, /* in db.c */
91 { "logo-mimetype", CONFIGSET_SKIN },
92 { "logo-image", CONFIGSET_SKIN },
93 { "background-mimetype", CONFIGSET_SKIN },
94 { "background-image", CONFIGSET_SKIN },
95 { "index-page", CONFIGSET_SKIN },
96
+63 -6
--- src/db.c
+++ src/db.c
@@ -1963,10 +1963,64 @@
19631963
}
19641964
/* Prefer the versioned setting */
19651965
return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting;
19661966
}
19671967
1968
+
1969
+/*
1970
+** Translate a local CONFIG parameter name based on the g.zSkin setting
1971
+** and return a pointer to the new name.
1972
+**
1973
+** The returned string is only valid until the next call to this routine.
1974
+**
1975
+** If g.zSkin==0 (which is the overwhelmingly common case) then just
1976
+** return zName immediately, without change. But if g.zSkin is set and
1977
+** if zName is one of the CONFIG parameters that affect the screen
1978
+** appearance, then return a copy of zName with "("+g.zSkin+")" appended.
1979
+** Space to hold the copy is managed locally and is freed on the next
1980
+** call to this routine.
1981
+*/
1982
+const char *db_skin_name(const char *zName){
1983
+ static const char *azSkinVars[] = { /* These are the names of CONFIG */
1984
+ "adunit", /* variables that affect appearance. */
1985
+ "adunit-omit-if-admin", /* Keep this list in sorted order, */
1986
+ "adunit-omit-if-user", /* and in sync with the list of */
1987
+ "background-image", /* CONFIGSET_SKIN and CONFIGSET_CSS */
1988
+ "background-mimetype", /* names in configure.c */
1989
+ "css",
1990
+ "footer",
1991
+ "header",
1992
+ "index-page",
1993
+ "logo-image",
1994
+ "logo-mimetype",
1995
+ "timeline-block-markup",
1996
+ "timeline-max-comment",
1997
+ "timeline-plaintext",
1998
+ };
1999
+ int i, c, lwr, upr;
2000
+ static char *zToFree = 0;
2001
+ if( g.zSkin==0 ) return zName; /* The common case */
2002
+ if( zToFree ){
2003
+ fossil_free(zToFree);
2004
+ zToFree = 0;
2005
+ }
2006
+ lwr = 0;
2007
+ upr = sizeof(azSkinVars)/sizeof(azSkinVars[0])-1;
2008
+ while( lwr<=upr ){
2009
+ i = (lwr+upr)/2;
2010
+ c = fossil_strcmp(azSkinVars[i], zName);
2011
+ if( c<0 ){
2012
+ lwr = i+1;
2013
+ }else if( c>0 ){
2014
+ upr = i-1;
2015
+ }else{
2016
+ zToFree = mprintf("%s(%s)", zName, g.zSkin);
2017
+ return zToFree;
2018
+ }
2019
+ }
2020
+ return zName;
2021
+}
19682022
19692023
/*
19702024
** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
19712025
** repository and local databases.
19722026
*/
@@ -1980,11 +2034,12 @@
19802034
ctrlSetting = &(ctrlSettings[i]);
19812035
break;
19822036
}
19832037
}
19842038
if( g.repositoryOpen ){
1985
- z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName);
2039
+ z = db_text(0, "SELECT value FROM config WHERE name=%Q",
2040
+ db_skin_name(zName));
19862041
}
19872042
if( z==0 && g.zConfigDbName ){
19882043
db_swap_connections();
19892044
z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName);
19902045
db_swap_connections();
@@ -2000,11 +2055,12 @@
20002055
return z;
20012056
}
20022057
char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){
20032058
char *z = 0;
20042059
if( g.repositoryOpen ){
2005
- z = db_text(0, "SELECT mtime FROM config WHERE name=%Q", zName);
2060
+ z = db_text(0, "SELECT mtime FROM config WHERE name=%Q",
2061
+ db_skin_name(zName));
20062062
}
20072063
if( z==0 ){
20082064
z = zDefault;
20092065
}else if( zFormat!=0 ){
20102066
z = db_text(0, "SELECT strftime(%Q,%Q,'unixepoch');", zFormat, z);
@@ -2018,11 +2074,11 @@
20182074
db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%Q)",
20192075
zName, zValue);
20202076
db_swap_connections();
20212077
}else{
20222078
db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
2023
- zName, zValue);
2079
+ db_skin_name(zName), zValue);
20242080
}
20252081
if( globalFlag && g.repositoryOpen ){
20262082
db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
20272083
}
20282084
db_end_transaction(0);
@@ -2032,11 +2088,11 @@
20322088
if( globalFlag ){
20332089
db_swap_connections();
20342090
db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName);
20352091
db_swap_connections();
20362092
}else{
2037
- db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2093
+ db_multi_exec("DELETE FROM config WHERE name=%Q", db_skin_name(zName));
20382094
}
20392095
if( globalFlag && g.repositoryOpen ){
20402096
db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
20412097
}
20422098
db_end_transaction(0);
@@ -2053,11 +2109,12 @@
20532109
int db_get_int(const char *zName, int dflt){
20542110
int v = dflt;
20552111
int rc;
20562112
if( g.repositoryOpen ){
20572113
Stmt q;
2058
- db_prepare(&q, "SELECT value FROM config WHERE name=%Q", zName);
2114
+ db_prepare(&q, "SELECT value FROM config WHERE name=%Q",
2115
+ db_skin_name(zName));
20592116
rc = db_step(&q);
20602117
if( rc==SQLITE_ROW ){
20612118
v = db_column_int(&q, 0);
20622119
}
20632120
db_finalize(&q);
@@ -2077,11 +2134,11 @@
20772134
db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%d)",
20782135
zName, value);
20792136
db_swap_connections();
20802137
}else{
20812138
db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%d,now())",
2082
- zName, value);
2139
+ db_skin_name(zName), value);
20832140
}
20842141
if( globalFlag && g.repositoryOpen ){
20852142
db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
20862143
}
20872144
}
20882145
--- src/db.c
+++ src/db.c
@@ -1963,10 +1963,64 @@
1963 }
1964 /* Prefer the versioned setting */
1965 return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting;
1966 }
1967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1968
1969 /*
1970 ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
1971 ** repository and local databases.
1972 */
@@ -1980,11 +2034,12 @@
1980 ctrlSetting = &(ctrlSettings[i]);
1981 break;
1982 }
1983 }
1984 if( g.repositoryOpen ){
1985 z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName);
 
1986 }
1987 if( z==0 && g.zConfigDbName ){
1988 db_swap_connections();
1989 z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName);
1990 db_swap_connections();
@@ -2000,11 +2055,12 @@
2000 return z;
2001 }
2002 char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){
2003 char *z = 0;
2004 if( g.repositoryOpen ){
2005 z = db_text(0, "SELECT mtime FROM config WHERE name=%Q", zName);
 
2006 }
2007 if( z==0 ){
2008 z = zDefault;
2009 }else if( zFormat!=0 ){
2010 z = db_text(0, "SELECT strftime(%Q,%Q,'unixepoch');", zFormat, z);
@@ -2018,11 +2074,11 @@
2018 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%Q)",
2019 zName, zValue);
2020 db_swap_connections();
2021 }else{
2022 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
2023 zName, zValue);
2024 }
2025 if( globalFlag && g.repositoryOpen ){
2026 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2027 }
2028 db_end_transaction(0);
@@ -2032,11 +2088,11 @@
2032 if( globalFlag ){
2033 db_swap_connections();
2034 db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName);
2035 db_swap_connections();
2036 }else{
2037 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2038 }
2039 if( globalFlag && g.repositoryOpen ){
2040 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2041 }
2042 db_end_transaction(0);
@@ -2053,11 +2109,12 @@
2053 int db_get_int(const char *zName, int dflt){
2054 int v = dflt;
2055 int rc;
2056 if( g.repositoryOpen ){
2057 Stmt q;
2058 db_prepare(&q, "SELECT value FROM config WHERE name=%Q", zName);
 
2059 rc = db_step(&q);
2060 if( rc==SQLITE_ROW ){
2061 v = db_column_int(&q, 0);
2062 }
2063 db_finalize(&q);
@@ -2077,11 +2134,11 @@
2077 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%d)",
2078 zName, value);
2079 db_swap_connections();
2080 }else{
2081 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%d,now())",
2082 zName, value);
2083 }
2084 if( globalFlag && g.repositoryOpen ){
2085 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2086 }
2087 }
2088
--- src/db.c
+++ src/db.c
@@ -1963,10 +1963,64 @@
1963 }
1964 /* Prefer the versioned setting */
1965 return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting;
1966 }
1967
1968
1969 /*
1970 ** Translate a local CONFIG parameter name based on the g.zSkin setting
1971 ** and return a pointer to the new name.
1972 **
1973 ** The returned string is only valid until the next call to this routine.
1974 **
1975 ** If g.zSkin==0 (which is the overwhelmingly common case) then just
1976 ** return zName immediately, without change. But if g.zSkin is set and
1977 ** if zName is one of the CONFIG parameters that affect the screen
1978 ** appearance, then return a copy of zName with "("+g.zSkin+")" appended.
1979 ** Space to hold the copy is managed locally and is freed on the next
1980 ** call to this routine.
1981 */
1982 const char *db_skin_name(const char *zName){
1983 static const char *azSkinVars[] = { /* These are the names of CONFIG */
1984 "adunit", /* variables that affect appearance. */
1985 "adunit-omit-if-admin", /* Keep this list in sorted order, */
1986 "adunit-omit-if-user", /* and in sync with the list of */
1987 "background-image", /* CONFIGSET_SKIN and CONFIGSET_CSS */
1988 "background-mimetype", /* names in configure.c */
1989 "css",
1990 "footer",
1991 "header",
1992 "index-page",
1993 "logo-image",
1994 "logo-mimetype",
1995 "timeline-block-markup",
1996 "timeline-max-comment",
1997 "timeline-plaintext",
1998 };
1999 int i, c, lwr, upr;
2000 static char *zToFree = 0;
2001 if( g.zSkin==0 ) return zName; /* The common case */
2002 if( zToFree ){
2003 fossil_free(zToFree);
2004 zToFree = 0;
2005 }
2006 lwr = 0;
2007 upr = sizeof(azSkinVars)/sizeof(azSkinVars[0])-1;
2008 while( lwr<=upr ){
2009 i = (lwr+upr)/2;
2010 c = fossil_strcmp(azSkinVars[i], zName);
2011 if( c<0 ){
2012 lwr = i+1;
2013 }else if( c>0 ){
2014 upr = i-1;
2015 }else{
2016 zToFree = mprintf("%s(%s)", zName, g.zSkin);
2017 return zToFree;
2018 }
2019 }
2020 return zName;
2021 }
2022
2023 /*
2024 ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
2025 ** repository and local databases.
2026 */
@@ -1980,11 +2034,12 @@
2034 ctrlSetting = &(ctrlSettings[i]);
2035 break;
2036 }
2037 }
2038 if( g.repositoryOpen ){
2039 z = db_text(0, "SELECT value FROM config WHERE name=%Q",
2040 db_skin_name(zName));
2041 }
2042 if( z==0 && g.zConfigDbName ){
2043 db_swap_connections();
2044 z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName);
2045 db_swap_connections();
@@ -2000,11 +2055,12 @@
2055 return z;
2056 }
2057 char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){
2058 char *z = 0;
2059 if( g.repositoryOpen ){
2060 z = db_text(0, "SELECT mtime FROM config WHERE name=%Q",
2061 db_skin_name(zName));
2062 }
2063 if( z==0 ){
2064 z = zDefault;
2065 }else if( zFormat!=0 ){
2066 z = db_text(0, "SELECT strftime(%Q,%Q,'unixepoch');", zFormat, z);
@@ -2018,11 +2074,11 @@
2074 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%Q)",
2075 zName, zValue);
2076 db_swap_connections();
2077 }else{
2078 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
2079 db_skin_name(zName), zValue);
2080 }
2081 if( globalFlag && g.repositoryOpen ){
2082 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2083 }
2084 db_end_transaction(0);
@@ -2032,11 +2088,11 @@
2088 if( globalFlag ){
2089 db_swap_connections();
2090 db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName);
2091 db_swap_connections();
2092 }else{
2093 db_multi_exec("DELETE FROM config WHERE name=%Q", db_skin_name(zName));
2094 }
2095 if( globalFlag && g.repositoryOpen ){
2096 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2097 }
2098 db_end_transaction(0);
@@ -2053,11 +2109,12 @@
2109 int db_get_int(const char *zName, int dflt){
2110 int v = dflt;
2111 int rc;
2112 if( g.repositoryOpen ){
2113 Stmt q;
2114 db_prepare(&q, "SELECT value FROM config WHERE name=%Q",
2115 db_skin_name(zName));
2116 rc = db_step(&q);
2117 if( rc==SQLITE_ROW ){
2118 v = db_column_int(&q, 0);
2119 }
2120 db_finalize(&q);
@@ -2077,11 +2134,11 @@
2134 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%d)",
2135 zName, value);
2136 db_swap_connections();
2137 }else{
2138 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%d,now())",
2139 db_skin_name(zName), value);
2140 }
2141 if( globalFlag && g.repositoryOpen ){
2142 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
2143 }
2144 }
2145
+15
--- src/main.c
+++ src/main.c
@@ -149,10 +149,11 @@
149149
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
150150
int fSshTrace; /* Trace the SSH setup traffic */
151151
int fSshClient; /* HTTP client flags for SSH client */
152152
char *zSshCmd; /* SSH command string */
153153
int fNoSync; /* Do not do an autosync ever. --nosync */
154
+ const char *zSkin; /* Alternative webpage skin name */
154155
char *zPath; /* Name of webpage being served */
155156
char *zExtra; /* Extra path information past the webpage name */
156157
char *zBaseURL; /* Full text of the URL being served */
157158
char *zHttpsURL; /* zBaseURL translated to https: */
158159
char *zTop; /* Parent directory of zPath */
@@ -1856,10 +1857,21 @@
18561857
** to function as a primitive web-server delivering arbitrary content.
18571858
*/
18581859
pFileGlob = glob_create(blob_str(&value));
18591860
blob_reset(&value);
18601861
continue;
1862
+ }
1863
+ if( blob_eq(&key, "skin:") && blob_token(&line, &value) ){
1864
+ /* skin: NAME
1865
+ **
1866
+ ** Use an alternative "skin" for this instance. NAME is the name
1867
+ ** of the alternative skin to use. See comments on db_skin_name()
1868
+ ** for addition information.
1869
+ */
1870
+ g.zSkin = mprintf("%s", blob_str(&value));
1871
+ blob_reset(&value);
1872
+ continue;
18611873
}
18621874
if( blob_eq(&key, "setenv:") && blob_token(&line, &value)
18631875
&& blob_token(&line, &value2) ){
18641876
/* setenv: NAME VALUE
18651877
**
@@ -1991,10 +2003,11 @@
19912003
** --nossl signal that no SSL connections are available
19922004
** --notfound URL use URL as "HTTP 404, object not found" page.
19932005
** --files GLOB comma-separate glob patterns for static file to serve
19942006
** --baseurl URL base URL (useful with reverse proxies)
19952007
** --scgi Interpret input as SCGI rather than HTTP
2008
+** --skin NAME Use an alternative labeled NAME
19962009
**
19972010
** See also: cgi, server, winsrv
19982011
*/
19992012
void cmd_http(void){
20002013
const char *zIpAddr = 0;
@@ -2017,10 +2030,11 @@
20172030
zFileGlob = find_option("files",0,1);
20182031
}
20192032
zNotFound = find_option("notfound", 0, 1);
20202033
g.useLocalauth = find_option("localauth", 0, 0)!=0;
20212034
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2035
+ g.zSkin = find_option("skin", 0, 1);
20222036
useSCGI = find_option("scgi", 0, 0)!=0;
20232037
zAltBase = find_option("baseurl", 0, 1);
20242038
if( zAltBase ) set_base_url(zAltBase);
20252039
if( find_option("https",0,0)!=0 ){
20262040
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
@@ -2210,10 +2224,11 @@
22102224
g.useLocalauth = find_option("localauth", 0, 0)!=0;
22112225
Th_InitTraceLog();
22122226
zPort = find_option("port", "P", 1);
22132227
zNotFound = find_option("notfound", 0, 1);
22142228
zAltBase = find_option("baseurl", 0, 1);
2229
+ g.zSkin = find_option("skin",0,1);
22152230
if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
22162231
if( zAltBase ){
22172232
set_base_url(zAltBase);
22182233
}
22192234
if( find_option("localhost", 0, 0)!=0 ){
22202235
--- src/main.c
+++ src/main.c
@@ -149,10 +149,11 @@
149 int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
150 int fSshTrace; /* Trace the SSH setup traffic */
151 int fSshClient; /* HTTP client flags for SSH client */
152 char *zSshCmd; /* SSH command string */
153 int fNoSync; /* Do not do an autosync ever. --nosync */
 
154 char *zPath; /* Name of webpage being served */
155 char *zExtra; /* Extra path information past the webpage name */
156 char *zBaseURL; /* Full text of the URL being served */
157 char *zHttpsURL; /* zBaseURL translated to https: */
158 char *zTop; /* Parent directory of zPath */
@@ -1856,10 +1857,21 @@
1856 ** to function as a primitive web-server delivering arbitrary content.
1857 */
1858 pFileGlob = glob_create(blob_str(&value));
1859 blob_reset(&value);
1860 continue;
 
 
 
 
 
 
 
 
 
 
 
1861 }
1862 if( blob_eq(&key, "setenv:") && blob_token(&line, &value)
1863 && blob_token(&line, &value2) ){
1864 /* setenv: NAME VALUE
1865 **
@@ -1991,10 +2003,11 @@
1991 ** --nossl signal that no SSL connections are available
1992 ** --notfound URL use URL as "HTTP 404, object not found" page.
1993 ** --files GLOB comma-separate glob patterns for static file to serve
1994 ** --baseurl URL base URL (useful with reverse proxies)
1995 ** --scgi Interpret input as SCGI rather than HTTP
 
1996 **
1997 ** See also: cgi, server, winsrv
1998 */
1999 void cmd_http(void){
2000 const char *zIpAddr = 0;
@@ -2017,10 +2030,11 @@
2017 zFileGlob = find_option("files",0,1);
2018 }
2019 zNotFound = find_option("notfound", 0, 1);
2020 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2021 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
 
2022 useSCGI = find_option("scgi", 0, 0)!=0;
2023 zAltBase = find_option("baseurl", 0, 1);
2024 if( zAltBase ) set_base_url(zAltBase);
2025 if( find_option("https",0,0)!=0 ){
2026 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
@@ -2210,10 +2224,11 @@
2210 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2211 Th_InitTraceLog();
2212 zPort = find_option("port", "P", 1);
2213 zNotFound = find_option("notfound", 0, 1);
2214 zAltBase = find_option("baseurl", 0, 1);
 
2215 if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
2216 if( zAltBase ){
2217 set_base_url(zAltBase);
2218 }
2219 if( find_option("localhost", 0, 0)!=0 ){
2220
--- src/main.c
+++ src/main.c
@@ -149,10 +149,11 @@
149 int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
150 int fSshTrace; /* Trace the SSH setup traffic */
151 int fSshClient; /* HTTP client flags for SSH client */
152 char *zSshCmd; /* SSH command string */
153 int fNoSync; /* Do not do an autosync ever. --nosync */
154 const char *zSkin; /* Alternative webpage skin name */
155 char *zPath; /* Name of webpage being served */
156 char *zExtra; /* Extra path information past the webpage name */
157 char *zBaseURL; /* Full text of the URL being served */
158 char *zHttpsURL; /* zBaseURL translated to https: */
159 char *zTop; /* Parent directory of zPath */
@@ -1856,10 +1857,21 @@
1857 ** to function as a primitive web-server delivering arbitrary content.
1858 */
1859 pFileGlob = glob_create(blob_str(&value));
1860 blob_reset(&value);
1861 continue;
1862 }
1863 if( blob_eq(&key, "skin:") && blob_token(&line, &value) ){
1864 /* skin: NAME
1865 **
1866 ** Use an alternative "skin" for this instance. NAME is the name
1867 ** of the alternative skin to use. See comments on db_skin_name()
1868 ** for addition information.
1869 */
1870 g.zSkin = mprintf("%s", blob_str(&value));
1871 blob_reset(&value);
1872 continue;
1873 }
1874 if( blob_eq(&key, "setenv:") && blob_token(&line, &value)
1875 && blob_token(&line, &value2) ){
1876 /* setenv: NAME VALUE
1877 **
@@ -1991,10 +2003,11 @@
2003 ** --nossl signal that no SSL connections are available
2004 ** --notfound URL use URL as "HTTP 404, object not found" page.
2005 ** --files GLOB comma-separate glob patterns for static file to serve
2006 ** --baseurl URL base URL (useful with reverse proxies)
2007 ** --scgi Interpret input as SCGI rather than HTTP
2008 ** --skin NAME Use an alternative labeled NAME
2009 **
2010 ** See also: cgi, server, winsrv
2011 */
2012 void cmd_http(void){
2013 const char *zIpAddr = 0;
@@ -2017,10 +2030,11 @@
2030 zFileGlob = find_option("files",0,1);
2031 }
2032 zNotFound = find_option("notfound", 0, 1);
2033 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2034 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2035 g.zSkin = find_option("skin", 0, 1);
2036 useSCGI = find_option("scgi", 0, 0)!=0;
2037 zAltBase = find_option("baseurl", 0, 1);
2038 if( zAltBase ) set_base_url(zAltBase);
2039 if( find_option("https",0,0)!=0 ){
2040 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
@@ -2210,10 +2224,11 @@
2224 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2225 Th_InitTraceLog();
2226 zPort = find_option("port", "P", 1);
2227 zNotFound = find_option("notfound", 0, 1);
2228 zAltBase = find_option("baseurl", 0, 1);
2229 g.zSkin = find_option("skin",0,1);
2230 if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
2231 if( zAltBase ){
2232 set_base_url(zAltBase);
2233 }
2234 if( find_option("localhost", 0, 0)!=0 ){
2235
+12 -14
--- src/setup.c
+++ src/setup.c
@@ -1800,51 +1800,49 @@
18001800
Blob img;
18011801
Stmt ins;
18021802
blob_init(&img, aLogoImg, szLogoImg);
18031803
db_prepare(&ins,
18041804
"REPLACE INTO config(name,value,mtime)"
1805
- " VALUES('logo-image',:bytes,now())"
1805
+ " VALUES(%Q,:bytes,now())",
1806
+ db_skin_name("logo-image")
18061807
);
18071808
db_bind_blob(&ins, ":bytes", &img);
18081809
db_step(&ins);
18091810
db_finalize(&ins);
18101811
db_multi_exec(
1811
- "REPLACE INTO config(name,value,mtime) VALUES('logo-mimetype',%Q,now())",
1812
- zLogoMime
1812
+ "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
1813
+ db_skin_name("logo-mimetype"), zLogoMime
18131814
);
18141815
db_end_transaction(0);
18151816
cgi_redirect("setup_logo");
18161817
}else if( P("clrlogo")!=0 ){
1817
- db_multi_exec(
1818
- "DELETE FROM config WHERE name IN "
1819
- "('logo-image','logo-mimetype')"
1820
- );
1818
+ db_unset("logo-image", 0);
1819
+ db_unset("logo-mimetype", 0);
18211820
db_end_transaction(0);
18221821
cgi_redirect("setup_logo");
18231822
}else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){
18241823
Blob img;
18251824
Stmt ins;
18261825
blob_init(&img, aBgImg, szBgImg);
18271826
db_prepare(&ins,
18281827
"REPLACE INTO config(name,value,mtime)"
1829
- " VALUES('background-image',:bytes,now())"
1828
+ " VALUES(%Q,:bytes,now())",
1829
+ db_skin_name("background-image")
18301830
);
18311831
db_bind_blob(&ins, ":bytes", &img);
18321832
db_step(&ins);
18331833
db_finalize(&ins);
18341834
db_multi_exec(
18351835
"REPLACE INTO config(name,value,mtime)"
1836
- " VALUES('background-mimetype',%Q,now())",
1837
- zBgMime
1836
+ " VALUES(%Q,%Q,now())",
1837
+ db_skin_name("background-mimetype"),zBgMime
18381838
);
18391839
db_end_transaction(0);
18401840
cgi_redirect("setup_logo");
18411841
}else if( P("clrbg")!=0 ){
1842
- db_multi_exec(
1843
- "DELETE FROM config WHERE name IN "
1844
- "('background-image','background-mimetype')"
1845
- );
1842
+ db_unset("background-image", 0);
1843
+ db_unset("background-mimetype", 0);
18461844
db_end_transaction(0);
18471845
cgi_redirect("setup_logo");
18481846
}
18491847
style_header("Edit Project Logo And Background");
18501848
@ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b>
18511849
--- src/setup.c
+++ src/setup.c
@@ -1800,51 +1800,49 @@
1800 Blob img;
1801 Stmt ins;
1802 blob_init(&img, aLogoImg, szLogoImg);
1803 db_prepare(&ins,
1804 "REPLACE INTO config(name,value,mtime)"
1805 " VALUES('logo-image',:bytes,now())"
 
1806 );
1807 db_bind_blob(&ins, ":bytes", &img);
1808 db_step(&ins);
1809 db_finalize(&ins);
1810 db_multi_exec(
1811 "REPLACE INTO config(name,value,mtime) VALUES('logo-mimetype',%Q,now())",
1812 zLogoMime
1813 );
1814 db_end_transaction(0);
1815 cgi_redirect("setup_logo");
1816 }else if( P("clrlogo")!=0 ){
1817 db_multi_exec(
1818 "DELETE FROM config WHERE name IN "
1819 "('logo-image','logo-mimetype')"
1820 );
1821 db_end_transaction(0);
1822 cgi_redirect("setup_logo");
1823 }else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){
1824 Blob img;
1825 Stmt ins;
1826 blob_init(&img, aBgImg, szBgImg);
1827 db_prepare(&ins,
1828 "REPLACE INTO config(name,value,mtime)"
1829 " VALUES('background-image',:bytes,now())"
 
1830 );
1831 db_bind_blob(&ins, ":bytes", &img);
1832 db_step(&ins);
1833 db_finalize(&ins);
1834 db_multi_exec(
1835 "REPLACE INTO config(name,value,mtime)"
1836 " VALUES('background-mimetype',%Q,now())",
1837 zBgMime
1838 );
1839 db_end_transaction(0);
1840 cgi_redirect("setup_logo");
1841 }else if( P("clrbg")!=0 ){
1842 db_multi_exec(
1843 "DELETE FROM config WHERE name IN "
1844 "('background-image','background-mimetype')"
1845 );
1846 db_end_transaction(0);
1847 cgi_redirect("setup_logo");
1848 }
1849 style_header("Edit Project Logo And Background");
1850 @ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b>
1851
--- src/setup.c
+++ src/setup.c
@@ -1800,51 +1800,49 @@
1800 Blob img;
1801 Stmt ins;
1802 blob_init(&img, aLogoImg, szLogoImg);
1803 db_prepare(&ins,
1804 "REPLACE INTO config(name,value,mtime)"
1805 " VALUES(%Q,:bytes,now())",
1806 db_skin_name("logo-image")
1807 );
1808 db_bind_blob(&ins, ":bytes", &img);
1809 db_step(&ins);
1810 db_finalize(&ins);
1811 db_multi_exec(
1812 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
1813 db_skin_name("logo-mimetype"), zLogoMime
1814 );
1815 db_end_transaction(0);
1816 cgi_redirect("setup_logo");
1817 }else if( P("clrlogo")!=0 ){
1818 db_unset("logo-image", 0);
1819 db_unset("logo-mimetype", 0);
 
 
1820 db_end_transaction(0);
1821 cgi_redirect("setup_logo");
1822 }else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){
1823 Blob img;
1824 Stmt ins;
1825 blob_init(&img, aBgImg, szBgImg);
1826 db_prepare(&ins,
1827 "REPLACE INTO config(name,value,mtime)"
1828 " VALUES(%Q,:bytes,now())",
1829 db_skin_name("background-image")
1830 );
1831 db_bind_blob(&ins, ":bytes", &img);
1832 db_step(&ins);
1833 db_finalize(&ins);
1834 db_multi_exec(
1835 "REPLACE INTO config(name,value,mtime)"
1836 " VALUES(%Q,%Q,now())",
1837 db_skin_name("background-mimetype"),zBgMime
1838 );
1839 db_end_transaction(0);
1840 cgi_redirect("setup_logo");
1841 }else if( P("clrbg")!=0 ){
1842 db_unset("background-image", 0);
1843 db_unset("background-mimetype", 0);
 
 
1844 db_end_transaction(0);
1845 cgi_redirect("setup_logo");
1846 }
1847 style_header("Edit Project Logo And Background");
1848 @ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b>
1849
+17 -9
--- src/skins.c
+++ src/skins.c
@@ -58,11 +58,15 @@
5858
** If ifExists is true, and the named skin does not exist, return NULL.
5959
*/
6060
static char *skinVarName(const char *zSkinName, int ifExists){
6161
char *z;
6262
if( zSkinName==0 || zSkinName[0]==0 ) return 0;
63
- z = mprintf("skin:%s", zSkinName);
63
+ if( g.zSkin ){
64
+ z = mprintf("skin(%s):%s", g.zSkin, zSkinName);
65
+ }else{
66
+ z = mprintf("skin:%s", zSkinName);
67
+ }
6468
if( ifExists && !db_exists("SELECT 1 FROM config WHERE name=%Q", z) ){
6569
free(z);
6670
z = 0;
6771
}
6872
return z;
@@ -96,11 +100,11 @@
96100
fossil_free(zLabel);
97101
}
98102
}
99103
blob_appendf(&val,
100104
"REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now());\n",
101
- azType[i], z
105
+ db_skin_name(azType[i]), z
102106
);
103107
}
104108
return blob_str(&val);
105109
}
106110
@@ -166,17 +170,19 @@
166170
seen = 1;
167171
break;
168172
}
169173
}
170174
if( !seen ){
171
- seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
172
- " AND value=%Q", zCurrent);
175
+ seen = db_exists("SELECT 1 FROM config"
176
+ " WHERE name GLOB %Q"
177
+ " AND value=%Q",
178
+ skinVarName("*",0), zCurrent);
173179
if( !seen ){
174180
db_multi_exec(
175
- "INSERT INTO config(name,value,mtime) VALUES("
176
- " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
177
- " %Q,now())", zCurrent
181
+ "INSERT INTO config(name,value,mtime) "
182
+ " VALUES(strftime(%Q),%Q,now())",
183
+ skinVarName("Backup On %Y-%m-%d %H:%M:%S",0), zCurrent
178184
);
179185
}
180186
}
181187
seen = 0;
182188
for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
@@ -219,17 +225,19 @@
219225
}
220226
@ </tr>
221227
}
222228
db_prepare(&q,
223229
"SELECT substr(name, 6), value FROM config"
224
- " WHERE name GLOB 'skin:*'"
225
- " ORDER BY name"
230
+ " WHERE name GLOB %Q"
231
+ " ORDER BY name",
232
+ skinVarName("*",0)
226233
);
227234
while( db_step(&q)==SQLITE_ROW ){
228235
const char *zN = db_column_text(&q, 0);
229236
const char *zV = db_column_text(&q, 1);
230237
i++;
238
+ if( g.zSkin ) zN += strlen(g.zSkin)+2;
231239
@ <tr><td>%d(i).<td>%h(zN)<td>&nbsp;&nbsp;<td>
232240
if( fossil_strcmp(zV, zCurrent)==0 ){
233241
@ (Currently In Use)
234242
}else{
235243
@ <form action="%s(g.zTop)/setup_skin" method="post">
236244
--- src/skins.c
+++ src/skins.c
@@ -58,11 +58,15 @@
58 ** If ifExists is true, and the named skin does not exist, return NULL.
59 */
60 static char *skinVarName(const char *zSkinName, int ifExists){
61 char *z;
62 if( zSkinName==0 || zSkinName[0]==0 ) return 0;
63 z = mprintf("skin:%s", zSkinName);
 
 
 
 
64 if( ifExists && !db_exists("SELECT 1 FROM config WHERE name=%Q", z) ){
65 free(z);
66 z = 0;
67 }
68 return z;
@@ -96,11 +100,11 @@
96 fossil_free(zLabel);
97 }
98 }
99 blob_appendf(&val,
100 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now());\n",
101 azType[i], z
102 );
103 }
104 return blob_str(&val);
105 }
106
@@ -166,17 +170,19 @@
166 seen = 1;
167 break;
168 }
169 }
170 if( !seen ){
171 seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'"
172 " AND value=%Q", zCurrent);
 
 
173 if( !seen ){
174 db_multi_exec(
175 "INSERT INTO config(name,value,mtime) VALUES("
176 " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S'),"
177 " %Q,now())", zCurrent
178 );
179 }
180 }
181 seen = 0;
182 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
@@ -219,17 +225,19 @@
219 }
220 @ </tr>
221 }
222 db_prepare(&q,
223 "SELECT substr(name, 6), value FROM config"
224 " WHERE name GLOB 'skin:*'"
225 " ORDER BY name"
 
226 );
227 while( db_step(&q)==SQLITE_ROW ){
228 const char *zN = db_column_text(&q, 0);
229 const char *zV = db_column_text(&q, 1);
230 i++;
 
231 @ <tr><td>%d(i).<td>%h(zN)<td>&nbsp;&nbsp;<td>
232 if( fossil_strcmp(zV, zCurrent)==0 ){
233 @ (Currently In Use)
234 }else{
235 @ <form action="%s(g.zTop)/setup_skin" method="post">
236
--- src/skins.c
+++ src/skins.c
@@ -58,11 +58,15 @@
58 ** If ifExists is true, and the named skin does not exist, return NULL.
59 */
60 static char *skinVarName(const char *zSkinName, int ifExists){
61 char *z;
62 if( zSkinName==0 || zSkinName[0]==0 ) return 0;
63 if( g.zSkin ){
64 z = mprintf("skin(%s):%s", g.zSkin, zSkinName);
65 }else{
66 z = mprintf("skin:%s", zSkinName);
67 }
68 if( ifExists && !db_exists("SELECT 1 FROM config WHERE name=%Q", z) ){
69 free(z);
70 z = 0;
71 }
72 return z;
@@ -96,11 +100,11 @@
100 fossil_free(zLabel);
101 }
102 }
103 blob_appendf(&val,
104 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now());\n",
105 db_skin_name(azType[i]), z
106 );
107 }
108 return blob_str(&val);
109 }
110
@@ -166,17 +170,19 @@
170 seen = 1;
171 break;
172 }
173 }
174 if( !seen ){
175 seen = db_exists("SELECT 1 FROM config"
176 " WHERE name GLOB %Q"
177 " AND value=%Q",
178 skinVarName("*",0), zCurrent);
179 if( !seen ){
180 db_multi_exec(
181 "INSERT INTO config(name,value,mtime) "
182 " VALUES(strftime(%Q),%Q,now())",
183 skinVarName("Backup On %Y-%m-%d %H:%M:%S",0), zCurrent
184 );
185 }
186 }
187 seen = 0;
188 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
@@ -219,17 +225,19 @@
225 }
226 @ </tr>
227 }
228 db_prepare(&q,
229 "SELECT substr(name, 6), value FROM config"
230 " WHERE name GLOB %Q"
231 " ORDER BY name",
232 skinVarName("*",0)
233 );
234 while( db_step(&q)==SQLITE_ROW ){
235 const char *zN = db_column_text(&q, 0);
236 const char *zV = db_column_text(&q, 1);
237 i++;
238 if( g.zSkin ) zN += strlen(g.zSkin)+2;
239 @ <tr><td>%d(i).<td>%h(zN)<td>&nbsp;&nbsp;<td>
240 if( fossil_strcmp(zV, zCurrent)==0 ){
241 @ (Currently In Use)
242 }else{
243 @ <form action="%s(g.zTop)/setup_skin" method="post">
244
--- src/style.c
+++ src/style.c
@@ -1229,10 +1229,13 @@
12291229
@ g.userUid = %d(g.userUid)<br />
12301230
@ g.zLogin = %h(g.zLogin)<br />
12311231
@ g.isHuman = %d(g.isHuman)<br />
12321232
@ capabilities = %s(zCap)<br />
12331233
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
1234
+ if( g.zSkin ){
1235
+ @ g.zSkin = %h(g.zSkin)<br />
1236
+ }
12341237
@ load_average() = %f(load_average())<br />
12351238
@ <hr>
12361239
P("HTTP_USER_AGENT");
12371240
cgi_print_all(showAll);
12381241
if( showAll && blob_size(&g.httpHeader)>0 ){
12391242
--- src/style.c
+++ src/style.c
@@ -1229,10 +1229,13 @@
1229 @ g.userUid = %d(g.userUid)<br />
1230 @ g.zLogin = %h(g.zLogin)<br />
1231 @ g.isHuman = %d(g.isHuman)<br />
1232 @ capabilities = %s(zCap)<br />
1233 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
 
 
 
1234 @ load_average() = %f(load_average())<br />
1235 @ <hr>
1236 P("HTTP_USER_AGENT");
1237 cgi_print_all(showAll);
1238 if( showAll && blob_size(&g.httpHeader)>0 ){
1239
--- src/style.c
+++ src/style.c
@@ -1229,10 +1229,13 @@
1229 @ g.userUid = %d(g.userUid)<br />
1230 @ g.zLogin = %h(g.zLogin)<br />
1231 @ g.isHuman = %d(g.isHuman)<br />
1232 @ capabilities = %s(zCap)<br />
1233 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
1234 if( g.zSkin ){
1235 @ g.zSkin = %h(g.zSkin)<br />
1236 }
1237 @ load_average() = %f(load_average())<br />
1238 @ <hr>
1239 P("HTTP_USER_AGENT");
1240 cgi_print_all(showAll);
1241 if( showAll && blob_size(&g.httpHeader)>0 ){
1242

Keyboard Shortcuts

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