| ︙ | | | ︙ | |
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# include "tcl.h"
#endif
#ifdef FOSSIL_ENABLE_JSON
# include "cson_amalgamation.h" /* JSON API. */
# include "json_detail.h"
#endif
/*
** Size of a UUID in characters. A UUID is a randomly generated
** lower-case hexadecimal number used to identify tickets.
**
** In Fossil 1.x, UUID also referred to a SHA1 artifact hash. But that
** usage is now obsolete. The term UUID should now mean only a very large
** random number used as a unique identifier for tickets or other objects.
*/
#define UUID_SIZE 40
/*
** Maximum number of auxiliary parameters on reports
*/
#define MX_AUX 5
/*
** Holds flags for fossil user permissions.
|
<
<
<
<
<
<
<
<
<
<
|
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# include "tcl.h"
#endif
#ifdef FOSSIL_ENABLE_JSON
# include "cson_amalgamation.h" /* JSON API. */
# include "json_detail.h"
#endif
/*
** Maximum number of auxiliary parameters on reports
*/
#define MX_AUX 5
/*
** Holds flags for fossil user permissions.
|
| ︙ | | | ︙ | |
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
char ModTkt; /* q: approve and publish ticket changes (Moderator) */
char Attach; /* b: add attachments */
char TktFmt; /* t: create new ticket report formats */
char RdAddr; /* e: read email addresses or other private data */
char Zip; /* z: download zipped artifact via /zip URL */
char Private; /* x: can send and receive private content */
char WrUnver; /* y: can push unversioned content */
};
#ifdef FOSSIL_ENABLE_TCL
/*
** All Tcl related context information is in this structure. This structure
** definition has been copied from and should be kept in sync with the one in
** "th_tcl.c".
|
>
>
>
>
>
>
>
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
char ModTkt; /* q: approve and publish ticket changes (Moderator) */
char Attach; /* b: add attachments */
char TktFmt; /* t: create new ticket report formats */
char RdAddr; /* e: read email addresses or other private data */
char Zip; /* z: download zipped artifact via /zip URL */
char Private; /* x: can send and receive private content */
char WrUnver; /* y: can push unversioned content */
char RdForum; /* 2: Read forum posts */
char WrForum; /* 3: Create new forum posts */
char WrTForum; /* 4: Post to forums not subject to moderation */
char ModForum; /* 5: Moderate (approve or reject) forum posts */
char AdminForum; /* 6: Edit forum posts by other users */
char EmailAlert; /* 7: Sign up for email notifications */
char Announce; /* A: Send announcements */
};
#ifdef FOSSIL_ENABLE_TCL
/*
** All Tcl related context information is in this structure. This structure
** definition has been copied from and should be kept in sync with the one in
** "th_tcl.c".
|
| ︙ | | | ︙ | |
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
sqlite3 *db; /* The connection to the databases */
sqlite3 *dbConfig; /* Separate connection for global_config table */
char *zAuxSchema; /* Main repository aux-schema */
int dbIgnoreErrors; /* Ignore database errors if true */
const char *zConfigDbName;/* Path of the config database. NULL if not open */
sqlite3_int64 now; /* Seconds since 1970 */
int repositoryOpen; /* True if the main repository database is open */
char *zRepositoryOption; /* Most recent cached repository option value */
char *zRepositoryName; /* Name of the repository database file */
char *zLocalDbName; /* Name of the local database file */
char *zOpenRevision; /* Check-in version to use during database open */
int localOpen; /* True if the local database is open */
char *zLocalRoot; /* The directory holding the local database */
int minPrefix; /* Number of digits needed for a distinct UUID */
int eHashPolicy; /* Current hash policy. One of HPOLICY_* */
int fSqlTrace; /* True if --sqltrace flag is present */
int fSqlStats; /* True if --sqltrace or --sqlstats are present */
int fSqlPrint; /* True if -sqlprint flag is present */
int fQuiet; /* True if -quiet flag is present */
int fJail; /* True if running with a chroot jail */
int fHttpTrace; /* Trace outbound HTTP requests */
int fAnyTrace; /* Any kind of tracing */
char *zHttpAuth; /* HTTP Authorization user:pass information */
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
int fSshTrace; /* Trace the SSH setup traffic */
int fSshClient; /* HTTP client flags for SSH client */
char *zSshCmd; /* SSH command string */
int fNoSync; /* Do not do an autosync ever. --nosync */
int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
char *zPath; /* Name of webpage being served */
char *zExtra; /* Extra path information past the webpage name */
char *zBaseURL; /* Full text of the URL being served */
char *zHttpsURL; /* zBaseURL translated to https: */
char *zTop; /* Parent directory of zPath */
const char *zContentType; /* The content type of the input HTTP request */
int iErrPriority; /* Priority of current error message */
char *zErrMsg; /* Text of an error message */
int sslNotAvailable; /* SSL is not available. Do not redirect to https: */
Blob cgiIn; /* Input to an xfer www method */
int cgiOutput; /* Write error and status messages to CGI */
int xferPanic; /* Write error messages in XFER protocol */
int fullHttpReply; /* True for full HTTP reply. False for CGI reply */
Th_Interp *interp; /* The TH1 interpreter */
char *th1Setup; /* The TH1 post-creation setup script, if any */
int th1Flags; /* The TH1 integration state flags */
FILE *httpIn; /* Accept HTTP input from here */
FILE *httpOut; /* Send HTTP output here */
|
>
|
>
>
|
|
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
sqlite3 *db; /* The connection to the databases */
sqlite3 *dbConfig; /* Separate connection for global_config table */
char *zAuxSchema; /* Main repository aux-schema */
int dbIgnoreErrors; /* Ignore database errors if true */
const char *zConfigDbName;/* Path of the config database. NULL if not open */
sqlite3_int64 now; /* Seconds since 1970 */
int repositoryOpen; /* True if the main repository database is open */
unsigned iRepoDataVers; /* Initial data version for repository database */
char *zRepositoryOption; /* Most recent cached repository option value */
char *zRepositoryName; /* Name of the repository database file */
char *zLocalDbName; /* Name of the local database file */
char *zOpenRevision; /* Check-in version to use during database open */
int localOpen; /* True if the local database is open */
char *zLocalRoot; /* The directory holding the local database */
int minPrefix; /* Number of digits needed for a distinct UUID */
int eHashPolicy; /* Current hash policy. One of HPOLICY_* */
int fSqlTrace; /* True if --sqltrace flag is present */
int fSqlStats; /* True if --sqltrace or --sqlstats are present */
int fSqlPrint; /* True if --sqlprint flag is present */
int fCgiTrace; /* True if --cgitrace is enabled */
int fQuiet; /* True if -quiet flag is present */
int fJail; /* True if running with a chroot jail */
int fHttpTrace; /* Trace outbound HTTP requests */
int fAnyTrace; /* Any kind of tracing */
char *zHttpAuth; /* HTTP Authorization user:pass information */
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
int fSshTrace; /* Trace the SSH setup traffic */
int fSshClient; /* HTTP client flags for SSH client */
int fNoHttpCompress; /* Do not compress HTTP traffic (for debugging) */
char *zSshCmd; /* SSH command string */
int fNoSync; /* Do not do an autosync ever. --nosync */
int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
char *zPath; /* Name of webpage being served */
char *zExtra; /* Extra path information past the webpage name */
char *zBaseURL; /* Full text of the URL being served */
char *zHttpsURL; /* zBaseURL translated to https: */
char *zTop; /* Parent directory of zPath */
const char *zContentType; /* The content type of the input HTTP request */
int iErrPriority; /* Priority of current error message */
char *zErrMsg; /* Text of an error message */
int sslNotAvailable; /* SSL is not available. Do not redirect to https: */
Blob cgiIn; /* Input to an xfer www method */
int cgiOutput; /* 0: command-line 1: CGI. 2: CGI after an error */
int xferPanic; /* Write error messages in XFER protocol */
int fullHttpReply; /* True for full HTTP reply. False for CGI reply */
Th_Interp *interp; /* The TH1 interpreter */
char *th1Setup; /* The TH1 post-creation setup script, if any */
int th1Flags; /* The TH1 integration state flags */
FILE *httpIn; /* Accept HTTP input from here */
FILE *httpOut; /* Send HTTP output here */
|
| ︙ | | | ︙ | |
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
char *azAuxParam[MX_AUX]; /* Param of each aux() or option() value */
const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */
const char **azAuxOpt[MX_AUX]; /* Options of each option() value */
int anAuxCols[MX_AUX]; /* Number of columns for option() values */
int allowSymlinks; /* Cached "allow-symlinks" option */
int mainTimerId; /* Set to fossil_timer_start() */
int nPendingRequest; /* # of HTTP requests in "fossil server" */
#ifdef FOSSIL_ENABLE_JSON
struct FossilJsonBits {
int isJsonMode; /* True if running in JSON mode, else
false. This changes how errors are
reported. In JSON mode we try to
always output JSON-form error
responses and always exit() with
|
>
|
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
char *azAuxParam[MX_AUX]; /* Param of each aux() or option() value */
const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */
const char **azAuxOpt[MX_AUX]; /* Options of each option() value */
int anAuxCols[MX_AUX]; /* Number of columns for option() values */
int allowSymlinks; /* Cached "allow-symlinks" option */
int mainTimerId; /* Set to fossil_timer_start() */
int nPendingRequest; /* # of HTTP requests in "fossil server" */
int nRequest; /* Total # of HTTP request */
#ifdef FOSSIL_ENABLE_JSON
struct FossilJsonBits {
int isJsonMode; /* True if running in JSON mode, else
false. This changes how errors are
reported. In JSON mode we try to
always output JSON-form error
responses and always exit() with
|
| ︙ | | | ︙ | |
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
|
}
}
return zCode;
}
/* Error logs from SQLite */
static void fossil_sqlite_log(void *notUsed, int iCode, const char *zErrmsg){
#ifdef __APPLE__
/* Disable the file alias warning on apple products because Time Machine
** creates lots of aliases and the warning alarms people. */
if( iCode==SQLITE_WARNING ) return;
#endif
if( iCode==SQLITE_SCHEMA ) return;
if( g.dbIgnoreErrors ) return;
#ifdef SQLITE_READONLY_DIRECTORY
if( iCode==SQLITE_READONLY_DIRECTORY ){
zErrmsg = "database is in a read-only directory";
}
#endif
fossil_warning("%s: %s", fossil_sqlite_return_code_name(iCode), zErrmsg);
}
/*
** This function attempts to find command line options known to contain
** bitwise flags and initializes the associated global variables. After
** this function executes, all global variables (i.e. in the "g" struct)
** containing option-settable bitwise flag fields must be initialized.
*/
static void fossil_init_flags_from_options(void){
const char *zValue = find_option("comfmtflags", 0, 1);
if( zValue ){
g.comFmtFlags = atoi(zValue);
}else{
g.comFmtFlags = COMMENT_PRINT_DEFAULT;
}
}
/*
** This procedure runs first.
*/
#if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE)
int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
int wmain(int argc, wchar_t **argv)
#else
#if defined(_WIN32)
int _CRT_glob = 0x0001; /* See MinGW bug #2062 */
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
const CmdOrPage *pCmd = 0;
int rc;
fossil_limit_memory(1);
if( sqlite3_libversion_number()<3014000 ){
fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0",
sqlite3_libversion());
}
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
g.httpHeader = empty_blob;
|
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
|
}
}
return zCode;
}
/* Error logs from SQLite */
static void fossil_sqlite_log(void *notUsed, int iCode, const char *zErrmsg){
sqlite3_stmt *p;
Blob msg;
#ifdef __APPLE__
/* Disable the file alias warning on apple products because Time Machine
** creates lots of aliases and the warnings alarm people. */
if( iCode==SQLITE_WARNING ) return;
#endif
#ifndef FOSSIL_DEBUG
/* Disable the automatic index warning except in FOSSIL_DEBUG builds. */
if( iCode==SQLITE_WARNING_AUTOINDEX ) return;
#endif
if( iCode==SQLITE_SCHEMA ) return;
if( g.dbIgnoreErrors ) return;
#ifdef SQLITE_READONLY_DIRECTORY
if( iCode==SQLITE_READONLY_DIRECTORY ){
zErrmsg = "database is in a read-only directory";
}
#endif
blob_init(&msg, 0, 0);
blob_appendf(&msg, "%s(%d): %s",
fossil_sqlite_return_code_name(iCode), iCode, zErrmsg);
if( g.db ){
for(p=sqlite3_next_stmt(g.db, 0); p; p=sqlite3_next_stmt(g.db,p)){
const char *zSql;
if( !sqlite3_stmt_busy(p) ) continue;
zSql = sqlite3_sql(p);
if( zSql==0 ) continue;
blob_appendf(&msg, "\nSQL: %s", zSql);
}
}
fossil_warning("%s", blob_str(&msg));
blob_reset(&msg);
}
/*
** This function attempts to find command line options known to contain
** bitwise flags and initializes the associated global variables. After
** this function executes, all global variables (i.e. in the "g" struct)
** containing option-settable bitwise flag fields must be initialized.
*/
static void fossil_init_flags_from_options(void){
const char *zValue = find_option("comfmtflags", 0, 1);
if( zValue ){
g.comFmtFlags = atoi(zValue);
}else{
g.comFmtFlags = COMMENT_PRINT_DEFAULT;
}
}
/*
** Check to see if the Fossil binary contains an appended repository
** file using the appendvfs extension. If so, change command-line arguments
** to cause Fossil to launch with "fossil ui" on that repo.
*/
static int fossilExeHasAppendedRepo(void){
extern int deduceDatabaseType(const char*,int);
if( 2==deduceDatabaseType(g.nameOfExe,0) ){
static char *azAltArgv[] = { 0, "ui", 0, 0 };
azAltArgv[0] = g.nameOfExe;
azAltArgv[2] = g.nameOfExe;
g.argv = azAltArgv;
g.argc = 3;
return 1;
}else{
return 0;
}
}
/*
** This procedure runs first.
*/
#if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE)
int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
int wmain(int argc, wchar_t **argv)
#else
#if defined(_WIN32)
int _CRT_glob = 0x0001; /* See MinGW bug #2062 */
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
const CmdOrPage *pCmd = 0;
int rc;
fossil_limit_memory(1);
if( sqlite3_libversion_number()<3014000 ){
fossil_panic("Unsuitable SQLite version %s, must be at least 3.14.0",
sqlite3_libversion());
}
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
g.httpHeader = empty_blob;
|
| ︙ | | | ︙ | |
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
|
g.zVfsName = fossil_getenv("FOSSIL_VFS");
}
if( g.zVfsName ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName);
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
fossil_fatal("no such VFS: \"%s\"", g.zVfsName);
}
}
if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
zCmdName = "cgi";
g.isHTTP = 1;
}else if( g.argc<2 ){
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMAND -- for help with the named command\n",
g.argv[0], g.argv[0], g.argv[0]);
fossil_print(
"\nCommands and filenames may be passed on to fossil from a file\n"
|
|
|
|
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
|
g.zVfsName = fossil_getenv("FOSSIL_VFS");
}
if( g.zVfsName ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName);
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
fossil_panic("no such VFS: \"%s\"", g.zVfsName);
}
}
if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
zCmdName = "cgi";
g.isHTTP = 1;
}else if( g.argc<2 && !fossilExeHasAppendedRepo() ){
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMAND -- for help with the named command\n",
g.argv[0], g.argv[0], g.argv[0]);
fossil_print(
"\nCommands and filenames may be passed on to fossil from a file\n"
|
| ︙ | | | ︙ | |
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
|
g.isHTTP = 0;
g.rcvid = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fSshClient = 0;
g.zSshCmd = 0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
#ifdef FOSSIL_ENABLE_TH1_HOOKS
g.fNoThHook = find_option("no-th-hook", 0, 0)!=0;
#endif
g.fAnyTrace = g.fSqlTrace|g.fSystemTrace|g.fSshTrace|g.fHttpTrace;
g.zHttpAuth = 0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
g.zErrlog = find_option("errorlog", 0, 1);
fossil_init_flags_from_options();
if( find_option("utc",0,0) ) g.fTimeFormat = 1;
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
if( zChdir && file_chdir(zChdir, 0) ){
fossil_fatal("unable to change directories to %s", zChdir);
}
if( find_option("help",0,0)!=0 ){
/* If --help is found anywhere on the command line, translate the command
* to "fossil help cmdname" where "cmdname" is the first argument that
* does not begin with a "-" character. If all arguments start with "-",
* translate to "fossil help argv[1] argv[2]...". */
int i, nNewArgc;
|
>
|
>
|
|
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
|
g.isHTTP = 0;
g.rcvid = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fCgiTrace = find_option("cgitrace", 0, 0)!=0;
g.fSshClient = 0;
g.zSshCmd = 0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
#ifdef FOSSIL_ENABLE_TH1_HOOKS
g.fNoThHook = find_option("no-th-hook", 0, 0)!=0;
#endif
g.fAnyTrace = g.fSqlTrace|g.fSystemTrace|g.fSshTrace|
g.fHttpTrace|g.fCgiTrace;
g.zHttpAuth = 0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
g.zErrlog = find_option("errorlog", 0, 1);
fossil_init_flags_from_options();
if( find_option("utc",0,0) ) g.fTimeFormat = 1;
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
if( zChdir && file_chdir(zChdir, 0) ){
fossil_panic("unable to change directories to %s", zChdir);
}
if( find_option("help",0,0)!=0 ){
/* If --help is found anywhere on the command line, translate the command
* to "fossil help cmdname" where "cmdname" is the first argument that
* does not begin with a "-" character. If all arguments start with "-",
* translate to "fossil help argv[1] argv[2]...". */
int i, nNewArgc;
|
| ︙ | | | ︙ | |
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
|
if( fd>=2 ) break;
if( fd<0 ) x = errno;
}while( nTry++ < 2 );
if( fd<2 ){
g.cgiOutput = 1;
g.httpOut = stdout;
g.fullHttpReply = !g.isHTTP;
fossil_fatal("file descriptor 2 is not open. (fd=%d, errno=%d)",
fd, x);
}
}
#endif
rc = dispatch_name_search(zCmdName, CMDFLAG_COMMAND|CMDFLAG_PREFIX, &pCmd);
if( rc==1 ){
#ifdef FOSSIL_ENABLE_TH1_HOOKS
if( !g.isHTTP && !g.fNoThHook ){
rc = Th_CommandHook(zCmdName, 0);
}else{
rc = TH_OK;
}
if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
if( rc==TH_OK || rc==TH_RETURN ){
#endif
fossil_fatal("%s: unknown command: %s\n"
"%s: use \"help\" for more information",
g.argv[0], zCmdName, g.argv[0]);
#ifdef FOSSIL_ENABLE_TH1_HOOKS
}
if( !g.isHTTP && !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
Th_CommandNotify(zCmdName, 0);
}
|
|
|
|
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
|
if( fd>=2 ) break;
if( fd<0 ) x = errno;
}while( nTry++ < 2 );
if( fd<2 ){
g.cgiOutput = 1;
g.httpOut = stdout;
g.fullHttpReply = !g.isHTTP;
fossil_panic("file descriptor 2 is not open. (fd=%d, errno=%d)",
fd, x);
}
}
#endif
rc = dispatch_name_search(zCmdName, CMDFLAG_COMMAND|CMDFLAG_PREFIX, &pCmd);
if( rc==1 ){
#ifdef FOSSIL_ENABLE_TH1_HOOKS
if( !g.isHTTP && !g.fNoThHook ){
rc = Th_CommandHook(zCmdName, 0);
}else{
rc = TH_OK;
}
if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
if( rc==TH_OK || rc==TH_RETURN ){
#endif
fossil_panic("%s: unknown command: %s\n"
"%s: use \"help\" for more information",
g.argv[0], zCmdName, g.argv[0]);
#ifdef FOSSIL_ENABLE_TH1_HOOKS
}
if( !g.isHTTP && !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
Th_CommandNotify(zCmdName, 0);
}
|
| ︙ | | | ︙ | |
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
|
return 0;
}
/*
** Print a usage comment and quit
*/
void usage(const char *zFormat){
fossil_fatal("Usage: %s %s %s", g.argv[0], g.argv[1], zFormat);
}
/*
** Remove n elements from g.argv beginning with the i-th element.
*/
static void remove_from_argv(int i, int n){
int j;
|
|
|
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
|
return 0;
}
/*
** Print a usage comment and quit
*/
void usage(const char *zFormat){
fossil_panic("Usage: %s %s %s", g.argv[0], g.argv[1], zFormat);
}
/*
** Remove n elements from g.argv beginning with the i-th element.
*/
static void remove_from_argv(int i, int n){
int j;
|
| ︙ | | | ︙ | |
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
|
** Any remaining command-line argument begins with "-" print
** an error message and quit.
*/
void verify_all_options(void){
int i;
for(i=1; i<g.argc; i++){
if( g.argv[i][0]=='-' && g.argv[i][1]!=0 ){
fossil_fatal(
"unrecognized command-line option, or missing argument: %s",
g.argv[i]);
}
}
}
/*
|
|
|
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
|
** Any remaining command-line argument begins with "-" print
** an error message and quit.
*/
void verify_all_options(void){
int i;
for(i=1; i<g.argc; i++){
if( g.argv[i][0]=='-' && g.argv[i][1]!=0 ){
fossil_panic(
"unrecognized command-line option, or missing argument: %s",
g.argv[i]);
}
}
}
/*
|
| ︙ | | | ︙ | |
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
|
int bVerbose /* Non-zero for full information. */
){
#if defined(FOSSIL_ENABLE_TCL)
int rc;
const char *zRc;
#endif
Stmt q;
blob_zero(pOut);
blob_appendf(pOut, "This is fossil version %s\n", get_version());
if( !bVerbose ) return;
blob_appendf(pOut, "Compiled on %s %s using %s (%d-bit)\n",
__DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
blob_appendf(pOut, "Schema version %s\n", AUX_SCHEMA_MAX);
#if defined(FOSSIL_ENABLE_MINIZ)
blob_appendf(pOut, "miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
blob_appendf(pOut, "zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if FOSSIL_HARDENED_SHA1
blob_appendf(pOut, "hardened-SHA1 by Marc Stevens and Dan Shumow\n");
|
>
>
>
>
|
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
|
int bVerbose /* Non-zero for full information. */
){
#if defined(FOSSIL_ENABLE_TCL)
int rc;
const char *zRc;
#endif
Stmt q;
size_t pageSize = 0;
blob_zero(pOut);
blob_appendf(pOut, "This is fossil version %s\n", get_version());
if( !bVerbose ) return;
blob_appendf(pOut, "Compiled on %s %s using %s (%d-bit)\n",
__DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
blob_appendf(pOut, "Schema version %s\n", AUX_SCHEMA_MAX);
fossil_get_page_size(&pageSize);
blob_appendf(pOut, "Detected memory page size is %lu bytes\n",
(unsigned long)pageSize);
#if defined(FOSSIL_ENABLE_MINIZ)
blob_appendf(pOut, "miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
blob_appendf(pOut, "zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if FOSSIL_HARDENED_SHA1
blob_appendf(pOut, "hardened-SHA1 by Marc Stevens and Dan Shumow\n");
|
| ︙ | | | ︙ | |
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
|
blob_append(pOut, "UNICODE_COMMAND_LINE\n", -1);
#endif
#if defined(FOSSIL_DYNAMIC_BUILD)
blob_append(pOut, "FOSSIL_DYNAMIC_BUILD\n", -1);
#else
blob_append(pOut, "FOSSIL_STATIC_BUILD\n", -1);
#endif
#if defined(USE_SEE)
blob_append(pOut, "USE_SEE\n", -1);
#endif
#if defined(FOSSIL_ALLOW_OUT_OF_ORDER_DATES)
blob_append(pOut, "FOSSIL_ALLOW_OUT_OF_ORDER_DATES\n");
#endif
blob_appendf(pOut, "SQLite %s %.30s\n", sqlite3_libversion(),
|
>
>
>
>
>
>
|
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
|
blob_append(pOut, "UNICODE_COMMAND_LINE\n", -1);
#endif
#if defined(FOSSIL_DYNAMIC_BUILD)
blob_append(pOut, "FOSSIL_DYNAMIC_BUILD\n", -1);
#else
blob_append(pOut, "FOSSIL_STATIC_BUILD\n", -1);
#endif
#if defined(HAVE_PLEDGE)
blob_append(pOut, "HAVE_PLEDGE\n", -1);
#endif
#if defined(USE_MMAN_H)
blob_append(pOut, "USE_MMAN_H\n", -1);
#endif
#if defined(USE_SEE)
blob_append(pOut, "USE_SEE\n", -1);
#endif
#if defined(FOSSIL_ALLOW_OUT_OF_ORDER_DATES)
blob_append(pOut, "FOSSIL_ALLOW_OUT_OF_ORDER_DATES\n");
#endif
blob_appendf(pOut, "SQLite %s %.30s\n", sqlite3_libversion(),
|
| ︙ | | | ︙ | |
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
|
if( strncmp(g.zTop, "http://", 7)==0 ){
/* it is HTTP, replace prefix with HTTPS. */
g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
}else if( strncmp(g.zTop, "https://", 8)==0 ){
/* it is already HTTPS, use it. */
g.zHttpsURL = mprintf("%s", g.zTop);
}else{
fossil_fatal("argument to --baseurl should be 'http://host/path'"
" or 'https://host/path'");
}
for(i=n=0; (c = g.zTop[i])!=0; i++){
if( c=='/' ){
n++;
if( n==3 ){
g.zTop += i;
break;
}
}
}
if( g.zTop==g.zBaseURL ){
fossil_fatal("argument to --baseurl should be 'http://host/path'"
" or 'https://host/path'");
}
if( g.zTop[1]==0 ) g.zTop++;
}else{
zHost = PD("HTTP_HOST","");
zMode = PD("HTTPS","off");
zCur = PD("SCRIPT_NAME","/");
|
|
|
|
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
|
if( strncmp(g.zTop, "http://", 7)==0 ){
/* it is HTTP, replace prefix with HTTPS. */
g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
}else if( strncmp(g.zTop, "https://", 8)==0 ){
/* it is already HTTPS, use it. */
g.zHttpsURL = mprintf("%s", g.zTop);
}else{
fossil_panic("argument to --baseurl should be 'http://host/path'"
" or 'https://host/path'");
}
for(i=n=0; (c = g.zTop[i])!=0; i++){
if( c=='/' ){
n++;
if( n==3 ){
g.zTop += i;
break;
}
}
}
if( g.zTop==g.zBaseURL ){
fossil_panic("argument to --baseurl should be 'http://host/path'"
" or 'https://host/path'");
}
if( g.zTop[1]==0 ) g.zTop++;
}else{
zHost = PD("HTTP_HOST","");
zMode = PD("HTTPS","off");
zCur = PD("SCRIPT_NAME","/");
|
| ︙ | | | ︙ | |
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
|
** Assume the user-id and group-id of the repository, or if zRepo
** is a directory, of that directory.
**
** The noJail flag means that the chroot jail is not entered. But
** privileges are still lowered to that of the user-id and group-id
** of the repository file.
*/
static char *enter_chroot_jail(char *zRepo, int noJail){
#if !defined(_WIN32)
if( getuid()==0 ){
int i;
struct stat sStat;
Blob dir;
char *zDir;
if( g.db!=0 ){
db_close(1);
}
file_canonical_name(zRepo, &dir, 0);
zDir = blob_str(&dir);
if( !noJail ){
if( file_isdir(zDir, ExtFILE)==1 ){
if( file_chdir(zDir, 1) ){
fossil_fatal("unable to chroot into %s", zDir);
}
g.fJail = 1;
zRepo = "/";
}else{
for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
if( i>0 ){
zDir[i] = 0;
if( file_chdir(zDir, 1) ){
fossil_fatal("unable to chroot into %s", zDir);
}
zDir[i] = '/';
}
zRepo = &zDir[i];
}
}
if( stat(zRepo, &sStat)!=0 ){
fossil_fatal("cannot stat() repository: %s", zRepo);
}
i = setgid(sStat.st_gid);
i = i || setuid(sStat.st_uid);
if(i){
fossil_fatal("setgid/uid() failed with errno %d", errno);
}
if( g.db==0 && file_isfile(zRepo, ExtFILE) ){
db_open_repository(zRepo);
}
}
#endif
return zRepo;
|
|
|
|
|
|
|
|
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
|
** Assume the user-id and group-id of the repository, or if zRepo
** is a directory, of that directory.
**
** The noJail flag means that the chroot jail is not entered. But
** privileges are still lowered to that of the user-id and group-id
** of the repository file.
*/
char *enter_chroot_jail(char *zRepo, int noJail){
#if !defined(_WIN32)
if( getuid()==0 ){
int i;
struct stat sStat;
Blob dir;
char *zDir;
if( g.db!=0 ){
db_close(1);
}
file_canonical_name(zRepo, &dir, 0);
zDir = blob_str(&dir);
if( !noJail ){
if( file_isdir(zDir, ExtFILE)==1 ){
if( file_chdir(zDir, 1) ){
fossil_panic("unable to chroot into %s", zDir);
}
g.fJail = 1;
zRepo = "/";
}else{
for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo);
if( i>0 ){
zDir[i] = 0;
if( file_chdir(zDir, 1) ){
fossil_panic("unable to chroot into %s", zDir);
}
zDir[i] = '/';
}
zRepo = &zDir[i];
}
}
if( stat(zRepo, &sStat)!=0 ){
fossil_panic("cannot stat() repository: %s", zRepo);
}
i = setgid(sStat.st_gid);
i = i || setuid(sStat.st_uid);
if(i){
fossil_panic("setgid/uid() failed with errno %d", errno);
}
if( g.db==0 && file_isfile(zRepo, ExtFILE) ){
db_open_repository(zRepo);
}
}
#endif
return zRepo;
|
| ︙ | | | ︙ | |
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
|
@ <base href="%s(g.zBaseURL)/" />
@ <title>Repository List</title>
@ </head>
@ <body>
n = db_int(0, "SELECT count(*) FROM sfile");
if( n>0 ){
Stmt q;
@ <h1>Available Repositories:</h1>
@ <ol>
db_prepare(&q, "SELECT pathname"
" FROM sfile ORDER BY pathname COLLATE nocase;");
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int nName = (int)strlen(zName);
char *zUrl;
if( nName<7 ) continue;
zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
if( sqlite3_strglob("*.fossil", zName)!=0 ){
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
** do not work for repositories whose names do not end in ".fossil".
** So do not hyperlink those cases. */
@ <li>%h(zName)</li>
} else if( sqlite3_strglob("*/.*", zName)==0 ){
/* Do not show hidden repos */
@ <li>%h(zName) (hidden)</li>
} else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
@ <li><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a></li>
}else{
@ <li><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a></li>
}
sqlite3_free(zUrl);
}
@ </ol>
}else{
@ <h1>No Repositories Found</h1>
}
@ </body>
@ </html>
cgi_reply();
sqlite3_close(g.db);
g.db = 0;
return n;
}
/*
** Preconditions:
**
** * Environment variables are set up according to the CGI standard.
**
** If the repository is known, it has already been opened. If unknown,
|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
|
@ <base href="%s(g.zBaseURL)/" />
@ <title>Repository List</title>
@ </head>
@ <body>
n = db_int(0, "SELECT count(*) FROM sfile");
if( n>0 ){
Stmt q;
sqlite3_int64 iNow, iMTime;
@ <h1 align="center">Fossil Repositories</h1>
@ <table border="0" class="sortable" data-init-sort="1" \
@ data-column-types="tnk"><thead>
@ <tr><th>Filename<th width="20"><th>Last Modified</tr>
@ </thead><tbody>
db_prepare(&q, "SELECT pathname"
" FROM sfile ORDER BY pathname COLLATE nocase;");
iNow = db_int64(0, "SELECT strftime('%%s','now')");
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int nName = (int)strlen(zName);
char *zUrl;
char *zAge;
char *zFull;
if( nName<7 ) continue;
zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
if( zName[0]=='/'
#ifdef _WIN32
|| sqlite3_strglob("[a-zA-Z]:/*", zName)==0
#endif
){
zFull = mprintf("%s", zName);
}else if ( allRepo ){
zFull = mprintf("/%s", zName);
}else{
zFull = mprintf("%s/%s", g.zRepositoryName, zName);
}
iMTime = file_mtime(zFull, ExtFILE);
fossil_free(zFull);
if( iMTime<=0 ){
zAge = mprintf("...");
}else{
zAge = human_readable_age((iNow - iMTime)/86400.0);
}
if( sqlite3_strglob("*.fossil", zName)!=0 ){
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
** do not work for repositories whose names do not end in ".fossil".
** So do not hyperlink those cases. */
@ <tr><td>%h(zName)
} else if( sqlite3_strglob("*/.*", zName)==0 ){
/* Do not show hidden repos */
@ <tr><td>%h(zName) (hidden)
} else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
@ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
}else{
@ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
}
@ <td></td><td data-sortkey='%010llx(iNow - iMTime)'>%h(zAge)</tr>
fossil_free(zAge);
sqlite3_free(zUrl);
}
@ </tbody></table>
}else{
@ <h1>No Repositories Found</h1>
}
@ <script>%s(builtin_text("sorttable.js"))</script>
@ </body>
@ </html>
cgi_reply();
sqlite3_close(g.db);
g.db = 0;
return n;
}
/*
** COMMAND: test-list-page
**
** Usage: %fossil test-list-page DIRECTORY
**
** Show all repositories underneath DIRECTORY. Or if DIRECTORY is "/"
** show all repositories in the ~/.fossil file.
*/
void test_list_page(void){
if( g.argc<3 ){
g.zRepositoryName = "/";
}else{
g.zRepositoryName = g.argv[2];
}
g.httpOut = stdout;
repo_list_page();
}
/*
** Called whenever a crash is encountered while processing a webpage.
*/
void sigsegv_handler(int x){
fossil_errorlog("Segfault");
exit(1);
}
/*
** Called if a server gets a SIGPIPE. This often happens when a client
** webbrowser opens a connection but never sends the HTTP request
*/
void sigpipe_handler(int x){
#ifndef _WIN32
if( g.fAnyTrace ){
fprintf(stderr,"/**** sigpipe received by subprocess %d ****\n", getpid());
}
#endif
fossil_exit(1);
}
/*
** Preconditions:
**
** * Environment variables are set up according to the CGI standard.
**
** If the repository is known, it has already been opened. If unknown,
|
| ︙ | | | ︙ | |
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
|
int allowRepoList /* Send repo list for "/" URL */
){
const char *zPathInfo = PD("PATH_INFO", "");
char *zPath = NULL;
int i;
const CmdOrPage *pCmd = 0;
const char *zBase = g.zRepositoryName;
/* Handle universal query parameters */
if( PB("utc") ){
g.fTimeFormat = 1;
}else if( PB("localtime") ){
g.fTimeFormat = 2;
}
|
>
>
>
>
|
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
|
int allowRepoList /* Send repo list for "/" URL */
){
const char *zPathInfo = PD("PATH_INFO", "");
char *zPath = NULL;
int i;
const CmdOrPage *pCmd = 0;
const char *zBase = g.zRepositoryName;
#if !defined(_WIN32)
signal(SIGSEGV, sigsegv_handler);
#endif
/* Handle universal query parameters */
if( PB("utc") ){
g.fTimeFormat = 1;
}else if( PB("localtime") ){
g.fTimeFormat = 2;
}
|
| ︙ | | | ︙ | |
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
|
if( zPathInfo && strncmp(zPathInfo,"/draft",6)==0
&& zPathInfo[6]>='1' && zPathInfo[6]<='9'
&& (zPathInfo[7]=='/' || zPathInfo[7]==0)
){
int iSkin = zPathInfo[6] - '0';
char *zNewScript;
skin_use_draft(iSkin);
zNewScript = mprintf("%s/draft%d", P("SCRIPT_NAME"), iSkin);
if( g.zTop ) g.zTop = mprintf("%s/draft%d", g.zTop, iSkin);
if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
zPathInfo += 7;
cgi_replace_parameter("PATH_INFO", zPathInfo);
cgi_replace_parameter("SCRIPT_NAME", zNewScript);
}
|
|
|
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
|
if( zPathInfo && strncmp(zPathInfo,"/draft",6)==0
&& zPathInfo[6]>='1' && zPathInfo[6]<='9'
&& (zPathInfo[7]=='/' || zPathInfo[7]==0)
){
int iSkin = zPathInfo[6] - '0';
char *zNewScript;
skin_use_draft(iSkin);
zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
if( g.zTop ) g.zTop = mprintf("%s/draft%d", g.zTop, iSkin);
if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
zPathInfo += 7;
cgi_replace_parameter("PATH_INFO", zPathInfo);
cgi_replace_parameter("SCRIPT_NAME", zNewScript);
}
|
| ︙ | | | ︙ | |
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
|
#endif
{
@ <h1>Server Configuration Error</h1>
@ <p>The database schema on the server is out-of-date. Please ask
@ the administrator to run <b>fossil rebuild</b>.</p>
}
}else{
#ifdef FOSSIL_ENABLE_TH1_HOOKS
/*
** The TH1 return codes from the hook will be handled as follows:
**
** TH_OK: The xFunc() and the TH1 notification will both be executed.
**
** TH_ERROR: The xFunc() will be skipped, the TH1 notification will be
|
>
>
>
>
|
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
|
#endif
{
@ <h1>Server Configuration Error</h1>
@ <p>The database schema on the server is out-of-date. Please ask
@ the administrator to run <b>fossil rebuild</b>.</p>
}
}else{
if( g.fCgiTrace ){
fossil_trace("######## Calling %s #########\n", pCmd->zName);
cgi_print_all(1, 1);
}
#ifdef FOSSIL_ENABLE_TH1_HOOKS
/*
** The TH1 return codes from the hook will be handled as follows:
**
** TH_OK: The xFunc() and the TH1 notification will both be executed.
**
** TH_ERROR: The xFunc() will be skipped, the TH1 notification will be
|
| ︙ | | | ︙ | |
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
|
/*
** If g.argv[arg] exists then it is either the name of a repository
** that will be used by a server, or else it is a directory that
** contains multiple repositories that can be served. If g.argv[arg]
** is a directory, the repositories it contains must be named
** "*.fossil". If g.argv[arg] does not exist, then we must be within
** an open check-out and the repository serve is the repository of
** that check-out.
**
** Open the repository to be served if it is known. If g.argv[arg] is
** a directory full of repositories, then set g.zRepositoryName to
** the name of that directory and the specific repository will be
** opened later by process_one_web_page() based on the content of
** the PATH_INFO variable.
|
|
|
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
|
/*
** If g.argv[arg] exists then it is either the name of a repository
** that will be used by a server, or else it is a directory that
** contains multiple repositories that can be served. If g.argv[arg]
** is a directory, the repositories it contains must be named
** "*.fossil". If g.argv[arg] does not exist, then we must be within
** an open check-out and the repository to serve is the repository of
** that check-out.
**
** Open the repository to be served if it is known. If g.argv[arg] is
** a directory full of repositories, then set g.zRepositoryName to
** the name of that directory and the specific repository will be
** opened later by process_one_web_page() based on the content of
** the PATH_INFO variable.
|
| ︙ | | | ︙ | |
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
|
LPVOID *ppAddress, /* The extracted pointer value. */
SIZE_T *pnSize /* The extracted size value. */
){
unsigned int nSize = 0;
if( sscanf(zPidKey, "%lu:%p:%u", pProcessId, ppAddress, &nSize)==3 ){
*pnSize = (SIZE_T)nSize;
}else{
fossil_fatal("failed to parse pid key");
}
}
#endif
/*
** undocumented format:
**
|
|
|
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
|
LPVOID *ppAddress, /* The extracted pointer value. */
SIZE_T *pnSize /* The extracted size value. */
){
unsigned int nSize = 0;
if( sscanf(zPidKey, "%lu:%p:%u", pProcessId, ppAddress, &nSize)==3 ){
*pnSize = (SIZE_T)nSize;
}else{
fossil_panic("failed to parse pid key");
}
}
#endif
/*
** undocumented format:
**
|
| ︙ | | | ︙ | |
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
|
**
** Options:
** --baseurl URL base URL (useful with reverse proxies)
** --files GLOB comma-separate glob patterns for static file to serve
** --localauth enable automatic login for local connections
** --host NAME specify hostname of the server
** --https signal a request coming in via https
** --nojail drop root privilege but do not enter the chroot jail
** --nossl signal that no SSL connections are available
** --notfound URL use URL as "HTTP 404, object not found" page.
** --repolist If REPOSITORY is directory, URL "/" lists all repos
** --scgi Interpret input as SCGI rather than HTTP
** --skin LABEL Use override skin LABEL
** --th-trace trace TH1 execution (for debugging purposes)
|
>
|
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
|
**
** Options:
** --baseurl URL base URL (useful with reverse proxies)
** --files GLOB comma-separate glob patterns for static file to serve
** --localauth enable automatic login for local connections
** --host NAME specify hostname of the server
** --https signal a request coming in via https
** --nocompress Do not compress HTTP replies
** --nojail drop root privilege but do not enter the chroot jail
** --nossl signal that no SSL connections are available
** --notfound URL use URL as "HTTP 404, object not found" page.
** --repolist If REPOSITORY is directory, URL "/" lists all repos
** --scgi Interpret input as SCGI rather than HTTP
** --skin LABEL Use override skin LABEL
** --th-trace trace TH1 execution (for debugging purposes)
|
| ︙ | | | ︙ | |
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
|
}
skin_override();
zNotFound = find_option("notfound", 0, 1);
noJail = find_option("nojail",0,0)!=0;
allowRepoList = find_option("repolist",0,0)!=0;
g.useLocalauth = find_option("localauth", 0, 0)!=0;
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
useSCGI = find_option("scgi", 0, 0)!=0;
zAltBase = find_option("baseurl", 0, 1);
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
cgi_replace_parameter("HTTPS","on");
}
|
>
|
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
|
}
skin_override();
zNotFound = find_option("notfound", 0, 1);
noJail = find_option("nojail",0,0)!=0;
allowRepoList = find_option("repolist",0,0)!=0;
g.useLocalauth = find_option("localauth", 0, 0)!=0;
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
useSCGI = find_option("scgi", 0, 0)!=0;
zAltBase = find_option("baseurl", 0, 1);
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
cgi_replace_parameter("HTTPS","on");
}
|
| ︙ | | | ︙ | |
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
|
}
#endif
/* We should be done with options.. */
verify_all_options();
if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
fossil_fatal("no repository specified");
}
g.cgiOutput = 1;
g.fullHttpReply = 1;
if( g.argc>=5 ){
g.httpIn = fossil_fopen(g.argv[2], "rb");
g.httpOut = fossil_fopen(g.argv[3], "wb");
zIpAddr = g.argv[4];
|
|
|
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
|
}
#endif
/* We should be done with options.. */
verify_all_options();
if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
fossil_panic("no repository specified");
}
g.cgiOutput = 1;
g.fullHttpReply = 1;
if( g.argc>=5 ){
g.httpIn = fossil_fopen(g.argv[2], "rb");
g.httpOut = fossil_fopen(g.argv[3], "wb");
zIpAddr = g.argv[4];
|
| ︙ | | | ︙ | |
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
|
Th_InitTraceLog();
login_set_capabilities("sx", 0);
g.useLocalauth = 1;
g.httpIn = stdin;
g.httpOut = stdout;
find_server_repository(2, 0);
g.cgiOutput = 1;
g.fullHttpReply = 1;
zIpAddr = cgi_ssh_remote_addr(0);
if( zIpAddr && zIpAddr[0] ){
g.fSshClient |= CGI_SSH_CLIENT;
ssh_request_loop(zIpAddr, 0);
}else{
cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
|
>
|
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
|
Th_InitTraceLog();
login_set_capabilities("sx", 0);
g.useLocalauth = 1;
g.httpIn = stdin;
g.httpOut = stdout;
find_server_repository(2, 0);
g.cgiOutput = 1;
g.fNoHttpCompress = 1;
g.fullHttpReply = 1;
zIpAddr = cgi_ssh_remote_addr(0);
if( zIpAddr && zIpAddr[0] ){
g.fSshClient |= CGI_SSH_CLIENT;
ssh_request_loop(zIpAddr, 0);
}else{
cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
|
| ︙ | | | ︙ | |
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
|
** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
** --files GLOBLIST Comma-separated list of glob patterns for static files
** --localauth enable automatic login for requests from localhost
** --localhost listen on 127.0.0.1 only (always true for "ui")
** --https signal a request coming in via https
** --max-latency N Do not let any single HTTP request run for more than N
** seconds (only works on unix)
** --nojail Drop root privileges but do not enter the chroot jail
** --nossl signal that no SSL connections are available
** --notfound URL Redirect
** -P|--port TCPPORT listen to request on port TCPPORT
** --th-trace trace TH1 execution (for debugging purposes)
** --repolist If REPOSITORY is dir, URL "/" lists repos.
** --scgi Accept SCGI rather than HTTP
|
>
|
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
|
** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
** --files GLOBLIST Comma-separated list of glob patterns for static files
** --localauth enable automatic login for requests from localhost
** --localhost listen on 127.0.0.1 only (always true for "ui")
** --https signal a request coming in via https
** --max-latency N Do not let any single HTTP request run for more than N
** seconds (only works on unix)
** --nocompress Do not compress HTTP replies
** --nojail Drop root privileges but do not enter the chroot jail
** --nossl signal that no SSL connections are available
** --notfound URL Redirect
** -P|--port TCPPORT listen to request on port TCPPORT
** --th-trace trace TH1 execution (for debugging purposes)
** --repolist If REPOSITORY is dir, URL "/" lists repos.
** --scgi Accept SCGI rather than HTTP
|
| ︙ | | | ︙ | |
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
|
const char *zBrowser; /* Name of web browser program */
char *zBrowserCmd = 0; /* Command to launch the web browser */
int isUiCmd; /* True if command is "ui", not "server' */
const char *zNotFound; /* The --notfound option or NULL */
int flags = 0; /* Server flags */
#if !defined(_WIN32)
int noJail; /* Do not enter the chroot jail */
#endif
int allowRepoList; /* List repositories on URL "/" */
const char *zAltBase; /* Argument to the --baseurl option */
const char *zFileGlob; /* Static content must match this */
const char *zMaxLatency; /* Maximum runtime of any single HTTP request */
char *zIpAddr = 0; /* Bind to this IP address */
int fCreate = 0; /* The --create flag */
const char *zInitPage = 0; /* Start on this page. --page option */
#if defined(_WIN32) && USE_SEE
const char *zPidKey;
#endif
#if defined(_WIN32)
const char *zStopperFile; /* Name of file used to terminate server */
zStopperFile = find_option("stopper", 0, 1);
#endif
zMaxLatency = find_option("max-latency",0,1);
zFileGlob = find_option("files-urlenc",0,1);
if( zFileGlob ){
char *z = mprintf("%s", zFileGlob);
dehttpize(z);
zFileGlob = z;
}else{
zFileGlob = find_option("files",0,1);
}
skin_override();
#if !defined(_WIN32)
noJail = find_option("nojail",0,0)!=0;
#endif
g.useLocalauth = find_option("localauth", 0, 0)!=0;
Th_InitTraceLog();
zPort = find_option("port", "P", 1);
isUiCmd = g.argv[1][0]=='u';
if( isUiCmd ){
zInitPage = find_option("page", 0, 1);
}
zNotFound = find_option("notfound", 0, 1);
allowRepoList = find_option("repolist",0,0)!=0;
zAltBase = find_option("baseurl", 0, 1);
fCreate = find_option("create",0,0)!=0;
if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
if( zAltBase ){
set_base_url(zAltBase);
}
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
if( find_option("https",0,0)!=0 ){
cgi_replace_parameter("HTTPS","on");
}else{
/* without --https, defaults to not available. */
g.sslNotAvailable = 1;
}
if( find_option("localhost", 0, 0)!=0 ){
flags |= HTTP_SERVER_LOCALHOST;
}
#if defined(_WIN32) && USE_SEE
zPidKey = find_option("usepidkey", 0, 1);
|
>
<
>
|
>
>
>
<
<
<
|
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
|
const char *zBrowser; /* Name of web browser program */
char *zBrowserCmd = 0; /* Command to launch the web browser */
int isUiCmd; /* True if command is "ui", not "server' */
const char *zNotFound; /* The --notfound option or NULL */
int flags = 0; /* Server flags */
#if !defined(_WIN32)
int noJail; /* Do not enter the chroot jail */
const char *zMaxLatency; /* Maximum runtime of any single HTTP request */
#endif
int allowRepoList; /* List repositories on URL "/" */
const char *zAltBase; /* Argument to the --baseurl option */
const char *zFileGlob; /* Static content must match this */
char *zIpAddr = 0; /* Bind to this IP address */
int fCreate = 0; /* The --create flag */
const char *zInitPage = 0; /* Start on this page. --page option */
#if defined(_WIN32) && USE_SEE
const char *zPidKey;
#endif
#if defined(_WIN32)
const char *zStopperFile; /* Name of file used to terminate server */
zStopperFile = find_option("stopper", 0, 1);
#endif
if( g.zErrlog==0 ){
g.zErrlog = "-";
}
zFileGlob = find_option("files-urlenc",0,1);
if( zFileGlob ){
char *z = mprintf("%s", zFileGlob);
dehttpize(z);
zFileGlob = z;
}else{
zFileGlob = find_option("files",0,1);
}
skin_override();
#if !defined(_WIN32)
noJail = find_option("nojail",0,0)!=0;
zMaxLatency = find_option("max-latency",0,1);
#endif
g.useLocalauth = find_option("localauth", 0, 0)!=0;
Th_InitTraceLog();
zPort = find_option("port", "P", 1);
isUiCmd = g.argv[1][0]=='u';
if( isUiCmd ){
zInitPage = find_option("page", 0, 1);
}
zNotFound = find_option("notfound", 0, 1);
allowRepoList = find_option("repolist",0,0)!=0;
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
zAltBase = find_option("baseurl", 0, 1);
fCreate = find_option("create",0,0)!=0;
if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
if( zAltBase ){
set_base_url(zAltBase);
}
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
if( find_option("https",0,0)!=0 ){
cgi_replace_parameter("HTTPS","on");
}
if( find_option("localhost", 0, 0)!=0 ){
flags |= HTTP_SERVER_LOCALHOST;
}
#if defined(_WIN32) && USE_SEE
zPidKey = find_option("usepidkey", 0, 1);
|
| ︙ | | | ︙ | |
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
|
if( isUiCmd && g.localOpen ){
zInitPage = "timeline?c=current";
}else{
zInitPage = "";
}
}
if( zPort ){
int i;
for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
if( i>0 ){
zIpAddr = mprintf("%.*s", i, zPort);
zPort += i+1;
}
iPort = mxPort = atoi(zPort);
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#if !defined(_WIN32)
|
>
|
|
|
>
>
>
|
>
|
>
|
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
|
if( isUiCmd && g.localOpen ){
zInitPage = "timeline?c=current";
}else{
zInitPage = "";
}
}
if( zPort ){
if( strchr(zPort,':') ){
int i;
for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
if( i>0 ){
if( zPort[0]=='[' && zPort[i-1]==']' ){
zIpAddr = mprintf("%.*s", i-2, zPort+1);
}else{
zIpAddr = mprintf("%.*s", i, zPort);
}
zPort += i+1;
}
}
iPort = mxPort = atoi(zPort);
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#if !defined(_WIN32)
|
| ︙ | | | ︙ | |
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
|
break;
}
}
}
#else
zBrowser = db_get("web-browser", "open");
#endif
if( zIpAddr ){
zBrowserCmd = mprintf("%s \"http://%s:%%d/%s\" &",
zBrowser, zIpAddr, zInitPage);
}else{
zBrowserCmd = mprintf("%s \"http://localhost:%%d/%s\" &",
zBrowser, zInitPage);
}
}
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
db_close(1);
if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
fossil_fatal("unable to listen on TCP socket %d", iPort);
}
if( zMaxLatency ){
signal(SIGALRM, sigalrm_handler);
alarm(atoi(zMaxLatency));
}
g.httpIn = stdin;
g.httpOut = stdout;
if( g.fHttpTrace || g.fSqlTrace ){
fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
}
g.cgiOutput = 1;
find_server_repository(2, 0);
if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
allowRepoList = 1;
}else{
g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
}
if( flags & HTTP_SERVER_SCGI ){
cgi_handle_scgi_request();
}else{
cgi_handle_http_request(0);
}
process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
#else
/* Win32 implementation */
if( isUiCmd ){
zBrowser = db_get("web-browser", "start");
if( zIpAddr ){
zBrowserCmd = mprintf("%s http://%s:%%d/%s &",
zBrowser, zIpAddr, zInitPage);
}else{
zBrowserCmd = mprintf("%s http://localhost:%%d/%s &",
zBrowser, zInitPage);
}
}
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
db_close(1);
if( allowRepoList ){
flags |= HTTP_SERVER_REPOLIST;
|
|
>
>
>
|
|
|
|
|
>
>
>
>
|
>
>
>
>
>
>
|
|
>
>
>
|
|
|
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
|
break;
}
}
}
#else
zBrowser = db_get("web-browser", "open");
#endif
if( zIpAddr==0 ){
zBrowserCmd = mprintf("%s http://localhost:%%d/%s &",
zBrowser, zInitPage);
}else if( strchr(zIpAddr,':') ){
zBrowserCmd = mprintf("%s http://[%s]:%%d/%s &",
zBrowser, zIpAddr, zInitPage);
}else{
zBrowserCmd = mprintf("%s http://%s:%%d/%s &",
zBrowser, zIpAddr, zInitPage);
}
}
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
db_close(1);
if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
fossil_panic("unable to listen on TCP socket %d", iPort);
}
if( zMaxLatency ){
signal(SIGALRM, sigalrm_handler);
alarm(atoi(zMaxLatency));
}
g.httpIn = stdin;
g.httpOut = stdout;
#if !defined(_WIN32)
signal(SIGSEGV, sigsegv_handler);
signal(SIGPIPE, sigpipe_handler);
#endif
if( g.fAnyTrace ){
fprintf(stderr, "/***** Subprocess %d *****/\n", getpid());
}
g.cgiOutput = 1;
find_server_repository(2, 0);
if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
allowRepoList = 1;
}else{
g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
}
if( flags & HTTP_SERVER_SCGI ){
cgi_handle_scgi_request();
}else{
cgi_handle_http_request(0);
}
process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
if( g.fAnyTrace ){
fprintf(stderr, "/***** Webpage finished in subprocess %d *****/\n",
getpid());
}
#else
/* Win32 implementation */
if( isUiCmd ){
zBrowser = db_get("web-browser", "start");
if( zIpAddr==0 ){
zBrowserCmd = mprintf("%s http://localhost:%%d/%s &",
zBrowser, zInitPage);
}else if( strchr(zIpAddr,':') ){
zBrowserCmd = mprintf("%s http://[%s]:%%d/%s &",
zBrowser, zIpAddr, zInitPage);
}else{
zBrowserCmd = mprintf("%s http://%s:%%d/%s &",
zBrowser, zIpAddr, zInitPage);
}
}
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
db_close(1);
if( allowRepoList ){
flags |= HTTP_SERVER_REPOLIST;
|
| ︙ | | | ︙ | |
2616
2617
2618
2619
2620
2621
2622
|
for(j=0; (c = z[j])!=0; j++){
fossil_print("%02x", c);
}
fossil_print("]\n");
}
}
}
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
|
for(j=0; (c = z[j])!=0; j++){
fossil_print("%02x", c);
}
fossil_print("]\n");
}
}
}
/*
** WEBPAGE: test-warning
**
** Test error and warning log operation. This webpage is accessible to
** the administrator only.
**
** case=1 Issue a fossil_warning() while generating the page.
** case=2 Extra db_begin_transaction()
** case=3 Extra db_end_transaction()
*/
void test_warning_page(void){
int iCase = atoi(PD("case","0"));
int i;
login_check_credentials();
if( !g.perm.Setup && !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Warning Test Page");
style_submenu_element("Error Log","%R/errorlog");
if( iCase<1 || iCase>4 ){
@ <p>Generate a message to the <a href="%R/errorlog">error log</a>
@ by clicking on one of the following cases:
}else{
@ <p>This is the test page for case=%d(iCase). All possible cases:
}
for(i=1; i<=4; i++){
@ <a href='./test-warning?case=%d(i)'>[%d(i)]</a>
}
@ </p>
@ <p><ol>
@ <li value='1'> Call fossil_warning()
if( iCase==1 ){
fossil_warning("Test warning message from /test-warning");
}
@ <li value='2'> Call db_begin_transaction()
if( iCase==2 ){
db_begin_transaction();
}
@ <li value='3'> Call db_end_transaction()
if( iCase==3 ){
db_end_transaction(0);
}
@ <li value='4'> warning during SQL
if( iCase==4 ){
Stmt q;
db_prepare(&q, "SELECT uuid FROM blob LIMIT 5");
db_step(&q);
sqlite3_log(SQLITE_ERROR, "Test warning message during SQL");
db_finalize(&q);
}
@ </ol>
@ <p>End of test</p>
style_footer();
}
|