Fossil SCM

If the REPOSITORY argument to the "server" or "http" commands is a directory, then use the first element of PATH_INFO as the basename of a repository in that directory.

drh 2010-01-31 20:29 trunk
Commit 9cd2c42e79a2fee98d0ca4932ad3e094199f90d8
2 files changed +2 -1 +86 -22
+2 -1
--- src/file.c
+++ src/file.c
@@ -101,11 +101,11 @@
101101
int file_isdir(const char *zFilename){
102102
int rc;
103103
104104
if( zFilename ){
105105
char *zFN = mprintf("%s", zFilename);
106
- file_simplify_name(zFN, strlen(zFN));
106
+ file_simplify_name(zFN, -1);
107107
rc = getStat(zFN);
108108
free(zFN);
109109
}else{
110110
rc = getStat(0);
111111
}
@@ -229,10 +229,11 @@
229229
**
230230
** Changes are made in-place. Return the new name length.
231231
*/
232232
int file_simplify_name(char *z, int n){
233233
int i, j;
234
+ if( n<0 ) n = strlen(z);
234235
#ifdef __MINGW32__
235236
for(i=0; i<n; i++){
236237
if( z[i]=='\\' ) z[i] = '/';
237238
}
238239
#endif
239240
--- src/file.c
+++ src/file.c
@@ -101,11 +101,11 @@
101 int file_isdir(const char *zFilename){
102 int rc;
103
104 if( zFilename ){
105 char *zFN = mprintf("%s", zFilename);
106 file_simplify_name(zFN, strlen(zFN));
107 rc = getStat(zFN);
108 free(zFN);
109 }else{
110 rc = getStat(0);
111 }
@@ -229,10 +229,11 @@
229 **
230 ** Changes are made in-place. Return the new name length.
231 */
232 int file_simplify_name(char *z, int n){
233 int i, j;
 
234 #ifdef __MINGW32__
235 for(i=0; i<n; i++){
236 if( z[i]=='\\' ) z[i] = '/';
237 }
238 #endif
239
--- src/file.c
+++ src/file.c
@@ -101,11 +101,11 @@
101 int file_isdir(const char *zFilename){
102 int rc;
103
104 if( zFilename ){
105 char *zFN = mprintf("%s", zFilename);
106 file_simplify_name(zFN, -1);
107 rc = getStat(zFN);
108 free(zFN);
109 }else{
110 rc = getStat(0);
111 }
@@ -229,10 +229,11 @@
229 **
230 ** Changes are made in-place. Return the new name length.
231 */
232 int file_simplify_name(char *z, int n){
233 int i, j;
234 if( n<0 ) n = strlen(z);
235 #ifdef __MINGW32__
236 for(i=0; i<n; i++){
237 if( z[i]=='\\' ) z[i] = '/';
238 }
239 #endif
240
+86 -22
--- src/main.c
+++ src/main.c
@@ -453,11 +453,11 @@
453453
printf("\n");
454454
}
455455
}
456456
457457
/*
458
-** COM MAND: commands
458
+** COM -off- MAND: commands
459459
**
460460
** Usage: %fossil commands
461461
** List all supported commands.
462462
*/
463463
void cmd_cmd_list(void){
@@ -541,11 +541,11 @@
541541
putchar('\n');
542542
}
543543
544544
/*
545545
** Set the g.zBaseURL value to the full URL for the toplevel of
546
-** the fossil tree. Set g.zHomeURL to g.zBaseURL without the
546
+** the fossil tree. Set g.zTop to g.zBaseURL without the
547547
** leading "http://" and the host and port.
548548
*/
549549
void set_base_url(void){
550550
int i;
551551
const char *zHost = PD("HTTP_HOST","");
@@ -571,27 +571,63 @@
571571
}
572572
573573
/*
574574
** Preconditions:
575575
**
576
-** * Environment variables are set up according to the CGI standard.
577
-** * The respository database has been located and opened.
576
+** * Environment variables are set up according to the CGI standard.
577
+**
578
+** If the repository is known, it has already been opened. If unknown,
579
+** then g.zRepositoryName holds the directory that contains the repository
580
+** and the actual repository is taken from the first element of PATH_INFO.
578581
**
579582
** Process the webpage specified by the PATH_INFO or REQUEST_URI
580583
** environment variable.
581584
*/
582585
static void process_one_web_page(void){
583586
const char *zPathInfo;
584587
char *zPath = NULL;
585588
int idx;
586589
int i;
590
+
591
+ /* If the repository has not been opened already, then find the
592
+ ** repository based on the first element of PATH_INFO and open it.
593
+ */
594
+ zPathInfo = P("PATH_INFO");
595
+ if( !g.repositoryOpen ){
596
+ char *zRepo;
597
+ const char *zOldScript = PD("SCRIPT_NAME", "");
598
+ char *zNewScript;
599
+ int j, k;
600
+
601
+ i = 1;
602
+ while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
603
+ zRepo = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
604
+
605
+ /* To avoid mischief, make sure the repository basename contains no
606
+ ** characters other than alphanumerics, "-", and "_".
607
+ */
608
+ for(j=strlen(g.zRepositoryName)+1, k=0; k<i-1; j++, k++){
609
+ if( !isalnum(zRepo[j]) && zRepo[j]!='-' ) zRepo[j] = '_';
610
+ }
611
+
612
+ if( file_size(zRepo)<1024 ){
613
+ @ <h1>Not Found</h1>
614
+ cgi_set_status(404, "not found");
615
+ cgi_reply();
616
+ return;
617
+ }
618
+ zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
619
+ cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
620
+ zPathInfo += i;
621
+ cgi_replace_parameter("SCRIPT_NAME", zNewScript);
622
+ db_open_repository(zRepo);
623
+ }
587624
588625
/* Find the page that the user has requested, construct and deliver that
589626
** page.
590627
*/
591628
set_base_url();
592
- zPathInfo = P("PATH_INFO");
593629
if( zPathInfo==0 || zPathInfo[0]==0
594630
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
595631
fossil_redirect_home();
596632
}else{
597633
zPath = mprintf("%s", zPathInfo);
@@ -707,10 +743,39 @@
707743
cgi_panic("Unable to find or open the project repository");
708744
}
709745
cgi_init();
710746
process_one_web_page();
711747
}
748
+
749
+/*
750
+** If g.argv[2] exists then it is either the name of a repository
751
+** that will be used by a server, or else it is a directory that
752
+** contains multiple repositories that can be served. If g.argv[2]
753
+** is a directory, the repositories it contains must be named
754
+** "*.fossil". If g.argv[2] does not exists, then we must be within
755
+** a check-out and the repository to be served is the repository of
756
+** that check-out.
757
+**
758
+** Open the respository to be served if it is known. If g.argv[2] is
759
+** a directory full of repositories, then set g.zRepositoryName to
760
+** the name of that directory and the specific repository will be
761
+** opened later by process_one_web_page() based on the content of
762
+** the PATH_INFO variable.
763
+**
764
+** If disallowDir is set, then the directory full of repositories method
765
+** is disallowed.
766
+*/
767
+static void find_server_repository(int disallowDir){
768
+ if( g.argc<3 ){
769
+ db_must_be_within_tree();
770
+ }else if( !disallowDir && file_isdir(g.argv[2])==1 ){
771
+ g.zRepositoryName = mprintf("%s", g.argv[2]);
772
+ file_simplify_name(g.zRepositoryName, -1);
773
+ }else{
774
+ db_open_repository(g.argv[2]);
775
+ }
776
+}
712777
713778
/*
714779
** undocumented format:
715780
**
716781
** fossil http REPOSITORY INFILE OUTFILE IPADDR
@@ -723,10 +788,14 @@
723788
**
724789
** Handle a single HTTP request appearing on stdin. The resulting webpage
725790
** is delivered on stdout. This method is used to launch an HTTP request
726791
** handler from inetd, for example. The argument is the name of the
727792
** repository.
793
+**
794
+** If REPOSITORY is a directory that contains one or more respositories
795
+** with names of the form "*.fossil" then the first element of the URL
796
+** pathname selects among the various repositories.
728797
*/
729798
void cmd_http(void){
730799
const char *zIpAddr;
731800
if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
732801
cgi_panic("no repository specified");
@@ -759,15 +828,11 @@
759828
}else{
760829
g.httpIn = stdin;
761830
g.httpOut = stdout;
762831
zIpAddr = 0;
763832
}
764
- if( g.argc>=3 ){
765
- db_open_repository(g.argv[2]);
766
- }else{
767
- db_must_be_within_tree();
768
- }
833
+ find_server_repository(0);
769834
cgi_handle_http_request(zIpAddr);
770835
process_one_web_page();
771836
}
772837
773838
/*
@@ -817,16 +882,22 @@
817882
** The repository argument may be omitted if the working directory is
818883
** within an open checkout.
819884
**
820885
** The "ui" command automatically starts a web browser after initializing
821886
** the web server.
887
+**
888
+** In the "server" command, the REPOSITORY can be a directory (aka folder)
889
+** that contains one or more respositories with names ending in ".fossil".
890
+** In that case, the first element of the URL is used to select among the
891
+** various repositories.
822892
*/
823893
void cmd_webserver(void){
824894
int iPort, mxPort;
825895
const char *zPort;
826896
char *zBrowser;
827897
char *zBrowserCmd = 0;
898
+ int isUiCmd; /* True if command is "ui", not "server' */
828899
829900
#ifdef __MINGW32__
830901
const char *zStopperFile; /* Name of file used to terminate server */
831902
zStopperFile = find_option("stopper", 0, 1);
832903
#endif
@@ -835,24 +906,21 @@
835906
if( g.thTrace ){
836907
blob_zero(&g.thLog);
837908
}
838909
zPort = find_option("port", "P", 1);
839910
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
840
- if( g.argc==2 ){
841
- db_must_be_within_tree();
842
- }else{
843
- db_open_repository(g.argv[2]);
844
- }
911
+ isUiCmd = g.argv[1][0]=='u';
912
+ find_server_repository(isUiCmd);
845913
if( zPort ){
846914
iPort = mxPort = atoi(zPort);
847915
}else{
848916
iPort = db_get_int("http-port", 8080);
849917
mxPort = iPort+100;
850918
}
851919
#ifndef __MINGW32__
852920
/* Unix implementation */
853
- if( g.argv[1][0]=='u' ){
921
+ if( isUiCmd ){
854922
#if !defined(__DARWIN__) && !defined(__APPLE__)
855923
zBrowser = db_get("web-browser", 0);
856924
if( zBrowser==0 ){
857925
static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
858926
int i;
@@ -877,22 +945,18 @@
877945
g.httpOut = stdout;
878946
if( g.fHttpTrace || g.fSqlTrace ){
879947
fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
880948
}
881949
g.cgiPanic = 1;
882
- if( g.argc==2 ){
883
- db_must_be_within_tree();
884
- }else{
885
- db_open_repository(g.argv[2]);
886
- }
950
+ find_server_repository(isUiCmd);
887951
cgi_handle_http_request(0);
888952
process_one_web_page();
889953
#else
890954
/* Win32 implementation */
891
- if( g.argv[1][0]=='u' ){
955
+ if( isUiCmd ){
892956
zBrowser = db_get("web-browser", "start");
893957
zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
894958
}
895959
db_close();
896960
win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile);
897961
#endif
898962
}
899963
--- src/main.c
+++ src/main.c
@@ -453,11 +453,11 @@
453 printf("\n");
454 }
455 }
456
457 /*
458 ** COM MAND: commands
459 **
460 ** Usage: %fossil commands
461 ** List all supported commands.
462 */
463 void cmd_cmd_list(void){
@@ -541,11 +541,11 @@
541 putchar('\n');
542 }
543
544 /*
545 ** Set the g.zBaseURL value to the full URL for the toplevel of
546 ** the fossil tree. Set g.zHomeURL to g.zBaseURL without the
547 ** leading "http://" and the host and port.
548 */
549 void set_base_url(void){
550 int i;
551 const char *zHost = PD("HTTP_HOST","");
@@ -571,27 +571,63 @@
571 }
572
573 /*
574 ** Preconditions:
575 **
576 ** * Environment variables are set up according to the CGI standard.
577 ** * The respository database has been located and opened.
 
 
 
578 **
579 ** Process the webpage specified by the PATH_INFO or REQUEST_URI
580 ** environment variable.
581 */
582 static void process_one_web_page(void){
583 const char *zPathInfo;
584 char *zPath = NULL;
585 int idx;
586 int i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
588 /* Find the page that the user has requested, construct and deliver that
589 ** page.
590 */
591 set_base_url();
592 zPathInfo = P("PATH_INFO");
593 if( zPathInfo==0 || zPathInfo[0]==0
594 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
595 fossil_redirect_home();
596 }else{
597 zPath = mprintf("%s", zPathInfo);
@@ -707,10 +743,39 @@
707 cgi_panic("Unable to find or open the project repository");
708 }
709 cgi_init();
710 process_one_web_page();
711 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
712
713 /*
714 ** undocumented format:
715 **
716 ** fossil http REPOSITORY INFILE OUTFILE IPADDR
@@ -723,10 +788,14 @@
723 **
724 ** Handle a single HTTP request appearing on stdin. The resulting webpage
725 ** is delivered on stdout. This method is used to launch an HTTP request
726 ** handler from inetd, for example. The argument is the name of the
727 ** repository.
 
 
 
 
728 */
729 void cmd_http(void){
730 const char *zIpAddr;
731 if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
732 cgi_panic("no repository specified");
@@ -759,15 +828,11 @@
759 }else{
760 g.httpIn = stdin;
761 g.httpOut = stdout;
762 zIpAddr = 0;
763 }
764 if( g.argc>=3 ){
765 db_open_repository(g.argv[2]);
766 }else{
767 db_must_be_within_tree();
768 }
769 cgi_handle_http_request(zIpAddr);
770 process_one_web_page();
771 }
772
773 /*
@@ -817,16 +882,22 @@
817 ** The repository argument may be omitted if the working directory is
818 ** within an open checkout.
819 **
820 ** The "ui" command automatically starts a web browser after initializing
821 ** the web server.
 
 
 
 
 
822 */
823 void cmd_webserver(void){
824 int iPort, mxPort;
825 const char *zPort;
826 char *zBrowser;
827 char *zBrowserCmd = 0;
 
828
829 #ifdef __MINGW32__
830 const char *zStopperFile; /* Name of file used to terminate server */
831 zStopperFile = find_option("stopper", 0, 1);
832 #endif
@@ -835,24 +906,21 @@
835 if( g.thTrace ){
836 blob_zero(&g.thLog);
837 }
838 zPort = find_option("port", "P", 1);
839 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
840 if( g.argc==2 ){
841 db_must_be_within_tree();
842 }else{
843 db_open_repository(g.argv[2]);
844 }
845 if( zPort ){
846 iPort = mxPort = atoi(zPort);
847 }else{
848 iPort = db_get_int("http-port", 8080);
849 mxPort = iPort+100;
850 }
851 #ifndef __MINGW32__
852 /* Unix implementation */
853 if( g.argv[1][0]=='u' ){
854 #if !defined(__DARWIN__) && !defined(__APPLE__)
855 zBrowser = db_get("web-browser", 0);
856 if( zBrowser==0 ){
857 static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
858 int i;
@@ -877,22 +945,18 @@
877 g.httpOut = stdout;
878 if( g.fHttpTrace || g.fSqlTrace ){
879 fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
880 }
881 g.cgiPanic = 1;
882 if( g.argc==2 ){
883 db_must_be_within_tree();
884 }else{
885 db_open_repository(g.argv[2]);
886 }
887 cgi_handle_http_request(0);
888 process_one_web_page();
889 #else
890 /* Win32 implementation */
891 if( g.argv[1][0]=='u' ){
892 zBrowser = db_get("web-browser", "start");
893 zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
894 }
895 db_close();
896 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile);
897 #endif
898 }
899
--- src/main.c
+++ src/main.c
@@ -453,11 +453,11 @@
453 printf("\n");
454 }
455 }
456
457 /*
458 ** COM -off- MAND: commands
459 **
460 ** Usage: %fossil commands
461 ** List all supported commands.
462 */
463 void cmd_cmd_list(void){
@@ -541,11 +541,11 @@
541 putchar('\n');
542 }
543
544 /*
545 ** Set the g.zBaseURL value to the full URL for the toplevel of
546 ** the fossil tree. Set g.zTop to g.zBaseURL without the
547 ** leading "http://" and the host and port.
548 */
549 void set_base_url(void){
550 int i;
551 const char *zHost = PD("HTTP_HOST","");
@@ -571,27 +571,63 @@
571 }
572
573 /*
574 ** Preconditions:
575 **
576 ** * Environment variables are set up according to the CGI standard.
577 **
578 ** If the repository is known, it has already been opened. If unknown,
579 ** then g.zRepositoryName holds the directory that contains the repository
580 ** and the actual repository is taken from the first element of PATH_INFO.
581 **
582 ** Process the webpage specified by the PATH_INFO or REQUEST_URI
583 ** environment variable.
584 */
585 static void process_one_web_page(void){
586 const char *zPathInfo;
587 char *zPath = NULL;
588 int idx;
589 int i;
590
591 /* If the repository has not been opened already, then find the
592 ** repository based on the first element of PATH_INFO and open it.
593 */
594 zPathInfo = P("PATH_INFO");
595 if( !g.repositoryOpen ){
596 char *zRepo;
597 const char *zOldScript = PD("SCRIPT_NAME", "");
598 char *zNewScript;
599 int j, k;
600
601 i = 1;
602 while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
603 zRepo = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
604
605 /* To avoid mischief, make sure the repository basename contains no
606 ** characters other than alphanumerics, "-", and "_".
607 */
608 for(j=strlen(g.zRepositoryName)+1, k=0; k<i-1; j++, k++){
609 if( !isalnum(zRepo[j]) && zRepo[j]!='-' ) zRepo[j] = '_';
610 }
611
612 if( file_size(zRepo)<1024 ){
613 @ <h1>Not Found</h1>
614 cgi_set_status(404, "not found");
615 cgi_reply();
616 return;
617 }
618 zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
619 cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
620 zPathInfo += i;
621 cgi_replace_parameter("SCRIPT_NAME", zNewScript);
622 db_open_repository(zRepo);
623 }
624
625 /* Find the page that the user has requested, construct and deliver that
626 ** page.
627 */
628 set_base_url();
 
629 if( zPathInfo==0 || zPathInfo[0]==0
630 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
631 fossil_redirect_home();
632 }else{
633 zPath = mprintf("%s", zPathInfo);
@@ -707,10 +743,39 @@
743 cgi_panic("Unable to find or open the project repository");
744 }
745 cgi_init();
746 process_one_web_page();
747 }
748
749 /*
750 ** If g.argv[2] exists then it is either the name of a repository
751 ** that will be used by a server, or else it is a directory that
752 ** contains multiple repositories that can be served. If g.argv[2]
753 ** is a directory, the repositories it contains must be named
754 ** "*.fossil". If g.argv[2] does not exists, then we must be within
755 ** a check-out and the repository to be served is the repository of
756 ** that check-out.
757 **
758 ** Open the respository to be served if it is known. If g.argv[2] is
759 ** a directory full of repositories, then set g.zRepositoryName to
760 ** the name of that directory and the specific repository will be
761 ** opened later by process_one_web_page() based on the content of
762 ** the PATH_INFO variable.
763 **
764 ** If disallowDir is set, then the directory full of repositories method
765 ** is disallowed.
766 */
767 static void find_server_repository(int disallowDir){
768 if( g.argc<3 ){
769 db_must_be_within_tree();
770 }else if( !disallowDir && file_isdir(g.argv[2])==1 ){
771 g.zRepositoryName = mprintf("%s", g.argv[2]);
772 file_simplify_name(g.zRepositoryName, -1);
773 }else{
774 db_open_repository(g.argv[2]);
775 }
776 }
777
778 /*
779 ** undocumented format:
780 **
781 ** fossil http REPOSITORY INFILE OUTFILE IPADDR
@@ -723,10 +788,14 @@
788 **
789 ** Handle a single HTTP request appearing on stdin. The resulting webpage
790 ** is delivered on stdout. This method is used to launch an HTTP request
791 ** handler from inetd, for example. The argument is the name of the
792 ** repository.
793 **
794 ** If REPOSITORY is a directory that contains one or more respositories
795 ** with names of the form "*.fossil" then the first element of the URL
796 ** pathname selects among the various repositories.
797 */
798 void cmd_http(void){
799 const char *zIpAddr;
800 if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
801 cgi_panic("no repository specified");
@@ -759,15 +828,11 @@
828 }else{
829 g.httpIn = stdin;
830 g.httpOut = stdout;
831 zIpAddr = 0;
832 }
833 find_server_repository(0);
 
 
 
 
834 cgi_handle_http_request(zIpAddr);
835 process_one_web_page();
836 }
837
838 /*
@@ -817,16 +882,22 @@
882 ** The repository argument may be omitted if the working directory is
883 ** within an open checkout.
884 **
885 ** The "ui" command automatically starts a web browser after initializing
886 ** the web server.
887 **
888 ** In the "server" command, the REPOSITORY can be a directory (aka folder)
889 ** that contains one or more respositories with names ending in ".fossil".
890 ** In that case, the first element of the URL is used to select among the
891 ** various repositories.
892 */
893 void cmd_webserver(void){
894 int iPort, mxPort;
895 const char *zPort;
896 char *zBrowser;
897 char *zBrowserCmd = 0;
898 int isUiCmd; /* True if command is "ui", not "server' */
899
900 #ifdef __MINGW32__
901 const char *zStopperFile; /* Name of file used to terminate server */
902 zStopperFile = find_option("stopper", 0, 1);
903 #endif
@@ -835,24 +906,21 @@
906 if( g.thTrace ){
907 blob_zero(&g.thLog);
908 }
909 zPort = find_option("port", "P", 1);
910 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
911 isUiCmd = g.argv[1][0]=='u';
912 find_server_repository(isUiCmd);
 
 
 
913 if( zPort ){
914 iPort = mxPort = atoi(zPort);
915 }else{
916 iPort = db_get_int("http-port", 8080);
917 mxPort = iPort+100;
918 }
919 #ifndef __MINGW32__
920 /* Unix implementation */
921 if( isUiCmd ){
922 #if !defined(__DARWIN__) && !defined(__APPLE__)
923 zBrowser = db_get("web-browser", 0);
924 if( zBrowser==0 ){
925 static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
926 int i;
@@ -877,22 +945,18 @@
945 g.httpOut = stdout;
946 if( g.fHttpTrace || g.fSqlTrace ){
947 fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
948 }
949 g.cgiPanic = 1;
950 find_server_repository(isUiCmd);
 
 
 
 
951 cgi_handle_http_request(0);
952 process_one_web_page();
953 #else
954 /* Win32 implementation */
955 if( isUiCmd ){
956 zBrowser = db_get("web-browser", "start");
957 zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
958 }
959 db_close();
960 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile);
961 #endif
962 }
963

Keyboard Shortcuts

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