Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge the "spelling" branch into trunk, fixing a huge number of typos, mostly in comments, but occasionally in error messages or help screens. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
db0c512767ac7e8854bf9df9dae42849 |
| User & Date: | drh 2012-11-04 17:41:29.329 |
Context
|
2012-11-05
| ||
| 21:10 | Do not run the graphical merging tool nor leave merge-droppings after a dry-run merge. Also improve the merge summary message at the end of a merge. check-in: cd2c0e4cb5 user: drh tags: trunk | |
| 13:56 | merge trunk check-in: b0e05a90b6 user: jan.nijtmans tags: use-blob_strip_bom | |
| 13:10 | If the committed file has CR/NL or UTF-16 (or both), give the user the possibility to convert it to resp NL or UTF-8 (or both) without committing check-in: c6223a8e2a user: jan.nijtmans tags: convert_before_commit | |
|
2012-11-04
| ||
| 18:03 | merge trunk check-in: e86aa2a1e8 user: jan.nijtmans tags: improve_commit_warning | |
| 17:41 | Merge the "spelling" branch into trunk, fixing a huge number of typos, mostly in comments, but occasionally in error messages or help screens. check-in: db0c512767 user: drh tags: trunk | |
| 12:59 | Fix typos. Closed-Leaf check-in: 45065c5c28 user: dmitry tags: spelling | |
| 11:58 | Improvements to the fix for [0ff64b0a5fc88e7e]: (1) Better error message and (2) allow the partial commit of the renamed file as long as its destination files is also part of the partial commit. check-in: c0fe455c78 user: drh tags: trunk | |
Changes
Changes to src/add.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
".fos",
".fos-journal",
".fos-wal",
".fos-shm",
};
/* Names of auxiliary files generated by SQLite when the "manifest"
| | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
".fos",
".fos-journal",
".fos-wal",
".fos-shm",
};
/* Names of auxiliary files generated by SQLite when the "manifest"
** property is enabled
*/
static const char *const azManifest[] = {
"manifest",
"manifest.uuid",
};
/* Cached setting "manifest" */
|
| ︙ | ︙ | |||
449 450 451 452 453 454 455 |
vid = db_lget_int("checkout",0);
if( vid==0 ){
fossil_panic("no checkout to add to");
}
db_begin_transaction();
/* step 1:
| | | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
vid = db_lget_int("checkout",0);
if( vid==0 ){
fossil_panic("no checkout to add to");
}
db_begin_transaction();
/* step 1:
** Populate the temp table "sfile" with the names of all unmanaged
** files currently in the check-out, except for files that match the
** --ignore or ignore-glob patterns and dot-files. Then add all of
** the files in the sfile temp table to the set of managed files.
*/
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
n = strlen(g.zLocalRoot);
blob_init(&path, g.zLocalRoot, n-1);
|
| ︙ | ︙ | |||
485 486 487 488 489 490 491 |
db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
}
fossil_print("DELETED %s\n", zFile);
nDelete++;
}
}
db_finalize(&q);
| | | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
}
fossil_print("DELETED %s\n", zFile);
nDelete++;
}
}
db_finalize(&q);
/* show command summary */
fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
db_end_transaction(isTest);
}
/*
|
| ︙ | ︙ |
Changes to src/blob.c.
| ︙ | ︙ | |||
669 670 671 672 673 674 675 |
}
}
void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
if( pBlob ) vxprintf(pBlob, zFormat, ap);
}
/*
| | | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 |
}
}
void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
if( pBlob ) vxprintf(pBlob, zFormat, ap);
}
/*
** Initialize a blob to the data on an input channel. Return
** the number of bytes read into the blob. Any prior content
** of the blob is discarded, not freed.
*/
int blob_read_from_channel(Blob *pBlob, FILE *in, int nToRead){
size_t n;
blob_zero(pBlob);
if( nToRead<0 ){
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | ** This file contains code to implement the file browser web interface. */ #include "config.h" #include "browse.h" #include <assert.h> /* | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** This file contains code to implement the file browser web interface. */ #include "config.h" #include "browse.h" #include <assert.h> /* ** This is the implementation of the "pathelement(X,N)" SQL function. ** ** If X is a unix-like pathname (with "/" separators) and N is an ** integer, then skip the initial N characters of X and return the ** name of the path component that begins on the N+1th character ** (numbered from 0). If the path component is a directory (if ** it is followed by other path components) then prepend "/". ** |
| ︙ | ︙ |
Changes to src/captcha.c.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code to a simple text-based CAPTCHA. Though easily ** defeated by a sophisticated attacker, this CAPTCHA does at least make ** scripting attacks more difficult. */ #include <assert.h> #include "config.h" #include "captcha.h" |
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
963 964 965 966 967 968 969 |
for(i=0; zOut[i]; i++){}
while( i>0 && fossil_isspace(zOut[i-1]) ) zOut[--i] = 0;
return zOut;
}
/*
** Return the name of the i-th CGI parameter. Return NULL if there
| | | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 |
for(i=0; zOut[i]; i++){}
while( i>0 && fossil_isspace(zOut[i-1]) ) zOut[--i] = 0;
return zOut;
}
/*
** Return the name of the i-th CGI parameter. Return NULL if there
** are fewer than i registered CGI parameters.
*/
const char *cgi_parameter_name(int i){
if( i>=0 && i<nUsedQP ){
return aParamQP[i].zName;
}else{
return 0;
}
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
715 716 717 718 719 720 721 | Blob *pComment, /* Check-in comment text */ int vid, /* blob-id of the parent manifest */ int verifyDate, /* Verify that child is younger */ Blob *pCksum, /* Repository checksum. May be 0 */ const char *zDateOvrd, /* Date override. If 0 then use 'now' */ const char *zUserOvrd, /* User override. If 0 then use g.zLogin */ const char *zBranch, /* Branch name. May be 0 */ | | | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 |
Blob *pComment, /* Check-in comment text */
int vid, /* blob-id of the parent manifest */
int verifyDate, /* Verify that child is younger */
Blob *pCksum, /* Repository checksum. May be 0 */
const char *zDateOvrd, /* Date override. If 0 then use 'now' */
const char *zUserOvrd, /* User override. If 0 then use g.zLogin */
const char *zBranch, /* Branch name. May be 0 */
const char *zColor, /* One-time background color. May be 0 */
const char *zBrClr, /* Persistent branch color. May be 0 */
const char **azTag, /* Tags to apply to this check-in */
int *pnFBcard /* Number of generated B- and F-cards */
){
char *zDate; /* Date of the check-in */
char *zParentUuid; /* UUID of parent check-in */
Blob filename; /* A single filename */
|
| ︙ | ︙ | |||
1248 1249 1250 1251 1252 1253 1254 |
db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
db_end_transaction(0);
db_begin_transaction();
}
/* Step 1: Insert records for all modified files into the blob
** table. If there were arguments passed to this command, only
| | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 |
db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
db_end_transaction(0);
db_begin_transaction();
}
/* Step 1: Insert records for all modified files into the blob
** table. If there were arguments passed to this command, only
** the identified files are inserted (if they have been modified).
*/
db_prepare(&q,
"SELECT id, %Q || pathname, mrid, %s, chnged, %s FROM vfile "
"WHERE chnged==1 AND NOT deleted AND is_selected(id)",
g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob","")),
glob_expr("pathname", db_get("binary-glob",""))
);
|
| ︙ | ︙ |
Changes to src/clone.c.
| ︙ | ︙ | |||
68 69 70 71 72 73 74 |
/*
** Delete all private content from a repository.
*/
void delete_private_content(void){
fix_private_blob_dependencies(1);
db_multi_exec(
"DELETE FROM blob WHERE rid IN private;"
| | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/*
** Delete all private content from a repository.
*/
void delete_private_content(void){
fix_private_blob_dependencies(1);
db_multi_exec(
"DELETE FROM blob WHERE rid IN private;"
"DELETE FROM delta WHERE rid IN private;"
"DELETE FROM private;"
"DROP TABLE IF EXISTS modreq;"
);
}
/*
|
| ︙ | ︙ |
Changes to src/configure.c.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to manage repository configurations. ** | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to manage repository configurations. ** ** By "repository configure" we mean the local state of a repository ** distinct from the versioned files. */ #include "config.h" #include "configure.h" #include <assert.h> #if INTERFACE |
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
const char *zName; /* Name of the configuration set */
int groupMask; /* Mask for that configuration set */
const char *zHelp; /* What it does */
} aGroupName[] = {
{ "/email", CONFIGSET_ADDR, "Concealed email addresses in tickets" },
{ "/project", CONFIGSET_PROJ, "Project name and description" },
{ "/skin", CONFIGSET_SKIN | CONFIGSET_CSS,
| | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
const char *zName; /* Name of the configuration set */
int groupMask; /* Mask for that configuration set */
const char *zHelp; /* What it does */
} aGroupName[] = {
{ "/email", CONFIGSET_ADDR, "Concealed email addresses in tickets" },
{ "/project", CONFIGSET_PROJ, "Project name and description" },
{ "/skin", CONFIGSET_SKIN | CONFIGSET_CSS,
"Web interface appearance settings" },
{ "/css", CONFIGSET_CSS, "Style sheet" },
{ "/shun", CONFIGSET_SHUN, "List of shunned artifacts" },
{ "/ticket", CONFIGSET_TKT, "Ticket setup", },
{ "/user", CONFIGSET_USER, "Users and privilege settings" },
{ "/xfer", CONFIGSET_XFER, "Transfer setup", },
{ "/all", CONFIGSET_ALL, "All of the above" },
};
|
| ︙ | ︙ | |||
162 163 164 165 166 167 168 | } return 0; } /* ** Return a pointer to a string that contains the RHS of an IN operator ** that will select CONFIG table names that are part of the configuration | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
}
return 0;
}
/*
** Return a pointer to a string that contains the RHS of an IN operator
** that will select CONFIG table names that are part of the configuration
** that matches iMatch.
*/
const char *configure_inop_rhs(int iMask){
Blob x;
int i;
const char *zSep = "";
blob_zero(&x);
|
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
){
int m = sqlite3_value_int(argv[0]);
configHasBeenReset |= m;
}
/*
** Create the temporary _xfer_reportfmt and _xfer_user tables that are
| | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
){
int m = sqlite3_value_int(argv[0]);
configHasBeenReset |= m;
}
/*
** Create the temporary _xfer_reportfmt and _xfer_user tables that are
** necessary in order to evaluate the SQL text generated by the
** configure_render_special_name() routine.
**
** If replaceFlag is true, then the setup is such that the content in
** the SQL text will completely replace the current repository configuration.
** If replaceFlag is false, then the SQL text will be merged with the
** existing configuration. When merging, existing values take priority
** over SQL text values.
|
| ︙ | ︙ | |||
458 459 460 461 462 463 464 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE ** /shun $MTIME $UUID scom $VALUE ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE ** /concealed $MTIME $HASH content $VALUE ** ** OLD FORMAT: ** | | | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE ** /shun $MTIME $UUID scom $VALUE ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE ** /concealed $MTIME $HASH content $VALUE ** ** OLD FORMAT: ** ** The old format is retained for backwards compatibility, but is deprecated. ** The cutover from old format to new was on 2011-04-25. After sufficient ** time has passed, support for the old format will be removed. ** ** zName is either the NAME of an element of the CONFIG table, or else ** one of the special names "@shun", "@reportfmt", "@user", or "@concealed". ** If zName is a CONFIG table name, then CONTENT replaces (overwrites) the ** element in the CONFIG table. For one of the @-labels, CONTENT is raw |
| ︙ | ︙ | |||
780 781 782 783 784 785 786 | ** Usage: %fossil configuration METHOD ... ?OPTIONS? ** ** Where METHOD is one of: export import merge pull push reset. All methods ** accept the -R or --repository option to specific a repository. ** ** %fossil configuration export AREA FILENAME ** | | | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | ** Usage: %fossil configuration METHOD ... ?OPTIONS? ** ** Where METHOD is one of: export import merge pull push reset. All methods ** accept the -R or --repository option to specific a repository. ** ** %fossil configuration export AREA FILENAME ** ** Write to FILENAME exported configuration information for AREA. ** AREA can be one of: all email project shun skin ticket user ** ** %fossil configuration import FILENAME ** ** Read a configuration from FILENAME, overwriting the current ** configuration. ** |
| ︙ | ︙ |
Changes to src/content.c.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | ** Procedures store and retrieve records from the repository */ #include "config.h" #include "content.h" #include <assert.h> /* | | | | | 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 |
** Procedures store and retrieve records from the repository
*/
#include "config.h"
#include "content.h"
#include <assert.h>
/*
** The artifact retrieval cache
*/
static struct {
i64 szTotal; /* Total size of all entries in the cache */
int n; /* Current number of cache entries */
int nAlloc; /* Number of slots allocated in a[] */
int nextAge; /* Age counter for implementing LRU */
int skipCnt; /* Used to limit entries expelled from cache */
struct cacheLine { /* One instance of this for each cache entry */
int rid; /* Artifact id */
int age; /* Age. Newer is larger */
Blob content; /* Content of the artifact */
} *a; /* The positive cache */
Bag inCache; /* Set of artifacts currently in cache */
/*
** The missing artifact cache.
**
** Artifacts whose record ID are in missingCache cannot be retrieved
** either because they are phantoms or because they are a delta that
** depends on a phantom. Artifacts whose content we are certain is
** available are in availableCache. If an artifact is in neither cache
** then its current availability is unknown.
*/
Bag missing; /* Cache of artifacts that are incomplete */
Bag available; /* Cache of artifacts that are complete */
} contentCache;
/*
** Remove the oldest element from the content cache
|
| ︙ | ︙ | |||
469 470 471 472 473 474 475 | ** and zUuid is zero then the correct zUuid is computed from pBlob. ** ** If the record already exists but is a phantom, the pBlob content ** is inserted and the phatom becomes a real record. ** ** The original content of pBlob is not disturbed. The caller continues ** to be responsible for pBlob. This routine does *not* take over | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | ** and zUuid is zero then the correct zUuid is computed from pBlob. ** ** If the record already exists but is a phantom, the pBlob content ** is inserted and the phatom becomes a real record. ** ** The original content of pBlob is not disturbed. The caller continues ** to be responsible for pBlob. This routine does *not* take over ** responsibility for freeing pBlob. */ int content_put_ex( Blob *pBlob, /* Content to add to the repository */ const char *zUuid, /* SHA1 hash of reconstructed pBlob */ int srcId, /* pBlob is a delta from this entry */ int nBlob, /* pBlob is compressed. Original size is this */ int isPrivate /* The content should be marked private */ |
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
211 212 213 214 215 216 217 | } } /* ** Install a commit hook. Hooks are installed in sequence order. ** It is an error to install the same commit hook more than once. ** | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
}
}
/*
** Install a commit hook. Hooks are installed in sequence order.
** It is an error to install the same commit hook more than once.
**
** Each commit hook is called (in order of ascending sequence) at
** each commit operation. If any commit hook returns non-zero,
** the subsequence commit hooks are omitted and the transaction
** rolls back rather than commit. It is the responsibility of the
** hooks themselves to issue any error messages.
*/
void db_commit_hook(int (*x)(void), int sequence){
int i;
|
| ︙ | ︙ | |||
323 324 325 326 327 328 329 |
}
int db_bind_blob(Stmt *pStmt, const char *zParamName, Blob *pBlob){
return sqlite3_bind_blob(pStmt->pStmt, paramIdx(pStmt, zParamName),
blob_buffer(pBlob), blob_size(pBlob), SQLITE_STATIC);
}
/* bind_str() treats a Blob object like a TEXT string and binds it
| | | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
}
int db_bind_blob(Stmt *pStmt, const char *zParamName, Blob *pBlob){
return sqlite3_bind_blob(pStmt->pStmt, paramIdx(pStmt, zParamName),
blob_buffer(pBlob), blob_size(pBlob), SQLITE_STATIC);
}
/* bind_str() treats a Blob object like a TEXT string and binds it
** to the SQL variable. Contrast this to bind_blob() which treats
** the Blob object like an SQL BLOB.
*/
int db_bind_str(Stmt *pStmt, const char *zParamName, Blob *pBlob){
return sqlite3_bind_text(pStmt->pStmt, paramIdx(pStmt, zParamName),
blob_buffer(pBlob), blob_size(pBlob), SQLITE_STATIC);
}
|
| ︙ | ︙ | |||
447 448 449 450 451 452 453 |
}
void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){
blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
sqlite3_column_bytes(pStmt->pStmt, N));
}
/*
| | | 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
}
void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){
blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
sqlite3_column_bytes(pStmt->pStmt, N));
}
/*
** Initialize a blob to an ephemeral copy of the content of a
** column in the current row. The data in the blob will become
** invalid when the statement is stepped or reset.
*/
void db_ephemeral_blob(Stmt *pStmt, int N, Blob *pBlob){
blob_init(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
sqlite3_column_bytes(pStmt->pStmt, N));
}
|
| ︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 |
){
if( g.zLogin!=0 ){
sqlite3_result_text(context, g.zLogin, -1, SQLITE_STATIC);
}
}
/*
| | | | 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 |
){
if( g.zLogin!=0 ){
sqlite3_result_text(context, g.zLogin, -1, SQLITE_STATIC);
}
}
/*
** Implement the cgi() SQL function. cgi() takes an argument which is
** a name of CGI query parameter. The value of that parameter is returned,
** if available. Optional second argument will be returned if the first
** doesn't exist as a CGI parameter.
*/
static void db_sql_cgi(sqlite3_context *context, int argc, sqlite3_value **argv){
const char* zP;
if( argc!=1 && argc!=2 ) return;
zP = P((const char*)sqlite3_value_text(argv[0]));
if( zP ){
|
| ︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 | ** Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output" ** Ex: xxdiff "%original" "%baseline" "%merge" -M "%output" ** Ex: meld "%baseline" "%original" "%merge" "%output" ** ** http-port The TCP/IP port number to use by the "server" ** and "ui" commands. Default: 8080 ** | | | 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 | ** Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output" ** Ex: xxdiff "%original" "%baseline" "%merge" -M "%output" ** Ex: meld "%baseline" "%original" "%merge" "%output" ** ** http-port The TCP/IP port number to use by the "server" ** and "ui" commands. Default: 8080 ** ** https-login Send login credentials using HTTPS instead of HTTP ** even if the login page request came via HTTP. ** ** ignore-glob The VALUE is a comma or newline-separated list of GLOB ** (versionable) patterns specifying files that the "extra" command will ** ignore. Example: *.o,*.obj,*.exe ** ** localauth If enabled, require that HTTP connections from |
| ︙ | ︙ | |||
2292 2293 2294 2295 2296 2297 2298 |
}
}else{
usage("?PROPERTY? ?VALUE?");
}
}
/*
| | | 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 |
}
}else{
usage("?PROPERTY? ?VALUE?");
}
}
/*
** The input in a timespan measured in days. Return a string which
** describes that timespan in units of seconds, minutes, hours, days,
** or years, depending on its duration.
*/
char *db_timespan_name(double rSpan){
if( rSpan<0 ) rSpan = -rSpan;
rSpan *= 24.0*3600.0; /* Convert units to seconds */
if( rSpan<120.0 ){
|
| ︙ | ︙ |
Changes to src/delta.c.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 | ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This module implements the delta compress algorithm. ** ** Though developed specifically for fossil, the code in this file | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This module implements the delta compress algorithm. ** ** Though developed specifically for fossil, the code in this file ** is generally applicable and is thus easily separated from the ** fossil source code base. Nothing in this file depends on anything ** else in fossil. */ #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <string.h> |
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** | | | | 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 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to find descendants of a version ** or leaves of a version tree. */ #include "config.h" #include "descendants.h" #include <assert.h> /* ** Create a temporary table named "leaves" if it does not ** already exist. Load this table with the RID of all ** check-ins that are leaves which are descended from ** check-in iBase. ** ** A "leaf" is a check-in that has no children in the same branch. ** There is a separate permanent table LEAF that contains all leaves ** in the tree. This routine is used to compute a subset of that ** table consisting of leaves that are descended from a single checkin. ** |
| ︙ | ︙ | |||
69 70 71 72 73 74 75 |
/* Initialize the bags. */
bag_init(&seen);
bag_init(&pending);
bag_insert(&pending, iBase);
/* This query returns all non-branch-merge children of check-in :rid.
**
| | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
/* Initialize the bags. */
bag_init(&seen);
bag_init(&pending);
bag_insert(&pending, iBase);
/* This query returns all non-branch-merge children of check-in :rid.
**
** If a child is a merge of a fork within the same branch, it is
** returned. Only merge children in different branches are excluded.
*/
db_prepare(&q1,
"SELECT cid FROM plink"
" WHERE pid=:rid"
" AND (isprim"
" OR coalesce((SELECT value FROM tagxref"
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 | #include "config.h" #include "diff.h" #include <assert.h> #if INTERFACE /* | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include "config.h" #include "diff.h" #include <assert.h> #if INTERFACE /* ** Allowed flag parameters to the text_diff() and html_sbsdiff() functions: */ #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ #define DIFF_SIDEBYSIDE ((u64)0x02000000) /* Generate a side-by-side diff */ #define DIFF_NEWFILE ((u64)0x04000000) /* Missing shown as empty files */ #define DIFF_BRIEF ((u64)0x08000000) /* Show filenames only */ |
| ︙ | ︙ | |||
2087 2088 2089 2090 2091 2092 2093 |
*/
void annotate_cmd(void){
int fnid; /* Filename ID */
int fid; /* File instance ID */
int mid; /* Manifest where file was checked in */
int cid; /* Checkout ID */
Blob treename; /* FILENAME translated to canonical form */
| | | 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 |
*/
void annotate_cmd(void){
int fnid; /* Filename ID */
int fid; /* File instance ID */
int mid; /* Manifest where file was checked in */
int cid; /* Checkout ID */
Blob treename; /* FILENAME translated to canonical form */
char *zFilename; /* Canonical filename */
Annotator ann; /* The annotation of the file */
int i; /* Loop counter */
const char *zLimit; /* The value to the --limit option */
int iLimit; /* How far back in time to look */
int showLog; /* True to show the log */
int fileVers; /* Show file version instead of check-in versions */
int annFlags = 0; /* Flags to control annotation properties */
|
| ︙ | ︙ |
Changes to src/encode.c.
| ︙ | ︙ | |||
132 133 134 135 136 137 138 | zOut[i] = 0; return zOut; } /* ** Convert the input string into a form that is suitable for use as ** a token in the HTTP protocol. Spaces are encoded as '+' and special | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
zOut[i] = 0;
return zOut;
}
/*
** Convert the input string into a form that is suitable for use as
** a token in the HTTP protocol. Spaces are encoded as '+' and special
** characters are encoded as "%HH" where HH is a two-digit hexadecimal
** representation of the character. The "/" character is encoded
** as "%2F".
*/
char *httpize(const char *z, int n){
return EncodeHttp(z, n, 1);
}
|
| ︙ | ︙ |
Changes to src/glob.c.
| ︙ | ︙ | |||
214 215 216 217 218 219 220 |
}
}
return *z==0;
}
/*
** Return true (non-zero) if zString matches any of the patterns in
| | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
}
}
return *z==0;
}
/*
** Return true (non-zero) if zString matches any of the patterns in
** the Glob. The value returned is actually a 1-based index of the pattern
** that matched. Return 0 if none of the patterns match zString.
**
** A NULL glob matches nothing.
*/
int glob_match(Glob *pGlob, const char *zString){
int i;
if( pGlob==0 ) return 0;
|
| ︙ | ︙ |
Changes to src/http_socket.c.
| ︙ | ︙ | |||
124 125 126 127 128 129 130 |
#endif
iSocket = -1;
}
}
/*
** Open a socket connection. The identify of the server is determined
| | | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
#endif
iSocket = -1;
}
}
/*
** Open a socket connection. The identify of the server is determined
** by global variables that are set using url_parse():
**
** g.urlName Name of the server. Ex: www.fossil-scm.org
** g.urlPort TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int socket_open(void){
|
| ︙ | ︙ |
Changes to src/http_ssl.c.
| ︙ | ︙ | |||
180 181 182 183 184 185 186 |
(void)BIO_reset(iBio);
BIO_free_all(iBio);
}
}
/*
** Open an SSL connection. The identify of the server is determined
| | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
(void)BIO_reset(iBio);
BIO_free_all(iBio);
}
}
/*
** Open an SSL connection. The identify of the server is determined
** by global variables that are set using url_parse():
**
** g.urlName Name of the server. Ex: www.fossil-scm.org
** g.urlPort TCP/IP port to use. Ex: 80
**
** Return the number of errors.
*/
int ssl_open(void){
|
| ︙ | ︙ |
Changes to src/http_transport.c.
| ︙ | ︙ | |||
290 291 292 293 294 295 296 |
n -= sent;
}
}
}
/*
** This routine is called when the outbound message is complete and
| | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
n -= sent;
}
}
}
/*
** This routine is called when the outbound message is complete and
** it is time to being receiving a reply.
*/
void transport_flip(void){
if( g.urlIsSsh ){
fprintf(sshOut, "\n\n");
}else if( g.urlIsFile ){
char *zCmd;
fclose(transport.pFile);
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
320 321 322 323 324 325 326 |
static char buf[BufSize] = {'F','O','S','S','I','L','-',0};
assert((code >= 1000) && (code <= 9999) && "Invalid Fossil/JSON code.");
sprintf(buf+7,"%04d", code);
return buf;
}
/*
| | | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
static char buf[BufSize] = {'F','O','S','S','I','L','-',0};
assert((code >= 1000) && (code <= 9999) && "Invalid Fossil/JSON code.");
sprintf(buf+7,"%04d", code);
return buf;
}
/*
** Adds v to the API-internal cleanup mechanism. key is ignored
** (legacy) but might be re-introduced and "should" be a unique
** (app-wide) value. Failure to insert an item may be caused by any
** of the following:
**
** - Allocation error.
** - g.json.gc.a is NULL
** - key is NULL or empty.
|
| ︙ | ︙ | |||
822 823 824 825 826 827 828 |
them in.
*/
v = cson_value_new_array();
g.json.gc.v = v;
g.json.gc.a = cson_value_get_array(v);
cson_value_add_reference(v)
/* Needed to allow us to include this value in other JSON
| | | 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 |
them in.
*/
v = cson_value_new_array();
g.json.gc.v = v;
g.json.gc.a = cson_value_get_array(v);
cson_value_add_reference(v)
/* Needed to allow us to include this value in other JSON
containers without transferring ownership to those containers.
All other persistent g.json.XXX.v values get appended to
g.json.gc.a, and therefore already have a live reference
for this purpose.
*/
;
/*
|
| ︙ | ︙ | |||
1464 1465 1466 1467 1468 1469 1470 | ** on error. ** ** If payload is not NULL and resultCode is 0 then it is set as the ** "payload" property of the returned object. If resultCode is 0 then ** it defaults to g.json.resultCode. If resultCode is (or defaults to) ** non-zero and payload is not NULL then this function calls ** cson_value_free(payload) and does not insert the payload into the | | | 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 | ** on error. ** ** If payload is not NULL and resultCode is 0 then it is set as the ** "payload" property of the returned object. If resultCode is 0 then ** it defaults to g.json.resultCode. If resultCode is (or defaults to) ** non-zero and payload is not NULL then this function calls ** cson_value_free(payload) and does not insert the payload into the ** response. In either case, ownership of payload is transfered to (or ** shared with, if the caller holds a reference) this function. ** ** pMsg is an optional message string property (resultText) of the ** response. If resultCode is non-0 and pMsg is NULL then ** json_err_cstr() is used to get the error string. The caller may ** provide his own or may use an empty string to suppress the ** resultText property. |
| ︙ | ︙ | |||
1535 1536 1537 1538 1539 1540 1541 |
tmp = g.json.cmd.v;
SET("$commandPath");
}
if(g.json.param.v){
tmp = g.json.param.v;
SET("$params");
}
| | | | 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 |
tmp = g.json.cmd.v;
SET("$commandPath");
}
if(g.json.param.v){
tmp = g.json.param.v;
SET("$params");
}
if(0){/*Only for debugging, add some info to the response.*/
tmp = cson_value_new_integer( g.json.cmd.offset );
cson_object_set( o, "cmd.offset", tmp );
cson_object_set( o, "isCGI", cson_value_new_bool( g.isHTTP ) );
}
}
if(HAS_TIMER){
/* This is, philosophically speaking, not quite the right place
for ending the timer, but this is the one function which all of
the JSON exit paths use (and they call it after processing,
just before they end).
*/
double span;
span = END_TIMER;
/* I'm actually seeing sub-ms runtimes in some tests, but a time of
0 is "just wrong", so we'll bump that up to 1ms.
*/
cson_object_set(o,"procTimeMs", cson_value_new_integer((cson_int_t)((span>1.0)?span:1)));
}
if(g.json.warnings){
tmp = cson_array_value(g.json.warnings);
SET("warnings");
|
| ︙ | ︙ | |||
2182 2183 2184 2185 2186 2187 2188 |
++g.json.dispatchDepth;
return (*def->func)();
}
}
/*
| | | 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 |
++g.json.dispatchDepth;
return (*def->func)();
}
}
/*
** Impl of /json/rebuild. Requires admin privileges.
*/
static cson_value * json_page_rebuild(){
if( !g.perm.Admin ){
json_set_err(FSL_JSON_E_DENIED,"Requires 'a' privileges.");
return NULL;
}else{
/* Reminder: the db_xxx() ops "should" fail via the fossil core
|
| ︙ | ︙ | |||
2355 2356 2357 2358 2359 2360 2361 | ** ** In CLI mode, the -R REPO common option is supported. Due to limitations ** in the argument dispatching code, any -FLAGS must come after the final ** sub- (or subsub-) command. ** ** The commands include: ** | | | 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 | ** ** In CLI mode, the -R REPO common option is supported. Due to limitations ** in the argument dispatching code, any -FLAGS must come after the final ** sub- (or subsub-) command. ** ** The commands include: ** ** anonymousPassword ** artifact ** branch ** cap ** config ** diff ** dir ** g |
| ︙ | ︙ |
Changes to src/json_detail.h.
| ︙ | ︙ | |||
115 116 117 118 119 120 121 | ** responsible for handling one JSON request/command and/or ** dispatching to sub-commands. ** ** By the time the callback is called, json_page_top() (HTTP mode) or ** json_cmd_top() (CLI mode) will have set up the JSON-related ** environment. Implementations may generate a "result payload" of any ** JSON type by returning its value from this function (ownership is | | | | | | 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 | ** responsible for handling one JSON request/command and/or ** dispatching to sub-commands. ** ** By the time the callback is called, json_page_top() (HTTP mode) or ** json_cmd_top() (CLI mode) will have set up the JSON-related ** environment. Implementations may generate a "result payload" of any ** JSON type by returning its value from this function (ownership is ** transferred to the caller). On error they should set ** g.json.resultCode to one of the FossilJsonCodes values and return ** either their payload object or NULL. Note that NULL is a legal ** success value - it simply means the response will contain no ** payload. If g.json.resultCode is non-zero when this function ** returns then the top-level dispatcher will destroy any payload ** returned by this function and will output a JSON error response ** instead. ** ** All of the setup/response code is handled by the top dispatcher ** functions and the callbacks concern themselves only with: ** ** a) Permissions checking (inspecting g.perm). ** b) generating a response payload (if applicable) ** c) Setting g.json's error state (if applicable). See json_set_err(). ** ** It is imperative that NO callback functions EVER output ANYTHING to ** stdout, as that will effectively corrupt any JSON output, and ** almost certainly will corrupt any HTTP response headers. Output ** sent to stderr ends up in my apache log, so that might be useful ** for debugging in some cases, but no such code should be left ** enabled for non-debugging builds. */ typedef cson_value * (*fossil_json_f)(); /* ** Holds name-to-function mappings for JSON page/command dispatching. ** ** Internally we model page dispatching lists as arrays of these |
| ︙ | ︙ | |||
173 174 175 176 177 178 179 | fossil_json_f func; /* ** Which mode(s) of execution does func() support: ** ** <0 = CLI only, >0 = HTTP only, 0==both ** ** Now that we can simulate POST in CLI mode, the distinction | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | fossil_json_f func; /* ** Which mode(s) of execution does func() support: ** ** <0 = CLI only, >0 = HTTP only, 0==both ** ** Now that we can simulate POST in CLI mode, the distinction ** between them has disappeared in most (or all) cases, so 0 is ** the standard value. ** ** 201207: this is not needed any more. We can get rid of it. Or ** keep it around in case it becomes useful again at some point. */ char runMode; } JsonPageDef; |
| ︙ | ︙ | |||
206 207 208 209 210 211 212 | /* ** A page/command dispatch helper for fossil_json_f() implementations. ** pages must be an array of JsonPageDef commands which we can ** dispatch. The final item in the array MUST have a NULL name ** element. ** ** This function takes the command specified in | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | /* ** A page/command dispatch helper for fossil_json_f() implementations. ** pages must be an array of JsonPageDef commands which we can ** dispatch. The final item in the array MUST have a NULL name ** element. ** ** This function takes the command specified in ** json_command_arg(1+g.json.dispatchDepth) and searches pages for a ** matching name. If found then that page's func() is called to fetch ** the payload, which is returned to the caller. ** ** On error, g.json.resultCode is set to one of the FossilJsonCodes ** values and NULL is returned. If non-NULL is returned, ownership is ** transfered to the caller (but the g.json error state might still be ** set in that case, so the caller must check that or pass it on up |
| ︙ | ︙ | |||
249 250 251 252 253 254 255 | ** ** a) Not running in JSON mode (via json command or /json path). ** ** b) We are running in JSON CLI mode, but no POST data has been fed ** in. ** ** Whether or not we need to take args from CLI or POST data makes a | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
**
** a) Not running in JSON mode (via json command or /json path).
**
** b) We are running in JSON CLI mode, but no POST data has been fed
** in.
**
** Whether or not we need to take args from CLI or POST data makes a
** difference in argument/parameter handling in many JSON routines,
** and thus this distinction.
*/
char fossil_has_json();
enum json_get_changed_files_flags {
json_get_changed_files_ELIDE_PARENT = 1 << 0
};
#endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/
#endif /* FOSSIL_ENABLE_JSON */
|
Changes to src/json_login.c.
| ︙ | ︙ | |||
167 168 169 170 171 172 173 |
the expiry time is assigned. (Remember that JSON doesn't do
unsigned int.)
For non-anonymous users we could also simply query the
user.cexpire db field after calling login_set_user_cookie(),
but for anonymous we need to get the time when the cookie is
set because anon does not get a db entry like normal users
| | | | | 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 |
the expiry time is assigned. (Remember that JSON doesn't do
unsigned int.)
For non-anonymous users we could also simply query the
user.cexpire db field after calling login_set_user_cookie(),
but for anonymous we need to get the time when the cookie is
set because anon does not get a db entry like normal users
do. Anonymous cookies currently have a hard-coded lifetime in
login_set_anon_cookie() (currently 6 hours), which we "should
arguably" change to use the time configured for non-anonymous
users (see login_set_user_cookie() for details).
*/
return payload;
}
}
/*
** Impl of /json/logout.
**
*/
cson_value * json_page_logout(){
cson_value const *token = g.json.authToken;
/* Remember that json_mode_bootstrap() replaces the login cookie
with the JSON auth token if the request contains it. If the
request is missing the auth token then this will fetch fossil's
original cookie. Either way, it's what we want :).
We require the auth token to avoid someone maliciously
trying to log someone else out (not 100% sure if that
would be possible, given fossil's hardened cookie, but
I'll assume it would be for the time being).
*/
;
if(!token){
g.json.resultCode = FSL_JSON_E_MISSING_AUTH;
}else{
login_clear_login_data();
g.json.authToken = NULL /* memory is owned elsewhere.*/;
|
| ︙ | ︙ |
Changes to src/json_tag.c.
| ︙ | ︙ | |||
283 284 285 286 287 288 289 |
" coalesce(ecomment,comment) AS comment,"
" coalesce(euser,user) AS user,"
" CASE event.type"
" WHEN 'ci' THEN 'checkin'"
" WHEN 'w' THEN 'wiki'"
" WHEN 'e' THEN 'event'"
" WHEN 't' THEN 'ticket'"
| | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
" coalesce(ecomment,comment) AS comment,"
" coalesce(euser,user) AS user,"
" CASE event.type"
" WHEN 'ci' THEN 'checkin'"
" WHEN 'w' THEN 'wiki'"
" WHEN 'e' THEN 'event'"
" WHEN 't' THEN 'ticket'"
" ELSE 'unknown'"
" END"
" AS eventType"
" FROM event, blob"
" WHERE blob.rid=event.objid"
;
/* FIXME: re-add tags. */
db_prepare(&q,
|
| ︙ | ︙ |
Changes to src/json_timeline.c.
| ︙ | ︙ | |||
627 628 629 630 631 632 633 |
int const rid = db_column_int(&q,0);
Manifest * pMan = NULL;
cson_value * rowV;
cson_object * row;
/*printf("rid=%d\n",rid);*/
pMan = manifest_get(rid, CFTYPE_TICKET);
if(!pMan){
| | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
int const rid = db_column_int(&q,0);
Manifest * pMan = NULL;
cson_value * rowV;
cson_object * row;
/*printf("rid=%d\n",rid);*/
pMan = manifest_get(rid, CFTYPE_TICKET);
if(!pMan){
/* this might be an attachment? I'm seeing this with
rid 15380, uuid [1292fef05f2472108].
/json/artifact/1292fef05f2472108 returns not-found,
probably because we haven't added artifact/ticket
yet(?).
*/
continue;
|
| ︙ | ︙ |
Changes to src/json_wiki.c.
| ︙ | ︙ | |||
208 209 210 211 212 213 214 |
char contentFormat ){
if(!zSymname || !*zSymname){
return json_get_wiki_page_by_name(zPageName, contentFormat);
}else{
int rid = symbolic_name_to_rid( zSymname ? zSymname : zPageName, "w" );
if(rid<0){
json_set_err(FSL_JSON_E_AMBIGUOUS_UUID,
| | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
char contentFormat ){
if(!zSymname || !*zSymname){
return json_get_wiki_page_by_name(zPageName, contentFormat);
}else{
int rid = symbolic_name_to_rid( zSymname ? zSymname : zPageName, "w" );
if(rid<0){
json_set_err(FSL_JSON_E_AMBIGUOUS_UUID,
"UUID [%s] is ambiguous.", zSymname);
return NULL;
}else if(rid==0){
json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,
"UUID [%s] does not resolve to a wiki page.", zSymname);
return NULL;
}else{
return json_get_wiki_page_by_rid(rid, contentFormat);
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
352 353 354 355 356 357 358 |
login_cookie_path(), -86400);
db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, "
" cexpire=0 WHERE uid=%d"
" AND login NOT IN ('anonymous','nobody',"
" 'developer','reader')", g.userUid);
cgi_replace_parameter(cookie, NULL)
/* At the time of this writing, cgi_replace_parameter() was
| | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
login_cookie_path(), -86400);
db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, "
" cexpire=0 WHERE uid=%d"
" AND login NOT IN ('anonymous','nobody',"
" 'developer','reader')", g.userUid);
cgi_replace_parameter(cookie, NULL)
/* At the time of this writing, cgi_replace_parameter() was
** "NULL-value-safe", and I'm hoping the NULL doesn't cause any
** downstream problems here. We could alternately use "" here.
*/
;
}
}
/*
|
| ︙ | ︙ | |||
465 466 467 468 469 470 471 |
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
const char *zGoto = P("g");
int anonFlag;
char *zErrMsg = "";
| | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
const char *zGoto = P("g");
int anonFlag;
char *zErrMsg = "";
int uid; /* User id logged in user */
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
login_check_credentials();
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
zUsername = P("u");
|
| ︙ | ︙ | |||
758 759 760 761 762 763 764 |
" AND constant_time_cmp(cookie,%Q)=0",
zLogin, zRemoteAddr, zCookie
);
return uid;
}
/*
| | | 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
" AND constant_time_cmp(cookie,%Q)=0",
zLogin, zRemoteAddr, zCookie
);
return uid;
}
/*
** This routine examines the login cookie to see if it exists and
** is valid. If the login cookie checks out, it then sets global
** variables appropriately. Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
**
** If the
*/
void login_check_credentials(void){
|
| ︙ | ︙ | |||
1158 1159 1160 1161 1162 1163 1164 |
*/
void login_insert_csrf_secret(void){
@ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" />
}
/*
** Before using the results of a form, first call this routine to verify
| | | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
*/
void login_insert_csrf_secret(void){
@ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" />
}
/*
** Before using the results of a form, first call this routine to verify
** that this Anti-CSRF token is present and is valid. If the Anti-CSRF token
** is missing or is incorrect, that indicates a cross-site scripting attach
** so emits an error message and abort.
*/
void login_verify_csrf_secret(void){
if( g.okCsrf ) return;
if( fossil_strcmp(P("csrf"), g.zCsrfToken)==0 ){
g.okCsrf = 1;
|
| ︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 |
" AND name <> 'peer-repo-%q'"
" ORDER BY +value",
zSelfCode
);
while( db_step(&q)==SQLITE_ROW ){
const char *zRepoName = db_column_text(&q, 1);
if( file_size(zRepoName)<0 ){
| | | 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 |
" AND name <> 'peer-repo-%q'"
" ORDER BY +value",
zSelfCode
);
while( db_step(&q)==SQLITE_ROW ){
const char *zRepoName = db_column_text(&q, 1);
if( file_size(zRepoName)<0 ){
/* Silently remove non-existent repositories from the login group. */
const char *zLabel = db_column_text(&q, 0);
db_multi_exec(
"DELETE FROM config WHERE name GLOB 'peer-*-%q'",
&zLabel[10]
);
continue;
}
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
148 149 150 151 152 153 154 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ | | | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ char isHTTP; /* True if server/CGI modes, else assume CLI. */ char javascriptHyperlink; /* If true, set href= using script, not HTML */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlHostname; /* The HOST: parameter on http headers */ |
| ︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 |
** will use g.zExtra directly.
** Reminder: the login mechanism uses 'name' differently, and may
** eventually have a problem/collision with this.
**
** Disabled by stephan when running in JSON mode because this
** particular parameter name is very common and i have had no end
** of grief with this handling. The JSON API never relies on the
| | | 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 |
** will use g.zExtra directly.
** Reminder: the login mechanism uses 'name' differently, and may
** eventually have a problem/collision with this.
**
** Disabled by stephan when running in JSON mode because this
** particular parameter name is very common and i have had no end
** of grief with this handling. The JSON API never relies on the
** handling below, and by disabling it in JSON mode I can remove
** lots of special-case handling in several JSON handlers.
*/
#ifdef FOSSIL_ENABLE_JSON
if(!g.json.isJsonMode){
#endif
dehttpize(g.zExtra);
cgi_set_parameter_nocopy("name", g.zExtra);
|
| ︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 | ** inserted. Paint an error page if no match is found. ** ** If there is a line of the form: ** ** redirect: * URL ** ** Then a redirect is made to URL if no match is found. Otherwise a | | | 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 |
** inserted. Paint an error page if no match is found.
**
** If there is a line of the form:
**
** redirect: * URL
**
** Then a redirect is made to URL if no match is found. Otherwise a
** very primitive error message is returned.
*/
void redirect_web_page(int nRedirect, char **azRedirect){
int i; /* Loop counter */
const char *zNotFound = 0; /* Not found URL */
const char *zName = P("name");
set_base_url(0);
if( zName==0 ){
|
| ︙ | ︙ | |||
1882 1883 1884 1885 1886 1887 1888 | ** within an open checkout. ** ** The "ui" command automatically starts a web browser after initializing ** the web server. The "ui" command also binds to 127.0.0.1 and so will ** only process HTTP traffic from the local machine. ** ** In the "server" command, the REPOSITORY can be a directory (aka folder) | | | 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 | ** within an open checkout. ** ** The "ui" command automatically starts a web browser after initializing ** the web server. The "ui" command also binds to 127.0.0.1 and so will ** only process HTTP traffic from the local machine. ** ** In the "server" command, the REPOSITORY can be a directory (aka folder) ** that contains one or more repositories with names ending in ".fossil". ** In that case, the first element of the URL is used to select among the ** various repositories. ** ** By default, the "ui" command provides full administrative access without ** having to log in. This can be disabled by setting turning off the ** "localauth" setting. Automatic login for the "server" command is available ** if the --localauth option is present and the "localauth" setting is off |
| ︙ | ︙ |
Changes to src/makeheaders.c.
| ︙ | ︙ | |||
745 746 747 748 749 750 751 |
#define TT_Comment 4 /* Either C or C++ style comment */
#define TT_Number 5 /* Any numeric constant */
#define TT_String 6 /* String or character constants. ".." or '.' */
#define TT_Braces 7 /* All text between { and a matching } */
#define TT_EOF 8 /* End of file */
#define TT_Error 9 /* An error condition */
#define TT_BlockComment 10 /* A C-Style comment at the left margin that
| | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
#define TT_Comment 4 /* Either C or C++ style comment */
#define TT_Number 5 /* Any numeric constant */
#define TT_String 6 /* String or character constants. ".." or '.' */
#define TT_Braces 7 /* All text between { and a matching } */
#define TT_EOF 8 /* End of file */
#define TT_Error 9 /* An error condition */
#define TT_BlockComment 10 /* A C-Style comment at the left margin that
* spans multiple lines */
#define TT_Other 0 /* None of the above */
/*
** Get a single low-level token from the input file. Update the
** file pointer so that it points to the first character beyond the
** token.
**
|
| ︙ | ︙ | |||
1484 1485 1486 1487 1488 1489 1490 | /* ** At this point, we know we have a type declaration that is bounded ** by pList and pEnd and has the name pName. */ /* | | | 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 |
/*
** At this point, we know we have a type declaration that is bounded
** by pList and pEnd and has the name pName.
*/
/*
** If the braces are followed immediately by a semicolon, then we are
** dealing a type declaration only. There is not variable definition
** following the type declaration. So reset...
*/
if( pEnd->pNext==0 || pEnd->pNext->zText[0]==';' ){
*pReset = ';';
need_to_collapse = 0;
}else{
|
| ︙ | ︙ | |||
1880 1881 1882 1883 1884 1885 1886 | ** definition or a function prototype. Return TRUE if we are dealing ** with a variable defintion and FALSE for a prototype. ** ** pEnd is the token that ends the object. It can be either a ';' or ** a '='. If it is '=', then assume we have a variable definition. ** ** If pEnd is ';', then the determination is more difficult. We have | | | 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 |
** definition or a function prototype. Return TRUE if we are dealing
** with a variable defintion and FALSE for a prototype.
**
** pEnd is the token that ends the object. It can be either a ';' or
** a '='. If it is '=', then assume we have a variable definition.
**
** If pEnd is ';', then the determination is more difficult. We have
** to search for an occurrence of an ID followed immediately by '('.
** If found, we have a prototype. Otherwise we are dealing with a
** variable definition.
*/
static int isVariableDef(Token *pFirst, Token *pEnd){
if( pEnd && pEnd->zText[0]=='=' &&
(pEnd->pPrev->nText!=8 || strncmp(pEnd->pPrev->zText,"operator",8)!=0)
){
|
| ︙ | ︙ | |||
2634 2635 2636 2637 2638 2639 2640 |
DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag);
}else{
DeclClearProperty(p,DP_Flag);
}
}
/*
| | | 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 |
DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag);
}else{
DeclClearProperty(p,DP_Flag);
}
}
/*
** Call ScanText() recursively (this routine is called from ScanText())
** to include declarations required to come before these declarations.
*/
for(p=pDecl; p; p=p->pSameName){
if( DeclHasProperty(p,DP_Flag) ){
if( p->zDecl[0]=='#' ){
ScanText(&p->zDecl[1],pState);
}else{
|
| ︙ | ︙ | |||
2758 2759 2760 2761 2762 2763 2764 |
}
}
/* printf("END SCANTEXT\n"); */
}
/*
** Provide a full declaration to any object which so far has had only
| | | 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 |
}
}
/* printf("END SCANTEXT\n"); */
}
/*
** Provide a full declaration to any object which so far has had only
** a forward declaration.
*/
static void CompleteForwardDeclarations(GenState *pState){
Decl *pDecl;
int progress;
do{
progress = 0;
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
448 449 450 451 452 453 454 |
p->zAttachTarget = zTarget;
break;
}
/*
** B <uuid>
**
| | | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
p->zAttachTarget = zTarget;
break;
}
/*
** B <uuid>
**
** A B-line gives the UUID for the baseline of a delta-manifest.
*/
case 'B': {
if( p->zBaseline ) SYNTAX("more than one B-card");
p->zBaseline = next_token(&x, &sz);
if( p->zBaseline==0 ) SYNTAX("missing UUID on B-card");
if( sz!=UUID_SIZE || !validate16(p->zBaseline, UUID_SIZE) ){
SYNTAX("invalid UUID on B-card");
|
| ︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | /* ** Add a single entry to the mlink table. Also add the filename to ** the filename table if it is not there already. */ static void add_one_mlink( int mid, /* The record ID of the manifest */ const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ | | | 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 |
/*
** Add a single entry to the mlink table. Also add the filename to
** the filename table if it is not there already.
*/
static void add_one_mlink(
int mid, /* The record ID of the manifest */
const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */
const char *zToUuid, /* UUID for the mlink.fid. "" to delete */
const char *zFilename, /* Filename */
const char *zPrior, /* Previous filename. NULL if unchanged */
int isPublic, /* True if mid is not a private manifest */
int mperm /* 1: exec, 2: symlink */
){
int fnid, pfnid, pid, fid;
static Stmt s1;
|
| ︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 |
manifest_destroy(*ppOther);
return;
}
isPublic = !content_is_private(cid);
/* Try to make the parent manifest a delta from the child, if that
** is an appropriate thing to do. For a new baseline, make the
| | | 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 |
manifest_destroy(*ppOther);
return;
}
isPublic = !content_is_private(cid);
/* Try to make the parent manifest a delta from the child, if that
** is an appropriate thing to do. For a new baseline, make the
** previous baseline a delta from the current baseline.
*/
if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){
content_deltify(pid, cid, 0);
}else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){
content_deltify(pParent->pBaseline->rid, cid, 0);
}
|
| ︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 |
if( p->aTag[i].zUuid ){
tid = uuid_to_rid(p->aTag[i].zUuid, 1);
}else{
tid = rid;
}
if( tid ){
switch( p->aTag[i].zName[0] ){
| | | 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 |
if( p->aTag[i].zUuid ){
tid = uuid_to_rid(p->aTag[i].zUuid, 1);
}else{
tid = rid;
}
if( tid ){
switch( p->aTag[i].zName[0] ){
case '-': type = 0; break; /* Cancel prior occurrences */
case '+': type = 1; break; /* Apply to target only */
case '*': type = 2; break; /* Propagate to descendants */
default:
fossil_fatal("unknown tag type in manifest: %s", p->aTag);
return 0;
}
tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
|
| ︙ | ︙ |
Changes to src/md5.c.
| ︙ | ︙ | |||
364 365 366 367 368 369 370 | } return zOut; } /* ** Compute the MD5 checksum of a file on disk. Store the resulting | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
}
return zOut;
}
/*
** Compute the MD5 checksum of a file on disk. Store the resulting
** checksum in the blob pCksum. pCksum is assumed to be initialized.
**
** Return the number of errors.
*/
int md5sum_file(const char *zFilename, Blob *pCksum){
FILE *in;
MD5Context ctx;
unsigned char zResult[16];
|
| ︙ | ︙ |
Changes to src/merge3.c.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 | ** The aC[] array contains triples of integers. Within each triple, the ** elements are: ** ** (0) The number of lines to copy ** (1) The number of lines to delete ** (2) The number of liens to insert ** | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
** The aC[] array contains triples of integers. Within each triple, the
** elements are:
**
** (0) The number of lines to copy
** (1) The number of lines to delete
** (2) The number of liens to insert
**
** Suppose we want to advance over sz lines of the original file. This routine
** returns true if that advance would land us on a copy operation. It
** returns false if the advance would end on a delete.
*/
static int ends_at_CPY(int *aC, int sz){
while( sz>0 && (aC[0]>0 || aC[1]>0 || aC[2]>0) ){
if( aC[0]>=sz ) return 1;
sz -= aC[0];
|
| ︙ | ︙ |
Changes to src/mkindex.c.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 | ** ** Comment text following COMMAND: through the end of the comment is ** understood to be help text for the command specified. This help ** text is accumulated and a table containing the text for each command ** is generated. That table is used implement the "fossil help" command ** and the "/help" HTTP method. ** | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | ** ** Comment text following COMMAND: through the end of the comment is ** understood to be help text for the command specified. This help ** text is accumulated and a table containing the text for each command ** is generated. That table is used implement the "fossil help" command ** and the "/help" HTTP method. ** ** Multiple occurrences of WEBPAGE: or COMMAND: (but not both) can appear ** before each function name. In this way, webpages and commands can ** have aliases. */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <assert.h> |
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
60 61 62 63 64 65 66 | ** The following additional forms are available in local checkouts: ** ** * "current" ** * "prev" or "previous" ** * "next" ** ** Return the RID of the matching artifact. Or return 0 if the name does not | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
** The following additional forms are available in local checkouts:
**
** * "current"
** * "prev" or "previous"
** * "next"
**
** Return the RID of the matching artifact. Or return 0 if the name does not
** match any known object. Or return -1 if the name is ambiguous.
**
** The zType parameter specifies the type of artifact: ci, t, w, e, g.
** If zType is NULL or "" or "*" then any type of artifact will serve.
** zType is "ci" in most use cases since we are usually searching for
** a check-in.
*/
int symbolic_name_to_rid(const char *zTag, const char *zType){
|
| ︙ | ︙ | |||
375 376 377 378 379 380 381 | return name_to_typed_rid(zName, "*"); } /* ** WEBPAGE: ambiguous ** URL: /ambiguous?name=UUID&src=WEBPAGE ** | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
return name_to_typed_rid(zName, "*");
}
/*
** WEBPAGE: ambiguous
** URL: /ambiguous?name=UUID&src=WEBPAGE
**
** The UUID given by the name parameter is ambiguous. Display a page
** that shows all possible choices and let the user select between them.
*/
void ambiguous_page(void){
Stmt q;
const char *zName = P("name");
const char *zSrc = P("src");
char *z;
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ #define etEXP 3 /* Exponential notation. %e and %E */ #define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ #define etSIZE 5 /* Return number of characters processed so far. %n */ #define etSTRING 6 /* Strings. %s */ #define etDYNSTRING 7 /* Dynamically allocated strings. %z */ #define etPERCENT 8 /* Percent symbol. %% */ #define etCHARX 9 /* Characters. %c */ #define etERROR 10 /* Used to indicate no such conversion type */ |
| ︙ | ︙ |
Changes to src/rebuild.c.
| ︙ | ︙ | |||
203 204 205 206 207 208 209 | ** rid with content pBase and all of its descendants. This ** routine clears the content buffer before returning. ** ** If the zFNameFormat variable is set, then this routine is ** called to run "fossil deconstruct" instead of the usual ** "fossil rebuild". In that case, instead of rebuilding the ** cross-referencing information, write the file content out | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
** rid with content pBase and all of its descendants. This
** routine clears the content buffer before returning.
**
** If the zFNameFormat variable is set, then this routine is
** called to run "fossil deconstruct" instead of the usual
** "fossil rebuild". In that case, instead of rebuilding the
** cross-referencing information, write the file content out
** to the appropriate directory.
**
** In both cases, this routine automatically recurses to process
** other artifacts that are deltas off of the current artifact.
** This is the most efficient way to extract all of the original
** artifact content from the Fossil repository.
*/
static void rebuild_step(int rid, int size, Blob *pBase){
|
| ︙ | ︙ | |||
315 316 317 318 319 320 321 |
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) return;
tag_add_artifact("sym-", "trunk", zUuid, 0, 2, 0, 0);
tag_add_artifact("", "branch", zUuid, "trunk", 2, 0, 0);
}
/*
| | | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) return;
tag_add_artifact("sym-", "trunk", zUuid, 0, 2, 0, 0);
tag_add_artifact("", "branch", zUuid, "trunk", 2, 0, 0);
}
/*
** Core function to rebuild the information in the derived tables of a
** fossil repository from the blobs. This function is shared between
** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
** ('reconstruct'), both of which have to regenerate this information
** from scratch.
**
** If the randomize parameter is true, then the BLOBs are deliberately
** extracted in a random order. This feature is used to test the
|
| ︙ | ︙ | |||
950 951 952 953 954 955 956 |
zPrefixOpt=find_option("prefixlength","L",1);
if( !zPrefixOpt ){
prefixLength = 2;
}else{
if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
prefixLength = (int)(*zPrefixOpt-'0');
}else{
| | | 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 |
zPrefixOpt=find_option("prefixlength","L",1);
if( !zPrefixOpt ){
prefixLength = 2;
}else{
if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
prefixLength = (int)(*zPrefixOpt-'0');
}else{
fossil_fatal("N(%s) is not a valid prefix length!",zPrefixOpt);
}
}
/* open repository and open query for all artifacts */
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
privateFlag = find_option("private",0,0)!=0;
verify_all_options();
/* check number of arguments */
|
| ︙ | ︙ | |||
972 973 974 975 976 977 978 |
}
#ifndef _WIN32
if( file_access(zDestDir, W_OK) ){
fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
}
#else
/* write access on windows is not checked, errors will be
| | | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
}
#ifndef _WIN32
if( file_access(zDestDir, W_OK) ){
fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
}
#else
/* write access on windows is not checked, errors will be
** detected on blob_write_to_file
*/
#endif
if( prefixLength ){
zFNameFormat = mprintf("%s/%%.%ds/%%s",zDestDir,prefixLength);
}else{
zFNameFormat = mprintf("%s/%%s",zDestDir);
}
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
116 117 118 119 120 121 122 |
return mprintf("%d", atoi(zOrig));
}
return "";
}
/*
** Remove blank lines from the beginning of a string and
| | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
return mprintf("%d", atoi(zOrig));
}
return "";
}
/*
** Remove blank lines from the beginning of a string and
** all whitespace from the end. Removes whitespace preceding a NL,
** which also converts any CRNL sequence into a single NL.
*/
char *remove_blank_lines(const char *zOrig){
int i, j, n;
char *z;
for(i=j=0; fossil_isspace(zOrig[i]); i++){ if( zOrig[i]=='\n' ) j = i+1; }
n = strlen(&zOrig[j]);
|
| ︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 |
fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
}
return 0;
}
/*
** Generate a report. The rn query parameter is the report number.
| | | 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
}
return 0;
}
/*
** Generate a report. The rn query parameter is the report number.
** The output is written to stdout as flat file. The zFilter parameter
** is a full WHERE-condition.
*/
void rptshow(
const char *zRep,
const char *zSepIn,
const char *zFilter,
tTktShowEncoding enc
|
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
91 92 93 94 95 96 97 | }; /* ** Compare a search pattern against an input string and return a score. ** ** Scoring: ** * All terms must match at least once or the score is zero | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
};
/*
** Compare a search pattern against an input string and return a score.
**
** Scoring:
** * All terms must match at least once or the score is zero
** * 10 bonus points if the first occurrence is an exact match
** * 1 additional point for each subsequent match of the same word
** * Extra points of two consecutive words of the pattern are consecutive
** in the document
*/
int search_score(Search *p, const char *zDoc){
int iPrev = 999;
int score = 10;
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
307 308 309 310 311 312 313 |
int uid, i;
int higherUser = 0; /* True if user being edited is SETUP and the */
/* user doing the editing is ADMIN. Disallow editing */
char *inherit[128];
int a[128];
char *oa[128];
| | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
int uid, i;
int higherUser = 0; /* True if user being edited is SETUP and the */
/* user doing the editing is ADMIN. Disallow editing */
char *inherit[128];
int a[128];
char *oa[128];
/* Must have ADMIN privileges to access this page
*/
login_check_credentials();
if( !g.perm.Admin ){ login_needed(); return; }
/* Check to see if an ADMIN user is trying to edit a SETUP account.
** Don't allow that.
*/
|
| ︙ | ︙ |
Changes to src/sha1.c.
| ︙ | ︙ | |||
269 270 271 272 273 274 275 | } return zOut; } /* ** Compute the SHA1 checksum of a file on disk. Store the resulting | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
}
return zOut;
}
/*
** Compute the SHA1 checksum of a file on disk. Store the resulting
** checksum in the blob pCksum. pCksum is assumed to be initialized.
**
** Return the number of errors.
*/
int sha1sum_file(const char *zFilename, Blob *pCksum){
FILE *in;
SHA1Context ctx;
unsigned char zResult[20];
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
302 303 304 305 306 307 308 | } return *z==0; } /* ** A global char* and an SQL function to access its current value ** from within an SQL statement. This program used to use the | | | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | } return *z==0; } /* ** A global char* and an SQL function to access its current value ** from within an SQL statement. This program used to use the ** sqlite_exec_printf() API to substitute a string into an SQL statement. ** The correct way to do this with sqlite3 is to use the bind API, but ** since the shell is built around the callback paradigm it would be a lot ** of work. Instead just use this hack, which is quite harmless. */ static const char *zShellStatic = 0; static void shellstaticFunc( sqlite3_context *context, |
| ︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 |
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
continue;
}
| | | 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 |
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
continue;
}
/* save off the prepared statement handle and reset row count */
if( pArg ){
pArg->pStmt = pStmt;
pArg->cnt = 0;
}
/* echo the sql statement if echo on */
if( pArg && pArg->echoOn ){
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
101 102 103 104 105 106 107 |
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
}else{
sqlite3_result_error(context, "input is not zlib compressed", -1);
}
}
/*
| | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
}else{
sqlite3_result_error(context, "input is not zlib compressed", -1);
}
}
/*
** This is the "automatic extension" initializer that runs right after
** the connection to the repository database is opened. Set up the
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
sqlite3 *db,
const char **pzErrMsg,
const void *notUsed
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
698 699 700 701 702 703 704 |
@ color: red;
},
{ "span.note",
"format for leading text for notes",
@ font-weight: bold;
},
{ "span.textareaLabel",
| | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 |
@ color: red;
},
{ "span.note",
"format for leading text for notes",
@ font-weight: bold;
},
{ "span.textareaLabel",
"format for textarea labels",
@ font-weight: bold;
},
{ "table.usetupLayoutTable",
"format for the user setup layout table",
@ outline-style: none;
@ padding: 0;
@ margin: 25px;
|
| ︙ | ︙ | |||
798 799 800 801 802 803 804 |
"selected lines of text within a linenumbered artifact display",
@ font-weight: bold;
@ color: blue;
@ background-color: #d5d5ff;
@ border: 1px blue solid;
},
{ "p.missingPriv",
| | | 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
"selected lines of text within a linenumbered artifact display",
@ font-weight: bold;
@ color: blue;
@ background-color: #d5d5ff;
@ border: 1px blue solid;
},
{ "p.missingPriv",
"format for missing privileges note on user setup page",
@ color: blue;
},
{ "span.wikiruleHead",
"format for leading text in wikirules definitions",
@ font-weight: bold;
},
{ "td.tktDspLabel",
|
| ︙ | ︙ | |||
932 933 934 935 936 937 938 |
@ color: #0000ff;
},
{ "span.diffln",
"line numbers in a diff",
@ color: #a0a0a0;
},
{ "span.modpending",
| | | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
@ color: #0000ff;
},
{ "span.diffln",
"line numbers in a diff",
@ color: #a0a0a0;
},
{ "span.modpending",
"Moderation Pending message on timeline",
@ color: #b03800;
@ font-style: italic;
},
{ 0,
0,
0
}
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
339 340 341 342 343 344 345 | ** Run various subcommands to control tags and properties ** ** %fossil tag add ?--raw? ?--propagate? TAGNAME CHECK-IN ?VALUE? ** ** Add a new tag or property to CHECK-IN. The tag will ** be usable instead of a CHECK-IN in commands such as ** update and merge. If the --propagate flag is present, | | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | ** Run various subcommands to control tags and properties ** ** %fossil tag add ?--raw? ?--propagate? TAGNAME CHECK-IN ?VALUE? ** ** Add a new tag or property to CHECK-IN. The tag will ** be usable instead of a CHECK-IN in commands such as ** update and merge. If the --propagate flag is present, ** the tag value propagates to all descendants of CHECK-IN ** ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN ** ** Remove the tag TAGNAME from CHECK-IN, and also remove ** the propagation of the tag to any descendants. ** ** %fossil tag find ?--raw? ?--type TYPE? TAGNAME |
| ︙ | ︙ |
Changes to src/th.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 | ** is stored in Th_Variable.nRef. ** ** For scalar variables, Th_Variable.zData is never 0. Th_Variable.nData ** stores the number of bytes in the value pointed to by zData. ** ** For an array variable, Th_Variable.zData is 0 and pHash points to ** a hash table mapping between array key name (a th1 string) and | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
** is stored in Th_Variable.nRef.
**
** For scalar variables, Th_Variable.zData is never 0. Th_Variable.nData
** stores the number of bytes in the value pointed to by zData.
**
** For an array variable, Th_Variable.zData is 0 and pHash points to
** a hash table mapping between array key name (a th1 string) and
** a pointer to the Th_Variable structure holding the scalar
** value.
*/
struct Th_Variable {
int nRef; /* Number of references to this structure */
int nData; /* Number of bytes at Th_Variable.zData */
char *zData; /* Data for scalar variables */
Th_Hash *pHash; /* Data for array variables */
|
| ︙ | ︙ | |||
250 251 252 253 254 255 256 |
case 'f': case 'F': return 15;
}
return -1;
}
/*
** Argument pEntry points to an entry in a stack frame hash table
| | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
case 'f': case 'F': return 15;
}
return -1;
}
/*
** Argument pEntry points to an entry in a stack frame hash table
** (Th_Frame.paVar). Decrement the reference count of the Th_Variable
** structure that the entry points to. Free the Th_Variable if its
** reference count reaches 0.
**
** Argument pContext is a pointer to the interpreter structure.
*/
static void thFreeVariable(Th_HashEntry *pEntry, void *pContext){
Th_Variable *pValue = (Th_Variable *)pEntry->pData;
|
| ︙ | ︙ | |||
874 875 876 877 878 879 880 |
/* Call the command procedure. */
if( rc==TH_OK ){
Th_Command *p = (Th_Command *)(pEntry->pData);
const char **azArg = (const char **)argv;
rc = p->xProc(interp, p->pContext, argc, azArg, argl);
}
| | | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 |
/* Call the command procedure. */
if( rc==TH_OK ){
Th_Command *p = (Th_Command *)(pEntry->pData);
const char **azArg = (const char **)argv;
rc = p->xProc(interp, p->pContext, argc, azArg, argl);
}
/* If an error occurred, add this command to the stack trace report. */
if( rc==TH_ERROR ){
char *zRes;
int nRes;
char *zStack = 0;
int nStack = 0;
zRes = Th_TakeResult(interp, &nRes);
|
| ︙ | ︙ | |||
1057 1058 1059 1060 1061 1062 1063 | ** arrayok is true an array name is Ok. */ static Th_Variable *thFindValue( Th_Interp *interp, const char *zVar, /* Pointer to variable name */ int nVar, /* Number of bytes at nVar */ int create, /* If true, create the variable if not found */ | | | 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 |
** arrayok is true an array name is Ok.
*/
static Th_Variable *thFindValue(
Th_Interp *interp,
const char *zVar, /* Pointer to variable name */
int nVar, /* Number of bytes at nVar */
int create, /* If true, create the variable if not found */
int arrayok /* If true, an array is Ok. Otherwise array==error */
){
const char *zOuter;
int nOuter;
const char *zInner;
int nInner;
int isGlobal;
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
484 485 486 487 488 489 490 | return TH_OK; } /* ** TH1 command: stime ** ** Return the number of microseconds of CPU time consumed by the current | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | return TH_OK; } /* ** TH1 command: stime ** ** Return the number of microseconds of CPU time consumed by the current ** process in system space. */ static int stimeCmd( Th_Interp *interp, void *p, int argc, const char **argv, int *argl |
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
880 881 882 883 884 885 886 | ** ** a=TIMEORTAG after this event ** b=TIMEORTAG before this event ** c=TIMEORTAG "circa" this event ** n=COUNT max number of events in output ** p=UUID artifact and up to COUNT parents and ancestors ** d=UUID artifact and up to COUNT descendants | | | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 |
**
** a=TIMEORTAG after this event
** b=TIMEORTAG before this event
** c=TIMEORTAG "circa" this event
** n=COUNT max number of events in output
** p=UUID artifact and up to COUNT parents and ancestors
** d=UUID artifact and up to COUNT descendants
** dp=UUID The same as d=UUID&p=UUID
** t=TAGID show only check-ins with the given tagid
** r=TAGID show check-ins related to tagid
** u=USER only if belonging to this user
** y=TYPE 'ci', 'w', 't', 'e'
** s=TEXT string search (comment and brief)
** ng Suppress the graph if present
** nd Suppress "divider" lines
** fc Show details of files changed
** f=UUID Show family (immediate parents and children) of UUID
** from=UUID Path from...
** to=UUID ... to this
** nomerge ... avoid merge links on the path
** brbg Background color from branch name
** ubg Background color from user
**
** p= and d= can appear individually or together. If either p= or d=
** appear, then u=, y=, a=, and b= are ignored.
**
** If a= and b= appear, only a= is used. If neither appear, the most
** recent events are chosen.
**
** If n= is missing, the default count is 20.
*/
void page_timeline(void){
Stmt q; /* Query used to generate the timeline */
Blob sql; /* text of SQL used to generate timeline */
Blob desc; /* Description of the timeline */
|
| ︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 |
blob_appendf(&sql,
"AND (EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
if( zBrName ){
url_add_parameter(&url, "r", zBrName);
/* The next two blob_appendf() calls add SQL that causes checkins that
| | | | | | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 |
blob_appendf(&sql,
"AND (EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
if( zBrName ){
url_add_parameter(&url, "r", zBrName);
/* The next two blob_appendf() calls add SQL that causes checkins that
** are not part of the branch which are parents or children of the
** branch to be included in the report. This related check-ins are
** useful in helping to visualize what has happened on a quiescent
** branch that is infrequently merged with a much more activate branch.
*/
blob_appendf(&sql,
" OR EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
" WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
tagid
);
if( P("mionly")==0 ){
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
89 90 91 92 93 94 95 | ** ** Only load those fields which do not already exist as ** variables. ** ** Fields of the TICKET table that begin with "private_" are ** expanded using the db_reveal() function. If g.perm.RdAddr is ** true, then the db_reveal() function will decode the content | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
**
** Only load those fields which do not already exist as
** variables.
**
** Fields of the TICKET table that begin with "private_" are
** expanded using the db_reveal() function. If g.perm.RdAddr is
** true, then the db_reveal() function will decode the content
** using the CONCEALED table so that the content legible.
** Otherwise, db_reveal() is a no-op and the content remains
** obscured.
*/
static void initializeVariablesFromDb(void){
const char *zName;
Stmt q;
int i, n, size, j;
|
| ︙ | ︙ | |||
497 498 499 500 501 502 503 | } /* ** WEBPAGE: tktnew ** WEBPAGE: debug_tktnew ** | | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | } /* ** WEBPAGE: tktnew ** WEBPAGE: debug_tktnew ** ** Enter a new ticket. The tktnew_template script in the ticket ** configuration is used. The /tktnew page is the official ticket ** entry page. The /debug_tktnew page is used for debugging the ** tktnew_template in the ticket configuration. /debug_tktnew works ** just like /tktnew except that it does not really save the new ticket ** when you press submit - it just prints the ticket artifact at the ** top of the screen. */ |
| ︙ | ︙ |
Changes to src/tktsetup.c.
| ︙ | ︙ | |||
94 95 96 97 98 99 100 | ** Common implementation for the ticket setup editor pages. */ static void tktsetup_generic( const char *zTitle, /* Page title */ const char *zDbField, /* Configuration field being edited */ const char *zDfltValue, /* Default text value */ const char *zDesc, /* Description of this field */ | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
** Common implementation for the ticket setup editor pages.
*/
static void tktsetup_generic(
const char *zTitle, /* Page title */
const char *zDbField, /* Configuration field being edited */
const char *zDfltValue, /* Default text value */
const char *zDesc, /* Description of this field */
char *(*xText)(const char*), /* Validity test or NULL */
void (*xRebuild)(void), /* Run after successful update */
int height /* Height of the edit box */
){
const char *z;
int isSubmit;
login_check_credentials();
if( !g.perm.Setup ){
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
104 105 106 107 108 109 110 | int debugFlag; /* --debug option */ int setmtimeFlag; /* --setmtime. Set mtimes on files */ int nChng; /* Number of file renames */ int *aChng; /* Array of file renames */ int i; /* Loop counter */ int nConflict = 0; /* Number of merge conflicts */ int nOverwrite = 0; /* Number of unmanaged files overwritten */ | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
int debugFlag; /* --debug option */
int setmtimeFlag; /* --setmtime. Set mtimes on files */
int nChng; /* Number of file renames */
int *aChng; /* Array of file renames */
int i; /* Loop counter */
int nConflict = 0; /* Number of merge conflicts */
int nOverwrite = 0; /* Number of unmanaged files overwritten */
int nUpdate = 0; /* Number of changes of any kind */
Stmt mtimeXfer; /* Statement to transfer mtimes */
if( !internalUpdate ){
undo_capture_command_line();
url_proxy_options();
}
latestFlag = find_option("latest",0, 0)!=0;
nochangeFlag = find_option("nochange","n",0)!=0;
|
| ︙ | ︙ | |||
149 150 151 152 153 154 155 |
}else if( !is_a_version(tid) ){
fossil_fatal("no such version: %s", g.argv[2]);
}
}
}
/* If no VERSION is specified on the command-line, then look for a
| | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
}else if( !is_a_version(tid) ){
fossil_fatal("no such version: %s", g.argv[2]);
}
}
}
/* If no VERSION is specified on the command-line, then look for a
** descendent of the current version. If there are multiple descendants,
** look for one from the same branch as the current version. If there
** are still multiple descendants, show them all and refuse to update
** until the user selects one.
*/
if( tid==0 ){
int closeCode = 1;
compute_leaves(vid, closeCode);
if( !db_exists("SELECT 1 FROM leaves") ){
closeCode = 0;
|
| ︙ | ︙ |
Changes to src/verify.c.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to help verify the integrity of ** the repository. ** ** This file primarily implements the verify_before_commit() interface. ** Any function can call verify_before_commit() with a record id (RID) ** as an argument. Then before the next change to the database commits, ** this routine will reach in and check that the record can be extracted ** correctly from the BLOB table. |
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
25 26 27 28 29 30 31 | /* ** Return true if the input string is a well-formed wiki page name. ** ** Well-formed wiki page names do not begin or end with whitespace, ** and do not contain tabs or other control characters and do not ** contain more than a single space character in a row. Well-formed | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/*
** Return true if the input string is a well-formed wiki page name.
**
** Well-formed wiki page names do not begin or end with whitespace,
** and do not contain tabs or other control characters and do not
** contain more than a single space character in a row. Well-formed
** names must be between 3 and 100 characters in length, inclusive.
*/
int wiki_name_is_wellformed(const unsigned char *z){
int i;
if( z[0]<=0x20 ){
return 0;
}
for(i=1; z[i]; i++){
|
| ︙ | ︙ | |||
880 881 882 883 884 885 886 | ** ** Create a new wiki page with initial content taken from ** FILE or from standard input. ** ** %fossil wiki list ** ** Lists all wiki entries, one per line, ordered | | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
**
** Create a new wiki page with initial content taken from
** FILE or from standard input.
**
** %fossil wiki list
**
** Lists all wiki entries, one per line, ordered
** case-insensitively by name.
**
*/
void wiki_cmd(void){
int n;
db_find_and_open_repository(0, 0);
if( g.argc<3 ){
goto wiki_cmd_usage;
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
1076 1077 1078 1079 1080 1081 1082 | } db_reset(&q); return rc; } /* ** Resolve a hyperlink. The zTarget argument is the content of the [...] | | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | } db_reset(&q); return rc; } /* ** Resolve a hyperlink. The zTarget argument is the content of the [...] ** in the wiki. Append to the output string whatever text is appropriate ** for opening the hyperlink. Write into zClose[0...nClose-1] text that will ** close the markup. ** ** Actually, this routine might or might not append the hyperlink, depending ** on current rendering rules: specifically does the current user have ** "History" permission. ** |
| ︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 | ** ** [#fragment] ** ** [2010-02-27 07:13] */ static void openHyperlink( Renderer *p, /* Rendering context */ | | | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 |
**
** [#fragment]
**
** [2010-02-27 07:13]
*/
static void openHyperlink(
Renderer *p, /* Rendering context */
const char *zTarget, /* Hyperlink target; text within [...] */
char *zClose, /* Write hyperlink closing text here */
int nClose, /* Bytes available in zClose[] */
const char *zOrig /* Complete document text */
){
const char *zTerm = "</a>";
assert( nClose>=20 );
|
| ︙ | ︙ |
Changes to src/winhttp.c.
| ︙ | ︙ | |||
269 270 271 272 273 274 275 |
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
DWORD nErr = GetLastError();
LPWSTR tmp = NULL;
char *zMsg = NULL;
| | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
DWORD nErr = GetLastError();
LPWSTR tmp = NULL;
char *zMsg = NULL;
/* Try first to get the error text in English. */
nMsg = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErr,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
546 547 548 549 550 551 552 | ** ** login LOGIN NONCE SIGNATURE ** ** The NONCE is the SHA1 hash of the remainder of the input. ** SIGNATURE is the SHA1 checksum of the NONCE concatenated ** with the users password. ** | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | ** ** login LOGIN NONCE SIGNATURE ** ** The NONCE is the SHA1 hash of the remainder of the input. ** SIGNATURE is the SHA1 checksum of the NONCE concatenated ** with the users password. ** ** The parameters to this routine are ephemeral blobs holding the ** LOGIN, NONCE and SIGNATURE. ** ** This routine attempts to locate the user and verify the signature. ** If everything checks out, the USER.CAP column for the USER table ** is consulted to set privileges in the global g variable. ** ** If anything fails to check out, no changes are made to privileges. |
| ︙ | ︙ |
Changes to src/xfersetup.c.
| ︙ | ︙ | |||
46 47 48 49 50 51 52 | ** Common implementation for the transfer setup editor pages. */ static void xfersetup_generic( const char *zTitle, /* Page title */ const char *zDbField, /* Configuration field being edited */ const char *zDfltValue, /* Default text value */ const char *zDesc, /* Description of this field */ | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
** Common implementation for the transfer setup editor pages.
*/
static void xfersetup_generic(
const char *zTitle, /* Page title */
const char *zDbField, /* Configuration field being edited */
const char *zDfltValue, /* Default text value */
const char *zDesc, /* Description of this field */
char *(*xText)(const char*), /* Validity test or NULL */
void (*xRebuild)(void), /* Run after successful update */
int height /* Height of the edit box */
){
const char *z;
int isSubmit;
login_check_credentials();
if( !g.perm.Setup ){
|
| ︙ | ︙ |