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.
Commit
b36e24110009ef9d80e32591a6cbeef9632ddced
Parent
236087b98e559e3…
6 files changed
+3
-3
+63
-6
+15
+12
-14
+17
-9
+3
+3
-3
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -83,13 +83,13 @@ | ||
| 83 | 83 | */ |
| 84 | 84 | static struct { |
| 85 | 85 | const char *zName; /* Name of the configuration parameter */ |
| 86 | 86 | int groupMask; /* Which config groups is it part of */ |
| 87 | 87 | } 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 */ | |
| 91 | 91 | { "logo-mimetype", CONFIGSET_SKIN }, |
| 92 | 92 | { "logo-image", CONFIGSET_SKIN }, |
| 93 | 93 | { "background-mimetype", CONFIGSET_SKIN }, |
| 94 | 94 | { "background-image", CONFIGSET_SKIN }, |
| 95 | 95 | { "index-page", CONFIGSET_SKIN }, |
| 96 | 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 }, |
| 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 |
M
src/db.c
+63
-6
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1963,10 +1963,64 @@ | ||
| 1963 | 1963 | } |
| 1964 | 1964 | /* Prefer the versioned setting */ |
| 1965 | 1965 | return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting; |
| 1966 | 1966 | } |
| 1967 | 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 | +} | |
| 1968 | 2022 | |
| 1969 | 2023 | /* |
| 1970 | 2024 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1971 | 2025 | ** repository and local databases. |
| 1972 | 2026 | */ |
| @@ -1980,11 +2034,12 @@ | ||
| 1980 | 2034 | ctrlSetting = &(ctrlSettings[i]); |
| 1981 | 2035 | break; |
| 1982 | 2036 | } |
| 1983 | 2037 | } |
| 1984 | 2038 | 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)); | |
| 1986 | 2041 | } |
| 1987 | 2042 | if( z==0 && g.zConfigDbName ){ |
| 1988 | 2043 | db_swap_connections(); |
| 1989 | 2044 | z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName); |
| 1990 | 2045 | db_swap_connections(); |
| @@ -2000,11 +2055,12 @@ | ||
| 2000 | 2055 | return z; |
| 2001 | 2056 | } |
| 2002 | 2057 | char *db_get_mtime(const char *zName, char *zFormat, char *zDefault){ |
| 2003 | 2058 | char *z = 0; |
| 2004 | 2059 | 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)); | |
| 2006 | 2062 | } |
| 2007 | 2063 | if( z==0 ){ |
| 2008 | 2064 | z = zDefault; |
| 2009 | 2065 | }else if( zFormat!=0 ){ |
| 2010 | 2066 | z = db_text(0, "SELECT strftime(%Q,%Q,'unixepoch');", zFormat, z); |
| @@ -2018,11 +2074,11 @@ | ||
| 2018 | 2074 | db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%Q)", |
| 2019 | 2075 | zName, zValue); |
| 2020 | 2076 | db_swap_connections(); |
| 2021 | 2077 | }else{ |
| 2022 | 2078 | db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())", |
| 2023 | - zName, zValue); | |
| 2079 | + db_skin_name(zName), zValue); | |
| 2024 | 2080 | } |
| 2025 | 2081 | if( globalFlag && g.repositoryOpen ){ |
| 2026 | 2082 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| 2027 | 2083 | } |
| 2028 | 2084 | db_end_transaction(0); |
| @@ -2032,11 +2088,11 @@ | ||
| 2032 | 2088 | if( globalFlag ){ |
| 2033 | 2089 | db_swap_connections(); |
| 2034 | 2090 | db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName); |
| 2035 | 2091 | db_swap_connections(); |
| 2036 | 2092 | }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)); | |
| 2038 | 2094 | } |
| 2039 | 2095 | if( globalFlag && g.repositoryOpen ){ |
| 2040 | 2096 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| 2041 | 2097 | } |
| 2042 | 2098 | db_end_transaction(0); |
| @@ -2053,11 +2109,12 @@ | ||
| 2053 | 2109 | int db_get_int(const char *zName, int dflt){ |
| 2054 | 2110 | int v = dflt; |
| 2055 | 2111 | int rc; |
| 2056 | 2112 | if( g.repositoryOpen ){ |
| 2057 | 2113 | 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)); | |
| 2059 | 2116 | rc = db_step(&q); |
| 2060 | 2117 | if( rc==SQLITE_ROW ){ |
| 2061 | 2118 | v = db_column_int(&q, 0); |
| 2062 | 2119 | } |
| 2063 | 2120 | db_finalize(&q); |
| @@ -2077,11 +2134,11 @@ | ||
| 2077 | 2134 | db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%d)", |
| 2078 | 2135 | zName, value); |
| 2079 | 2136 | db_swap_connections(); |
| 2080 | 2137 | }else{ |
| 2081 | 2138 | db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%d,now())", |
| 2082 | - zName, value); | |
| 2139 | + db_skin_name(zName), value); | |
| 2083 | 2140 | } |
| 2084 | 2141 | if( globalFlag && g.repositoryOpen ){ |
| 2085 | 2142 | db_multi_exec("DELETE FROM config WHERE name=%Q", zName); |
| 2086 | 2143 | } |
| 2087 | 2144 | } |
| 2088 | 2145 |
| --- 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 @@ | ||
| 149 | 149 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 150 | 150 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 151 | 151 | int fSshClient; /* HTTP client flags for SSH client */ |
| 152 | 152 | char *zSshCmd; /* SSH command string */ |
| 153 | 153 | int fNoSync; /* Do not do an autosync ever. --nosync */ |
| 154 | + const char *zSkin; /* Alternative webpage skin name */ | |
| 154 | 155 | char *zPath; /* Name of webpage being served */ |
| 155 | 156 | char *zExtra; /* Extra path information past the webpage name */ |
| 156 | 157 | char *zBaseURL; /* Full text of the URL being served */ |
| 157 | 158 | char *zHttpsURL; /* zBaseURL translated to https: */ |
| 158 | 159 | char *zTop; /* Parent directory of zPath */ |
| @@ -1856,10 +1857,21 @@ | ||
| 1856 | 1857 | ** to function as a primitive web-server delivering arbitrary content. |
| 1857 | 1858 | */ |
| 1858 | 1859 | pFileGlob = glob_create(blob_str(&value)); |
| 1859 | 1860 | blob_reset(&value); |
| 1860 | 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; | |
| 1861 | 1873 | } |
| 1862 | 1874 | if( blob_eq(&key, "setenv:") && blob_token(&line, &value) |
| 1863 | 1875 | && blob_token(&line, &value2) ){ |
| 1864 | 1876 | /* setenv: NAME VALUE |
| 1865 | 1877 | ** |
| @@ -1991,10 +2003,11 @@ | ||
| 1991 | 2003 | ** --nossl signal that no SSL connections are available |
| 1992 | 2004 | ** --notfound URL use URL as "HTTP 404, object not found" page. |
| 1993 | 2005 | ** --files GLOB comma-separate glob patterns for static file to serve |
| 1994 | 2006 | ** --baseurl URL base URL (useful with reverse proxies) |
| 1995 | 2007 | ** --scgi Interpret input as SCGI rather than HTTP |
| 2008 | +** --skin NAME Use an alternative labeled NAME | |
| 1996 | 2009 | ** |
| 1997 | 2010 | ** See also: cgi, server, winsrv |
| 1998 | 2011 | */ |
| 1999 | 2012 | void cmd_http(void){ |
| 2000 | 2013 | const char *zIpAddr = 0; |
| @@ -2017,10 +2030,11 @@ | ||
| 2017 | 2030 | zFileGlob = find_option("files",0,1); |
| 2018 | 2031 | } |
| 2019 | 2032 | zNotFound = find_option("notfound", 0, 1); |
| 2020 | 2033 | g.useLocalauth = find_option("localauth", 0, 0)!=0; |
| 2021 | 2034 | g.sslNotAvailable = find_option("nossl", 0, 0)!=0; |
| 2035 | + g.zSkin = find_option("skin", 0, 1); | |
| 2022 | 2036 | useSCGI = find_option("scgi", 0, 0)!=0; |
| 2023 | 2037 | zAltBase = find_option("baseurl", 0, 1); |
| 2024 | 2038 | if( zAltBase ) set_base_url(zAltBase); |
| 2025 | 2039 | if( find_option("https",0,0)!=0 ){ |
| 2026 | 2040 | zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */ |
| @@ -2210,10 +2224,11 @@ | ||
| 2210 | 2224 | g.useLocalauth = find_option("localauth", 0, 0)!=0; |
| 2211 | 2225 | Th_InitTraceLog(); |
| 2212 | 2226 | zPort = find_option("port", "P", 1); |
| 2213 | 2227 | zNotFound = find_option("notfound", 0, 1); |
| 2214 | 2228 | zAltBase = find_option("baseurl", 0, 1); |
| 2229 | + g.zSkin = find_option("skin",0,1); | |
| 2215 | 2230 | if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI; |
| 2216 | 2231 | if( zAltBase ){ |
| 2217 | 2232 | set_base_url(zAltBase); |
| 2218 | 2233 | } |
| 2219 | 2234 | if( find_option("localhost", 0, 0)!=0 ){ |
| 2220 | 2235 |
| --- 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 @@ | ||
| 1800 | 1800 | Blob img; |
| 1801 | 1801 | Stmt ins; |
| 1802 | 1802 | blob_init(&img, aLogoImg, szLogoImg); |
| 1803 | 1803 | db_prepare(&ins, |
| 1804 | 1804 | "REPLACE INTO config(name,value,mtime)" |
| 1805 | - " VALUES('logo-image',:bytes,now())" | |
| 1805 | + " VALUES(%Q,:bytes,now())", | |
| 1806 | + db_skin_name("logo-image") | |
| 1806 | 1807 | ); |
| 1807 | 1808 | db_bind_blob(&ins, ":bytes", &img); |
| 1808 | 1809 | db_step(&ins); |
| 1809 | 1810 | db_finalize(&ins); |
| 1810 | 1811 | 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 | |
| 1813 | 1814 | ); |
| 1814 | 1815 | db_end_transaction(0); |
| 1815 | 1816 | cgi_redirect("setup_logo"); |
| 1816 | 1817 | }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); | |
| 1821 | 1820 | db_end_transaction(0); |
| 1822 | 1821 | cgi_redirect("setup_logo"); |
| 1823 | 1822 | }else if( P("setbg")!=0 && zBgMime && zBgMime[0] && szBgImg>0 ){ |
| 1824 | 1823 | Blob img; |
| 1825 | 1824 | Stmt ins; |
| 1826 | 1825 | blob_init(&img, aBgImg, szBgImg); |
| 1827 | 1826 | db_prepare(&ins, |
| 1828 | 1827 | "REPLACE INTO config(name,value,mtime)" |
| 1829 | - " VALUES('background-image',:bytes,now())" | |
| 1828 | + " VALUES(%Q,:bytes,now())", | |
| 1829 | + db_skin_name("background-image") | |
| 1830 | 1830 | ); |
| 1831 | 1831 | db_bind_blob(&ins, ":bytes", &img); |
| 1832 | 1832 | db_step(&ins); |
| 1833 | 1833 | db_finalize(&ins); |
| 1834 | 1834 | db_multi_exec( |
| 1835 | 1835 | "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 | |
| 1838 | 1838 | ); |
| 1839 | 1839 | db_end_transaction(0); |
| 1840 | 1840 | cgi_redirect("setup_logo"); |
| 1841 | 1841 | }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); | |
| 1846 | 1844 | db_end_transaction(0); |
| 1847 | 1845 | cgi_redirect("setup_logo"); |
| 1848 | 1846 | } |
| 1849 | 1847 | style_header("Edit Project Logo And Background"); |
| 1850 | 1848 | @ <p>The current project logo has a MIME-Type of <b>%h(zLogoMime)</b> |
| 1851 | 1849 |
| --- 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 @@ | ||
| 58 | 58 | ** If ifExists is true, and the named skin does not exist, return NULL. |
| 59 | 59 | */ |
| 60 | 60 | static char *skinVarName(const char *zSkinName, int ifExists){ |
| 61 | 61 | char *z; |
| 62 | 62 | 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 | + } | |
| 64 | 68 | if( ifExists && !db_exists("SELECT 1 FROM config WHERE name=%Q", z) ){ |
| 65 | 69 | free(z); |
| 66 | 70 | z = 0; |
| 67 | 71 | } |
| 68 | 72 | return z; |
| @@ -96,11 +100,11 @@ | ||
| 96 | 100 | fossil_free(zLabel); |
| 97 | 101 | } |
| 98 | 102 | } |
| 99 | 103 | blob_appendf(&val, |
| 100 | 104 | "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now());\n", |
| 101 | - azType[i], z | |
| 105 | + db_skin_name(azType[i]), z | |
| 102 | 106 | ); |
| 103 | 107 | } |
| 104 | 108 | return blob_str(&val); |
| 105 | 109 | } |
| 106 | 110 | |
| @@ -166,17 +170,19 @@ | ||
| 166 | 170 | seen = 1; |
| 167 | 171 | break; |
| 168 | 172 | } |
| 169 | 173 | } |
| 170 | 174 | 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); | |
| 173 | 179 | if( !seen ){ |
| 174 | 180 | 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 | |
| 178 | 184 | ); |
| 179 | 185 | } |
| 180 | 186 | } |
| 181 | 187 | seen = 0; |
| 182 | 188 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| @@ -219,17 +225,19 @@ | ||
| 219 | 225 | } |
| 220 | 226 | @ </tr> |
| 221 | 227 | } |
| 222 | 228 | db_prepare(&q, |
| 223 | 229 | "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) | |
| 226 | 233 | ); |
| 227 | 234 | while( db_step(&q)==SQLITE_ROW ){ |
| 228 | 235 | const char *zN = db_column_text(&q, 0); |
| 229 | 236 | const char *zV = db_column_text(&q, 1); |
| 230 | 237 | i++; |
| 238 | + if( g.zSkin ) zN += strlen(g.zSkin)+2; | |
| 231 | 239 | @ <tr><td>%d(i).<td>%h(zN)<td> <td> |
| 232 | 240 | if( fossil_strcmp(zV, zCurrent)==0 ){ |
| 233 | 241 | @ (Currently In Use) |
| 234 | 242 | }else{ |
| 235 | 243 | @ <form action="%s(g.zTop)/setup_skin" method="post"> |
| 236 | 244 |
| --- 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> <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> <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 |
+3
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1229,10 +1229,13 @@ | ||
| 1229 | 1229 | @ g.userUid = %d(g.userUid)<br /> |
| 1230 | 1230 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1231 | 1231 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1232 | 1232 | @ capabilities = %s(zCap)<br /> |
| 1233 | 1233 | @ g.zRepositoryName = %h(g.zRepositoryName)<br /> |
| 1234 | + if( g.zSkin ){ | |
| 1235 | + @ g.zSkin = %h(g.zSkin)<br /> | |
| 1236 | + } | |
| 1234 | 1237 | @ load_average() = %f(load_average())<br /> |
| 1235 | 1238 | @ <hr> |
| 1236 | 1239 | P("HTTP_USER_AGENT"); |
| 1237 | 1240 | cgi_print_all(showAll); |
| 1238 | 1241 | if( showAll && blob_size(&g.httpHeader)>0 ){ |
| 1239 | 1242 |
| --- 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 |