Fossil

Check-in [22150aba]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merged in trunk.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | double-dash-flag2
Files: files | file ages | folders
SHA3-256: 22150abaf2b6e55d761c3838cc07d7d667fa4d78a0bda07563917daf2fbb2cfa
User & Date: stephan 2019-10-10 05:49:47.006
Context
2019-10-28
19:16
Merged in double-dash-flag2 branch, which adds conventional -- handling to the vast majority of commands (the exception being those few which don't call verify_all_arguments()). ... (check-in: 5cca4646 user: stephan tags: trunk)
2019-10-10
05:49
Merged in trunk. ... (Closed-Leaf check-in: 22150aba user: stephan tags: double-dash-flag2)
2019-10-08
16:00
Increase the version number to 2.11 for the next release cycle. ... (check-in: 10fb90fc user: drh tags: trunk)
2019-10-03
15:19
Clarified a falsehood in the new verify_all_options() docs. ... (check-in: 6edf8bcd user: stephan tags: double-dash-flag2)
Changes
Unified Diff Ignore Whitespace Patch
Added .editorconfig.
























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
# EditorConfig (https://editorconfig.com) Configuration for Fossil
#
# Following https://fossil-scm.org/fossil/doc/trunk/www/style.wiki
#

# Defaults for all files
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

Changes to VERSION.
1
2.10
|
1
2.11
Changes to src/db.c.
4004
4005
4006
4007
4008
4009
4010

4011
4012
4013
4014
4015
4016

4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029




4030
4031
4032
4033
4034
4035
4036
** Set the value of the "checkout" entry in the VVAR table.
**
** Also set "fingerprint" and "checkout-hash".
*/
void db_set_checkout(int rid){
  char *z;
  db_lset_int("checkout", rid);

  z = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid);
  db_lset("checkout-hash", z);
  fossil_free(z);
  z = db_fingerprint(0, 1);
  db_lset("fingerprint", z);
  fossil_free(z);

}

/*
** Verify that the fingerprint recorded in the "fingerprint" entry
** of the VVAR table matches the fingerprint on the currently
** connected repository.  Return true if the fingerprint is ok, and
** return false if the fingerprint does not match.
*/
int db_fingerprint_ok(void){
  char *zCkout;   /* The fingerprint recorded in the checkout database */
  char *zRepo;    /* The fingerprint of the repository */
  int rc;         /* Result */





  zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
  if( zCkout==0 ){
    /* This is an older checkout that does not record a fingerprint.
    ** We have to assume everything is ok */
    return 2;
  }
  zRepo = db_fingerprint(atoi(zCkout), 1);







>
|
|
|
|
|
|
>













>
>
>
>







4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
** Set the value of the "checkout" entry in the VVAR table.
**
** Also set "fingerprint" and "checkout-hash".
*/
void db_set_checkout(int rid){
  char *z;
  db_lset_int("checkout", rid);
  if (rid != 0) {
    z = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid);
    db_lset("checkout-hash", z);
    fossil_free(z);
    z = db_fingerprint(0, 1);
    db_lset("fingerprint", z);
    fossil_free(z);
  }
}

/*
** Verify that the fingerprint recorded in the "fingerprint" entry
** of the VVAR table matches the fingerprint on the currently
** connected repository.  Return true if the fingerprint is ok, and
** return false if the fingerprint does not match.
*/
int db_fingerprint_ok(void){
  char *zCkout;   /* The fingerprint recorded in the checkout database */
  char *zRepo;    /* The fingerprint of the repository */
  int rc;         /* Result */

  if( !db_lget_int("checkout", 0) ){
    /* We have an empty checkout, fingerprint is still NULL. */
    return 2;
  }
  zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
  if( zCkout==0 ){
    /* This is an older checkout that does not record a fingerprint.
    ** We have to assume everything is ok */
    return 2;
  }
  zRepo = db_fingerprint(atoi(zCkout), 1);
Changes to src/info.c.
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the repository of the current tree that the argument refers
** to.  Or if the argument is the name of a repository, show
** information about that repository.
**
** If the argument is a repository name, then the --verbose option shows
** known the check-out locations for that repository and all URLs used
** to access the repository.  The --verbose is (currently) a no-op if
** the argument is the name of a object within the repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the repository of the current tree that the argument refers
** to.  Or if the argument is the name of a repository, show
** information about that repository.
**
** If the argument is a repository name, then the --verbose option shows
** all known check-out locations for that repository and all URLs used
** to access the repository.  The --verbose is (currently) a no-op if
** the argument is the name of a object within the repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:
Changes to src/shell.c.
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
    open_db(p,0);
    if( nArg<=1 ) goto parameter_syntax_error;

    /* .parameter clear
    ** Clear all bind parameters by dropping the TEMP table that holds them.
    */
    if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
      int wrSchema = 0;
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
      sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
                   0, 0, 0);
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
    }else

    /* .parameter list
    ** List all bind parameters.
    */
    if( nArg==2 && strcmp(azArg[1],"list")==0 ){
      sqlite3_stmt *pStmt = 0;







<
<
<


<







16689
16690
16691
16692
16693
16694
16695



16696
16697

16698
16699
16700
16701
16702
16703
16704
    open_db(p,0);
    if( nArg<=1 ) goto parameter_syntax_error;

    /* .parameter clear
    ** Clear all bind parameters by dropping the TEMP table that holds them.
    */
    if( nArg==2 && strcmp(azArg[1],"clear")==0 ){



      sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
                   0, 0, 0);

    }else

    /* .parameter list
    ** List all bind parameters.
    */
    if( nArg==2 && strcmp(azArg[1],"list")==0 ){
      sqlite3_stmt *pStmt = 0;
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
    }else{
      if( mType==0 ) mType = SQLITE_TRACE_STMT;
      sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#ifdef SQLITE_DEBUG
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;







|







17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
    }else{
      if( mType==0 ) mType = SQLITE_TRACE_STMT;
      sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;
Changes to src/sqlite3.c.
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.30.0"
#define SQLITE_VERSION_NUMBER 3030000
#define SQLITE_SOURCE_ID      "2019-09-26 16:57:42 49073b7003330027303c4c776e9f85112f8b99b89f848fec3f953eba501d7505"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.30.0"
#define SQLITE_VERSION_NUMBER 3030000
#define SQLITE_SOURCE_ID      "2019-10-04 15:03:17 c20a35336432025445f9f7e289d0cc3e4003fb17f45a4ce74c6269c407c6e09f"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
16169
16170
16171
16172
16173
16174
16175

16176
16177
16178
16179
16180
16181
16182
#define sqlite3_mutex_notheld(X)  ((void)(X),1)
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X)            X

#endif /* defined(SQLITE_MUTEX_OMIT) */

/************** End of mutex.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/

/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
** synchronous setting to EXTRA.  It is no longer supported.







>







16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
#define sqlite3_mutex_notheld(X)  ((void)(X),1)
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X)            X
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
#endif /* defined(SQLITE_MUTEX_OMIT) */

/************** End of mutex.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/

/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
** synchronous setting to EXTRA.  It is no longer supported.
17172
17173
17174
17175
17176
17177
17178



17179
17180
17181
17182
17183
17184
17185
17186
17187
  u16 nKeyField;      /* Number of key columns in the index */
  u16 nAllField;      /* Total columns, including key plus others */
  sqlite3 *db;        /* The database connection */
  u8 *aSortFlags;     /* Sort order for each column. */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};




#define KEYINFO_ORDER_DESC    0x01
#define KEYINFO_ORDER_BIGNULL 0x02

/*
** This object holds a record which has been parsed out into individual
** fields, for the purposes of doing a comparison.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store







>
>
>
|
|







17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
  u16 nKeyField;      /* Number of key columns in the index */
  u16 nAllField;      /* Total columns, including key plus others */
  sqlite3 *db;        /* The database connection */
  u8 *aSortFlags;     /* Sort order for each column. */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** Allowed bit values for entries in the KeyInfo.aSortFlags[] array.
*/
#define KEYINFO_ORDER_DESC    0x01    /* DESC sort order */
#define KEYINFO_ORDER_BIGNULL 0x02    /* NULL is larger than any other value */

/*
** This object holds a record which has been parsed out into individual
** fields, for the purposes of doing a comparison.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
17503
17504
17505
17506
17507
17508
17509

17510
17511
17512
17513
17514
17515
17516
#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood

                         ** TK_SELECT_COLUMN: Number of columns on the LHS
                         ** TK_SELECT: 1st register of result vector */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1).
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */







>







17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood
                         ** TK_IN: ephemerial table holding RHS
                         ** TK_SELECT_COLUMN: Number of columns on the LHS
                         ** TK_SELECT: 1st register of result vector */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1).
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
29224
29225
29226
29227
29228
29229
29230
29231

29232
29233
29234
29235
29236
29237
29238
29239
29240
      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }

    case TK_COLLATE: {
      /* COLLATE operators without the EP_Collate flag are intended to
      ** emulate collation associated with a table column.  Explicit

      ** COLLATE operators that appear in the original SQL always have
      ** the EP_Collate bit set */
      sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
        !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
        pExpr->u.zToken, zFlgs);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }








|
>
|
|







29229
29230
29231
29232
29233
29234
29235
29236
29237
29238
29239
29240
29241
29242
29243
29244
29245
29246
      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }

    case TK_COLLATE: {
      /* COLLATE operators without the EP_Collate flag are intended to
      ** emulate collation associated with a table column.  These show
      ** up in the treeview output as "SOFT-COLLATE".  Explicit COLLATE
      ** operators that appear in the original SQL always have the
      ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
      sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
        !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
        pExpr->u.zToken, zFlgs);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
      break;
    }

32581
32582
32583
32584
32585
32586
32587














32588
32589
32590
32591

32592
32593
32594

32595
32596
32597
32598
32599
32600
32601

#if SQLITE_ENABLE_LOCKING_STYLE
/* # include <sys/ioctl.h> */
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */















#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
                           (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
#  if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
       && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))

#    define HAVE_GETHOSTUUID 1
#  else
#    warning "gethostuuid() is disabled."

#  endif
#endif


#if OS_VXWORKS
/* # include <sys/ioctl.h> */
# include <semaphore.h>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
|
|
|
>







32587
32588
32589
32590
32591
32592
32593
32594
32595
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612
32613
32614
32615
32616
32617
32618
32619
32620
32621
32622
32623

#if SQLITE_ENABLE_LOCKING_STYLE
/* # include <sys/ioctl.h> */
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */

/*
** Try to determine if gethostuuid() is available based on standard
** macros.  This might sometimes compute the wrong value for some
** obscure platforms.  For those cases, simply compile with one of
** the following:
**
**    -DHAVE_GETHOSTUUID=0
**    -DHAVE_GETHOSTUUID=1
**
** None if this matters except when building on Apple products with
** -DSQLITE_ENABLE_LOCKING_STYLE.
*/
#ifndef HAVE_GETHOSTUUID
# define HAVE_GETHOSTUUID 0
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
                            (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
#    if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
         && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
#      undef HAVE_GETHOSTUUID
#      define HAVE_GETHOSTUUID 1
#    else
#      warning "gethostuuid() is disabled."
#    endif
#  endif
#endif


#if OS_VXWORKS
/* # include <sys/ioctl.h> */
# include <semaphore.h>
39603
39604
39605
39606
39607
39608
39609
39610
39611
39612
39613
39614
39615
39616
39617
39618
39619
39620
39621
39622
39623
39624
39625
39626
39627
39628
#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
SQLITE_API int sqlite3_hostid_num = 0;
#endif

#define PROXY_HOSTIDLEN    16  /* conch file host id length */

#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif

/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
  assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
  memset(pHostID, 0, PROXY_HOSTIDLEN);
#ifdef HAVE_GETHOSTUUID
  {
    struct timespec timeout = {1, 0}; /* 1 sec timeout */
    if( gethostuuid(pHostID, &timeout) ){
      int err = errno;
      if( pError ){
        *pError = err;
      }







|










|







39625
39626
39627
39628
39629
39630
39631
39632
39633
39634
39635
39636
39637
39638
39639
39640
39641
39642
39643
39644
39645
39646
39647
39648
39649
39650
#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
SQLITE_API int sqlite3_hostid_num = 0;
#endif

#define PROXY_HOSTIDLEN    16  /* conch file host id length */

#if HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif

/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
  assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
  memset(pHostID, 0, PROXY_HOSTIDLEN);
#if HAVE_GETHOSTUUID
  {
    struct timespec timeout = {1, 0}; /* 1 sec timeout */
    if( gethostuuid(pHostID, &timeout) ){
      int err = errno;
      if( pError ){
        *pError = err;
      }
84379
84380
84381
84382
84383
84384
84385
84386
84387
84388
84389
84390
84391
84392
84393
    printf(" si:%lld", p->u.i);
  }else if( (p->flags & (MEM_IntReal))!=0 ){
    printf(" ir:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
    printf(" r:%g", p->u.r);
#endif
  }else if( sqlite3VdbeMemIsRowSet(p) ){
    printf(" (rowset)");
  }else{
    char zBuf[200];
    sqlite3VdbeMemPrettyPrint(p, zBuf);
    printf(" %s", zBuf);







|







84401
84402
84403
84404
84405
84406
84407
84408
84409
84410
84411
84412
84413
84414
84415
    printf(" si:%lld", p->u.i);
  }else if( (p->flags & (MEM_IntReal))!=0 ){
    printf(" ir:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
    printf(" r:%.17g", p->u.r);
#endif
  }else if( sqlite3VdbeMemIsRowSet(p) ){
    printf(" (rowset)");
  }else{
    char zBuf[200];
    sqlite3VdbeMemPrettyPrint(p, zBuf);
    printf(" %s", zBuf);
102443
102444
102445
102446
102447
102448
102449

102450
102451
102452
102453
102454
102455
102456
102457
    if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
    if( pA->op!=TK_STRING
     && pA->op!=TK_TRUEFALSE
     && (combinedFlags & EP_Reduced)==0
    ){
      if( pA->iColumn!=pB->iColumn ) return 2;
      if( pA->op2!=pB->op2 ) return 2;

      if( pA->iTable!=pB->iTable 
       && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
    }
  }
  return 0;
}

/*







>
|







102465
102466
102467
102468
102469
102470
102471
102472
102473
102474
102475
102476
102477
102478
102479
102480
    if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
    if( pA->op!=TK_STRING
     && pA->op!=TK_TRUEFALSE
     && (combinedFlags & EP_Reduced)==0
    ){
      if( pA->iColumn!=pB->iColumn ) return 2;
      if( pA->op2!=pB->op2 ) return 2;
      if( pA->op!=TK_IN
       && pA->iTable!=pB->iTable 
       && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
    }
  }
  return 0;
}

/*
110434
110435
110436
110437
110438
110439
110440
110441

110442
110443
110444
110445
110446
110447
110448
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
    && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){

    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.







|
>







110457
110458
110459
110460
110461
110462
110463
110464
110465
110466
110467
110468
110469
110470
110471
110472
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
    && sqlite3StrNICmp(pTab->zName+7, "stat", 4)!=0
    && sqlite3StrNICmp(pTab->zName+7, "parameters", 10)!=0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
121077
121078
121079
121080
121081
121082
121083

121084



121085
121086
121087
121088
121089
121090
121091
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  /* Version 3.30.0 and later */

  sqlite3_drop_modules,



};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.







>

>
>
>







121101
121102
121103
121104
121105
121106
121107
121108
121109
121110
121111
121112
121113
121114
121115
121116
121117
121118
121119
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  /* Version 3.30.0 and later */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_drop_modules,
#else
  0,
#endif
};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.
162209
162210
162211
162212
162213
162214
162215












162216
162217
162218
162219
162220
162221
162222

/* #include "fts3.h" */
#ifndef SQLITE_CORE 
/* # include "sqlite3ext.h" */
  SQLITE_EXTENSION_INIT1
#endif













static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
    Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);

#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_DEBUG)







>
>
>
>
>
>
>
>
>
>
>
>







162237
162238
162239
162240
162241
162242
162243
162244
162245
162246
162247
162248
162249
162250
162251
162252
162253
162254
162255
162256
162257
162258
162259
162260
162261
162262

/* #include "fts3.h" */
#ifndef SQLITE_CORE 
/* # include "sqlite3ext.h" */
  SQLITE_EXTENSION_INIT1
#endif

/*
** The following are copied from sqliteInt.h.
**
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef SQLITE_AMALGAMATION
# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif

static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
    Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);

#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_DEBUG)
163987
163988
163989
163990
163991
163992
163993
163994
163995

163996
163997
163998
163999
164000
164001
164002
164003
164004
    p += n;
    *pp = p;
  }
  *ppPoslist = pEnd;
}

/*
** Value used to signify the end of an position-list. This is safe because
** it is not possible to have a document with 2^31 terms.

*/
#define POSITION_LIST_END 0x7fffffff

/*
** This function is used to help parse position-lists. When this function is
** called, *pp may point to the start of the next varint in the position-list
** being parsed, or it may point to 1 byte past the end of the position-list
** (in which case **pp will be a terminator bytes POS_END (0) or
** (1)).







|
|
>

|







164027
164028
164029
164030
164031
164032
164033
164034
164035
164036
164037
164038
164039
164040
164041
164042
164043
164044
164045
    p += n;
    *pp = p;
  }
  *ppPoslist = pEnd;
}

/*
** Value used to signify the end of an position-list. This must be
** as large or larger than any value that might appear on the
** position-list, even a position list that has been corrupted.
*/
#define POSITION_LIST_END LARGEST_INT64

/*
** This function is used to help parse position-lists. When this function is
** called, *pp may point to the start of the next varint in the position-list
** being parsed, or it may point to 1 byte past the end of the position-list
** (in which case **pp will be a terminator bytes POS_END (0) or
** (1)).
164066
164067
164068
164069
164070
164071
164072
164073
164074
164075
164076
164077
164078
164079
164080
164081
164082
164083
164084
164085
164086
164087
    int iCol1;         /* The current column index in pp1 */
    int iCol2;         /* The current column index in pp2 */

    if( *p1==POS_COLUMN ){ 
      fts3GetVarint32(&p1[1], &iCol1);
      if( iCol1==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
    else iCol1 = 0;

    if( *p2==POS_COLUMN ){
      fts3GetVarint32(&p2[1], &iCol2);
      if( iCol2==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
    else iCol2 = 0;

    if( iCol1==iCol2 ){
      sqlite3_int64 i1 = 0;       /* Last position from pp1 */
      sqlite3_int64 i2 = 0;       /* Last position from pp2 */
      sqlite3_int64 iPrev = 0;
      int n = fts3PutColNumber(&p, iCol1);







|






|







164107
164108
164109
164110
164111
164112
164113
164114
164115
164116
164117
164118
164119
164120
164121
164122
164123
164124
164125
164126
164127
164128
    int iCol1;         /* The current column index in pp1 */
    int iCol2;         /* The current column index in pp2 */

    if( *p1==POS_COLUMN ){ 
      fts3GetVarint32(&p1[1], &iCol1);
      if( iCol1==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p1==POS_END ) iCol1 = 0x7fffffff;
    else iCol1 = 0;

    if( *p2==POS_COLUMN ){
      fts3GetVarint32(&p2[1], &iCol2);
      if( iCol2==0 ) return FTS_CORRUPT_VTAB;
    }
    else if( *p2==POS_END ) iCol2 = 0x7fffffff;
    else iCol2 = 0;

    if( iCol1==iCol2 ){
      sqlite3_int64 i1 = 0;       /* Last position from pp1 */
      sqlite3_int64 i2 = 0;       /* Last position from pp2 */
      sqlite3_int64 iPrev = 0;
      int n = fts3PutColNumber(&p, iCol1);
165083
165084
165085
165086
165087
165088
165089
165090
165091
165092
165093
165094
165095
165096
165097
165098
165099
165100
165101
165102
165103
165104
165105
165106
165107
165108
  }else{
    rc = fts3EvalNext((Fts3Cursor *)pCursor);
  }
  assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
  return rc;
}

/*
** The following are copied from sqliteInt.h.
**
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef SQLITE_AMALGAMATION
# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif

/*
** If the numeric type of argument pVal is "integer", then return it
** converted to a 64-bit signed integer. Otherwise, return a copy of
** the second parameter, iDefault.
*/
static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){
  if( pVal ){







<
<
<
<
<
<
<
<
<
<
<
<







165124
165125
165126
165127
165128
165129
165130












165131
165132
165133
165134
165135
165136
165137
  }else{
    rc = fts3EvalNext((Fts3Cursor *)pCursor);
  }
  assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
  return rc;
}













/*
** If the numeric type of argument pVal is "integer", then return it
** converted to a 64-bit signed integer. Otherwise, return a copy of
** the second parameter, iDefault.
*/
static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){
  if( pVal ){
175824
175825
175826
175827
175828
175829
175830
175831
175832
175833
175834
175835
175836
175837
175838
175839
175840
175841
175842
175843
175844
175845
*/
static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
  memset(p, 0, sizeof(NodeReader));
  p->aNode = aNode;
  p->nNode = nNode;

  /* Figure out if this is a leaf or an internal node. */
  if( p->aNode[0] ){
    /* An internal node. */
    p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
  }else{
    p->iOff = 1;
  }

  return nodeReaderNext(p);
}

/*
** This function is called while writing an FTS segment each time a leaf o
** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
** to be greater than the largest key on the node just written, but smaller
** than or equal to the first key that will be written to the next leaf







|






|







175853
175854
175855
175856
175857
175858
175859
175860
175861
175862
175863
175864
175865
175866
175867
175868
175869
175870
175871
175872
175873
175874
*/
static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
  memset(p, 0, sizeof(NodeReader));
  p->aNode = aNode;
  p->nNode = nNode;

  /* Figure out if this is a leaf or an internal node. */
  if( aNode && aNode[0] ){
    /* An internal node. */
    p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
  }else{
    p->iOff = 1;
  }

  return aNode ? nodeReaderNext(p) : SQLITE_OK;
}

/*
** This function is called while writing an FTS segment each time a leaf o
** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
** to be greater than the largest key on the node just written, but smaller
** than or equal to the first key that will be written to the next leaf
176323
176324
176325
176326
176327
176328
176329

176330
176331
176332
176333
176334
176335
176336
176337
176338
        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
      }

      for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
        NodeReader reader;
        pNode = &pWriter->aNodeWriter[i];


        rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
        if( reader.aNode ){
          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){
            memcpy(pNode->key.a, reader.term.a, reader.term.n);
            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;







>
|
<







176352
176353
176354
176355
176356
176357
176358
176359
176360

176361
176362
176363
176364
176365
176366
176367
        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
      }

      for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
        NodeReader reader;
        pNode = &pWriter->aNodeWriter[i];

        if( pNode->block.a){
          rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);

          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){
            memcpy(pNode->key.a, reader.term.a, reader.term.n);
            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;
220234
220235
220236
220237
220238
220239
220240
220241
220242
220243
220244
220245
220246
220247
220248
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2019-09-25 18:44:49 36d35dbd5a80dc4a149ed7409cc4b43712622fc4c6a8915b4fbb62fd1d6b7763", -1, SQLITE_TRANSIENT);
}

/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){







|







220263
220264
220265
220266
220267
220268
220269
220270
220271
220272
220273
220274
220275
220276
220277
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2019-10-04 15:03:17 c20a35336432025445f9f7e289d0cc3e4003fb17f45a4ce74c6269c407c6e09f", -1, SQLITE_TRANSIENT);
}

/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
225002
225003
225004
225005
225006
225007
225008
225009
225010
225011
225012
225013
225014
225015
#endif
  return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */

/************** End of stmt.c ************************************************/
#if __LINE__!=225009
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID      "2019-09-26 16:57:42 49073b7003330027303c4c776e9f85112f8b99b89f848fec3f953eba501dalt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/







|

|




225031
225032
225033
225034
225035
225036
225037
225038
225039
225040
225041
225042
225043
225044
#endif
  return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */

/************** End of stmt.c ************************************************/
#if __LINE__!=225038
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID      "2019-10-04 15:03:17 c20a35336432025445f9f7e289d0cc3e4003fb17f45a4ce74c6269c407c6alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/
Changes to src/sqlite3.h.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.30.0"
#define SQLITE_VERSION_NUMBER 3030000
#define SQLITE_SOURCE_ID      "2019-09-26 16:57:42 49073b7003330027303c4c776e9f85112f8b99b89f848fec3f953eba501d7505"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.30.0"
#define SQLITE_VERSION_NUMBER 3030000
#define SQLITE_SOURCE_ID      "2019-10-04 15:03:17 c20a35336432025445f9f7e289d0cc3e4003fb17f45a4ce74c6269c407c6e09f"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
Changes to src/wiki.c.
1493
1494
1495
1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522

1523
1524
1525
1526
1527
1528

1529




1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
    return;
  }else if( strncmp(g.argv[2],"commit",n)==0
            || strncmp(g.argv[2],"create",n)==0 ){
    const char *zPageName;        /* page name */
    Blob content;                 /* Input content */
    int rid = 0;
    Manifest *pWiki = 0;          /* Parsed wiki page content */

    const char *zMimeType = find_option("mimetype", "M", 1);
    const char *zETime = find_option("technote", "t", 1);
    const char *zTags = find_option("technote-tags", NULL, 1);
    const char *zClr = find_option("technote-bgcolor", NULL, 1);
    if( g.argc!=4 && g.argc!=5 ){
      usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT]"
            " [--technote DATETIME] [--technote-tags TAGS]"
            " [--technote-bgcolor COLOR]");
    }
    zPageName = g.argv[3];
    if( g.argc==4 ){
      blob_read_from_channel(&content, stdin, -1);
    }else{
      blob_read_from_file(&content, g.argv[4], ExtFILE);
    }
    if( !zMimeType || !*zMimeType ){
      /* Try to deduce the mime type based on the prior version. */
      if ( !zETime ){
        rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
                     " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
                     " ORDER BY x.mtime DESC LIMIT 1",
                     zPageName
                     );

        if( rid>0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0
           && (pWiki->zMimetype && *pWiki->zMimetype) ){
          zMimeType = pWiki->zMimetype;
        }
      }else{
        rid = wiki_technote_to_rid(zETime);

        if( rid>0 && (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0




           && (pWiki->zMimetype && *pWiki->zMimetype) ){
          zMimeType = pWiki->zMimetype;
        }
      }
    }else{
      zMimeType = wiki_filter_mimetypes(zMimeType);
    }
    if( g.argv[2][1]=='r' && rid>0 ){
      if ( !zETime ){
        fossil_fatal("wiki page %s already exists", zPageName);
      }else{
        /* Creating a tech note with same timestamp is permitted
           and should create a new tech note */
        rid = 0;
      }
    }else if( g.argv[2][1]=='o' && rid == 0 ){
      if ( !zETime ){
        fossil_fatal("no such wiki page: %s", zPageName);
      }else{
        fossil_fatal("no such tech note: %s", zETime);
      }
    }








>















<
<
|
|
|
|
|
|
>
|
<
<
|
|
|
>
|
>
>
>
>
|
|
<




|







|







1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515


1516
1517
1518
1519
1520
1521
1522
1523


1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
    return;
  }else if( strncmp(g.argv[2],"commit",n)==0
            || strncmp(g.argv[2],"create",n)==0 ){
    const char *zPageName;        /* page name */
    Blob content;                 /* Input content */
    int rid = 0;
    Manifest *pWiki = 0;          /* Parsed wiki page content */
    const int isCreate = 'r'==g.argv[2][1] /* else "commit" */;
    const char *zMimeType = find_option("mimetype", "M", 1);
    const char *zETime = find_option("technote", "t", 1);
    const char *zTags = find_option("technote-tags", NULL, 1);
    const char *zClr = find_option("technote-bgcolor", NULL, 1);
    if( g.argc!=4 && g.argc!=5 ){
      usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT]"
            " [--technote DATETIME] [--technote-tags TAGS]"
            " [--technote-bgcolor COLOR]");
    }
    zPageName = g.argv[3];
    if( g.argc==4 ){
      blob_read_from_channel(&content, stdin, -1);
    }else{
      blob_read_from_file(&content, g.argv[4], ExtFILE);
    }


    if ( !zETime ){
      rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
                   " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
                   " ORDER BY x.mtime DESC LIMIT 1",
                   zPageName
                   );
      if( rid>0 ){
        pWiki = manifest_get(rid, CFTYPE_WIKI, 0);


      }
    }else{
      rid = wiki_technote_to_rid(zETime);
      if( rid>0 ){
        pWiki = manifest_get(rid, CFTYPE_EVENT, 0);
      }
    }
    if( !zMimeType || !*zMimeType ){
      /* Try to deduce the mime type based on the prior version. */
      if( pWiki!=0 && (pWiki->zMimetype && *pWiki->zMimetype) ){
        zMimeType = pWiki->zMimetype;

      }
    }else{
      zMimeType = wiki_filter_mimetypes(zMimeType);
    }
    if( isCreate && rid>0 ){
      if ( !zETime ){
        fossil_fatal("wiki page %s already exists", zPageName);
      }else{
        /* Creating a tech note with same timestamp is permitted
           and should create a new tech note */
        rid = 0;
      }
    }else if( !isCreate && rid == 0 ){
      if ( !zETime ){
        fossil_fatal("no such wiki page: %s", zPageName);
      }else{
        fossil_fatal("no such tech note: %s", zETime);
      }
    }

Changes to www/changes.wiki.
1
2
3
4
5
6
7
8
9
10
11
<title>Change Log</title>

<a name='v2_10'></a>
<h2>Changes for Version 2.10 (pending)</h2>

  *  Added support for [./serverext.wiki|CGI-based Server Extensions].
  *  Added the [/help?cmd=repolist-skin|repolist-skin] setting used to
     add style to repository list pages.
  *  Enhance the hierarchical display of Forum threads to do less
     indentation and to provide links back to the previous message
     in the thread.  Provide sequential numbers for all messages in



|







1
2
3
4
5
6
7
8
9
10
11
<title>Change Log</title>

<a name='v2_10'></a>
<h2>Changes for Version 2.10 (2019-10-04)</h2>

  *  Added support for [./serverext.wiki|CGI-based Server Extensions].
  *  Added the [/help?cmd=repolist-skin|repolist-skin] setting used to
     add style to repository list pages.
  *  Enhance the hierarchical display of Forum threads to do less
     indentation and to provide links back to the previous message
     in the thread.  Provide sequential numbers for all messages in
Added www/javascript.md.
















































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# Use of JavaScript in Fossil

## Philosophy

The Fossil development project’s policy is to use JavaScript where it
helps make its web UI better, but to offer graceful fallbacks wherever
practical. The intent is that the UI be usable with JavaScript entirely
disabled.  In every place where Fossil uses JavaScript, it is an
enhancement to provided functionality, and there is always another way
to accomplish a given end without using JavaScript.

This is not to say that Fossil’s fall-backs for such cases are always as
elegant and functional as a no-JS purist might wish. That is simply
because [the vast majority of web users run with JS enabled](#stats),
and a minority of those run with some kind of conditional JavaScript
blocking in place. Fossil’s active developers do not deviate from that
norm enough that we have many no-JS purists among us, so the no-JS case
doesn’t get as much attention as some might want. We do [accept code
contributions][cg], and we are philosophically in favor of graceful
fall-backs, so you are welcome to appoint yourself the position of no-JS
czar for the Fossil project!

Evil is in actions, not in nouns, so we do not believe JavaScript *can*
be evil. It is an active technology, but the actions that matter here
are those of writing the code and checking it into the Fossil project
repository. None of the JavaScript code in Fossil is evil, a fact we
enforce by being careful about who we give check-in rights on the
repository to and by policing what code does get contributed. The Fossil
project does not accept non-trivial outside contributions.

We think it’s better to ask not whether Fossil requires JavaScript but
whether Fossil uses JavaScript *well*, so that [you can decide](#block)
to block or allow Fossil’s use of JavaScript.

[cg]: ./contribute.wiki


## <a id="block"></a>Blocking JavaScript

Rather than either block JavaScript wholesale or give up on blocking
JavaScript entirely, we recommend that you use tools like [NoScript][ns]
or [uBlock Origin][ub] to selectively block problematic uses of
JavaScript so the rest of the web can use the technology productively,
as it was intended. There are doubtless other useful tools of this sort;
we recommend only these two due to our limited experience, not out of
any wish to exclude other tools.

The primary difference between these two for our purposes is that
NoScript lets you select scripts to run on a page on a case-by-case
basis, whereas uBlock Origin delegates those choices to a group of
motivated volunteers who maintain whitelists and blacklists to control
all of this; you can then override UBO’s stock rules as needed.

[ns]: https://noscript.net/
[ub]: https://github.com/gorhill/uBlock/


## <a id="stats"></a>How Many Users Run with JavaScript Disabled Anyway?

There are several studies that have directly measured the web audience
to answer this question:

* [What percentage of browsers with javascript disabled?][s1]
* [How many people are missing out on JavaScript enhancement?][s2]
* [Just how many web users really disable cookies or JavaScript?][s3]

Our sense of this data is that only about 0.2% of web users had
JavaScript disabled while participating in these studies.

The Fossil user community is not typical of the wider web, but if we
were able to comprehensively survey our users, we’d expect to find an
interesting dichotomy. Because Fossil is targeted at software
developers, who in turn are more likely to be power-users, we’d expect
to find Fossil users to be more in favor of some amount of JavaScript
blocking than the average web user. Yet, we’d also expect to find that
our user base has a disproportionately high number who run [powerful
conditional blocking plugins](#block) in their browsers, rather than
block JS entirely. We suspect that between these two forces, the number
of no-JS purists among Fossil’s user base is still a tiny minority.

[s1]: https://blockmetry.com/blog/javascript-disabled
[s2]: https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-on-javascript-enhancement/
[s3]: https://w3techs.com/technologies/overview/client_side_language/all


## <a id="3pjs"></a>No Third-Party JavaScript in Fossil

Fossil does not use any third-party JavaScript libraries, not even very
common ones like jQuery. Every bit of JavaScript served by the stock
version of Fossil was written specifically for the Fossil project and is
stored [in its code repository](https://fossil-scm.org/fossil/file).

Therefore, if you want to hack on the JavaScript code served by Fossil
and mechanisms like [skin editing][cs] don’t suffice for your purposes,
you can hack on the JavaScript in your local instance directly, just as
you can hack on its C, SQL, and Tcl code. Fossil is free and open source
software, under [a single license][2cbsd].

[2cbsd]: https://fossil-scm.org/home/doc/trunk/COPYRIGHT-BSD2.txt
[cs]:    ./customskin.md


## <a id="snoop"></a>Fossil Does Not Snoop On You

There is no tracking or other snooping technology in Fossil other than
that necessary for basic security, such as IP address logging on
check-ins. (This is in part why we have no [comprehensive user
statistics](#stats)!)

Fossil attempts to set two cookies on all web clients: a login session
cookie and a display preferences cookie. These cookies are restricted to
the Fossil instance, so even this limited data cannot leak between
Fossil instances or into other web sites.

There is some server-side event logging, but that is done entirely
without JavaScript, so it’s off-topic here.


## <a id="uses"></a>Places Where Fossil’s Web UI Uses JavaScript

The remainder of this document will explain how Fossil currently uses
JavaScript and what it does when these uses are blocked.


### <a id="timeline"></a>Timeline Graph

Fossil’s [web timeline][wt] uses JavaScript to render the graph
connecting the visible check-ins to each other, so you can visualize
parent/child relationships, merge actions, etc. We’re not sure it’s even
possible to render this in static HTML, even with the aid of SVG, due to
the vagaries of web layout among browser engines, screen sizes, etc.

Fossil also uses JavaScript to handle clicks on the graph nodes to allow
diffs between versions, to display tooltips showing local context, etc.

_Graceful Fallback:_ When JavaScript is disabled, this column of the
timeline simply collapses to zero width. All of the information you can
get from the timeline can be retrieved from Fossil in other ways not
using JavaScript: the “`fossil timeline`” command, the “`fossil info`”
command, by clicking around within the web UI, etc.

_Potential Workaround:_ The timeline could be enhanced with `<noscript>`
tags that replace the graph with a column of checkboxes that control
what a series of form submit buttons do when clicked, replicating the
current JS-based features of the graph using client-server round-trips.
For example, you could click two of those checkboxes and then a button
labeled “Diff Selected” to replicate the current “click two nodes to
diff them” feature.

[wt]: https://fossil-scm.org/fossil/timeline


### <a id="wedit"></a>WYSIWYG Wiki Editor

The Admin → Wiki → “Enable WYSIWYG Wiki Editing” toggle switches the
default plaintext editor for [Fossil wiki][fw] documents to one that
works like a basic word processor. This feature requires JavaScript in
order to react to editor button clicks like the “**B**” button, meaning
“make \[selected\] text boldface.” There is no standard WYSIWYG editor
component in browsers, doubtless because it’s relatively straightforward
to create one using JavaScript.

_Graceful Fallback:_ Edit your wiki documents in the default plain text
wiki editor. Fossil’s wiki and Markdown language processors were
designed to be edited that way.

[fw]: ./wikitheory.wiki


### <a id="ln"></a>Line Numbering

When viewing source files, Fossil offers to show line numbers in some
cases. Toggling them on and off is currently handled in JavaScript.
([Example][mainc].)

_Workaround:_ Edit the URL to give the “`ln`” query parameter per [the
`/file` docs](/help?cmd=/file), or provide a patch to reload the page
with this parameter included/excluded to implement the toggle via a
server round-trip.

[mainc]: https://fossil-scm.org/fossil/artifact?ln&name=87d67e745


### <a id="sort"></a>Table Sorting

On pages showing a data table, the column headers may be clickable to do
a client-side sort of the data on that column.

_Potential Workaround:_ This feature could be enhanced to do the sort on
the server side using a page re-load.


### <a id="tree"></a>File Browser Tree View

The [file browser’s tree view mode][tv] uses JavaScript to handle clicks
on folders so they fold and unfold without needing to reload the entire
page.

_Graceful Fallback:_ When JavaScript is disabled, clicks on folders
reload the page showing the folder contents instead. You then have to
use the browser’s Back button to return to the higher folder level.

[tv]: https://www.fossil-scm.org/fossil/dir?type=tree


### <a id="hash"></a>Version Hashes

In several places where the Fossil web UI shows a check-in hash or
similar, hovering over that check-in shows a tooltip with details about
the type of artifact the hash refers to and allows you to click to copy
the hash to the clipboard.

_Graceful Fallback:_ When JavaScript is disabled, these tooltips simply
don’t appear. You can then select and copy the hash using your browser,
make “`fossil info`” queries on those hashes, etc.


### <a id="bots"></a>Anti-Bot Defenses

Fossil has [anti-bot defenses][abd], and it has some JavaScript code
that, if run, can drop some of these defenses if it decides a given page
was loaded on behalf of a human, rather than a bot.

_Graceful Fallback:_ You can use Fossil’s anonymous login feature to
convince the remote Fossil instance that you are not a bot. Coupled with
[the Fossil user capability system][caps], you can restore all
functionality that Fossil’s anti-bot defenses deny to random web clients
by default.

[abd]:  ./antibot.wiki
[caps]: ./caps/


### <a id="hbm"></a>Hamburger Menu

The default skin includes a “hamburger menu” (&#9776;) which uses
JavaScript to show a simplified version of the Fossil UI site map using
an animated-in dropdown.

_Graceful Fallback:_ Clicking the hamburger menu button with JavaScript
disabled will take you to the `/sitemap` page instead of showing a
simplified version of that page’s content in a drop-down.

_Workaround:_ You can remove this button by [editing the skin][cs]
header.


### <a id="clock"></a>Clock

Some stock Fossil skins include JavaScript-based features such as the
current time of day. The Xekri skin includes this in its header, for
example. A clock feature requires JavaScript not only to get the time
and update inline on the page once a minute, but also so it displays *in
the local time zone.*

Since none of this code provides a necessary Fossil feature, the core
developers are unlikely to try to make these features work better in the
absence of JavaScript.

However, we are willing to study patches to make this better. For
example, the wall clock displays could include the page load time in the
dynamically generated HTML shipped from the remote Fossil server, so
that in the absence of JavaScript, you at least get the page generation
time, expressed in the server’s time zone.
Changes to www/mkindex.tcl.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  blame.wiki {The Annotate/Blame Algorithm Of Fossil}
  blockchain.md {Fossil As Blockchain}
  branching.wiki {Branching, Forking, Merging, and Tagging}
  bugtheory.wiki {Bug Tracking In Fossil}
  build.wiki {Compiling and Installing Fossil}
  caps/ {Administering User Capabilities}
  caps/admin-v-setup.md {Differences Between Setup and Admin Users}
  caps/login-groups.md {Differences Between Setup and Admin Users}
  caps/ref.html {User Capability Reference}
  cgi.wiki {CGI Script Configuration Options}
  changes.wiki {Fossil Changelog}
  checkin_names.wiki {Check-in And Version Names}
  checkin.wiki {Check-in Checklist}
  childprojects.wiki {Child Projects}
  copyright-release.html {Contributor License Agreement}







<







17
18
19
20
21
22
23

24
25
26
27
28
29
30
  blame.wiki {The Annotate/Blame Algorithm Of Fossil}
  blockchain.md {Fossil As Blockchain}
  branching.wiki {Branching, Forking, Merging, and Tagging}
  bugtheory.wiki {Bug Tracking In Fossil}
  build.wiki {Compiling and Installing Fossil}
  caps/ {Administering User Capabilities}
  caps/admin-v-setup.md {Differences Between Setup and Admin Users}

  caps/ref.html {User Capability Reference}
  cgi.wiki {CGI Script Configuration Options}
  changes.wiki {Fossil Changelog}
  checkin_names.wiki {Check-in And Version Names}
  checkin.wiki {Check-in Checklist}
  childprojects.wiki {Child Projects}
  copyright-release.html {Contributor License Agreement}
55
56
57
58
59
60
61

62
63
64
65
66
67
68
  hacker-howto.wiki {Hacker How-To}
  hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
  /help {Lists of Commands and Webpages}
  hints.wiki {Fossil Tips And Usage Hints}
  index.wiki {Home Page}
  inout.wiki {Import And Export To And From Git}
  image-format-vs-repo-size.md {Image Format vs Fossil Repo Size}

  makefile.wiki {The Fossil Build Process}
  mirrorlimitations.md {Limitations On Git Mirrors}
  mirrortogithub.md {How To Mirror A Fossil Repository On GitHub}
  /md_rules {Markdown Formatting Rules}
  newrepo.wiki {How To Create A New Fossil Repository}
  password.wiki {Password Management And Authentication}
  pop.wiki {Principles Of Operation}







>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  hacker-howto.wiki {Hacker How-To}
  hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
  /help {Lists of Commands and Webpages}
  hints.wiki {Fossil Tips And Usage Hints}
  index.wiki {Home Page}
  inout.wiki {Import And Export To And From Git}
  image-format-vs-repo-size.md {Image Format vs Fossil Repo Size}
  javascript.md {Use of JavaScript in Fossil}
  makefile.wiki {The Fossil Build Process}
  mirrorlimitations.md {Limitations On Git Mirrors}
  mirrortogithub.md {How To Mirror A Fossil Repository On GitHub}
  /md_rules {Markdown Formatting Rules}
  newrepo.wiki {How To Create A New Fossil Repository}
  password.wiki {Password Management And Authentication}
  pop.wiki {Principles Of Operation}
Changes to www/permutedindex.html.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<ul>
<li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Up and Running in</a></li>
<li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
<li><a href="tech_overview.wiki"><b>A Technical Overview Of The Design And Implementation Of Fossil</b></a></li>
<li><a href="serverext.wiki"><b>Adding Extensions To A Fossil Server Using CGI Scripts</b></a></li>
<li><a href="adding_code.wiki"><b>Adding New Features To Fossil</b></a></li>
<li><a href="caps/admin-v-setup.md">Admin Users &mdash; Differences Between Setup and</a></li>
<li><a href="caps/login-groups.md">Admin Users &mdash; Differences Between Setup and</a></li>
<li><a href="caps/"><b>Administering User Capabilities</b></a></li>
<li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
<li><a href="alerts.md">Alerts And Notifications &mdash; Email</a></li>
<li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
<li><a href="blame.wiki">Algorithm Of Fossil &mdash; The Annotate/Blame</a></li>
<li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil &mdash; The</a></li>
<li><a href="customskin.md">Appearance of Web Pages &mdash; Theming: Customizing The</a></li>
<li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
<li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
<li><a href="backoffice.md">Backoffice mechanism of Fossil &mdash; The</a></li>
<li><a href="fossil_prompt.wiki">Bash Prompt &mdash; Fossilized</a></li>
<li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li>
<li><a href="caps/admin-v-setup.md">Between Setup and Admin Users &mdash; Differences</a></li>
<li><a href="caps/login-groups.md">Between Setup and Admin Users &mdash; Differences</a></li>
<li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 &mdash; Hash Policy: Choosing</a></li>
<li><a href="blockchain.md">Blockchain &mdash; Fossil As</a></li>
<li><a href="antibot.wiki">Bots &mdash; Defense against Spiders and</a></li>
<li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
<li><a href="branching.wiki"><b>Branching, Forking, Merging, and Tagging</b></a></li>
<li><a href="bugtheory.wiki"><b>Bug Tracking In Fossil</b></a></li>
<li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>







<













<







22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
<ul>
<li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Up and Running in</a></li>
<li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
<li><a href="tech_overview.wiki"><b>A Technical Overview Of The Design And Implementation Of Fossil</b></a></li>
<li><a href="serverext.wiki"><b>Adding Extensions To A Fossil Server Using CGI Scripts</b></a></li>
<li><a href="adding_code.wiki"><b>Adding New Features To Fossil</b></a></li>
<li><a href="caps/admin-v-setup.md">Admin Users &mdash; Differences Between Setup and</a></li>

<li><a href="caps/"><b>Administering User Capabilities</b></a></li>
<li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
<li><a href="alerts.md">Alerts And Notifications &mdash; Email</a></li>
<li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
<li><a href="blame.wiki">Algorithm Of Fossil &mdash; The Annotate/Blame</a></li>
<li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil &mdash; The</a></li>
<li><a href="customskin.md">Appearance of Web Pages &mdash; Theming: Customizing The</a></li>
<li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
<li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
<li><a href="backoffice.md">Backoffice mechanism of Fossil &mdash; The</a></li>
<li><a href="fossil_prompt.wiki">Bash Prompt &mdash; Fossilized</a></li>
<li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li>
<li><a href="caps/admin-v-setup.md">Between Setup and Admin Users &mdash; Differences</a></li>

<li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 &mdash; Hash Policy: Choosing</a></li>
<li><a href="blockchain.md">Blockchain &mdash; Fossil As</a></li>
<li><a href="antibot.wiki">Bots &mdash; Defense against Spiders and</a></li>
<li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
<li><a href="branching.wiki"><b>Branching, Forking, Merging, and Tagging</b></a></li>
<li><a href="bugtheory.wiki"><b>Bug Tracking In Fossil</b></a></li>
<li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<li><a href="shunning.wiki">Deleting Content From Fossil &mdash; Shunning:</a></li>
<li><a href="private.wiki">Deleting Private Branches &mdash; Creating, Syncing, and</a></li>
<li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm &mdash; Fossil</a></li>
<li><a href="delta_format.wiki">Delta Format &mdash; Fossil</a></li>
<li><a href="tech_overview.wiki">Design And Implementation Of Fossil &mdash; A Technical Overview Of The</a></li>
<li><a href="theory1.wiki">Design Of The Fossil DVCS &mdash; Thoughts On The</a></li>
<li><a href="caps/admin-v-setup.md"><b>Differences Between Setup and Admin Users</b></a></li>
<li><a href="caps/login-groups.md"><b>Differences Between Setup and Admin Users</b></a></li>
<li><a href="embeddeddoc.wiki">Documentation &mdash; Embedded Project</a></li>
<li><a href="contribute.wiki">Documentation To The Fossil Project &mdash; Contributing Code or</a></li>
<li><a href="aboutdownload.wiki">Download Page Works &mdash; How The</a></li>
<li><a href="theory1.wiki">DVCS &mdash; Thoughts On The Design Of The Fossil</a></li>
<li><a href="quotes.wiki">DVCSes in General &mdash; Quotes: What People Are Saying About Fossil, Git, and</a></li>
<li><a href="alerts.md"><b>Email Alerts And Notifications</b></a></li>
<li><a href="embeddeddoc.wiki"><b>Embedded Project Documentation</b></a></li>







<







88
89
90
91
92
93
94

95
96
97
98
99
100
101
<li><a href="shunning.wiki">Deleting Content From Fossil &mdash; Shunning:</a></li>
<li><a href="private.wiki">Deleting Private Branches &mdash; Creating, Syncing, and</a></li>
<li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm &mdash; Fossil</a></li>
<li><a href="delta_format.wiki">Delta Format &mdash; Fossil</a></li>
<li><a href="tech_overview.wiki">Design And Implementation Of Fossil &mdash; A Technical Overview Of The</a></li>
<li><a href="theory1.wiki">Design Of The Fossil DVCS &mdash; Thoughts On The</a></li>
<li><a href="caps/admin-v-setup.md"><b>Differences Between Setup and Admin Users</b></a></li>

<li><a href="embeddeddoc.wiki">Documentation &mdash; Embedded Project</a></li>
<li><a href="contribute.wiki">Documentation To The Fossil Project &mdash; Contributing Code or</a></li>
<li><a href="aboutdownload.wiki">Download Page Works &mdash; How The</a></li>
<li><a href="theory1.wiki">DVCS &mdash; Thoughts On The Design Of The Fossil</a></li>
<li><a href="quotes.wiki">DVCSes in General &mdash; Quotes: What People Are Saying About Fossil, Git, and</a></li>
<li><a href="alerts.md"><b>Email Alerts And Notifications</b></a></li>
<li><a href="embeddeddoc.wiki"><b>Embedded Project Documentation</b></a></li>
171
172
173
174
175
176
177

178
179
180
181
182
183
184
<li><a href="image-format-vs-repo-size.md"><b>Image Format vs Fossil Repo Size</b></a></li>
<li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
<li><a href="inout.wiki"><b>Import And Export To And From Git</b></a></li>
<li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
<li><a href="fossil-from-msvc.wiki"><b>Integrating Fossil in the Microsoft Express 2010 IDE</b></a></li>
<li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
<li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>

<li><a href="th1.md">Language &mdash; The TH1 Scripting</a></li>
<li><a href="copyright-release.html">License Agreement &mdash; Contributor</a></li>
<li><a href="mirrorlimitations.md"><b>Limitations On Git Mirrors</b></a></li>
<li><a href="../../../help"><b>Lists of Commands and Webpages</b></a></li>
<li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
<li><a href="../../../sitemap">Map &mdash; Site</a></li>
<li><a href="../../../md_rules"><b>Markdown Formatting Rules</b></a></li>







>







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<li><a href="image-format-vs-repo-size.md"><b>Image Format vs Fossil Repo Size</b></a></li>
<li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
<li><a href="inout.wiki"><b>Import And Export To And From Git</b></a></li>
<li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
<li><a href="fossil-from-msvc.wiki"><b>Integrating Fossil in the Microsoft Express 2010 IDE</b></a></li>
<li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
<li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>
<li><a href="javascript.md">JavaScript in Fossil &mdash; Use of</a></li>
<li><a href="th1.md">Language &mdash; The TH1 Scripting</a></li>
<li><a href="copyright-release.html">License Agreement &mdash; Contributor</a></li>
<li><a href="mirrorlimitations.md"><b>Limitations On Git Mirrors</b></a></li>
<li><a href="../../../help"><b>Lists of Commands and Webpages</b></a></li>
<li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
<li><a href="../../../sitemap">Map &mdash; Site</a></li>
<li><a href="../../../md_rules"><b>Markdown Formatting Rules</b></a></li>
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
<li><a href="selfcheck.wiki">Self Checks &mdash; Fossil Repository Integrity</a></li>
<li><a href="selfhost.wiki">Self Hosting Repositories &mdash; Fossil</a></li>
<li><a href="server/">Server &mdash; How To Configure A Fossil</a></li>
<li><a href="serverext.wiki">Server Extensions &mdash; CGI</a></li>
<li><a href="serverext.wiki">Server Using CGI Scripts &mdash; Adding Extensions To A Fossil</a></li>
<li><a href="settings.wiki">Settings &mdash; Fossil</a></li>
<li><a href="caps/admin-v-setup.md">Setup and Admin Users &mdash; Differences Between</a></li>
<li><a href="caps/login-groups.md">Setup and Admin Users &mdash; Differences Between</a></li>
<li><a href="hashpolicy.wiki">SHA1 and SHA3-256 &mdash; Hash Policy: Choosing Between</a></li>
<li><a href="hashpolicy.wiki">SHA3-256 &mdash; Hash Policy: Choosing Between SHA1 and</a></li>
<li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li>
<li><a href="fiveminutes.wiki">Single User &mdash; Up and Running in 5 Minutes as a</a></li>
<li><a href="../../../sitemap"><b>Site Map</b></a></li>
<li><a href="image-format-vs-repo-size.md">Size &mdash; Image Format vs Fossil Repo</a></li>
<li><a href="customskin.md">Skins &mdash; Custom</a></li>







<







242
243
244
245
246
247
248

249
250
251
252
253
254
255
<li><a href="selfcheck.wiki">Self Checks &mdash; Fossil Repository Integrity</a></li>
<li><a href="selfhost.wiki">Self Hosting Repositories &mdash; Fossil</a></li>
<li><a href="server/">Server &mdash; How To Configure A Fossil</a></li>
<li><a href="serverext.wiki">Server Extensions &mdash; CGI</a></li>
<li><a href="serverext.wiki">Server Using CGI Scripts &mdash; Adding Extensions To A Fossil</a></li>
<li><a href="settings.wiki">Settings &mdash; Fossil</a></li>
<li><a href="caps/admin-v-setup.md">Setup and Admin Users &mdash; Differences Between</a></li>

<li><a href="hashpolicy.wiki">SHA1 and SHA3-256 &mdash; Hash Policy: Choosing Between</a></li>
<li><a href="hashpolicy.wiki">SHA3-256 &mdash; Hash Policy: Choosing Between SHA1 and</a></li>
<li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li>
<li><a href="fiveminutes.wiki">Single User &mdash; Up and Running in 5 Minutes as a</a></li>
<li><a href="../../../sitemap"><b>Site Map</b></a></li>
<li><a href="image-format-vs-repo-size.md">Size &mdash; Image Format vs Fossil Repo</a></li>
<li><a href="customskin.md">Skins &mdash; Custom</a></li>
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
<li><a href="tickets.wiki">Ticket System &mdash; The Fossil</a></li>
<li><a href="customgraph.md">Timeline Graph &mdash; Theming: Customizing the</a></li>
<li><a href="hints.wiki">Tips And Usage Hints &mdash; Fossil</a></li>
<li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
<li><a href="unvers.wiki"><b>Unversioned Files</b></a></li>
<li><a href="fiveminutes.wiki"><b>Up and Running in 5 Minutes as a Single User</b></a></li>
<li><a href="hints.wiki">Usage Hints &mdash; Fossil Tips And</a></li>

<li><a href="fiveminutes.wiki">User &mdash; Up and Running in 5 Minutes as a Single</a></li>
<li><a href="caps/">User Capabilities &mdash; Administering</a></li>
<li><a href="caps/ref.html"><b>User Capability Reference</b></a></li>
<li><a href="caps/admin-v-setup.md">Users &mdash; Differences Between Setup and Admin</a></li>
<li><a href="caps/login-groups.md">Users &mdash; Differences Between Setup and Admin</a></li>
<li><a href="serverext.wiki">Using CGI Scripts &mdash; Adding Extensions To A Fossil Server</a></li>
<li><a href="ssl.wiki"><b>Using SSL with Fossil</b></a></li>
<li><a href="env-opts.md">Variables and Global Options &mdash; Environment</a></li>
<li><a href="whyusefossil.wiki">Version Control &mdash; Benefits Of</a></li>
<li><a href="checkin_names.wiki">Version Names &mdash; Check-in And</a></li>
<li><a href="fossil-v-git.wiki">Versus Git &mdash; Fossil</a></li>
<li><a href="tls-nginx.md">via HTTPS with nginx &mdash; Proxying Fossil</a></li>







>




<







284
285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
<li><a href="tickets.wiki">Ticket System &mdash; The Fossil</a></li>
<li><a href="customgraph.md">Timeline Graph &mdash; Theming: Customizing the</a></li>
<li><a href="hints.wiki">Tips And Usage Hints &mdash; Fossil</a></li>
<li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
<li><a href="unvers.wiki"><b>Unversioned Files</b></a></li>
<li><a href="fiveminutes.wiki"><b>Up and Running in 5 Minutes as a Single User</b></a></li>
<li><a href="hints.wiki">Usage Hints &mdash; Fossil Tips And</a></li>
<li><a href="javascript.md"><b>Use of JavaScript in Fossil</b></a></li>
<li><a href="fiveminutes.wiki">User &mdash; Up and Running in 5 Minutes as a Single</a></li>
<li><a href="caps/">User Capabilities &mdash; Administering</a></li>
<li><a href="caps/ref.html"><b>User Capability Reference</b></a></li>
<li><a href="caps/admin-v-setup.md">Users &mdash; Differences Between Setup and Admin</a></li>

<li><a href="serverext.wiki">Using CGI Scripts &mdash; Adding Extensions To A Fossil Server</a></li>
<li><a href="ssl.wiki"><b>Using SSL with Fossil</b></a></li>
<li><a href="env-opts.md">Variables and Global Options &mdash; Environment</a></li>
<li><a href="whyusefossil.wiki">Version Control &mdash; Benefits Of</a></li>
<li><a href="checkin_names.wiki">Version Names &mdash; Check-in And</a></li>
<li><a href="fossil-v-git.wiki">Versus Git &mdash; Fossil</a></li>
<li><a href="tls-nginx.md">via HTTPS with nginx &mdash; Proxying Fossil</a></li>
Changes to www/server/windows/service.md.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Fossil as a Windows Service

If you need Fossil to start automatically on Windows, it is suggested to install
Fossil as a Windows Service.

## Assumptions

1. You have Administrative access to a Windows 2012r2 or above server.
2. You have PowerShell 5.1 or above installed.

## Place Fossil on Server

However you obtained your copy of Fossil, it is recommended that you follow
Windows conventions and place it within `\Program Files (x86)\FossilSCM`.  Since
Fossil is a 32bit binary, this is the proper location for the executable.  This
way Fossil is in an expected location and you will have minimal issues with
Windows interfering in your ability to run Fossil as a service.  You will need
Administrative rights to place fossil at the recommended location.  You do NOT
need to add this location to the path, though you may do so if you wish.

## Make Fossil a Windows Service

Luckily the hard work to use Fossil as a Windows Service has been done by the
Fossil team.  We simply have to install it with the proper command line options.
As of Fossil 2.9 the built in `fossil winsrv` command is failing, so an

alternative service install using PowerShell is documented here.  The below
should all be entered as a single line in an Administrative PowerShell console.

```PowerShell
New-Service -Name fossil -DisplayName fossil -BinaryPathName '"C:\Program Files (x86)\FossilSCM\fossil.exe"
server --port 8080 --repolist "D:/Path/to/Repos"' -StartupType Automatic
```

Please note the use of forward slashes in the paths passed to Fossil.  Windows
will accept either back slashes or forward slashes in path names, but Fossil has
a preference for forward slashes.  The use of `--repolist` will make this a
multiple repository server.  If you want to serve only a single repository,
then leave off the `--repolist` parameter and provide the full path to the
proper repository file. Other options are listed in the
[fossil server](/help?cmd=server) documentation.

The service will be installed by default to use the Local Service account.
Since Fossil only needs access to local files, this is fine and causes no
issues.  The service will not be running once installed.  You will need to start
it to proceed (the `-StartupType Automatic` parameter to `New-Service` will
result in the service auto-starting on boot).  This can be done by entering













|
|









|
>
|
|


|



|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Fossil as a Windows Service

If you need Fossil to start automatically on Windows, it is suggested to install
Fossil as a Windows Service.

## Assumptions

1. You have Administrative access to a Windows 2012r2 or above server.
2. You have PowerShell 5.1 or above installed.

## Place Fossil on Server

However you obtained your copy of Fossil, it is recommended that you follow
Windows conventions and place it within `\Program Files\FossilSCM`.  Since
Fossil 2.10 is a 64bit binary, this is the proper location for the executable.  This
way Fossil is in an expected location and you will have minimal issues with
Windows interfering in your ability to run Fossil as a service.  You will need
Administrative rights to place fossil at the recommended location.  You do NOT
need to add this location to the path, though you may do so if you wish.

## Make Fossil a Windows Service

Luckily the hard work to use Fossil as a Windows Service has been done by the
Fossil team.  We simply have to install it with the proper command line options.
Fossil on Windows has a command `fossil winsrv` to allow installing Fossil as a
service on Windows, but the options are limited, so an alternative service
install using PowerShell is documented here.  The below should all be entered
as a single line in an Administrative PowerShell console.

```PowerShell
New-Service -Name fossil -DisplayName fossil -BinaryPathName '"C:\Program Files\FossilSCM\fossil.exe"
server --port 8080 --repolist "D:/Path/to/Repos"' -StartupType Automatic
```

Please note the use of forward slashes in the repolist path passed to Fossil.
Windows will accept either back slashes or forward slashes in path names, but
Fossil has a preference for forward slashes.  The use of `--repolist` will make
this a multiple repository server.  If you want to serve only a single
repository, then leave off the `--repolist` parameter and provide the full path
to the proper repository file. Other options are listed in the
[fossil server](/help?cmd=server) documentation.

The service will be installed by default to use the Local Service account.
Since Fossil only needs access to local files, this is fine and causes no
issues.  The service will not be running once installed.  You will need to start
it to proceed (the `-StartupType Automatic` parameter to `New-Service` will
result in the service auto-starting on boot).  This can be done by entering
Changes to www/server/windows/stunnel.md.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
## Configure Fossil Service for https

Following most of [Fossil as a Windows Service](./service.md), you will need
to change the command to install the Fossil Service to configure it properly for
use with stunnel as an https proxy.  Run the following instead:

```PowerShell
New-Service -Name fossil-secure -DisplayName fossil-secure -BinaryPathName '"C:\Program Files (x86)\FossilSCM\fossil.exe"
server --localhost --port 9000 --https --repolist "D:/Path/to/Repos"' -StartupType Automatic

```

The use of `--localhost` means Fossil will only listen for traffic on the local
host on the designated port - 9000 in this case - and will not respond to
network traffic.  Using `--https` will tell Fossil to generate HTTPS URLs rather







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
## Configure Fossil Service for https

Following most of [Fossil as a Windows Service](./service.md), you will need
to change the command to install the Fossil Service to configure it properly for
use with stunnel as an https proxy.  Run the following instead:

```PowerShell
New-Service -Name fossil-secure -DisplayName fossil-secure -BinaryPathName '"C:\Program Files\FossilSCM\fossil.exe"
server --localhost --port 9000 --https --repolist "D:/Path/to/Repos"' -StartupType Automatic

```

The use of `--localhost` means Fossil will only listen for traffic on the local
host on the designated port - 9000 in this case - and will not respond to
network traffic.  Using `--https` will tell Fossil to generate HTTPS URLs rather
Changes to www/serverext.wiki.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[./server/any/cgi.md|CGI], then add a line to the 
[./cgi.wiki#extroot|CGI script file] that says:

<blockquote><pre>
extroot: <i>DIRECTORY</i>
</pre></blockquote>

Or, if the Fossil server is begin run as using the 
"[./server/any/none.md|fossil server]" or
"[./server/any/none.md|fossil ui]" or 
"[./server/any/inetd.md|fossil http]" commands, then add an extra 
"--extroot <i>DIRECTORY</i>" option to that command.

The <i>DIRECTORY</i> is the DOCUMENT_ROOT for the CGI.
Files in the DOCUMENT_ROOT are accessed via URLs like this:







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[./server/any/cgi.md|CGI], then add a line to the 
[./cgi.wiki#extroot|CGI script file] that says:

<blockquote><pre>
extroot: <i>DIRECTORY</i>
</pre></blockquote>

Or, if the Fossil server is being run using the 
"[./server/any/none.md|fossil server]" or
"[./server/any/none.md|fossil ui]" or 
"[./server/any/inetd.md|fossil http]" commands, then add an extra 
"--extroot <i>DIRECTORY</i>" option to that command.

The <i>DIRECTORY</i> is the DOCUMENT_ROOT for the CGI.
Files in the DOCUMENT_ROOT are accessed via URLs like this: