Fossil SCM
Add the "fossil all ui" and "fossil all server" commands.
Commit
98e9fd735211c57868c1f1115bb56e2675a62eac
Parent
4636b4b370dcf72…
2 files changed
+11
-1
+46
-16
+11
-1
| --- src/allrepo.c | ||
| +++ src/allrepo.c | ||
| @@ -134,10 +134,14 @@ | ||
| 134 | 134 | ** |
| 135 | 135 | ** setting Run the "setting", "set", or "unset" commands on all |
| 136 | 136 | ** set repositories. These command are particularly useful in |
| 137 | 137 | ** unset conjunction with the "max-loadavg" setting which cannot |
| 138 | 138 | ** otherwise be set globally. |
| 139 | +** | |
| 140 | +** server Run the "ui" or "server" commands on all repositories. | |
| 141 | +** ui The root URI gives a listing of all repos. | |
| 142 | +** | |
| 139 | 143 | ** |
| 140 | 144 | ** In addition, the following maintenance operations are supported: |
| 141 | 145 | ** |
| 142 | 146 | ** add Add all the repositories named to the set of repositories |
| 143 | 147 | ** tracked by Fossil. Normally Fossil is able to keep up with |
| @@ -189,10 +193,16 @@ | ||
| 189 | 193 | n = strlen(g.argv[2]); |
| 190 | 194 | db_open_config(1, 0); |
| 191 | 195 | blob_zero(&extra); |
| 192 | 196 | zCmd = g.argv[2]; |
| 193 | 197 | if( !login_is_nobody() ) blob_appendf(&extra, " -U %s", g.zLogin); |
| 198 | + if( strncmp(zCmd, "ui", n)==0 || strncmp(zCmd, "server", n)==0 ){ | |
| 199 | + g.argv[1] = g.argv[2]; | |
| 200 | + g.argv[2] = "/"; | |
| 201 | + cmd_webserver(); | |
| 202 | + return; | |
| 203 | + } | |
| 194 | 204 | if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){ |
| 195 | 205 | zCmd = "list"; |
| 196 | 206 | useCheckouts = find_option("ckout","c",0)!=0; |
| 197 | 207 | }else if( strncmp(zCmd, "clean", n)==0 ){ |
| 198 | 208 | zCmd = "clean --chdir"; |
| @@ -355,11 +365,11 @@ | ||
| 355 | 365 | showLabel = 1; |
| 356 | 366 | collect_argv(&extra, 3); |
| 357 | 367 | }else{ |
| 358 | 368 | fossil_fatal("\"all\" subcommand should be one of: " |
| 359 | 369 | "add cache changes clean dbstat extras fts-config ignore " |
| 360 | - "info list ls pull push rebuild setting sync unset"); | |
| 370 | + "info list ls pull push rebuild server setting sync ui unset"); | |
| 361 | 371 | } |
| 362 | 372 | verify_all_options(); |
| 363 | 373 | zFossil = quoteFilename(g.nameOfExe); |
| 364 | 374 | db_multi_exec("CREATE TEMP TABLE repolist(name,tag);"); |
| 365 | 375 | if( useCheckouts ){ |
| 366 | 376 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -134,10 +134,14 @@ | |
| 134 | ** |
| 135 | ** setting Run the "setting", "set", or "unset" commands on all |
| 136 | ** set repositories. These command are particularly useful in |
| 137 | ** unset conjunction with the "max-loadavg" setting which cannot |
| 138 | ** otherwise be set globally. |
| 139 | ** |
| 140 | ** In addition, the following maintenance operations are supported: |
| 141 | ** |
| 142 | ** add Add all the repositories named to the set of repositories |
| 143 | ** tracked by Fossil. Normally Fossil is able to keep up with |
| @@ -189,10 +193,16 @@ | |
| 189 | n = strlen(g.argv[2]); |
| 190 | db_open_config(1, 0); |
| 191 | blob_zero(&extra); |
| 192 | zCmd = g.argv[2]; |
| 193 | if( !login_is_nobody() ) blob_appendf(&extra, " -U %s", g.zLogin); |
| 194 | if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){ |
| 195 | zCmd = "list"; |
| 196 | useCheckouts = find_option("ckout","c",0)!=0; |
| 197 | }else if( strncmp(zCmd, "clean", n)==0 ){ |
| 198 | zCmd = "clean --chdir"; |
| @@ -355,11 +365,11 @@ | |
| 355 | showLabel = 1; |
| 356 | collect_argv(&extra, 3); |
| 357 | }else{ |
| 358 | fossil_fatal("\"all\" subcommand should be one of: " |
| 359 | "add cache changes clean dbstat extras fts-config ignore " |
| 360 | "info list ls pull push rebuild setting sync unset"); |
| 361 | } |
| 362 | verify_all_options(); |
| 363 | zFossil = quoteFilename(g.nameOfExe); |
| 364 | db_multi_exec("CREATE TEMP TABLE repolist(name,tag);"); |
| 365 | if( useCheckouts ){ |
| 366 |
| --- src/allrepo.c | |
| +++ src/allrepo.c | |
| @@ -134,10 +134,14 @@ | |
| 134 | ** |
| 135 | ** setting Run the "setting", "set", or "unset" commands on all |
| 136 | ** set repositories. These command are particularly useful in |
| 137 | ** unset conjunction with the "max-loadavg" setting which cannot |
| 138 | ** otherwise be set globally. |
| 139 | ** |
| 140 | ** server Run the "ui" or "server" commands on all repositories. |
| 141 | ** ui The root URI gives a listing of all repos. |
| 142 | ** |
| 143 | ** |
| 144 | ** In addition, the following maintenance operations are supported: |
| 145 | ** |
| 146 | ** add Add all the repositories named to the set of repositories |
| 147 | ** tracked by Fossil. Normally Fossil is able to keep up with |
| @@ -189,10 +193,16 @@ | |
| 193 | n = strlen(g.argv[2]); |
| 194 | db_open_config(1, 0); |
| 195 | blob_zero(&extra); |
| 196 | zCmd = g.argv[2]; |
| 197 | if( !login_is_nobody() ) blob_appendf(&extra, " -U %s", g.zLogin); |
| 198 | if( strncmp(zCmd, "ui", n)==0 || strncmp(zCmd, "server", n)==0 ){ |
| 199 | g.argv[1] = g.argv[2]; |
| 200 | g.argv[2] = "/"; |
| 201 | cmd_webserver(); |
| 202 | return; |
| 203 | } |
| 204 | if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){ |
| 205 | zCmd = "list"; |
| 206 | useCheckouts = find_option("ckout","c",0)!=0; |
| 207 | }else if( strncmp(zCmd, "clean", n)==0 ){ |
| 208 | zCmd = "clean --chdir"; |
| @@ -355,11 +365,11 @@ | |
| 365 | showLabel = 1; |
| 366 | collect_argv(&extra, 3); |
| 367 | }else{ |
| 368 | fossil_fatal("\"all\" subcommand should be one of: " |
| 369 | "add cache changes clean dbstat extras fts-config ignore " |
| 370 | "info list ls pull push rebuild server setting sync ui unset"); |
| 371 | } |
| 372 | verify_all_options(); |
| 373 | zFossil = quoteFilename(g.nameOfExe); |
| 374 | db_multi_exec("CREATE TEMP TABLE repolist(name,tag);"); |
| 375 | if( useCheckouts ){ |
| 376 |
+46
-16
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1182,34 +1182,54 @@ | ||
| 1182 | 1182 | } |
| 1183 | 1183 | |
| 1184 | 1184 | /* |
| 1185 | 1185 | ** Generate a web-page that lists all repositories located under the |
| 1186 | 1186 | ** g.zRepositoryName directory and return non-zero. |
| 1187 | +** | |
| 1188 | +** For the special case of g.zRepositoryName equal to "/", | |
| 1189 | +** compose the list using the "repo:" entries in the global_config | |
| 1190 | +** table of the configuration database. These entries comprise all | |
| 1191 | +** of the repositories known to the "all" command. | |
| 1187 | 1192 | ** |
| 1188 | 1193 | ** Or, if no repositories can be located beneath g.zRepositoryName, |
| 1189 | 1194 | ** return 0. |
| 1190 | 1195 | */ |
| 1191 | 1196 | static int repo_list_page(void){ |
| 1192 | 1197 | Blob base; |
| 1193 | 1198 | int n = 0; |
| 1194 | 1199 | |
| 1195 | 1200 | assert( g.db==0 ); |
| 1196 | - blob_init(&base, g.zRepositoryName, -1); | |
| 1197 | - sqlite3_open(":memory:", &g.db); | |
| 1198 | - db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); | |
| 1199 | - db_multi_exec("CREATE TABLE vfile(pathname);"); | |
| 1200 | - vfile_scan(&base, blob_size(&base), 0, 0, 0); | |
| 1201 | - db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'"); | |
| 1201 | + if( fossil_strcmp(g.zRepositoryName,"/")==0 ){ | |
| 1202 | + /* For the special case of the "repository directory" being "/", | |
| 1203 | + ** show all of the repositories named in the ~/.fossil database. | |
| 1204 | + */ | |
| 1205 | + db_open_config(1, 0); | |
| 1206 | + db_multi_exec( | |
| 1207 | + "CREATE TEMP VIEW sfile AS" | |
| 1208 | + " SELECT substr(name,7) AS 'pathname' FROM global_config" | |
| 1209 | + " WHERE name GLOB 'repo:*'" | |
| 1210 | + ); | |
| 1211 | + }else{ | |
| 1212 | + /* The default case: All repositories under the g.zRepositoryName | |
| 1213 | + ** directory. | |
| 1214 | + */ | |
| 1215 | + blob_init(&base, g.zRepositoryName, -1); | |
| 1216 | + sqlite3_open(":memory:", &g.db); | |
| 1217 | + db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); | |
| 1218 | + db_multi_exec("CREATE TABLE vfile(pathname);"); | |
| 1219 | + vfile_scan(&base, blob_size(&base), 0, 0, 0); | |
| 1220 | + db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'"); | |
| 1221 | + } | |
| 1222 | + @ <html> | |
| 1223 | + @ <head> | |
| 1224 | + @ <base href="%s(g.zBaseURL)/" /> | |
| 1225 | + @ <title>Repository List</title> | |
| 1226 | + @ </head> | |
| 1227 | + @ <body> | |
| 1202 | 1228 | n = db_int(0, "SELECT count(*) FROM sfile"); |
| 1203 | 1229 | if( n>0 ){ |
| 1204 | 1230 | Stmt q; |
| 1205 | - @ <html> | |
| 1206 | - @ <head> | |
| 1207 | - @ <base href="%s(g.zBaseURL)/" /> | |
| 1208 | - @ <title>Repository List</title> | |
| 1209 | - @ </head> | |
| 1210 | - @ <body> | |
| 1211 | 1231 | @ <h1>Available Repositories:</h1> |
| 1212 | 1232 | @ <ol> |
| 1213 | 1233 | db_prepare(&q, "SELECT pathname, substr(pathname,-7,-100000)||'/home'" |
| 1214 | 1234 | " FROM sfile ORDER BY pathname COLLATE nocase;"); |
| 1215 | 1235 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1216,14 +1236,16 @@ | ||
| 1216 | 1236 | const char *zName = db_column_text(&q, 0); |
| 1217 | 1237 | const char *zUrl = db_column_text(&q, 1); |
| 1218 | 1238 | @ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li> |
| 1219 | 1239 | } |
| 1220 | 1240 | @ </ol> |
| 1221 | - @ </body> | |
| 1222 | - @ </html> | |
| 1223 | - cgi_reply(); | |
| 1241 | + }else{ | |
| 1242 | + @ <h1>No Repositories Found</h1> | |
| 1224 | 1243 | } |
| 1244 | + @ </body> | |
| 1245 | + @ </html> | |
| 1246 | + cgi_reply(); | |
| 1225 | 1247 | sqlite3_close(g.db); |
| 1226 | 1248 | g.db = 0; |
| 1227 | 1249 | return n; |
| 1228 | 1250 | } |
| 1229 | 1251 | |
| @@ -2203,10 +2225,14 @@ | ||
| 2203 | 2225 | ** list of glob patterns given by --files and that have known suffixes |
| 2204 | 2226 | ** such as ".txt" or ".html" or ".jpeg" and do not match the pattern |
| 2205 | 2227 | ** "*.fossil*" will be served as static content. With the "ui" command, |
| 2206 | 2228 | ** the REPOSITORY can only be a directory if the --notfound option is |
| 2207 | 2229 | ** also present. |
| 2230 | +** | |
| 2231 | +** For the special case REPOSITORY name of "/", the list global configuration | |
| 2232 | +** database is consulted for a list of all known repositories. The --repolist | |
| 2233 | +** option is implied by this special case. | |
| 2208 | 2234 | ** |
| 2209 | 2235 | ** By default, the "ui" command provides full administrative access without |
| 2210 | 2236 | ** having to log in. This can be disabled by turning off the "localauth" |
| 2211 | 2237 | ** setting. Automatic login for the "server" command is available if the |
| 2212 | 2238 | ** --localauth option is present and the "localauth" setting is off and the |
| @@ -2377,11 +2403,15 @@ | ||
| 2377 | 2403 | if( g.fHttpTrace || g.fSqlTrace ){ |
| 2378 | 2404 | fprintf(stderr, "====== SERVER pid %d =======\n", getpid()); |
| 2379 | 2405 | } |
| 2380 | 2406 | g.cgiOutput = 1; |
| 2381 | 2407 | find_server_repository(2, 0); |
| 2382 | - g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail); | |
| 2408 | + if( fossil_strcmp(g.zRepositoryName,"/")==0 ){ | |
| 2409 | + allowRepoList = 1; | |
| 2410 | + }else{ | |
| 2411 | + g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail); | |
| 2412 | + } | |
| 2383 | 2413 | if( flags & HTTP_SERVER_SCGI ){ |
| 2384 | 2414 | cgi_handle_scgi_request(); |
| 2385 | 2415 | }else{ |
| 2386 | 2416 | cgi_handle_http_request(0); |
| 2387 | 2417 | } |
| 2388 | 2418 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1182,34 +1182,54 @@ | |
| 1182 | } |
| 1183 | |
| 1184 | /* |
| 1185 | ** Generate a web-page that lists all repositories located under the |
| 1186 | ** g.zRepositoryName directory and return non-zero. |
| 1187 | ** |
| 1188 | ** Or, if no repositories can be located beneath g.zRepositoryName, |
| 1189 | ** return 0. |
| 1190 | */ |
| 1191 | static int repo_list_page(void){ |
| 1192 | Blob base; |
| 1193 | int n = 0; |
| 1194 | |
| 1195 | assert( g.db==0 ); |
| 1196 | blob_init(&base, g.zRepositoryName, -1); |
| 1197 | sqlite3_open(":memory:", &g.db); |
| 1198 | db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); |
| 1199 | db_multi_exec("CREATE TABLE vfile(pathname);"); |
| 1200 | vfile_scan(&base, blob_size(&base), 0, 0, 0); |
| 1201 | db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'"); |
| 1202 | n = db_int(0, "SELECT count(*) FROM sfile"); |
| 1203 | if( n>0 ){ |
| 1204 | Stmt q; |
| 1205 | @ <html> |
| 1206 | @ <head> |
| 1207 | @ <base href="%s(g.zBaseURL)/" /> |
| 1208 | @ <title>Repository List</title> |
| 1209 | @ </head> |
| 1210 | @ <body> |
| 1211 | @ <h1>Available Repositories:</h1> |
| 1212 | @ <ol> |
| 1213 | db_prepare(&q, "SELECT pathname, substr(pathname,-7,-100000)||'/home'" |
| 1214 | " FROM sfile ORDER BY pathname COLLATE nocase;"); |
| 1215 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1216,14 +1236,16 @@ | |
| 1216 | const char *zName = db_column_text(&q, 0); |
| 1217 | const char *zUrl = db_column_text(&q, 1); |
| 1218 | @ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li> |
| 1219 | } |
| 1220 | @ </ol> |
| 1221 | @ </body> |
| 1222 | @ </html> |
| 1223 | cgi_reply(); |
| 1224 | } |
| 1225 | sqlite3_close(g.db); |
| 1226 | g.db = 0; |
| 1227 | return n; |
| 1228 | } |
| 1229 | |
| @@ -2203,10 +2225,14 @@ | |
| 2203 | ** list of glob patterns given by --files and that have known suffixes |
| 2204 | ** such as ".txt" or ".html" or ".jpeg" and do not match the pattern |
| 2205 | ** "*.fossil*" will be served as static content. With the "ui" command, |
| 2206 | ** the REPOSITORY can only be a directory if the --notfound option is |
| 2207 | ** also present. |
| 2208 | ** |
| 2209 | ** By default, the "ui" command provides full administrative access without |
| 2210 | ** having to log in. This can be disabled by turning off the "localauth" |
| 2211 | ** setting. Automatic login for the "server" command is available if the |
| 2212 | ** --localauth option is present and the "localauth" setting is off and the |
| @@ -2377,11 +2403,15 @@ | |
| 2377 | if( g.fHttpTrace || g.fSqlTrace ){ |
| 2378 | fprintf(stderr, "====== SERVER pid %d =======\n", getpid()); |
| 2379 | } |
| 2380 | g.cgiOutput = 1; |
| 2381 | find_server_repository(2, 0); |
| 2382 | g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail); |
| 2383 | if( flags & HTTP_SERVER_SCGI ){ |
| 2384 | cgi_handle_scgi_request(); |
| 2385 | }else{ |
| 2386 | cgi_handle_http_request(0); |
| 2387 | } |
| 2388 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1182,34 +1182,54 @@ | |
| 1182 | } |
| 1183 | |
| 1184 | /* |
| 1185 | ** Generate a web-page that lists all repositories located under the |
| 1186 | ** g.zRepositoryName directory and return non-zero. |
| 1187 | ** |
| 1188 | ** For the special case of g.zRepositoryName equal to "/", |
| 1189 | ** compose the list using the "repo:" entries in the global_config |
| 1190 | ** table of the configuration database. These entries comprise all |
| 1191 | ** of the repositories known to the "all" command. |
| 1192 | ** |
| 1193 | ** Or, if no repositories can be located beneath g.zRepositoryName, |
| 1194 | ** return 0. |
| 1195 | */ |
| 1196 | static int repo_list_page(void){ |
| 1197 | Blob base; |
| 1198 | int n = 0; |
| 1199 | |
| 1200 | assert( g.db==0 ); |
| 1201 | if( fossil_strcmp(g.zRepositoryName,"/")==0 ){ |
| 1202 | /* For the special case of the "repository directory" being "/", |
| 1203 | ** show all of the repositories named in the ~/.fossil database. |
| 1204 | */ |
| 1205 | db_open_config(1, 0); |
| 1206 | db_multi_exec( |
| 1207 | "CREATE TEMP VIEW sfile AS" |
| 1208 | " SELECT substr(name,7) AS 'pathname' FROM global_config" |
| 1209 | " WHERE name GLOB 'repo:*'" |
| 1210 | ); |
| 1211 | }else{ |
| 1212 | /* The default case: All repositories under the g.zRepositoryName |
| 1213 | ** directory. |
| 1214 | */ |
| 1215 | blob_init(&base, g.zRepositoryName, -1); |
| 1216 | sqlite3_open(":memory:", &g.db); |
| 1217 | db_multi_exec("CREATE TABLE sfile(pathname TEXT);"); |
| 1218 | db_multi_exec("CREATE TABLE vfile(pathname);"); |
| 1219 | vfile_scan(&base, blob_size(&base), 0, 0, 0); |
| 1220 | db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'"); |
| 1221 | } |
| 1222 | @ <html> |
| 1223 | @ <head> |
| 1224 | @ <base href="%s(g.zBaseURL)/" /> |
| 1225 | @ <title>Repository List</title> |
| 1226 | @ </head> |
| 1227 | @ <body> |
| 1228 | n = db_int(0, "SELECT count(*) FROM sfile"); |
| 1229 | if( n>0 ){ |
| 1230 | Stmt q; |
| 1231 | @ <h1>Available Repositories:</h1> |
| 1232 | @ <ol> |
| 1233 | db_prepare(&q, "SELECT pathname, substr(pathname,-7,-100000)||'/home'" |
| 1234 | " FROM sfile ORDER BY pathname COLLATE nocase;"); |
| 1235 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1216,14 +1236,16 @@ | |
| 1236 | const char *zName = db_column_text(&q, 0); |
| 1237 | const char *zUrl = db_column_text(&q, 1); |
| 1238 | @ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li> |
| 1239 | } |
| 1240 | @ </ol> |
| 1241 | }else{ |
| 1242 | @ <h1>No Repositories Found</h1> |
| 1243 | } |
| 1244 | @ </body> |
| 1245 | @ </html> |
| 1246 | cgi_reply(); |
| 1247 | sqlite3_close(g.db); |
| 1248 | g.db = 0; |
| 1249 | return n; |
| 1250 | } |
| 1251 | |
| @@ -2203,10 +2225,14 @@ | |
| 2225 | ** list of glob patterns given by --files and that have known suffixes |
| 2226 | ** such as ".txt" or ".html" or ".jpeg" and do not match the pattern |
| 2227 | ** "*.fossil*" will be served as static content. With the "ui" command, |
| 2228 | ** the REPOSITORY can only be a directory if the --notfound option is |
| 2229 | ** also present. |
| 2230 | ** |
| 2231 | ** For the special case REPOSITORY name of "/", the list global configuration |
| 2232 | ** database is consulted for a list of all known repositories. The --repolist |
| 2233 | ** option is implied by this special case. |
| 2234 | ** |
| 2235 | ** By default, the "ui" command provides full administrative access without |
| 2236 | ** having to log in. This can be disabled by turning off the "localauth" |
| 2237 | ** setting. Automatic login for the "server" command is available if the |
| 2238 | ** --localauth option is present and the "localauth" setting is off and the |
| @@ -2377,11 +2403,15 @@ | |
| 2403 | if( g.fHttpTrace || g.fSqlTrace ){ |
| 2404 | fprintf(stderr, "====== SERVER pid %d =======\n", getpid()); |
| 2405 | } |
| 2406 | g.cgiOutput = 1; |
| 2407 | find_server_repository(2, 0); |
| 2408 | if( fossil_strcmp(g.zRepositoryName,"/")==0 ){ |
| 2409 | allowRepoList = 1; |
| 2410 | }else{ |
| 2411 | g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail); |
| 2412 | } |
| 2413 | if( flags & HTTP_SERVER_SCGI ){ |
| 2414 | cgi_handle_scgi_request(); |
| 2415 | }else{ |
| 2416 | cgi_handle_http_request(0); |
| 2417 | } |
| 2418 |