Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge in the Fossil 2.0 and 2.1 enhancements. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | optimize-pragma |
| Files: | files | file ages | folders |
| SHA1: |
0dc479305f187140fcd79efa9e2a7820 |
| User & Date: | drh 2017-03-06 19:51:20.401 |
Context
|
2017-03-06
| ||
| 19:53 | Update the built-in SQLite to the latest 3.18.0 prerelease version that supports PRAGMA optimize. check-in: f32c36e58a user: drh tags: optimize-pragma | |
| 19:51 | Merge in the Fossil 2.0 and 2.1 enhancements. check-in: 0dc479305f user: drh tags: optimize-pragma | |
| 12:52 | Use "auto" hash-policy for new Docker repositories check-in: 3c9dc14831 user: jan.nijtmans tags: trunk | |
|
2017-02-23
| ||
| 14:55 | Add the /repo_stat1 webpage (accessible only to administrators). Enhance the /repo_schema page so that it can optionally show the schema for a single table. Include sqlite_stat1 information on the /repo_schema page. check-in: f9f5702d7a user: drh tags: optimize-pragma | |
Changes
Changes to VERSION.
|
| | | 1 | 2.1 |
Changes to src/attach.c.
1 2 3 4 5 6 | /* ** Copyright (c) 2010 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* ** Copyright (c) 2010 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ |
| ︙ | ︙ |
Changes to src/blob.c.
1 2 3 4 5 6 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ |
| ︙ | ︙ | |||
645 646 647 648 649 650 651 |
if( pTo ){
blob_append(pTo, &pFrom->aData[pFrom->iCursor], i - pFrom->iCursor);
}
pFrom->iCursor = i;
}
/*
| | > > > > > | < | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
if( pTo ){
blob_append(pTo, &pFrom->aData[pFrom->iCursor], i - pFrom->iCursor);
}
pFrom->iCursor = i;
}
/*
** Return true if the blob contains a valid base16 identifier artifact hash.
**
** The value returned is actually one of HNAME_SHA1 OR HNAME_K256 if the
** hash is valid. Both of these are non-zero and therefore "true".
** If the hash is not valid, then HNAME_ERROR is returned, which is zero or
** false.
*/
int blob_is_hname(Blob *pBlob){
return hname_validate(blob_buffer(pBlob), blob_size(pBlob));
}
/*
** Return true if the blob contains a valid filename
*/
int blob_is_filename(Blob *pBlob){
return file_is_simple_pathname(blob_str(pBlob), 1);
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
313 314 315 316 317 318 319 | FileTreeNode *pNext; /* Next entry in an ordered list of them all */ FileTreeNode *pParent; /* Directory containing this entry */ FileTreeNode *pSibling; /* Next element in the same subdirectory */ FileTreeNode *pChild; /* List of child nodes */ FileTreeNode *pLastChild; /* Last child on the pChild list */ char *zName; /* Name of this entry. The "tail" */ char *zFullName; /* Full pathname of this entry */ | | | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | FileTreeNode *pNext; /* Next entry in an ordered list of them all */ FileTreeNode *pParent; /* Directory containing this entry */ FileTreeNode *pSibling; /* Next element in the same subdirectory */ FileTreeNode *pChild; /* List of child nodes */ FileTreeNode *pLastChild; /* Last child on the pChild list */ char *zName; /* Name of this entry. The "tail" */ char *zFullName; /* Full pathname of this entry */ char *zUuid; /* Artifact hash of this file. May be NULL. */ double mtime; /* Modification time for this entry */ unsigned nFullName; /* Length of zFullName */ unsigned iLevel; /* Levels of parent directories */ }; /* ** A complete file hierarchy |
| ︙ | ︙ | |||
343 344 345 346 347 348 349 | ** When constructing a list of FileTreeNodes, all entries that have ** a common directory prefix must be added consecutively in order for ** the tree to be constructed properly. */ static void tree_add_node( FileTree *pTree, /* Tree into which nodes are added */ const char *zPath, /* The full pathname of file to add */ | | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
** When constructing a list of FileTreeNodes, all entries that have
** a common directory prefix must be added consecutively in order for
** the tree to be constructed properly.
*/
static void tree_add_node(
FileTree *pTree, /* Tree into which nodes are added */
const char *zPath, /* The full pathname of file to add */
const char *zUuid, /* Hash of the file. Might be NULL. */
double mtime /* Modification time for this entry */
){
int i;
FileTreeNode *pParent; /* Parent (directory) of the next node to insert */
/* Make pParent point to the most recent ancestor of zPath, or
** NULL if there are no prior entires that are a container for zPath.
|
| ︙ | ︙ | |||
366 367 368 369 370 371 372 |
i = pParent ? pParent->nFullName+1 : 0;
while( zPath[i] ){
FileTreeNode *pNew;
int iStart = i;
int nByte;
while( zPath[i] && zPath[i]!='/' ){ i++; }
nByte = sizeof(*pNew) + i + 1;
| | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
i = pParent ? pParent->nFullName+1 : 0;
while( zPath[i] ){
FileTreeNode *pNew;
int iStart = i;
int nByte;
while( zPath[i] && zPath[i]!='/' ){ i++; }
nByte = sizeof(*pNew) + i + 1;
if( zUuid!=0 && zPath[i]==0 ) nByte += HNAME_MAX+1;
pNew = fossil_malloc( nByte );
memset(pNew, 0, sizeof(*pNew));
pNew->zFullName = (char*)&pNew[1];
memcpy(pNew->zFullName, zPath, i);
pNew->zFullName[i] = 0;
pNew->nFullName = i;
if( zUuid!=0 && zPath[i]==0 ){
pNew->zUuid = pNew->zFullName + i + 1;
memcpy(pNew->zUuid, zUuid, strlen(zUuid)+1);
}
pNew->zName = pNew->zFullName + iStart;
if( pTree->pLast ){
pTree->pLast->pNext = pNew;
}else{
pTree->pFirst = pNew;
}
|
| ︙ | ︙ |
Changes to src/bundle.c.
| ︙ | ︙ | |||
33 34 35 36 37 38 39 | static const char zBundleInit[] = @ CREATE TABLE IF NOT EXISTS "%w".bconfig( @ bcname TEXT, @ bcvalue ANY @ ); @ CREATE TABLE IF NOT EXISTS "%w".bblob( @ blobid INTEGER PRIMARY KEY, -- Blob ID | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | static const char zBundleInit[] = @ CREATE TABLE IF NOT EXISTS "%w".bconfig( @ bcname TEXT, @ bcvalue ANY @ ); @ CREATE TABLE IF NOT EXISTS "%w".bblob( @ blobid INTEGER PRIMARY KEY, -- Blob ID @ uuid TEXT NOT NULL, -- hash of expanded blob @ sz INT NOT NULL, -- Size of blob after expansion @ delta ANY, -- Delta compression basis, or NULL @ notes TEXT, -- Description of content @ data BLOB -- compressed content @ ); ; |
| ︙ | ︙ | |||
437 438 439 440 441 442 443 |
"SELECT uuid, data, bblob.delta, bix.blobid"
" FROM bix, bblob"
" WHERE bix.delta=%d"
" AND bix.blobid=bblob.blobid;",
iSrc
);
while( db_step(&q)==SQLITE_ROW ){
| | | | < | < < | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
"SELECT uuid, data, bblob.delta, bix.blobid"
" FROM bix, bblob"
" WHERE bix.delta=%d"
" AND bix.blobid=bblob.blobid;",
iSrc
);
while( db_step(&q)==SQLITE_ROW ){
Blob h1, c1, c2;
int rid;
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
blob_zero(&c1);
db_column_blob(&q, 1, &c1);
blob_uncompress(&c1, &c1);
blob_zero(&c2);
if( db_column_type(&q,2)==SQLITE_TEXT && db_column_bytes(&q,2)>=HNAME_MIN ){
Blob basis;
rid = db_int(0,"SELECT rid FROM blob WHERE uuid=%Q",
db_column_text(&q,2));
content_get(rid, &basis);
blob_delta_apply(&basis, &c1, &c2);
blob_reset(&basis);
blob_reset(&c1);
}else if( pBasis ){
blob_delta_apply(pBasis, &c1, &c2);
blob_reset(&c1);
}else{
c2 = c1;
}
if( hname_verify_hash(&c2, blob_buffer(&h1), blob_size(&h1))==0 ){
fossil_fatal("artifact hash error on %b", &h1);
}
rid = content_put_ex(&c2, blob_str(&h1), 0, 0, isPriv);
if( rid==0 ){
fossil_fatal("%s", g.zErrMsg);
}else{
if( !isPriv ) content_make_public(rid);
content_get(rid, &c1);
manifest_crosslink(rid, &c1, MC_NO_ERRORS);
|
| ︙ | ︙ | |||
489 490 491 492 493 494 495 |
** Extract an item from content from the bundle
*/
static void bundle_extract_item(
int blobid, /* ID of the item to extract */
Blob *pOut /* Write the content into this blob */
){
Stmt q;
| | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 |
** Extract an item from content from the bundle
*/
static void bundle_extract_item(
int blobid, /* ID of the item to extract */
Blob *pOut /* Write the content into this blob */
){
Stmt q;
Blob x, basis, h1;
static Bag busy;
db_prepare(&q, "SELECT uuid, delta, data FROM bblob"
" WHERE blobid=%d", blobid);
if( db_step(&q)!=SQLITE_ROW ){
db_finalize(&q);
fossil_fatal("no such item: %d", blobid);
|
| ︙ | ︙ | |||
523 524 525 526 527 528 529 |
blob_reset(&basis);
blob_reset(&x);
}else{
*pOut = x;
}
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
| | < | < < | 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 |
blob_reset(&basis);
blob_reset(&x);
}else{
*pOut = x;
}
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
if( hname_verify_hash(pOut, blob_buffer(&h1), blob_size(&h1))==0 ){
fossil_fatal("incorrect hash for artifact %b", &h1);
}
blob_reset(&h1);
bag_remove(&busy, blobid);
db_finalize(&q);
}
/* fossil bundle cat BUNDLE UUID...
**
** Write elements of a bundle on standard output
|
| ︙ | ︙ | |||
595 596 597 598 599 600 601 |
/* If the bundle contains deltas with a basis that is external to the
** bundle and those external basis files are missing from the local
** repo, then the delta encodings cannot be decoded and the bundle cannot
** be extracted. */
zMissingDeltas = db_text(0,
"SELECT group_concat(substr(delta,1,10),' ')"
" FROM bblob"
| | | > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
/* If the bundle contains deltas with a basis that is external to the
** bundle and those external basis files are missing from the local
** repo, then the delta encodings cannot be decoded and the bundle cannot
** be extracted. */
zMissingDeltas = db_text(0,
"SELECT group_concat(substr(delta,1,10),' ')"
" FROM bblob"
" WHERE typeof(delta)='text' AND length(delta)>=%d"
" AND NOT EXISTS(SELECT 1 FROM blob WHERE uuid=bblob.delta)",
HNAME_MIN);
if( zMissingDeltas && zMissingDeltas[0] ){
fossil_fatal("delta basis artifacts not found in repository: %s",
zMissingDeltas);
}
db_begin_transaction();
db_multi_exec(
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
375 376 377 378 379 380 381 | ** can be overridden by using one or more filter options (listed below), ** in which case only files with the specified change type(s) are shown. ** As a special case, the --no-merge option does not inhibit this default. ** This default shows exactly the set of changes that would be checked ** in by the commit command. ** ** If no filter options are used, or if the --merge option is used, the | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | ** can be overridden by using one or more filter options (listed below), ** in which case only files with the specified change type(s) are shown. ** As a special case, the --no-merge option does not inhibit this default. ** This default shows exactly the set of changes that would be checked ** in by the commit command. ** ** If no filter options are used, or if the --merge option is used, the ** artifact hash of each merge contributor check-in version is displayed at ** the end of the report. The --no-merge option is useful to display the ** default set of changed files without the merge contributors. ** ** If change type classification is enabled, each output line starts with ** a code describing the file's change type, e.g. EDITED or RENAMED. It ** is enabled by default unless exactly one change type is selected. For ** the purposes of determining the default, --changed counts as selecting |
| ︙ | ︙ | |||
410 411 412 413 414 415 416 | ** ** The "fossil changes --extra" command is equivalent to "fossil extras". ** ** General options: ** --abs-paths Display absolute pathnames. ** --rel-paths Display pathnames relative to the current working ** directory. | | | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | ** ** The "fossil changes --extra" command is equivalent to "fossil extras". ** ** General options: ** --abs-paths Display absolute pathnames. ** --rel-paths Display pathnames relative to the current working ** directory. ** --hash Verify file status using hashing rather than ** relying on file mtimes. ** --case-sensitive <BOOL> Override case-sensitive setting. ** --dotfiles Include unmanaged files beginning with a dot. ** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns. ** --no-dir-symlinks Disables support for directory symlinks. ** ** Options specific to the changes command: |
| ︙ | ︙ | |||
462 463 464 465 466 467 468 |
{"classify", C_CLASSIFY},
}, noFlagDefs[] = {
{"no-merge", C_MERGE }, {"no-classify", C_CLASSIFY },
};
Blob report = BLOB_INITIALIZER;
enum {CHANGES, STATUS} command = *g.argv[1]=='s' ? STATUS : CHANGES;
| | | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
{"classify", C_CLASSIFY},
}, noFlagDefs[] = {
{"no-merge", C_MERGE }, {"no-classify", C_CLASSIFY },
};
Blob report = BLOB_INITIALIZER;
enum {CHANGES, STATUS} command = *g.argv[1]=='s' ? STATUS : CHANGES;
int useHash = find_option("hash", 0, 0)!=0;
int showHdr = command==CHANGES && find_option("header", 0, 0);
int verboseFlag = command==CHANGES && find_option("verbose", "v", 0);
const char *zIgnoreFlag = find_option("ignore", 0, 1);
unsigned scanFlags = 0;
unsigned flags = 0;
int vid, i;
|
| ︙ | ︙ | |||
526 527 528 529 530 531 532 |
scanFlags = SCAN_ALL;
}
/* We should be done with options. */
verify_all_options();
/* Check for changed files. */
| | | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
scanFlags = SCAN_ALL;
}
/* We should be done with options. */
verify_all_options();
/* Check for changed files. */
vfile_check_signature(vid, useHash ? CKSIG_HASH : 0);
/* Search for unmanaged files if requested. */
if( flags & C_EXTRA ){
Glob *pIgnore = glob_create(zIgnoreFlag);
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
glob_free(pIgnore);
}
|
| ︙ | ︙ | |||
1983 1984 1985 1986 1987 1988 1989 | ** blank commit message. The default value is "N", do not commit. ** ** The --private option creates a private check-in that is never synced. ** Children of private check-ins are automatically private. ** ** The --tag option applies the symbolic tag name to the check-in. ** | | | | 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 | ** blank commit message. The default value is "N", do not commit. ** ** The --private option creates a private check-in that is never synced. ** Children of private check-ins are automatically private. ** ** The --tag option applies the symbolic tag name to the check-in. ** ** The --hash option detects edited files by computing each file's ** artifact hash rather than just checking for changes to its size or mtime. ** ** Options: ** --allow-conflict allow unresolved merge conflicts ** --allow-empty allow a commit with no changes ** --allow-fork allow the commit to fork ** --allow-older allow a commit older than its ancestor ** --baseline use a baseline manifest in the commit process |
| ︙ | ︙ | |||
2008 2009 2010 2011 2012 2013 2014 | ** -n|--dry-run If given, display instead of run actions ** --no-prompt This option disables prompting the user for ** input and assumes an answer of 'No' for every ** question. ** --no-warnings omit all warnings about file contents ** --nosign do not attempt to sign this commit with gpg ** --private do not sync changes and their descendants | | | 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 | ** -n|--dry-run If given, display instead of run actions ** --no-prompt This option disables prompting the user for ** input and assumes an answer of 'No' for every ** question. ** --no-warnings omit all warnings about file contents ** --nosign do not attempt to sign this commit with gpg ** --private do not sync changes and their descendants ** --hash verify file status using hashing rather ** than relying on file mtimes ** --tag TAG-NAME assign given tag TAG-NAME to the check-in ** --date-override DATETIME DATE to use instead of 'now' ** --user-override USER USER to use instead of the current default ** ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in ** year-month-day form, it may be truncated, the "T" may be replaced by |
| ︙ | ︙ | |||
2031 2032 2033 2034 2035 2036 2037 | int vid; /* blob-id of parent version */ int nrid; /* blob-id of a modified file */ int nvid; /* Blob-id of the new check-in */ Blob comment; /* Check-in comment */ const char *zComment; /* Check-in comment */ Stmt q; /* Various queries */ char *zUuid; /* UUID of the new check-in */ | | | 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 | int vid; /* blob-id of parent version */ int nrid; /* blob-id of a modified file */ int nvid; /* Blob-id of the new check-in */ Blob comment; /* Check-in comment */ const char *zComment; /* Check-in comment */ Stmt q; /* Various queries */ char *zUuid; /* UUID of the new check-in */ int useHash = 0; /* True to verify file status using hashing */ int noSign = 0; /* True to omit signing the manifest using GPG */ int isAMerge = 0; /* True if checking in a merge */ int noWarningFlag = 0; /* True if skipping all warnings */ int noPrompt = 0; /* True if skipping all prompts */ int forceFlag = 0; /* Undocumented: Disables all checks */ int forceDelta = 0; /* Force a delta-manifest */ int forceBaseline = 0; /* Force a baseline-manifest */ |
| ︙ | ︙ | |||
2066 2067 2068 2069 2070 2071 2072 | int nConflict = 0; /* Number of unresolved merge conflicts */ int abortCommit = 0; Blob ans; char cReply; memset(&sCiInfo, 0, sizeof(sCiInfo)); url_proxy_options(); | | | 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 |
int nConflict = 0; /* Number of unresolved merge conflicts */
int abortCommit = 0;
Blob ans;
char cReply;
memset(&sCiInfo, 0, sizeof(sCiInfo));
url_proxy_options();
useHash = find_option("hash", 0, 0)!=0;
noSign = find_option("nosign",0,0)!=0;
forceDelta = find_option("delta",0,0)!=0;
forceBaseline = find_option("baseline",0,0)!=0;
if( forceDelta && forceBaseline ){
fossil_fatal("cannot use --delta and --baseline together");
}
dryRunFlag = find_option("dry-run","n",0)!=0;
|
| ︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 |
/*
** Check that the user exists.
*/
if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
fossil_fatal("no such user: %s", g.zLogin);
}
| | | 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 |
/*
** Check that the user exists.
*/
if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
fossil_fatal("no such user: %s", g.zLogin);
}
hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
db_begin_transaction();
db_record_repository_filename(0);
if( hasChanges==0 && !isAMerge && !allowEmpty && !forceFlag ){
fossil_fatal("nothing has changed; use --allow-empty to override");
}
/* If none of the files that were named on the command line have
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
132 133 134 135 136 137 138 |
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
char *zManFile;
Blob manifest;
| < | < < < < > > | 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 |
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
char *zManFile;
Blob manifest;
Blob taglist;
int flg;
flg = db_get_manifest_setting();
if( flg & MFESTFLG_RAW ){
blob_zero(&manifest);
content_get(vid, &manifest);
sterilize_manifest(&manifest);
zManFile = mprintf("%smanifest", g.zLocalRoot);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
}else{
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
zManFile = mprintf("%smanifest", g.zLocalRoot);
file_delete(zManFile);
free(zManFile);
}
}
if( flg & MFESTFLG_UUID ){
Blob hash;
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
blob_set_dynamic(&hash, rid_to_uuid(vid));
blob_append(&hash, "\n", 1);
blob_write_to_file(&hash, zManFile);
free(zManFile);
blob_reset(&hash);
}else{
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
|
| ︙ | ︙ |
Changes to src/clone.c.
| ︙ | ︙ | |||
173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
db_begin_transaction();
db_record_repository_filename(g.argv[3]);
db_initial_setup(0, 0, zDefaultUser);
user_select();
db_set("content-schema", CONTENT_SCHEMA, 0);
db_set("aux-schema", AUX_SCHEMA_MAX, 0);
db_set("rebuilt", get_version(), 0);
remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
url_remember();
if( g.zSSLIdentity!=0 ){
/* If the --ssl-identity option was specified, store it as a setting */
Blob fn;
blob_zero(&fn);
file_canonical_name(g.zSSLIdentity, &fn, 0);
| > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
db_begin_transaction();
db_record_repository_filename(g.argv[3]);
db_initial_setup(0, 0, zDefaultUser);
user_select();
db_set("content-schema", CONTENT_SCHEMA, 0);
db_set("aux-schema", AUX_SCHEMA_MAX, 0);
db_set("rebuilt", get_version(), 0);
db_unset("hash-policy", 0);
remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, g.argv[2]);
url_remember();
if( g.zSSLIdentity!=0 ){
/* If the --ssl-identity option was specified, store it as a setting */
Blob fn;
blob_zero(&fn);
file_canonical_name(g.zSSLIdentity, &fn, 0);
|
| ︙ | ︙ |
Changes to src/config.h.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #if defined(_WIN32) && !defined(_WIN64) && !defined(_MSC_VER) && !defined(_USE_32BIT_TIME_T) # define _USE_32BIT_TIME_T #endif #ifdef HAVE_AUTOCONFIG_H #include "autoconfig.h" #endif #ifndef _RC_COMPILE_ /* ** System header files used by all modules */ #include <unistd.h> | > > > > > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #if defined(_WIN32) && !defined(_WIN64) && !defined(_MSC_VER) && !defined(_USE_32BIT_TIME_T) # define _USE_32BIT_TIME_T #endif #ifdef HAVE_AUTOCONFIG_H #include "autoconfig.h" #endif /* Enable the hardened SHA1 implemenation by default */ #ifndef FOSSIL_HARDENED_SHA1 # define FOSSIL_HARDENED_SHA1 1 #endif #ifndef _RC_COMPILE_ /* ** System header files used by all modules */ #include <unistd.h> |
| ︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 176 177 178 179 | # else # define COMPILER_NAME "unknown" # endif #endif #if !defined(_RC_COMPILE_) && !defined(SQLITE_AMALGAMATION) #include "sqlite3.h" /* ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. */ #if HAVE_GETPASSPHRASE #define getpass getpassphrase | > | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | # else # define COMPILER_NAME "unknown" # endif #endif #if !defined(_RC_COMPILE_) && !defined(SQLITE_AMALGAMATION) #include <stdint.h> #include "sqlite3.h" /* ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. */ #if HAVE_GETPASSPHRASE #define getpass getpassphrase |
| ︙ | ︙ |
Changes to src/configure.c.
| ︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
{ "mv-rm-files", CONFIGSET_PROJ },
#endif
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
| > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
{ "hash-policy", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
{ "mv-rm-files", CONFIGSET_PROJ },
#endif
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
|
| ︙ | ︙ |
Changes to src/content.c.
| ︙ | ︙ | |||
310 311 312 313 314 315 316 | } /* ** COMMAND: artifact* ** ** Usage: %fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS? ** | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | } /* ** COMMAND: artifact* ** ** Usage: %fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS? ** ** Extract an artifact by its artifact hash and write the results on ** standard output, or if the optional 4th argument is given, in ** the named output file. ** ** Options: ** -R|--repository FILE Extract artifacts from repository FILE ** ** See also: finfo |
| ︙ | ︙ | |||
495 496 497 498 499 500 501 | ** ** 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 */ | | > > > > > > > > | > > > > > > < | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
**
** 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, /* artifact 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 */
){
int size;
int rid;
Stmt s1;
Blob cmpr;
Blob hash;
int markAsUnclustered = 0;
int isDephantomize = 0;
assert( g.repositoryOpen );
assert( pBlob!=0 );
assert( srcId==0 || zUuid!=0 );
db_begin_transaction();
if( zUuid==0 ){
assert( nBlob==0 );
/* First check the auxiliary hash to see if there is already an artifact
** that uses the auxiliary hash name */
hname_hash(pBlob, 1, &hash);
rid = fast_uuid_to_rid(blob_str(&hash));
if( rid==0 ){
/* No existing artifact with the auxiliary hash name. Therefore, use
** the primary hash name. */
blob_reset(&hash);
hname_hash(pBlob, 0, &hash);
}
}else{
blob_init(&hash, zUuid, -1);
}
if( g.eHashPolicy==HPOLICY_AUTO && blob_size(&hash)>HNAME_LEN_SHA1 ){
g.eHashPolicy = HPOLICY_SHA3;
db_set_int("hash-policy", HPOLICY_SHA3, 0);
}
if( nBlob ){
size = nBlob;
}else{
size = blob_size(pBlob);
if( srcId ){
size = delta_output_size(blob_buffer(pBlob), size);
}
}
/* Check to see if the entry already exists and if it does whether
** or not the entry is a phantom
*/
db_prepare(&s1, "SELECT rid, size FROM blob WHERE uuid=%B", &hash);
if( db_step(&s1)==SQLITE_ROW ){
rid = db_column_int(&s1, 0);
|
| ︙ | ︙ | |||
866 867 868 869 870 871 872 |
**
** --parse Parse all manifests, wikis, tickets, events, and
** so forth, reporting any errors found.
*/
void test_integrity(void){
Stmt q;
Blob content;
| < | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
**
** --parse Parse all manifests, wikis, tickets, events, and
** so forth, reporting any errors found.
*/
void test_integrity(void){
Stmt q;
Blob content;
int n1 = 0;
int n2 = 0;
int nErr = 0;
int total;
int nCA = 0;
int anCA[10];
int bParse = find_option("parse",0,0)!=0;
|
| ︙ | ︙ | |||
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 |
db_finalize(&q);
db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
total = db_int(0, "SELECT max(rid) FROM blob");
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
int size = db_column_int(&q, 2);
n1++;
fossil_print(" %d/%d\r", n1, total);
fflush(stdout);
if( size<0 ){
fossil_print("skip phantom %d %s\n", rid, zUuid);
continue; /* Ignore phantoms */
}
content_get(rid, &content);
if( blob_size(&content)!=size ){
fossil_print("size mismatch on artifact %d: wanted %d but got %d\n",
rid, size, blob_size(&content));
nErr++;
}
| > | < | < | < | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 |
db_finalize(&q);
db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
total = db_int(0, "SELECT max(rid) FROM blob");
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
int nUuid = db_column_bytes(&q, 1);
int size = db_column_int(&q, 2);
n1++;
fossil_print(" %d/%d\r", n1, total);
fflush(stdout);
if( size<0 ){
fossil_print("skip phantom %d %s\n", rid, zUuid);
continue; /* Ignore phantoms */
}
content_get(rid, &content);
if( blob_size(&content)!=size ){
fossil_print("size mismatch on artifact %d: wanted %d but got %d\n",
rid, size, blob_size(&content));
nErr++;
}
if( !hname_verify_hash(&content, zUuid, nUuid) ){
fossil_print("wrong hash on artifact %d\n",rid);
nErr++;
}
if( bParse && looks_like_control_artifact(&content) ){
Blob err;
int i, n;
char *z;
Manifest *p;
char zFirstLine[400];
blob_zero(&err);
z = blob_buffer(&content);
n = blob_size(&content);
for(i=0; i<n && z[i] && z[i]!='\n' && i<sizeof(zFirstLine)-1; i++){}
memcpy(zFirstLine, z, i);
zFirstLine[i] = 0;
p = manifest_parse(&content, 0, &err);
if( p==0 ){
fossil_print("manifest_parse failed for %s:\n%s\n",
zUuid, blob_str(&err));
if( strncmp(blob_str(&err), "line 1:", 7)==0 ){
fossil_print("\"%s\"\n", zFirstLine);
}
}else{
anCA[p->type]++;
manifest_destroy(p);
nCA++;
}
blob_reset(&err);
}else{
blob_reset(&content);
}
n2++;
}
db_finalize(&q);
fossil_print("%d non-phantom blobs (out of %d total) checked: %d errors\n",
n2, n1, nErr);
if( bParse ){
static const char *const azType[] = { 0, "manifest", "cluster",
|
| ︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 | ** WARNING: This command destroys data and can cause you to lose work. ** Make sure you have a backup copy before using this command! ** ** WARNING: You must run "fossil rebuild" after this command to rebuild ** the metadata. ** ** Note that the arguments are the integer raw RID values from the BLOB table, | | | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
** WARNING: This command destroys data and can cause you to lose work.
** Make sure you have a backup copy before using this command!
**
** WARNING: You must run "fossil rebuild" after this command to rebuild
** the metadata.
**
** Note that the arguments are the integer raw RID values from the BLOB table,
** not artifact hashs or labels.
*/
void test_content_erase(void){
int i;
Blob x;
char c;
Stmt q;
prompt_user("This command erases information from the repository and\n"
|
| ︙ | ︙ |
Changes to src/db.c.
1 2 3 4 5 6 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ |
| ︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 |
g.zRepositoryName = mprintf("%s", zDbName);
db_open_or_attach(g.zRepositoryName, "repository");
g.repositoryOpen = 1;
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
g.allowSymlinks = db_get_boolean("allow-symlinks",
db_allow_symlinks_by_default());
g.zAuxSchema = db_get("aux-schema","");
| | < < < < < | | < < > < < < | > < < < < < < < < > | 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 |
g.zRepositoryName = mprintf("%s", zDbName);
db_open_or_attach(g.zRepositoryName, "repository");
g.repositoryOpen = 1;
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
g.allowSymlinks = db_get_boolean("allow-symlinks",
db_allow_symlinks_by_default());
g.zAuxSchema = db_get("aux-schema","");
g.eHashPolicy = db_get_int("hash-policy",-1);
if( g.eHashPolicy<0 ){
g.eHashPolicy = hname_default_policy();
db_set_int("hash-policy", g.eHashPolicy, 0);
}
/* If the ALIAS table is not present, then some on-the-fly schema
** updates might be required.
*/
rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
}
/*
** Flags for the db_find_and_open_repository() function.
*/
#if INTERFACE
#define OPEN_OK_NOT_FOUND 0x001 /* Do not error out if not found */
|
| ︙ | ︙ | |||
1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 |
" SELECT name,value,mtime FROM settingSrc.config"
" WHERE (name IN %s OR name IN %s)"
" AND name NOT GLOB 'project-*'"
" AND name NOT GLOB 'short-project-*';",
configure_inop_rhs(CONFIGSET_ALL),
db_setting_inop_rhs()
);
db_multi_exec(
"REPLACE INTO reportfmt SELECT * FROM settingSrc.reportfmt;"
);
/*
** Copy the user permissions, contact information, last modified
** time, and photo for all the "system" users from the supplied
| > | 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 |
" SELECT name,value,mtime FROM settingSrc.config"
" WHERE (name IN %s OR name IN %s)"
" AND name NOT GLOB 'project-*'"
" AND name NOT GLOB 'short-project-*';",
configure_inop_rhs(CONFIGSET_ALL),
db_setting_inop_rhs()
);
g.eHashPolicy = db_get_int("hash-policy", g.eHashPolicy);
db_multi_exec(
"REPLACE INTO reportfmt SELECT * FROM settingSrc.reportfmt;"
);
/*
** Copy the user permissions, contact information, last modified
** time, and photo for all the "system" users from the supplied
|
| ︙ | ︙ | |||
1919 1920 1921 1922 1923 1924 1925 | ** repository is used, almost all of the settings accessible from the setup ** page, either directly or indirectly, will be copied. Normal users and ** their associated permissions will not be copied; however, the system ** default users "anonymous", "nobody", "reader", "developer", and their ** associated permissions will be copied. ** ** Options: | | | | > > > > > > > > | 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 |
** repository is used, almost all of the settings accessible from the setup
** page, either directly or indirectly, will be copied. Normal users and
** their associated permissions will not be copied; however, the system
** default users "anonymous", "nobody", "reader", "developer", and their
** associated permissions will be copied.
**
** Options:
** --template FILE Copy settings from repository file
** --admin-user|-A USERNAME Select given USERNAME as admin user
** --date-override DATETIME Use DATETIME as time of the initial check-in
** --sha1 Use a initial hash policy of "sha1"
**
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
** year-month-day form, it may be truncated, the "T" may be replaced by
** a space, and it may also name a timezone offset from UTC as "-HH:MM"
** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
** means UTC.
**
** See also: clone
*/
void create_repository_cmd(void){
char *zPassword;
const char *zTemplate; /* Repository from which to copy settings */
const char *zDate; /* Date of the initial check-in */
const char *zDefaultUser; /* Optional name of the default user */
int bUseSha1 = 0; /* True to set the hash-policy to sha1 */
zTemplate = find_option("template",0,1);
zDate = find_option("date-override",0,1);
zDefaultUser = find_option("admin-user","A",1);
bUseSha1 = find_option("sha1",0,0)!=0;
/* We should be done with options.. */
verify_all_options();
if( g.argc!=3 ){
usage("REPOSITORY-NAME");
}
if( -1 != file_size(g.argv[2]) ){
fossil_fatal("file already exists: %s", g.argv[2]);
}
db_create_repository(g.argv[2]);
db_open_repository(g.argv[2]);
db_open_config(0, 0);
if( zTemplate ) db_attach(zTemplate, "settingSrc");
db_begin_transaction();
if( bUseSha1 ){
g.eHashPolicy = HPOLICY_SHA1;
db_set_int("hash-policy", HPOLICY_SHA1, 0);
}
if( zDate==0 ) zDate = "now";
db_initial_setup(zTemplate, zDate, zDefaultUser);
db_end_transaction(0);
if( zTemplate ) db_detach("settingSrc");
fossil_print("project-id: %s\n", db_get("project-code", 0));
fossil_print("server-id: %s\n", db_get("server-code", 0));
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
|
| ︙ | ︙ | |||
2081 2082 2083 2084 2085 2086 2087 |
assert( rc==0 || rc==1 );
if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
sqlite3_result_value(context, argv[2-rc]);
}
}
/*
| | | | | | | 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 |
assert( rc==0 || rc==1 );
if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
sqlite3_result_value(context, argv[2-rc]);
}
}
/*
** Convert the input string into a artifact hash. Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.
**
** The value returned is stored in static space and will be overwritten
** on subsequent calls.
**
** If zContent is already a well-formed artifact hash, then return a copy
** of that hash, not a hash of the hash.
**
** The CONCEALED table is meant to obscure email addresses. Every valid
** email address will contain a "@" character and "@" is not valid within
** a SHA1 hash so there is no chance that a valid email address will go
** unconcealed.
*/
char *db_conceal(const char *zContent, int n){
static char zHash[HNAME_MAX+1];
Blob out;
if( hname_validate(zContent, n) ){
memcpy(zHash, zContent, n);
zHash[n] = 0;
}else{
sha1sum_step_text(zContent, n);
sha1sum_finish(&out);
sqlite3_snprintf(sizeof(zHash), zHash, "%s", blob_str(&out));
blob_reset(&out);
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
2276 2277 2278 2279 2280 2281 2282 | ** WEBPAGE: praise ** ** URL: /annotate?checkin=ID&filename=FILENAME ** URL: /blame?checkin=ID&filename=FILENAME ** URL: /praise?checkin=ID&filename=FILENAME ** ** Show the most recent change to each line of a text file. /annotate shows | | | 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 | ** WEBPAGE: praise ** ** URL: /annotate?checkin=ID&filename=FILENAME ** URL: /blame?checkin=ID&filename=FILENAME ** URL: /praise?checkin=ID&filename=FILENAME ** ** Show the most recent change to each line of a text file. /annotate shows ** the date of the changes and the check-in hash (with a link to the ** check-in). /blame and /praise also show the user who made the check-in. ** ** Query parameters: ** ** checkin=ID The manifest ID at which to start the annotation ** filename=FILENAME The filename. ** filevers Show file versions rather than check-in versions |
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | } /* ** Show the difference between two files, one in memory and one on disk. ** ** The difference is the set of edits needed to transform pFile1 into ** zFile2. The content of pFile1 is in memory. zFile2 exists on disk. ** ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the ** command zDiffCmd to do the diffing. ** ** When using an external diff program, zBinGlob contains the GLOB patterns ** for file names to treat as binary. If fIncludeBinary is zero, these files ** will be skipped in addition to files that may contain binary content. */ void diff_file( Blob *pFile1, /* In memory content to compare from */ int isBin1, /* Does the 'from' content appear to be binary */ const char *zFile2, /* On disk content to compare to */ const char *zName, /* Display name of the file */ const char *zDiffCmd, /* Command for comparison */ const char *zBinGlob, /* Treat file names matching this as binary */ int fIncludeBinary, /* Include binary files for external diff */ | > > > | > | 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 |
}
/*
** Show the difference between two files, one in memory and one on disk.
**
** The difference is the set of edits needed to transform pFile1 into
** zFile2. The content of pFile1 is in memory. zFile2 exists on disk.
**
** If fSwapDiff is 1, show the set of edits to transform zFile2 into pFile1
** instead of the opposite.
**
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
** command zDiffCmd to do the diffing.
**
** When using an external diff program, zBinGlob contains the GLOB patterns
** for file names to treat as binary. If fIncludeBinary is zero, these files
** will be skipped in addition to files that may contain binary content.
*/
void diff_file(
Blob *pFile1, /* In memory content to compare from */
int isBin1, /* Does the 'from' content appear to be binary */
const char *zFile2, /* On disk content to compare to */
const char *zName, /* Display name of the file */
const char *zDiffCmd, /* Command for comparison */
const char *zBinGlob, /* Treat file names matching this as binary */
int fIncludeBinary, /* Include binary files for external diff */
u64 diffFlags, /* Flags to control the diff */
int fSwapDiff /* Diff from Zfile2 to Pfile1 */
){
if( zDiffCmd==0 ){
Blob out; /* Diff output text */
Blob file2; /* Content of zFile2 */
const char *zName2; /* Name of zFile2 for display */
/* Read content of zFile2 into memory */
|
| ︙ | ︙ | |||
192 193 194 195 196 197 198 |
/* Compute and output the differences */
if( diffFlags & DIFF_BRIEF ){
if( blob_compare(pFile1, &file2) ){
fossil_print("CHANGED %s\n", zName);
}
}else{
blob_zero(&out);
| > > > | > | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
/* Compute and output the differences */
if( diffFlags & DIFF_BRIEF ){
if( blob_compare(pFile1, &file2) ){
fossil_print("CHANGED %s\n", zName);
}
}else{
blob_zero(&out);
if( fSwapDiff ){
text_diff(&file2, pFile1, &out, 0, diffFlags);
}else{
text_diff(pFile1, &file2, &out, 0, diffFlags);
}
if( blob_size(&out) ){
diff_print_filenames(zName, zName2, diffFlags);
fossil_print("%s\n", blob_str(&out));
}
blob_reset(&out);
}
|
| ︙ | ︙ | |||
250 251 252 253 254 255 256 |
blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++);
}while( file_access(blob_str(&nameFile1),F_OK)==0 );
blob_write_to_file(pFile1, blob_str(&nameFile1));
/* Construct the external diff command */
blob_zero(&cmd);
blob_appendf(&cmd, "%s ", zDiffCmd);
| > > > | > > | | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++);
}while( file_access(blob_str(&nameFile1),F_OK)==0 );
blob_write_to_file(pFile1, blob_str(&nameFile1));
/* Construct the external diff command */
blob_zero(&cmd);
blob_appendf(&cmd, "%s ", zDiffCmd);
if( fSwapDiff ){
shell_escape(&cmd, zFile2);
blob_append(&cmd, " ", 1);
shell_escape(&cmd, blob_str(&nameFile1));
}else{
shell_escape(&cmd, blob_str(&nameFile1));
blob_append(&cmd, " ", 1);
shell_escape(&cmd, zFile2);
}
/* Run the external diff command */
fossil_system(blob_str(&cmd));
/* Delete the temporary file and clean up memory used */
file_delete(blob_str(&nameFile1));
blob_reset(&nameFile1);
|
| ︙ | ︙ | |||
480 481 482 483 484 485 486 |
content_get(srcid, &content);
}else{
blob_zero(&content);
}
isBin = fIncludeBinary ? 0 : looks_like_binary(&content);
diff_print_index(zPathname, diffFlags);
diff_file(&content, isBin, zFullName, zPathname, zDiffCmd,
| | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
content_get(srcid, &content);
}else{
blob_zero(&content);
}
isBin = fIncludeBinary ? 0 : looks_like_binary(&content);
diff_print_index(zPathname, diffFlags);
diff_file(&content, isBin, zFullName, zPathname, zDiffCmd,
zBinGlob, fIncludeBinary, diffFlags, 0);
blob_reset(&content);
}
blob_reset(&fname);
}
db_finalize(&q);
db_end_transaction(1); /* ROLLBACK */
}
|
| ︙ | ︙ | |||
517 518 519 520 521 522 523 |
while( db_step(&q)==SQLITE_ROW ){
char *zFullName;
const char *zFile = (const char*)db_column_text(&q, 0);
if( !file_dir_match(pFileDir, zFile) ) continue;
zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
db_column_blob(&q, 1, &content);
diff_file(&content, 0, zFullName, zFile,
| | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
while( db_step(&q)==SQLITE_ROW ){
char *zFullName;
const char *zFile = (const char*)db_column_text(&q, 0);
if( !file_dir_match(pFileDir, zFile) ) continue;
zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
db_column_blob(&q, 1, &content);
diff_file(&content, 0, zFullName, zFile,
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0);
fossil_free(zFullName);
blob_reset(&content);
}
db_finalize(&q);
}
/*
|
| ︙ | ︙ | |||
748 749 750 751 752 753 754 |
/*
** Returns non-zero if files that may be binary should be used with external
** diff programs.
*/
int diff_include_binary_files(void){
const char* zArgIncludeBinary = find_option("diff-binary", 0, 1);
| | | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 |
/*
** Returns non-zero if files that may be binary should be used with external
** diff programs.
*/
int diff_include_binary_files(void){
const char* zArgIncludeBinary = find_option("diff-binary", 0, 1);
/* Command line argument have priority on settings */
if( zArgIncludeBinary ){
return is_truth(zArgIncludeBinary);
}else{
return db_get_boolean("diff-binary", 1);
}
}
|
| ︙ | ︙ |
Changes to src/doc.c.
| ︙ | ︙ | |||
525 526 527 528 529 530 531 | /* ** WEBPAGE: uv ** WEBPAGE: doc ** URL: /uv/FILE ** URL: /doc/CHECKIN/FILE ** | | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | /* ** WEBPAGE: uv ** WEBPAGE: doc ** URL: /uv/FILE ** URL: /doc/CHECKIN/FILE ** ** CHECKIN can be either tag or hash prefix or timestamp identifying a ** particular check, or the name of a branch (meaning the most recent ** check-in on that branch) or one of various magic words: ** ** "tip" means the most recent check-in ** ** "ckout" means the current check-out, if the server is run from ** within a check-out, otherwise it is the same as "tip" |
| ︙ | ︙ | |||
733 734 735 736 737 738 739 |
db_end_transaction(0);
return;
/* Jump here when unable to locate the document */
doc_not_found:
db_end_transaction(0);
if( isUV && P("name")==0 ){
| | | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
db_end_transaction(0);
return;
/* Jump here when unable to locate the document */
doc_not_found:
db_end_transaction(0);
if( isUV && P("name")==0 ){
uvlist_page();
return;
}
cgi_set_status(404, "Not Found");
style_header("Not Found");
@ <p>Document %h(zOrigName) not found
if( fossil_strcmp(zCheckin,"ckout")!=0 ){
@ in %z(href("%R/tree?ci=%T",zCheckin))%h(zCheckin)</a>
|
| ︙ | ︙ |
Changes to src/encode.c.
| ︙ | ︙ | |||
334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
}
}
z[j++] = c;
}
if( z[j] ) z[j] = 0;
}
/*
** The characters used for HTTP base64 encoding.
*/
static unsigned char zBase[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
}
}
z[j++] = c;
}
if( z[j] ) z[j] = 0;
}
/*
** The *pz variable points to a UTF8 string. Read the next character
** off of that string and return its codepoint value. Advance *pz to the
** next character
*/
u32 fossil_utf8_read(
const unsigned char **pz /* Pointer to string from which to read char */
){
unsigned int c;
/*
** This lookup table is used to help decode the first byte of
** a multi-byte UTF8 character.
*/
static const unsigned char utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
c = *((*pz)++);
if( c>=0xc0 ){
c = utf8Trans1[c-0xc0];
while( (*(*pz) & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *((*pz)++));
}
if( c<0x80
|| (c&0xFFFFF800)==0xD800
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
}
return c;
}
/*
** Encode a UTF8 string for JSON. All special characters are escaped.
*/
void blob_append_json_string(Blob *pBlob, const char *zStr){
const unsigned char *z;
char *zOut;
u32 c;
int n, i, j;
z = (const unsigned char*)zStr;
n = 0;
while( (c = fossil_utf8_read(&z))!=0 ){
if( c=='\\' || c=='"' ){
n += 2;
}else if( c<' ' || c>=0x7f ){
if( c=='\n' || c=='\r' ){
n += 2;
}else{
n += 6;
}
}else{
n++;
}
}
i = blob_size(pBlob);
blob_resize(pBlob, i+n);
zOut = blob_buffer(pBlob);
z = (const unsigned char*)zStr;
while( (c = fossil_utf8_read(&z))!=0 ){
if( c=='\\' ){
zOut[i++] = '\\';
zOut[i++] = c;
}else if( c<' ' || c>=0x7f ){
zOut[i++] = '\\';
if( c=='\n' ){
zOut[i++] = 'n';
}else if( c=='\r' ){
zOut[i++] = 'r';
}else{
zOut[i++] = 'u';
for(j=3; j>=0; j--){
zOut[i+j] = "0123456789abcdef"[c&0xf];
c >>= 4;
}
i += 4;
}
}else{
zOut[i++] = c;
}
}
zOut[i] = 0;
}
/*
** The characters used for HTTP base64 encoding.
*/
static unsigned char zBase[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
| ︙ | ︙ |
Changes to src/event.c.
| ︙ | ︙ | |||
382 383 384 385 386 387 388 |
}
zTag = mprintf("event-%s", zId);
rid = db_int(0,
"SELECT rid FROM tagxref"
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname GLOB '%q*')"
" ORDER BY mtime DESC", zTag
);
| | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
}
zTag = mprintf("event-%s", zId);
rid = db_int(0,
"SELECT rid FROM tagxref"
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname GLOB '%q*')"
" ORDER BY mtime DESC", zTag
);
if( rid && strlen(zId)<HNAME_MIN ){
zId = db_text(0,
"SELECT substr(tagname,7) FROM tag WHERE tagname GLOB '%q*'",
zTag
);
}
free(zTag);
|
| ︙ | ︙ |
Changes to src/export.c.
| ︙ | ︙ | |||
259 260 261 262 263 264 265 |
}
cur_tok = strtok(NULL, " \t");
if( !cur_tok ){
/* This mark was generated by an older version of Fossil and doesn't
** include the mark name and uuid. create_mark() will name the new mark
** exactly as it was when exported to git, so that we should have a
| | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
}
cur_tok = strtok(NULL, " \t");
if( !cur_tok ){
/* This mark was generated by an older version of Fossil and doesn't
** include the mark name and uuid. create_mark() will name the new mark
** exactly as it was when exported to git, so that we should have a
** valid mapping from git hash<->mark name<->fossil hash. */
unsigned int mid;
if( type_=='c' ){
mid = COMMITMARK(mark->rid);
}
else{
mid = BLOBMARK(mark->rid);
}
|
| ︙ | ︙ |
Changes to src/foci.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 |
** SELECT * FROM files_of_checkin('trunk');
**
** The "schema" for the temp.foci table is:
**
** CREATE TABLE files_of_checkin(
** checkinID INTEGER, -- RID for the check-in manifest
** filename TEXT, -- Name of a file
| | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
** SELECT * FROM files_of_checkin('trunk');
**
** The "schema" for the temp.foci table is:
**
** CREATE TABLE files_of_checkin(
** checkinID INTEGER, -- RID for the check-in manifest
** filename TEXT, -- Name of a file
** uuid TEXT, -- hash of the file
** previousName TEXT, -- Name of the file in previous check-in
** perm TEXT, -- Permissions on the file
** symname TEXT HIDDEN -- Symbolic name of the check-in.
** );
**
** The hidden symname column is (optionally) used as a query parameter to
** identify the particular check-in to parse. The checkinID parameter
|
| ︙ | ︙ | |||
52 53 54 55 56 57 58 | /* ** The schema for the virtual table: */ static const char zFociSchema[] = @ CREATE TABLE files_of_checkin( @ checkinID INTEGER, -- RID for the check-in manifest @ filename TEXT, -- Name of a file | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* ** The schema for the virtual table: */ static const char zFociSchema[] = @ CREATE TABLE files_of_checkin( @ checkinID INTEGER, -- RID for the check-in manifest @ filename TEXT, -- Name of a file @ uuid TEXT, -- hash of the file @ previousName TEXT, -- Name of the file in previous check-in @ perm TEXT, -- Permissions on the file @ symname TEXT HIDDEN -- Symbolic name of the check-in @ ); ; #define FOCI_CHECKINID 0 |
| ︙ | ︙ |
Changes to src/fusefs.c.
| ︙ | ︙ | |||
292 293 294 295 296 297 298 | ** Usage: %fossil fusefs [--debug] DIRECTORY ** ** This command uses the Fuse Filesystem (FuseFS) to mount a directory ** at DIRECTORY that contains the content of all check-ins in the ** repository. The names of files are DIRECTORY/checkins/VERSION/PATH ** where DIRECTORY is the root of the mount, VERSION is any valid ** check-in name (examples: "trunk" or "tip" or a tag or any unique | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | ** Usage: %fossil fusefs [--debug] DIRECTORY ** ** This command uses the Fuse Filesystem (FuseFS) to mount a directory ** at DIRECTORY that contains the content of all check-ins in the ** repository. The names of files are DIRECTORY/checkins/VERSION/PATH ** where DIRECTORY is the root of the mount, VERSION is any valid ** check-in name (examples: "trunk" or "tip" or a tag or any unique ** prefix of an artifact hash, etc) and PATH is the pathname of the file in ** the check-in. If DIRECTORY does not exist, then an attempt is made ** to create it. ** ** The DIRECTORY/checkins directory is not searchable so one cannot ** do "ls DIRECTORY/checkins" to get a listing of all possible check-in ** names. There are countless variations on check-in names and it is ** impractical to list them all. But all other directories are searchable |
| ︙ | ︙ |
Changes to src/graph.c.
| ︙ | ︙ | |||
177 178 179 180 181 182 183 | int graph_add_row( GraphContext *p, /* The context to which the row is added */ int rid, /* RID for the check-in */ int nParent, /* Number of parents */ int *aParent, /* Array of parents */ const char *zBranch, /* Branch for this check-in */ const char *zBgClr, /* Background color. NULL or "" for white. */ | | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
int graph_add_row(
GraphContext *p, /* The context to which the row is added */
int rid, /* RID for the check-in */
int nParent, /* Number of parents */
int *aParent, /* Array of parents */
const char *zBranch, /* Branch for this check-in */
const char *zBgClr, /* Background color. NULL or "" for white. */
const char *zUuid, /* hash name of the object being graphed */
int isLeaf /* True if this row is a leaf */
){
GraphRow *pRow;
int nByte;
if( p->nErr ) return 0;
nByte = sizeof(GraphRow);
|
| ︙ | ︙ |
Added src/hname.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
/*
** Copyright (c) 2017 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains generic code for dealing with hashes used for
** naming artifacts. Specific hash algorithms are implemented separately
** (for example in sha1.c and sha3.c). This file contains the generic
** interface logic.
**
** "hname" is intended to be an abbreviation of "hash name".
*/
#include "config.h"
#include "hname.h"
#if INTERFACE
/*
** Code numbers for the allowed hash algorithms.
*/
#define HNAME_ERROR 0 /* Not a valid hash */
#define HNAME_SHA1 1 /* SHA1 */
#define HNAME_K256 2 /* SHA3-256 */
/*
** Minimum and maximum lengths for a hash value when hex encoded.
*/
#define HNAME_MIN 40 /* Length for SHA1 */
#define HNAME_MAX 64 /* Length for SHA3-256 */
/*
** Hash lengths for the various algorithms
*/
#define HNAME_LEN_SHA1 40
#define HNAME_LEN_K256 64
/*
** The number of distinct hash algorithms:
*/
#define HNAME_COUNT 2 /* Just SHA1 and SHA3-256. Let's keep it that way! */
/*
** Hash naming policies
*/
#define HPOLICY_SHA1 0 /* Use SHA1 hashes */
#define HPOLICY_AUTO 1 /* SHA1 but auto-promote to SHA3 */
#define HPOLICY_SHA3 2 /* Use SHA3 hashes */
#define HPOLICY_SHA3_ONLY 3 /* Use SHA3 hashes exclusively */
#define HPOLICY_SHUN_SHA1 4 /* Shun all SHA1 objects */
#endif /* INTERFACE */
/*
** Return a human-readable name for the hash algorithm given a hash with
** a length of nHash hexadecimal digits.
*/
const char *hname_alg(int nHash){
if( nHash==HNAME_LEN_SHA1 ) return "SHA1";
if( nHash==HNAME_LEN_K256 ) return "SHA3-256";
return "?";
}
/*
** Return the integer hash algorithm code number (ex: HNAME_K256) for
** the hash string provided. Or return HNAME_ERROR (0) if the input string
** is not a valid artifact hash string.
*/
int hname_validate(const char *zHash, int nHash){
int id;
switch( nHash ){
case HNAME_LEN_SHA1: id = HNAME_SHA1; break;
case HNAME_LEN_K256: id = HNAME_K256; break;
default: return HNAME_ERROR;
}
if( !validate16(zHash, nHash) ) return HNAME_ERROR;
return id;
}
/*
** Verify that zHash is a valid hash for the content in pContent.
** Return true if the hash is correct. Return false if the content
** does not match the hash.
**
** Actually, the returned value is one of the hash algorithm constants
** corresponding to the hash that matched if the hash is correct.
** (Examples: HNAME_SHA1 or HNAME_K256). And the return is HNAME_ERROR
** if the hash does not match.
*/
int hname_verify_hash(Blob *pContent, const char *zHash, int nHash){
int id = HNAME_ERROR;
switch( nHash ){
case HNAME_LEN_SHA1: {
Blob hash;
sha1sum_blob(pContent, &hash);
if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1;
blob_reset(&hash);
break;
}
case HNAME_LEN_K256: {
sha3sum_init(256);
sha3sum_step_blob(pContent);
if( memcmp(sha3sum_finish(0),zHash,64)==0 ) id = HNAME_K256;
break;
}
}
return id;
}
/*
** Verify that zHash is a valid hash for the content of a file on
** disk named zFile.
**
** Return true if the hash is correct. Return false if the content
** does not match the hash.
**
** Actually, the returned value is one of the hash algorithm constants
** corresponding to the hash that matched if the hash is correct.
** (Examples: HNAME_SHA1 or HNAME_K256). And the return is HNAME_ERROR
** if the hash does not match.
*/
int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){
int id = HNAME_ERROR;
switch( nHash ){
case HNAME_LEN_SHA1: {
Blob hash;
sha1sum_file(zFile, &hash);
if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1;
blob_reset(&hash);
break;
}
case HNAME_LEN_K256: {
Blob hash;
sha3sum_file(zFile, 256, &hash);
if( memcmp(blob_buffer(&hash),zHash,64)==0 ) id = HNAME_LEN_K256;
blob_reset(&hash);
break;
}
}
return id;
}
/*
** Compute a hash on blob pContent. Write the hash into blob pHashOut.
** This routine assumes that pHashOut is uninitialized.
**
** The preferred hash is used for iHType==0 and the alternative hash is
** used if iHType==1. (The interface is designed to accommodate more than
** just two hashes, but HNAME_COUNT is currently fixed at 2.)
**
** Depending on the hash policy, the alternative hash may be disallowed.
** If the alterative hash is disallowed, the routine returns 0. This
** routine returns 1 if iHType>0 and the alternative hash is allowed,
** and it always returns 1 when iHType==0.
**
** Alternative hash is disallowed for all hash policies except auto,
** sha1 and sha3.
*/
int hname_hash(const Blob *pContent, unsigned int iHType, Blob *pHashOut){
assert( iHType==0 || iHType==1 );
if( iHType==1 ){
switch( g.eHashPolicy ){
case HPOLICY_AUTO:
case HPOLICY_SHA1:
sha3sum_blob(pContent, 256, pHashOut);
return 1;
case HPOLICY_SHA3:
sha1sum_blob(pContent, pHashOut);
return 1;
}
}
if( iHType==0 ){
switch( g.eHashPolicy ){
case HPOLICY_SHA1:
case HPOLICY_AUTO:
sha1sum_blob(pContent, pHashOut);
return 1;
case HPOLICY_SHA3:
case HPOLICY_SHA3_ONLY:
case HPOLICY_SHUN_SHA1:
sha3sum_blob(pContent, 256, pHashOut);
return 1;
}
}
blob_init(pHashOut, 0, 0);
return 0;
}
/*
** Return the default hash policy for repositories that do not currently
** have an assigned hash policy.
**
** Make the default HPOLICY_AUTO if there are SHA1 artficates but no SHA3
** artifacts in the repository. Make the default HPOLICY_SHA3 if there
** are one or more SHA3 artifacts or if the repository is initially empty.
*/
int hname_default_policy(void){
if( db_exists("SELECT 1 FROM blob WHERE length(uuid)>40")
|| !db_exists("SELECT 1 FROM blob WHERE length(uuid)==40")
){
return HPOLICY_SHA3;
}else{
return HPOLICY_AUTO;
}
}
/*
** Names of the hash policies.
*/
static const char *azPolicy[] = {
"sha1", "auto", "sha3", "sha3-only", "shun-sha1"
};
/* Return the name of the current hash policy.
*/
const char *hpolicy_name(void){
return azPolicy[g.eHashPolicy];
}
/*
** COMMAND: hash-policy*
**
** Usage: fossil hash-policy ?NEW-POLICY?
**
** Query or set the hash policy for the current repository. Available hash
** policies are as follows:
**
** sha1 New artifact names are created using SHA1
**
** auto New artifact names are created using SHA1, but
** automatically change the policy to "sha3" when
** any SHA3 artifact enters the repository.
**
** sha3 New artifact names are created using SHA3, but
** older artifacts with SHA1 names may be reused.
**
** sha3-only Use only SHA3 artifact names. Do not reuse legacy
** SHA1 names.
**
** shun-sha1 Shun any SHA1 artifacts received by sync operations
** other than clones. Older legacy SHA1 artifacts are
** are allowed during a clone.
**
** The default hash policy for existing repositories is "auto", which will
** immediately promote to "sha3" if the repository contains one or more
** artifacts with SHA3 names. The default hash policy for new repositories
** is "shun-sha1".
*/
void hash_policy_command(void){
int i;
db_find_and_open_repository(0, 0);
if( g.argc!=2 && g.argc!=3 ) usage("?NEW-POLICY?");
if( g.argc==2 ){
fossil_print("%s\n", azPolicy[g.eHashPolicy]);
return;
}
for(i=HPOLICY_SHA1; i<=HPOLICY_SHUN_SHA1; i++){
if( fossil_strcmp(g.argv[2],azPolicy[i])==0 ){
if( i==HPOLICY_AUTO
&& db_exists("SELECT 1 FROM blob WHERE length(uuid)>40")
){
i = HPOLICY_SHA3;
}
g.eHashPolicy = i;
db_set_int("hash-policy", i, 0);
fossil_print("%s\n", azPolicy[i]);
return;
}
}
fossil_fatal("unknown hash policy \"%s\" - should be one of: sha1 auto"
" sha3 sha3-only shun-sha1", g.argv[2]);
}
|
Changes to src/import.c.
| ︙ | ︙ | |||
147 148 149 150 151 152 153 | ** ** If saveUuid is true, then pContent is a commit record. Record its ** UUID in gg.zPrevCheckin. */ static int fast_insert_content( Blob *pContent, /* Content to insert */ const char *zMark, /* Label using this mark, if not NULL */ | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
**
** If saveUuid is true, then pContent is a commit record. Record its
** UUID in gg.zPrevCheckin.
*/
static int fast_insert_content(
Blob *pContent, /* Content to insert */
const char *zMark, /* Label using this mark, if not NULL */
int saveUuid, /* Save artifact hash in gg.zPrevCheckin */
int doParse /* Invoke manifest_crosslink() */
){
Blob hash;
Blob cmpr;
int rid;
hname_hash(pContent, 0, &hash);
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &hash);
if( rid==0 ){
static Stmt ins;
db_static_prepare(&ins,
"INSERT INTO blob(uuid, size, content) VALUES(:uuid, :size, :content)"
);
db_bind_text(&ins, ":uuid", blob_str(&hash));
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
66 67 68 69 70 71 72 |
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid ){
zDate = db_text(0,
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
rid
);
/* 01234567890123 */
| | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid ){
zDate = db_text(0,
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
rid
);
/* 01234567890123 */
fossil_print("%-13s %.40s %s\n", zUuidName, zUuid, zDate ? zDate : "");
free(zDate);
if( showComment ){
zComment = db_text(0,
"SELECT coalesce(ecomment,comment) || "
" ' (user: ' || coalesce(euser,user,'?') || ')' "
" FROM event WHERE objid=%d",
rid
|
| ︙ | ︙ | |||
89 90 91 92 93 94 95 |
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
const char *zType = db_column_int(&q, 2) ? "parent:" : "merged-from:";
zDate = db_text("",
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
db_column_int(&q, 1)
);
| | | | 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 |
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
const char *zType = db_column_int(&q, 2) ? "parent:" : "merged-from:";
zDate = db_text("",
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
db_column_int(&q, 1)
);
fossil_print("%-13s %.40s %s\n", zType, zUuid, zDate);
free(zDate);
}
db_finalize(&q);
db_prepare(&q, "SELECT uuid, cid, isprim FROM plink JOIN blob ON cid=rid "
" WHERE pid=%d"
" ORDER BY isprim DESC, mtime DESC /*sort*/", rid);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
const char *zType = db_column_int(&q, 2) ? "child:" : "merged-into:";
zDate = db_text("",
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
db_column_int(&q, 1)
);
fossil_print("%-13s %.40s %s\n", zType, zUuid, zDate);
free(zDate);
}
db_finalize(&q);
}
zTags = info_tags_of_checkin(rid, 0);
if( zTags && zTags[0] ){
fossil_print("tags: %s\n", zTags);
|
| ︙ | ︙ | |||
570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
" WHERE blob.rid=%d"
" AND event.objid=%d",
rid, rid
);
sideBySide = !is_false(PD("sbs","1"));
if( db_step(&q1)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q1, 0);
char *zEUser, *zEComment;
const char *zUser;
const char *zComment;
const char *zDate;
const char *zOrigDate;
style_header("Check-in [%S]", zUuid);
| > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 |
" WHERE blob.rid=%d"
" AND event.objid=%d",
rid, rid
);
sideBySide = !is_false(PD("sbs","1"));
if( db_step(&q1)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q1, 0);
int nUuid = db_column_bytes(&q1, 0);
char *zEUser, *zEComment;
const char *zUser;
const char *zComment;
const char *zDate;
const char *zOrigDate;
style_header("Check-in [%S]", zUuid);
|
| ︙ | ︙ | |||
591 592 593 594 595 596 597 |
TAG_COMMENT, rid);
zUser = db_column_text(&q1, 2);
zComment = db_column_text(&q1, 3);
zDate = db_column_text(&q1,1);
zOrigDate = db_column_text(&q1, 4);
@ <div class="section">Overview</div>
@ <table class="label-value">
| | | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
TAG_COMMENT, rid);
zUser = db_column_text(&q1, 2);
zComment = db_column_text(&q1, 3);
zDate = db_column_text(&q1,1);
zOrigDate = db_column_text(&q1, 4);
@ <div class="section">Overview</div>
@ <table class="label-value">
@ <tr><th>%s(hname_alg(nUuid)):</th><td>%s(zUuid)
if( g.perm.Setup ){
@ (Record ID: %d(rid))
}
@ </td></tr>
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
if( zOrigDate && fossil_strcmp(zDate, zOrigDate)!=0 ){
|
| ︙ | ︙ | |||
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 |
" FROM attachment"
" WHERE src=(SELECT uuid FROM blob WHERE rid=%d)"
" ORDER BY mtime DESC /*sort*/",
rid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zTarget = db_column_text(&q, 0);
const char *zFilename = db_column_text(&q, 1);
const char *zDate = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
objType |= OBJTYPE_ATTACHMENT;
| > | | 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 |
" FROM attachment"
" WHERE src=(SELECT uuid FROM blob WHERE rid=%d)"
" ORDER BY mtime DESC /*sort*/",
rid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zTarget = db_column_text(&q, 0);
int nTarget = db_column_bytes(&q, 0);
const char *zFilename = db_column_text(&q, 1);
const char *zDate = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
objType |= OBJTYPE_ATTACHMENT;
if( nTarget==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
if ( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
zTarget)
){
if( g.perm.Hyperlink && g.anon.RdTkt ){
@ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
}else{
@ ticket [%S(zTarget)]
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
48 49 50 51 52 53 54 | #endif #ifdef FOSSIL_ENABLE_JSON # include "cson_amalgamation.h" /* JSON API. */ # include "json_detail.h" #endif /* | | > > > > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #endif #ifdef FOSSIL_ENABLE_JSON # include "cson_amalgamation.h" /* JSON API. */ # include "json_detail.h" #endif /* ** Size of a UUID in characters. A UUID is a randomly generated ** lower-case hexadecimal number used to identify tickets. ** ** In Fossil 1.x, UUID also referred to a SHA1 artifact hash. But that ** usage is now obsolete. The term UUID should now mean only a very large ** random number used as a unique identifier for tickets or other objects. */ #define UUID_SIZE 40 /* ** Maximum number of auxiliary parameters on reports */ #define MX_AUX 5 |
| ︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 142 143 144 145 146 | char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fNoDirSymlinks; /* True if --no-dir-symlinks flag is present */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fJail; /* True if running with a chroot jail */ int fHttpTrace; /* Trace outbound HTTP requests */ | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int eHashPolicy; /* Current hash policy. One of HPOLICY_* */ int fNoDirSymlinks; /* True if --no-dir-symlinks flag is present */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fJail; /* True if running with a chroot jail */ int fHttpTrace; /* Trace outbound HTTP requests */ |
| ︙ | ︙ | |||
928 929 930 931 932 933 934 935 936 937 938 939 940 941 |
__DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
blob_appendf(pOut, "Schema version %s\n", AUX_SCHEMA_MAX);
#if defined(FOSSIL_ENABLE_MINIZ)
blob_appendf(pOut, "miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
blob_appendf(pOut, "zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if defined(FOSSIL_ENABLE_SSL)
blob_appendf(pOut, "SSL (%s)\n", SSLeay_version(SSLEAY_VERSION));
#endif
#if defined(FOSSIL_HAVE_FUSEFS)
blob_appendf(pOut, "libfuse %s, loaded %s\n", fusefs_inc_version(),
fusefs_lib_version());
#endif
| > > > | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 |
__DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
blob_appendf(pOut, "Schema version %s\n", AUX_SCHEMA_MAX);
#if defined(FOSSIL_ENABLE_MINIZ)
blob_appendf(pOut, "miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
blob_appendf(pOut, "zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if FOSSIL_HARDENED_SHA1
blob_appendf(pOut, "hardened-SHA1 by Marc Stevens and Dan Shumow\n");
#endif
#if defined(FOSSIL_ENABLE_SSL)
blob_appendf(pOut, "SSL (%s)\n", SSLeay_version(SSLEAY_VERSION));
#endif
#if defined(FOSSIL_HAVE_FUSEFS)
blob_appendf(pOut, "libfuse %s, loaded %s\n", fusefs_inc_version(),
fusefs_lib_version());
#endif
|
| ︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 | ** Open the repository to be served if it is known. If g.argv[arg] is ** a directory full of repositories, then set g.zRepositoryName to ** the name of that directory and the specific repository will be ** opened later by process_one_web_page() based on the content of ** the PATH_INFO variable. ** ** If the fCreate flag is set, then create the repository if it | | > > | 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 |
** Open the repository to be served if it is known. If g.argv[arg] is
** a directory full of repositories, then set g.zRepositoryName to
** the name of that directory and the specific repository will be
** opened later by process_one_web_page() based on the content of
** the PATH_INFO variable.
**
** If the fCreate flag is set, then create the repository if it
** does not already exist. Always use "auto" hash-policy in this case.
*/
static void find_server_repository(int arg, int fCreate){
if( g.argc<=arg ){
db_must_be_within_tree();
}else{
const char *zRepo = g.argv[arg];
int isDir = file_isdir(zRepo);
if( isDir==1 ){
g.zRepositoryName = mprintf("%s", zRepo);
file_simplify_name(g.zRepositoryName, -1, 0);
}else{
if( isDir==0 && fCreate ){
const char *zPassword;
db_create_repository(zRepo);
db_open_repository(zRepo);
db_begin_transaction();
g.eHashPolicy = HPOLICY_AUTO;
db_set_int("hash-policy", HPOLICY_AUTO, 0);
db_initial_setup(0, "now", g.zLogin);
db_end_transaction(0);
fossil_print("project-id: %s\n", db_get("project-code", 0));
fossil_print("server-id: %s\n", db_get("server-code", 0));
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
fossil_print("admin-user: %s (initial password is \"%s\")\n",
g.zLogin, zPassword);
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ | > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/hname.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ |
| ︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ | > > | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/sha1hard.c \ $(SRCDIR)/sha3.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ |
| ︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 234 235 236 237 238 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/hname_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ |
| ︙ | ︙ | |||
275 276 277 278 279 280 281 282 283 284 285 286 287 288 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ | > > | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/sha1hard_.c \ $(OBJDIR)/sha3_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ |
| ︙ | ︙ | |||
349 350 351 352 353 354 355 356 357 358 359 360 361 362 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ | > | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/hname.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ |
| ︙ | ︙ | |||
399 400 401 402 403 404 405 406 407 408 409 410 411 412 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ | > > | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/sha1hard.o \ $(OBJDIR)/sha3.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ |
| ︙ | ︙ | |||
634 635 636 637 638 639 640 641 642 643 644 645 646 647 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ | > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/hname_.c:$(OBJDIR)/hname.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ |
| ︙ | ︙ | |||
684 685 686 687 688 689 690 691 692 693 694 695 696 697 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | > > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/sha1hard_.c:$(OBJDIR)/sha1hard.h \ $(OBJDIR)/sha3_.c:$(OBJDIR)/sha3.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| ︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c | > > > > > > > > | 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/hname_.c: $(SRCDIR)/hname.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/hname.c >$@ $(OBJDIR)/hname.o: $(OBJDIR)/hname_.c $(OBJDIR)/hname.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/hname.o -c $(OBJDIR)/hname_.c $(OBJDIR)/hname.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c |
| ︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c | > > > > > > > > > > > > > > > > | 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/sha1hard_.c: $(SRCDIR)/sha1hard.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/sha1hard.c >$@ $(OBJDIR)/sha1hard.o: $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1hard.o -c $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h: $(OBJDIR)/headers $(OBJDIR)/sha3_.c: $(SRCDIR)/sha3.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/sha3.c >$@ $(OBJDIR)/sha3.o: $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha3.o -c $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c |
| ︙ | ︙ |
Changes to src/makeheaders.c.
| ︙ | ︙ | |||
1015 1016 1017 1018 1019 1020 1021 |
while( 1 ){
nErr += GetToken(pIn,pToken);
/* printf("%04d: Type=%d nIf=%d [%.*s]\n",
pToken->nLine,pToken->eType,nIf,pToken->nText,
pToken->eType!=TT_Space ? pToken->zText : "<space>"); */
pToken->pComment = blockComment;
switch( pToken->eType ){
| | > > > | 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
while( 1 ){
nErr += GetToken(pIn,pToken);
/* printf("%04d: Type=%d nIf=%d [%.*s]\n",
pToken->nLine,pToken->eType,nIf,pToken->nText,
pToken->eType!=TT_Space ? pToken->zText : "<space>"); */
pToken->pComment = blockComment;
switch( pToken->eType ){
case TT_Comment: /*0123456789 12345678 */
if( strncmp(pToken->zText, "/*MAKEHEADERS-STOP", 18)==0 ) return nErr;
break;
case TT_Space:
break;
case TT_BlockComment:
if( doc_flag ){
blockComment = SafeMalloc( sizeof(Token) );
*blockComment = *pToken;
|
| ︙ | ︙ | |||
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 |
if( *zArg==0 || *zArg=='\n' ){ return 0; }
nArg = pToken->nText + (int)(pToken->zText - zArg);
if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
}else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Local);
}else{
PushIfMacro(0,zArg,nArg,pToken->nLine,0);
}
}else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){
/*
** Push an #ifdef.
| > > | 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 |
if( *zArg==0 || *zArg=='\n' ){ return 0; }
nArg = pToken->nText + (int)(pToken->zText - zArg);
if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
}else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Local);
}else if( nArg==15 && strncmp(zArg,"MAKEHEADERS_STOPLOCAL_INTERFACE",15)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Local);
}else{
PushIfMacro(0,zArg,nArg,pToken->nLine,0);
}
}else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){
/*
** Push an #ifdef.
|
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | finfo foci fshell fusefs glob graph gzip http http_socket http_transport import info json json_artifact | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | finfo foci fshell fusefs glob graph gzip hname http http_socket http_transport import info json json_artifact |
| ︙ | ︙ | |||
105 106 107 108 109 110 111 112 113 114 115 116 117 118 | regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat statrep | > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | regexp report rss schema search setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
#define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */
/*
** A single F-card within a manifest
*/
struct ManifestFile {
char *zName; /* Name of a file */
| | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#define MC_NO_ERRORS 2 /* do not issue errors for a bad parse */
/*
** A single F-card within a manifest
*/
struct ManifestFile {
char *zName; /* Name of a file */
char *zUuid; /* Artifact hash for the file */
char *zPerm; /* File permissions */
char *zPrior; /* Prior name if the name was changed */
};
/*
** A parsed manifest or cluster.
|
| ︙ | ︙ | |||
75 76 77 78 79 80 81 | double rDate; /* Date and time from D card. 0.0 if no D card. */ char *zUser; /* Name of the user from the U card. */ char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */ char *zWiki; /* Text of the wiki page. W card. */ char *zWikiTitle; /* Name of the wiki page. L card. */ char *zMimetype; /* Mime type of wiki or comment text. N card. */ double rEventDate; /* Date of an event. E card. */ | | | | | | | | | 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 |
double rDate; /* Date and time from D card. 0.0 if no D card. */
char *zUser; /* Name of the user from the U card. */
char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
char *zWiki; /* Text of the wiki page. W card. */
char *zWikiTitle; /* Name of the wiki page. L card. */
char *zMimetype; /* Mime type of wiki or comment text. N card. */
double rEventDate; /* Date of an event. E card. */
char *zEventId; /* Artifact hash for an event. E card. */
char *zTicketUuid; /* UUID for a ticket. K card. */
char *zAttachName; /* Filename of an attachment. A card. */
char *zAttachSrc; /* Artifact hash for document being attached. A card. */
char *zAttachTarget; /* Ticket or wiki that attachment applies to. A card */
int nFile; /* Number of F cards */
int nFileAlloc; /* Slots allocated in aFile[] */
int iFile; /* Index of current file in iterator */
ManifestFile *aFile; /* One entry for each F-card */
int nParent; /* Number of parents. */
int nParentAlloc; /* Slots allocated in azParent[] */
char **azParent; /* Hashes of parents. One for each P card argument */
int nCherrypick; /* Number of entries in aCherrypick[] */
struct {
char *zCPTarget; /* Hash for cherry-picked version w/ +|- prefix */
char *zCPBase; /* Hash for cherry-pick baseline. NULL for singletons */
} *aCherrypick;
int nCChild; /* Number of cluster children */
int nCChildAlloc; /* Number of closts allocated in azCChild[] */
char **azCChild; /* Hashes of referenced objects in a cluster. M cards */
int nTag; /* Number of T Cards */
int nTagAlloc; /* Slots allocated in aTag[] */
struct TagType {
char *zName; /* Name of the tag */
char *zUuid; /* Hash of artifact that the tag is applied to */
char *zValue; /* Value if the tag is really a property */
} *aTag; /* One for each T card */
int nField; /* Number of J cards */
int nFieldAlloc; /* Slots allocated in aField[] */
struct {
char *zName; /* Key or field name */
char *zValue; /* Value of the field */
|
| ︙ | ︙ | |||
325 326 327 328 329 330 331 | /* ** Parse a blob into a Manifest object. The Manifest object ** takes over the input blob and will free it when the ** Manifest object is freed. Zeros are inserted into the blob ** as string terminators so that blob should not be used again. ** ** Return a pointer to an allocated Manifest object if the content | | | | > | | | | | < | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
/*
** Parse a blob into a Manifest object. The Manifest object
** takes over the input blob and will free it when the
** Manifest object is freed. Zeros are inserted into the blob
** as string terminators so that blob should not be used again.
**
** Return a pointer to an allocated Manifest object if the content
** really is a structural artifact of some kind. The returned Manifest
** object needs to be freed by a subsequent call to manifest_destroy().
** Return NULL if there are syntax errors or if the input blob does
** not describe a valid structural artifact.
**
** This routine is strict about the format of a structural artifacts.
** The format must match exactly or else it is rejected. This
** rule minimizes the risk that a content artifact will be mistaken
** for a structural artifact simply because they look the same.
**
** The pContent is reset. If a pointer is returned, then pContent will
** be reset when the Manifest object is cleared. If NULL is
** returned then the Manifest object is cleared automatically
** and pContent is reset before the return.
**
** The entire input blob can be PGP clear-signed. The signature is ignored.
** The artifact consists of zero or more cards, one card per line.
** (Except: the content of the W card can extend of multiple lines.)
** Each card is divided into tokens by a single space character.
** The first token is a single upper-case letter which is the card type.
** The card type determines the other parameters to the card.
** Cards must occur in lexicographical order.
*/
Manifest *manifest_parse(Blob *pContent, int rid, Blob *pErr){
Manifest *p;
int seenZ = 0;
int i, lineNo=0;
ManifestText x;
char cPrevType = 0;
char cType;
char *z;
int n;
char *zUuid;
int sz = 0;
int isRepeat, hasSelfRefTag = 0;
static Bag seen;
const char *zErr = 0;
if( rid==0 ){
isRepeat = 1;
}else if( bag_find(&seen, rid) ){
isRepeat = 1;
}else{
isRepeat = 0;
bag_insert(&seen, rid);
}
/* Every structural artifact ends with a '\n' character. Exit early
** if that is not the case for this artifact.
*/
if( !isRepeat ) g.parseCnt[0]++;
z = blob_materialize(pContent);
n = blob_size(pContent);
if( n<=0 || z[n-1]!='\n' ){
blob_reset(pContent);
|
| ︙ | ︙ | |||
404 405 406 407 408 409 410 |
*/
if( verify_z_card(z, n)==2 ){
blob_reset(pContent);
blob_appendf(pErr, "incorrect Z-card cksum");
return 0;
}
| < < < < < | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
*/
if( verify_z_card(z, n)==2 ){
blob_reset(pContent);
blob_appendf(pErr, "incorrect Z-card cksum");
return 0;
}
/* Allocate a Manifest object to hold the parsed control artifact.
*/
p = fossil_malloc( sizeof(*p) );
memset(p, 0, sizeof(*p));
memcpy(&p->content, pContent, sizeof(p->content));
p->rid = rid;
blob_zero(pContent);
|
| ︙ | ︙ | |||
447 448 449 450 451 452 453 |
if( zName==0 || zTarget==0 ) goto manifest_syntax_error;
if( p->zAttachName!=0 ) goto manifest_syntax_error;
defossilize(zName);
if( !file_is_simple_pathname(zName, 0) ){
SYNTAX("invalid filename on A-card");
}
defossilize(zTarget);
| | | | | | | | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
if( zName==0 || zTarget==0 ) goto manifest_syntax_error;
if( p->zAttachName!=0 ) goto manifest_syntax_error;
defossilize(zName);
if( !file_is_simple_pathname(zName, 0) ){
SYNTAX("invalid filename on A-card");
}
defossilize(zTarget);
if( !hname_validate(zTarget,nTarget)
&& !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
SYNTAX("invalid target on A-card");
}
if( zSrc && !hname_validate(zSrc,nSrc) ){
SYNTAX("invalid source on A-card");
}
p->zAttachName = (char*)file_tail(zName);
p->zAttachSrc = zSrc;
p->zAttachTarget = zTarget;
break;
}
/*
** B <uuid>
**
** A B-line gives the artifact hash 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 hash on B-card");
if( !hname_validate(p->zBaseline,sz) ){
SYNTAX("invalid hash on B-card");
}
break;
}
/*
** C <comment>
|
| ︙ | ︙ | |||
520 521 522 523 524 525 526 |
** is when the specific event is said to occur.
*/
case 'E': {
if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
p->zEventId = next_token(&x, &sz);
| | | | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 |
** is when the specific event is said to occur.
*/
case 'E': {
if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
p->zEventId = next_token(&x, &sz);
if( !hname_validate(p->zEventId, sz) ){
SYNTAX("malformed hash on E-card");
}
break;
}
/*
** F <filename> ?<uuid>? ?<permissions>? ?<old-name>?
**
|
| ︙ | ︙ | |||
543 544 545 546 547 548 549 |
if( zName==0 ) SYNTAX("missing filename on F-card");
defossilize(zName);
if( !file_is_simple_pathname(zName, 0) ){
SYNTAX("F-card filename is not a simple path");
}
zUuid = next_token(&x, &sz);
if( p->zBaseline==0 || zUuid!=0 ){
| | | > | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
if( zName==0 ) SYNTAX("missing filename on F-card");
defossilize(zName);
if( !file_is_simple_pathname(zName, 0) ){
SYNTAX("F-card filename is not a simple path");
}
zUuid = next_token(&x, &sz);
if( p->zBaseline==0 || zUuid!=0 ){
if( !hname_validate(zUuid,sz) ){
SYNTAX("F-card hash invalid");
}
}
zPerm = next_token(&x,0);
zPriorName = next_token(&x,0);
if( zPriorName ){
defossilize(zPriorName);
if( !file_is_simple_pathname(zPriorName, 0) ){
SYNTAX("F-card old filename is not a simple path");
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 |
if( !wiki_name_is_wellformed((const unsigned char *)p->zWikiTitle) ){
SYNTAX("L-card has malformed wiki name");
}
break;
}
/*
| | | | | | > | 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
if( !wiki_name_is_wellformed((const unsigned char *)p->zWikiTitle) ){
SYNTAX("L-card has malformed wiki name");
}
break;
}
/*
** M <hash>
**
** An M-line identifies another artifact by its hash. M-lines
** occur in clusters only.
*/
case 'M': {
zUuid = next_token(&x, &sz);
if( zUuid==0 ) SYNTAX("missing hash on M-card");
if( !hname_validate(zUuid,sz) ){
SYNTAX("Invalid hash on M-card");
}
if( p->nCChild>=p->nCChildAlloc ){
p->nCChildAlloc = p->nCChildAlloc*2 + 10;
p->azCChild = fossil_realloc(p->azCChild
, p->nCChildAlloc*sizeof(p->azCChild[0]) );
}
i = p->nCChild++;
p->azCChild[i] = zUuid;
|
| ︙ | ︙ | |||
681 682 683 684 685 686 687 |
** this artifact. The first parent is the primary parent. All
** others are parents by merge. Note that the initial empty
** check-in historically has an empty P-card, so empty P-cards
** must be accepted.
*/
case 'P': {
while( (zUuid = next_token(&x, &sz))!=0 ){
| | | > | < | | | < < | < | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
** this artifact. The first parent is the primary parent. All
** others are parents by merge. Note that the initial empty
** check-in historically has an empty P-card, so empty P-cards
** must be accepted.
*/
case 'P': {
while( (zUuid = next_token(&x, &sz))!=0 ){
if( !hname_validate(zUuid, sz) ){
SYNTAX("invalid hash on P-card");
}
if( p->nParent>=p->nParentAlloc ){
p->nParentAlloc = p->nParentAlloc*2 + 5;
p->azParent = fossil_realloc(p->azParent,
p->nParentAlloc*sizeof(char*));
}
i = p->nParent++;
p->azParent[i] = zUuid;
}
break;
}
/*
** Q (+|-)<uuid> ?<uuid>?
**
** Specify one or a range of check-ins that are cherrypicked into
** this check-in ("+") or backed out of this check-in ("-").
*/
case 'Q': {
if( (zUuid=next_token(&x, &sz))==0 ) SYNTAX("missing hash on Q-card");
if( zUuid[0]!='+' && zUuid[0]!='-' ){
SYNTAX("Q-card does not begin with '+' or '-'");
}
if( !hname_validate(&zUuid[1], sz-1) ){
SYNTAX("invalid hash on Q-card");
}
n = p->nCherrypick;
p->nCherrypick++;
p->aCherrypick = fossil_realloc(p->aCherrypick,
p->nCherrypick*sizeof(p->aCherrypick[0]));
p->aCherrypick[n].zCPTarget = zUuid;
p->aCherrypick[n].zCPBase = zUuid = next_token(&x, &sz);
if( zUuid && !hname_validate(zUuid,sz) ){
SYNTAX("invalid second hash on Q-card");
}
break;
}
/*
** R <md5sum>
**
|
| ︙ | ︙ | |||
758 759 760 761 762 763 764 |
** Tags are not allowed in clusters. Multiple T lines are allowed.
*/
case 'T': {
char *zName, *zValue;
zName = next_token(&x, 0);
if( zName==0 ) SYNTAX("missing name on T-card");
zUuid = next_token(&x, &sz);
| | | | | | | | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
** Tags are not allowed in clusters. Multiple T lines are allowed.
*/
case 'T': {
char *zName, *zValue;
zName = next_token(&x, 0);
if( zName==0 ) SYNTAX("missing name on T-card");
zUuid = next_token(&x, &sz);
if( zUuid==0 ) SYNTAX("missing artifact hash on T-card");
zValue = next_token(&x, 0);
if( zValue ) defossilize(zValue);
if( hname_validate(zUuid, sz) ){
/* A valid artifact hash */
if( p->zEventId ) SYNTAX("non-self-referential T-card in event");
}else if( sz==1 && zUuid[0]=='*' ){
zUuid = 0;
hasSelfRefTag = 1;
if( p->zEventId && zName[0]!='+' ){
SYNTAX("propagating T-card in event");
}
}else{
SYNTAX("malformed artifact hash on T-card");
}
defossilize(zName);
if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
SYNTAX("T-card name does not begin with '-', '+', or '*'");
}
if( validate16(&zName[1], strlen(&zName[1])) ){
/* Do not allow tags whose names look like a hash */
SYNTAX("T-card name looks like a hexadecimal hash");
}
if( p->nTag>=p->nTagAlloc ){
p->nTagAlloc = p->nTagAlloc*2 + 10;
p->aTag = fossil_realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) );
}
i = p->nTag++;
p->aTag[i].zName = zName;
|
| ︙ | ︙ | |||
949 950 951 952 953 954 955 |
if( p->rDate<=0.0 ) SYNTAX("missing date on control");
if( p->zMimetype ) SYNTAX("N-card in control");
if( !seenZ ) SYNTAX("missing Z-card on control");
p->type = CFTYPE_CONTROL;
}
md5sum_init();
if( !isRepeat ) g.parseCnt[p->type]++;
| < > > | | | > | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 |
if( p->rDate<=0.0 ) SYNTAX("missing date on control");
if( p->zMimetype ) SYNTAX("N-card in control");
if( !seenZ ) SYNTAX("missing Z-card on control");
p->type = CFTYPE_CONTROL;
}
md5sum_init();
if( !isRepeat ) g.parseCnt[p->type]++;
return p;
manifest_syntax_error:
{
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid ){
blob_appendf(pErr, "manifest [%s] ", zUuid);
fossil_free(zUuid);
}
}
if( zErr ){
blob_appendf(pErr, "line %d: %s", lineNo, zErr);
}else{
blob_appendf(pErr, "unknown error on line %d", lineNo);
}
md5sum_init();
|
| ︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 | ** An mlink entry is always created if isPrimary is true. But if ** isPrimary is false (meaning that pmid is a merge parent of mid) ** then the mlink entry is only created if there is already an mlink ** from primary parent for the same file. */ static void add_one_mlink( int pmid, /* The parent manifest */ | | | | 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 |
** An mlink entry is always created if isPrimary is true. But if
** isPrimary is false (meaning that pmid is a merge parent of mid)
** then the mlink entry is only created if there is already an mlink
** from primary parent for the same file.
*/
static void add_one_mlink(
int pmid, /* The parent manifest */
const char *zFromUuid, /* Artifact hash for content in parent */
int mid, /* The record ID of the manifest */
const char *zToUuid, /* artifact hash for content in child */
const char *zFilename, /* Filename */
const char *zPrior, /* Previous filename. NULL if unchanged */
int isPublic, /* True if mid is not a private manifest */
int isPrimary, /* pmid is the primary parent of mid */
int mperm /* 1: exec, 2: symlink */
){
int fnid, pfnid, pid, fid;
|
| ︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 |
add_mlink(pmid, 0, mid, pChild, 0);
}
}
}
/*
** For a check-in with RID "rid" that has nParent parent check-ins given
| | | | | 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 |
add_mlink(pmid, 0, mid, pChild, 0);
}
}
}
/*
** For a check-in with RID "rid" that has nParent parent check-ins given
** by the hashes in azParent[], create all appropriate plink and mlink table
** entries.
**
** The primary parent is the first hash on the azParent[] list.
**
** Return the RID of the primary parent.
*/
static int manifest_add_checkin_linkages(
int rid, /* The RID of the check-in */
Manifest *p, /* Manifest for this check-in */
int nParent, /* Number of parents for this check-in */
char **azParent /* hashes for each parent */
){
int i;
int parentid = 0;
char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
Stmt q;
if( p->zBaseline ){
|
| ︙ | ︙ | |||
1609 1610 1611 1612 1613 1614 1615 |
}
}
return parentid;
}
/*
** There exists a "parent" tag against checkin rid that has value zValue.
| | | | | | | | | | | | > > | > > < | > | 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 |
}
}
return parentid;
}
/*
** There exists a "parent" tag against checkin rid that has value zValue.
** If value is well-formed (meaning that it is a list of hashes), then use
** zValue to reparent check-in rid.
*/
void manifest_reparent_checkin(int rid, const char *zValue){
int nParent = 0;
char *zCopy = 0;
char **azParent = 0;
Manifest *p = 0;
int i, j;
int n = (int)strlen(zValue);
int mxParent = (n+1)/(HNAME_MIN+1);
if( mxParent<1 ) return;
zCopy = fossil_strdup(zValue);
azParent = fossil_malloc( sizeof(azParent[0])*mxParent );
for(nParent=0, i=0; zCopy[i]; i++){
char *z = &zCopy[i];
azParent[nParent++] = z;
if( nParent>mxParent ) goto reparent_abort;
for(j=HNAME_MIN; z[j]>' '; j++){}
if( !hname_validate(z, j) ) goto reparent_abort;
if( z[j]==0 ) break;
z[j] = 0;
i += j;
}
if( !db_exists("SELECT 1 FROM plink WHERE cid=%d AND pid=%d",
rid, uuid_to_rid(azParent[0],0))
){
p = manifest_get(rid, CFTYPE_MANIFEST, 0);
}
if( p!=0 ){
db_multi_exec(
"DELETE FROM plink WHERE cid=%d;"
"DELETE FROM mlink WHERE mid=%d;",
rid, rid
);
manifest_add_checkin_linkages(rid,p,nParent,azParent);
}
manifest_destroy(p);
reparent_abort:
fossil_free(azParent);
fossil_free(zCopy);
}
/*
** Setup to do multiple manifest_crosslink() calls.
**
|
| ︙ | ︙ | |||
2278 2279 2280 2281 2282 2283 2284 |
const char *zValue;
const char *zTagUuid;
int branchMove = 0;
blob_zero(&comment);
if( p->zComment ){
blob_appendf(&comment, " %s.", p->zComment);
}
| | | 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 |
const char *zValue;
const char *zTagUuid;
int branchMove = 0;
blob_zero(&comment);
if( p->zComment ){
blob_appendf(&comment, " %s.", p->zComment);
}
/* Next loop expects tags to be sorted on hash, so sort it. */
qsort(p->aTag, p->nTag, sizeof(p->aTag[0]), tag_compare);
for(i=0; i<p->nTag; i++){
zTagUuid = p->aTag[i].zUuid;
if( !zTagUuid ) continue;
if( i==0 || fossil_strcmp(zTagUuid, p->aTag[i-1].zUuid)!=0 ){
blob_appendf(&comment,
" Edit [%!S|%S]:",
|
| ︙ | ︙ |
Changes to src/md5.c.
| ︙ | ︙ | |||
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 |
*/
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <sqlite3.h>
#include "md5.h"
/*
* If compiled on a machine that doesn't have a 32-bit integer,
* you just set "uint32" to the appropriate datatype for an
* unsigned 32-bit integer. For example:
*
* cc -Duint32='unsigned long' md5.c
*
*/
#ifndef uint32
# define uint32 unsigned int
#endif
struct Context {
int isInit;
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
typedef struct Context MD5Context;
| > > > > > > > > > > > | > > | 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 |
*/
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <sqlite3.h>
#include "md5.h"
#ifdef FOSSIL_ENABLE_SSL
# include <openssl/md5.h>
# define MD5Context MD5_CTX
# define MD5Init MD5_Init
# define MD5Update MD5_Update
# define MD5Final MD5_Final
#else
/*
* If compiled on a machine that doesn't have a 32-bit integer,
* you just set "uint32" to the appropriate datatype for an
* unsigned 32-bit integer. For example:
*
* cc -Duint32='unsigned long' md5.c
*
*/
#ifndef uint32
# define uint32 unsigned int
#endif
struct Context {
int isInit;
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
typedef struct Context MD5Context;
#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__) || defined(_WIN32)
# define byteReverse(A,B)
#else
/*
* Convert an array of integers to little-endian.
* Note: this code is a no-op on little-endian machines.
*/
static void byteReverse (unsigned char *buf, unsigned longs){
|
| ︙ | ︙ | |||
264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
memcpy(&ctx->in[14*sizeof(uint32)], ctx->bits, 2*sizeof(uint32));
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
/*
** Convert a digest into base-16. digest should be declared as
** "unsigned char digest[16]" in the calling function. The MD5
** digest is stored in the first 16 bytes. zBuf should
** be "char zBuf[33]".
*/
| > | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
memcpy(&ctx->in[14*sizeof(uint32)], ctx->bits, 2*sizeof(uint32));
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
#endif
/*
** Convert a digest into base-16. digest should be declared as
** "unsigned char digest[16]" in the calling function. The MD5
** digest is stored in the first 16 bytes. zBuf should
** be "char zBuf[33]".
*/
|
| ︙ | ︙ |
Changes to src/mkversion.c.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 |
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
FILE *m,*u,*v;
char *z;
| | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
FILE *m,*u,*v;
char *z;
int i, j, x, d;
int vn[3];
char b[1000];
char vx[1000];
memset(b,0,sizeof(b));
memset(vx,0,sizeof(vx));
u = fopen(argv[1],"r");
if( fgets(b, sizeof(b)-1,u)==0 ){
fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]);
|
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
exit(1);
}
fclose(v);
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
*z = 0;
printf("#define RELEASE_VERSION \"%s\"\n", b);
x=0;
| | > < | | | 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 |
exit(1);
}
fclose(v);
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
*z = 0;
printf("#define RELEASE_VERSION \"%s\"\n", b);
x=0;
i=j=0;
z=b;
vn[0] = vn[1] = vn[2] = 0;
while(1){
if( z[0]>='0' && z[0]<='9' ){
x = x*10 + z[0] - '0';
}else{
if( j<3 ) vn[j++] = x;
x = 0;
if( z[0]==0 ) break;
}
z++;
}
for(z=vx; z[0]=='0'; z++){}
printf("#define RELEASE_VERSION_NUMBER %d%02d%02d\n", vn[0], vn[1], vn[2]);
memset(vx,0,sizeof(vx));
strcpy(vx,b);
d = 0;
for(z=vx; z[0]; z++){
if( z[0]=='-' ){
z[0] = 0;
break;
|
| ︙ | ︙ |
Changes to src/name.c.
1 2 3 4 5 6 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) | | | < < < < | 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 | /* ** Copyright (c) 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to resolved user-supplied object names. */ #include "config.h" #include "name.h" #include <assert.h> /* ** Return TRUE if the string begins with something that looks roughly |
| ︙ | ︙ | |||
78 79 80 81 82 83 84 | db_finalize(&q); return rid; } /* ** Convert a symbolic name into a RID. Acceptable forms: ** | | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | db_finalize(&q); return rid; } /* ** Convert a symbolic name into a RID. Acceptable forms: ** ** * artifact hash ** * 4-character or larger prefix of a artifact ** * Symbolic Name ** * "tag:" + symbolic name ** * Date or date-time ** * "date:" + Date or date-time ** * symbolic-name ":" date-time ** * "tip" ** |
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | ** 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. ** If zType is "br" then find the first check-in of the named branch ** rather than the last. ** zType is "ci" in most use cases since we are usually searching for ** a check-in. ** | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
** 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.
** If zType is "br" then find the first check-in of the named branch
** rather than the last.
** zType is "ci" in most use cases since we are usually searching for
** a check-in.
**
** Note that the input zTag for types "t" and "e" is the artifact hash of
** the ticket-change or event-change artifact, not the randomly generated
** hexadecimal identifier assigned to tickets and events. Those identifiers
** live in a separate namespace.
*/
int symbolic_name_to_rid(const char *zTag, const char *zType){
int vid;
int rid = 0;
|
| ︙ | ︙ | |||
230 231 232 233 234 235 236 |
" AND event.mtime<=julianday(%Q)"
" AND event.type GLOB '%q'",
zTagBase, zDate, zType
);
return rid;
}
| | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
" AND event.mtime<=julianday(%Q)"
" AND event.type GLOB '%q'",
zTagBase, zDate, zType
);
return rid;
}
/* artifact hash or prefix */
if( nTag>=4 && nTag<=HNAME_MAX && validate16(zTag, nTag) ){
Stmt q;
char zUuid[HNAME_MAX+1];
memcpy(zUuid, zTag, nTag+1);
canonical16(zUuid, nTag);
rid = 0;
if( zType[0]=='*' ){
db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
}else{
db_prepare(&q,
|
| ︙ | ︙ | |||
352 353 354 355 356 357 358 |
** collisions of a given UUID based on its length on UUIDs no shorter
** than 4 characters in length.
*/
int name_collisions(const char *zName){
int c = 0; /* count of collisions for zName */
int nLen; /* length of zName */
nLen = strlen(zName);
| | | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
** collisions of a given UUID based on its length on UUIDs no shorter
** than 4 characters in length.
*/
int name_collisions(const char *zName){
int c = 0; /* count of collisions for zName */
int nLen; /* length of zName */
nLen = strlen(zName);
if( nLen>=4 && nLen<=HNAME_MAX && validate16(zName, nLen) ){
c = db_int(0,
"SELECT"
" (SELECT count(*) FROM ticket"
" WHERE tkt_uuid GLOB '%q*') +"
" (SELECT count(*) FROM tag"
" WHERE tagname GLOB 'event-%q*') +"
" (SELECT count(*) FROM blob"
|
| ︙ | ︙ | |||
394 395 396 397 398 399 400 | } } /* ** Convert a name to a rid. If the name can be any of the various forms ** accepted: ** | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | } } /* ** Convert a name to a rid. If the name can be any of the various forms ** accepted: ** ** * artifact hash or prefix thereof ** * symbolic name ** * date ** * label:date ** * prev, previous ** * next ** * tip ** |
| ︙ | ︙ | |||
423 424 425 426 427 428 429 |
}
int name_to_rid(const char *zName){
return name_to_typed_rid(zName, "*");
}
/*
** WEBPAGE: ambiguous
| | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
}
int name_to_rid(const char *zName){
return name_to_typed_rid(zName, "*");
}
/*
** WEBPAGE: ambiguous
** URL: /ambiguous?name=NAME&src=WEBPAGE
**
** The NAME 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;
|
| ︙ | ︙ | |||
666 667 668 669 670 671 672 | } /* ** COMMAND: whatis* ** ** Usage: %fossil whatis NAME ** | | | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | } /* ** COMMAND: whatis* ** ** Usage: %fossil whatis NAME ** ** Resolve the symbol NAME into its canonical artifact hash ** artifact name and provide a description of what role that artifact ** plays. ** ** Options: ** ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't', ** 'w', 'g', or 'e'). |
| ︙ | ︙ | |||
742 743 744 745 746 747 748 | /* ** COMMAND: test-ambiguous ** ** Usage: %fossil test-ambiguous [--minsize N] ** | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 |
/*
** COMMAND: test-ambiguous
**
** Usage: %fossil test-ambiguous [--minsize N]
**
** Show a list of ambiguous artifact hash abbreviations of N characters or
** more where N defaults to 4. Change N to a different value using
** the "--minsize N" command-line option.
*/
void test_ambiguous_cmd(void){
Stmt q, ins;
int i;
int minSize = 4;
|
| ︙ | ︙ | |||
792 793 794 795 796 797 798 | /* ** Schema for the description table */ static const char zDescTab[] = @ CREATE TEMP TABLE IF NOT EXISTS description( @ rid INTEGER PRIMARY KEY, -- RID of the object | | | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 | /* ** Schema for the description table */ static const char zDescTab[] = @ CREATE TEMP TABLE IF NOT EXISTS description( @ rid INTEGER PRIMARY KEY, -- RID of the object @ uuid TEXT, -- hash of the object @ ctime DATETIME, -- Time of creation @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts @ type TEXT, -- file, checkin, wiki, ticket, etc. @ summary TEXT, -- Summary comment for the object @ detail TEXT -- File name, check-in comment, etc @ ); ; |
| ︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 |
" datetime(description.ctime)"
" FROM description, blob LEFT JOIN delta ON delta.rid=blob.rid"
" WHERE description.rid=blob.rid"
" ORDER BY length(content) DESC"
);
@ <table cellpadding="2" cellspacing="0" border="1" id="bigblobtab">
@ <thead><tr><th align="right">Size<th align="right">RID
| | | 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
" datetime(description.ctime)"
" FROM description, blob LEFT JOIN delta ON delta.rid=blob.rid"
" WHERE description.rid=blob.rid"
" ORDER BY length(content) DESC"
);
@ <table cellpadding="2" cellspacing="0" border="1" id="bigblobtab">
@ <thead><tr><th align="right">Size<th align="right">RID
@ <th align="right">Delta From<th>Hash<th>Description<th>Date</tr></thead>
@ <tbody>
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q,0);
const char *zUuid = db_column_text(&q, 1);
const char *zDesc = db_column_text(&q, 2);
int sz = db_column_int(&q,3);
const char *zSrcId = db_column_text(&q,4);
|
| ︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 |
describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
}
/* Maximum number of collision examples to remember */
#define MAX_COLLIDE 25
/*
| | | | | | | | | 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 |
describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
}
/* Maximum number of collision examples to remember */
#define MAX_COLLIDE 25
/*
** Generate a report on the number of collisions in artifact hashes
** generated by the SQL given in the argument.
*/
static void collision_report(const char *zSql){
int i, j, kk;
int nHash = 0;
Stmt q;
char zPrev[HNAME_MAX+1];
struct {
int cnt;
char *azHit[MAX_COLLIDE];
char z[HNAME_MAX+1];
} aCollide[HNAME_MAX+1];
memset(aCollide, 0, sizeof(aCollide));
memset(zPrev, 0, sizeof(zPrev));
db_prepare(&q,"%s",zSql/*safe-for-%s*/);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q,0);
int n = db_column_bytes(&q,0);
int i;
nHash++;
for(i=0; zPrev[i] && zPrev[i]==zUuid[i]; i++){}
if( i>0 && i<=HNAME_MAX ){
if( i>=4 && aCollide[i].cnt<MAX_COLLIDE ){
aCollide[i].azHit[aCollide[i].cnt] = mprintf("%.*s", i, zPrev);
}
aCollide[i].cnt++;
if( aCollide[i].z[0]==0 ) memcpy(aCollide[i].z, zPrev, n+1);
}
memcpy(zPrev, zUuid, n+1);
}
db_finalize(&q);
@ <table border=1><thead>
@ <tr><th>Length<th>Instances<th>First Instance</tr>
@ </thead><tbody>
for(i=1; i<=HNAME_MAX; i++){
if( aCollide[i].cnt==0 ) continue;
@ <tr><td>%d(i)<td>%d(aCollide[i].cnt)<td>%h(aCollide[i].z)</tr>
}
@ </tbody></table>
@ <p>Total number of hashes: %d(nHash)</p>
kk = 0;
for(i=HNAME_MAX; i>=4; i--){
if( aCollide[i].cnt==0 ) continue;
if( aCollide[i].cnt>200 ) break;
kk += aCollide[i].cnt;
if( aCollide[i].cnt<25 ){
@ <p>Collisions of length %d(i):
}else{
@ <p>First 25 collisions of length %d(i):
|
| ︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 |
** WEBPAGE: hash-collisions
**
** Show the number of hash collisions for hash prefixes of various lengths.
*/
void hash_collisions_webpage(void){
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
| | | 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 |
** WEBPAGE: hash-collisions
**
** Show the number of hash collisions for hash prefixes of various lengths.
*/
void hash_collisions_webpage(void){
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("Hash Prefix Collisions");
style_submenu_element("Activity Reports", "reports");
style_submenu_element("Stats", "stat");
@ <h1>Hash Prefix Collisions on Check-ins</h1>
collision_report("SELECT (SELECT uuid FROM blob WHERE rid=objid)"
" FROM event WHERE event.type='ci'"
" ORDER BY 1");
@ <h1>Hash Prefix Collisions on All Artifacts</h1>
collision_report("SELECT uuid FROM blob ORDER BY 1");
style_footer();
}
|
Changes to src/printf.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | #include "printf.h" #if defined(_WIN32) # include <io.h> # include <fcntl.h> #endif #include <time.h> | | | | 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 |
#include "printf.h"
#if defined(_WIN32)
# include <io.h>
# include <fcntl.h>
#endif
#include <time.h>
/* Two custom conversions are used to show a prefix of artifact hashes:
**
** %!S Prefix of a length appropriate for URLs
** %S Prefix of a length appropriate for human display
**
** The following macros help determine those lengths. FOSSIL_HASH_DIGITS
** is the default number of digits to display to humans. This value can
** be overridden using the hash-digits setting. FOSSIL_HASH_DIGITS_URL
** is the minimum number of digits to be used in URLs. The number used
** will always be at least 6 more than the number used for human output,
** or 40 if the number of digits in human output is 34 or more.
*/
#ifndef FOSSIL_HASH_DIGITS
# define FOSSIL_HASH_DIGITS 10 /* For %S (human display) */
#endif
#ifndef FOSSIL_HASH_DIGITS_URL
# define FOSSIL_HASH_DIGITS_URL 16 /* For %!S (embedded in URLs) */
#endif
/*
** Return the number of artifact hash digits to display. The number is for
** human output if the bForUrl is false and is destined for a URL if
** bForUrl is false.
*/
static int hashDigits(int bForUrl){
static int nDigitHuman = 0;
static int nDigitUrl = 0;
if( nDigitHuman==0 ){
|
| ︙ | ︙ |
Changes to src/purge.c.
| ︙ | ︙ | |||
41 42 43 44 45 46 47 | @ ctime DATETIME, -- When purge occurred. Seconds since 1970. @ pnotes TEXT -- Human-readable notes about the purge event @ ); @ CREATE TABLE IF NOT EXISTS "%w".purgeitem( @ piid INTEGER PRIMARY KEY, -- ID for the purge item @ peid INTEGER REFERENCES purgeevent ON DELETE CASCADE, -- Purge event @ orid INTEGER, -- Original RID before purged | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | @ ctime DATETIME, -- When purge occurred. Seconds since 1970. @ pnotes TEXT -- Human-readable notes about the purge event @ ); @ CREATE TABLE IF NOT EXISTS "%w".purgeitem( @ piid INTEGER PRIMARY KEY, -- ID for the purge item @ peid INTEGER REFERENCES purgeevent ON DELETE CASCADE, -- Purge event @ orid INTEGER, -- Original RID before purged @ uuid TEXT NOT NULL, -- hash of the purged artifact @ srcid INTEGER, -- Basis purgeitem for delta compression @ isPrivate BOOLEAN, -- True if artifact was originally private @ sz INT NOT NULL, -- Uncompressed size of the purged artifact @ desc TEXT, -- Brief description of this artifact @ data BLOB -- Compressed artifact content @ ); ; |
| ︙ | ︙ | |||
345 346 347 348 349 350 351 |
*/
static int purge_extract_item(
int piid, /* ID of the item to extract */
Blob *pOut /* Write the content into this blob */
){
Stmt q;
int srcid;
| | | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
*/
static int purge_extract_item(
int piid, /* ID of the item to extract */
Blob *pOut /* Write the content into this blob */
){
Stmt q;
int srcid;
Blob h1, x;
static Bag busy;
db_prepare(&q, "SELECT uuid, srcid, data FROM purgeitem"
" WHERE piid=%d", piid);
if( db_step(&q)!=SQLITE_ROW ){
db_finalize(&q);
fossil_fatal("missing purge-item %d", piid);
|
| ︙ | ︙ | |||
374 375 376 377 378 379 380 |
blob_reset(pOut);
*pOut = out;
blob_reset(&baseline);
}
bag_remove(&busy, piid);
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
| | < | < < | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
blob_reset(pOut);
*pOut = out;
blob_reset(&baseline);
}
bag_remove(&busy, piid);
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
if( hname_verify_hash(pOut, blob_buffer(&h1), blob_size(&h1))==0 ){
fossil_fatal("incorrect artifact hash on %b", &h1);
}
blob_reset(&h1);
db_finalize(&q);
return 0;
}
/*
** There is a TEMP table ix(piid,srcid) containing a set of purgeitems
** that need to be transferred to the BLOB table. This routine does
|
| ︙ | ︙ | |||
409 410 411 412 413 414 415 |
"SELECT uuid, data, isPrivate, ix.piid"
" FROM ix, purgeitem"
" WHERE ix.srcid=%d"
" AND ix.piid=purgeitem.piid;",
iSrc
);
while( db_step(&q)==SQLITE_ROW ){
| | | < | < < | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
"SELECT uuid, data, isPrivate, ix.piid"
" FROM ix, purgeitem"
" WHERE ix.srcid=%d"
" AND ix.piid=purgeitem.piid;",
iSrc
);
while( db_step(&q)==SQLITE_ROW ){
Blob h1, c1, c2;
int isPriv, rid;
blob_zero(&h1);
db_column_blob(&q, 0, &h1);
blob_zero(&c1);
db_column_blob(&q, 1, &c1);
blob_uncompress(&c1, &c1);
blob_zero(&c2);
if( pBasis ){
blob_delta_apply(pBasis, &c1, &c2);
blob_reset(&c1);
}else{
c2 = c1;
}
if( hname_verify_hash(&c2, blob_buffer(&h1), blob_size(&h1))==0 ){
fossil_fatal("incorrect hash on %b", &h1);
}
isPriv = db_column_int(&q, 2);
rid = content_put_ex(&c2, blob_str(&h1), 0, 0, isPriv);
if( rid==0 ){
fossil_fatal("%s", g.zErrMsg);
}else{
if( !isPriv ) content_make_public(rid);
content_get(rid, &c1);
|
| ︙ | ︙ |
Changes to src/rebuild.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | */ #include "config.h" #include "rebuild.h" #include <assert.h> #include <errno.h> /* | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > > > > | > > > > > > > > > > > | > > > > | | | > | | 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 |
*/
#include "config.h"
#include "rebuild.h"
#include <assert.h>
#include <errno.h>
/*
** Update the schema as necessary
*/
static void rebuild_update_schema(void){
/* Verify that the PLINK table has a new column added by the
** 2014-11-28 schema change. Create it if necessary. This code
** can be removed in the future, once all users have upgraded to the
** 2014-11-28 or later schema.
*/
if( !db_table_has_column("repository","plink","baseid") ){
db_multi_exec(
"ALTER TABLE repository.plink ADD COLUMN baseid;"
);
}
/* Verify that the MLINK table has the newer columns added by the
** 2015-01-24 schema change. Create them if necessary. This code
** can be removed in the future, once all users have upgraded to the
** 2015-01-24 or later schema.
*/
if( !db_table_has_column("repository","mlink","isaux") ){
db_begin_transaction();
db_multi_exec(
"ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;"
"ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;"
);
db_end_transaction(0);
}
/* Add the user.mtime column if it is missing. (2011-04-27)
*/
if( !db_table_has_column("repository", "user", "mtime") ){
db_multi_exec(
"CREATE TEMP TABLE temp_user AS SELECT * FROM user;"
"DROP TABLE user;"
"CREATE TABLE user(\n"
" uid INTEGER PRIMARY KEY,\n"
" login TEXT UNIQUE,\n"
" pw TEXT,\n"
|
| ︙ | ︙ | |||
107 108 109 110 111 112 113 |
"INSERT OR IGNORE INTO user"
" SELECT uid, login, pw, cap, cookie,"
" ipaddr, cexpire, info, now(), photo FROM temp_user;"
"DROP TABLE temp_user;"
);
}
| < | > | < | > > | | > > > > > > | > > > > > > | > | < | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
"INSERT OR IGNORE INTO user"
" SELECT uid, login, pw, cap, cookie,"
" ipaddr, cexpire, info, now(), photo FROM temp_user;"
"DROP TABLE temp_user;"
);
}
/* Add the config.mtime column if it is missing. (2011-04-27)
*/
if( !db_table_has_column("repository", "config", "mtime") ){
db_multi_exec(
"ALTER TABLE config ADD COLUMN mtime INTEGER;"
"UPDATE config SET mtime=now();"
);
}
/* Add the shun.mtime and shun.scom columns if they are missing.
** (2011-04-27)
*/
if( !db_table_has_column("repository", "shun", "mtime") ){
db_multi_exec(
"ALTER TABLE shun ADD COLUMN mtime INTEGER;"
"ALTER TABLE shun ADD COLUMN scom TEXT;"
"UPDATE shun SET mtime=now();"
);
}
/* Add the reportfmt.mtime column if it is missing. (2011-04-27)
*/
if( !db_table_has_column("repository", "reportfmt", "mtime") ){
static const char zCreateReportFmtTable[] =
@ -- An entry in this table describes a database query that generates a
@ -- table of tickets.
@ --
@ CREATE TABLE IF NOT EXISTS reportfmt(
@ rn INTEGER PRIMARY KEY, -- Report number
@ owner TEXT, -- Owner of this report format (not used)
@ title TEXT UNIQUE, -- Title of this report
@ mtime INTEGER, -- Time last modified. Seconds since 1970
@ cols TEXT, -- A color-key specification
@ sqlcode TEXT -- An SQL SELECT statement for this report
@ );
;
db_multi_exec(
"CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
"DROP TABLE reportfmt;"
);
db_multi_exec("%s", zCreateReportFmtTable/*safe-for-%s*/);
db_multi_exec(
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
" SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
" SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
" FROM old_fmt;"
);
}
/* Add the concealed.mtime column if it is missing. (2011-04-27)
*/
if( !db_table_has_column("repository", "concealed", "mtime") ){
db_multi_exec(
"ALTER TABLE concealed ADD COLUMN mtime INTEGER;"
"UPDATE concealed SET mtime=now();"
);
}
/* Do the fossil-2.0 updates to the schema. (2017-02-28)
*/
rebuild_schema_update_2_0();
}
/*
** Update the repository schema for Fossil version 2.0. (2017-02-28)
** (1) Change the CHECK constraint on BLOB.UUID so that the length
** is greater than or equal to 40, not exactly equal to 40.
*/
void rebuild_schema_update_2_0(void){
char *z = db_text(0, "SELECT sql FROM repository.sqlite_master WHERE name='blob'");
if( z ){
/* Search for: length(uuid)==40
** 0123456789 12345 */
int i;
for(i=10; z[i]; i++){
if( z[i]=='=' && strncmp(&z[i-6],"(uuid)==40",10)==0 ){
z[i] = '>';
db_multi_exec(
"PRAGMA writable_schema=ON;"
"UPDATE repository.sqlite_master SET sql=%Q WHERE name LIKE 'blob';"
"PRAGMA writable_schema=OFF;",
z
);
break;
}
}
fossil_free(z);
}
}
/*
** Variables used to store state information about an on-going "rebuild"
** or "deconstruct".
*/
static int totalSize; /* Total number of artifacts to process */
|
| ︙ | ︙ | |||
328 329 330 331 332 333 334 |
**
** If the randomize parameter is true, then the BLOBs are deliberately
** extracted in a random order. This feature is used to test the
** ability of fossil to accept records in any order and still
** construct a sane repository.
*/
int rebuild_db(int randomize, int doOut, int doClustering){
| | < > | | | | | | | | | | | | | < > > > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
**
** If the randomize parameter is true, then the BLOBs are deliberately
** extracted in a random order. This feature is used to test the
** ability of fossil to accept records in any order and still
** construct a sane repository.
*/
int rebuild_db(int randomize, int doOut, int doClustering){
Stmt s, q;
int errCnt = 0;
int incrSize;
Blob sql;
bag_init(&bagDone);
ttyOutput = doOut;
processCnt = 0;
if (ttyOutput && !g.fQuiet) {
percent_complete(0);
}
rebuild_update_schema();
blob_init(&sql, 0, 0);
db_prepare(&q,
"SELECT name FROM sqlite_master /*scan*/"
" WHERE type='table'"
" AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias',"
"'config','shun','private','reportfmt',"
"'concealed','accesslog','modreq',"
"'purgeevent','purgeitem','unversioned')"
" AND name NOT GLOB 'sqlite_*'"
" AND name NOT GLOB 'fx_*'"
);
while( db_step(&q)==SQLITE_ROW ){
blob_appendf(&sql, "DROP TABLE \"%w\";\n", db_column_text(&q,0));
}
db_finalize(&q);
db_multi_exec("%s", blob_str(&sql)/*safe-for-%s*/);
blob_reset(&sql);
db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
ticket_create_table(0);
shun_artifacts();
db_multi_exec(
"INSERT INTO unclustered"
" SELECT rid FROM blob EXCEPT SELECT rid FROM private"
|
| ︙ | ︙ | |||
992 993 994 995 996 997 998 | ** ** Usage %fossil deconstruct ?OPTIONS? DESTINATION ** ** ** This command exports all artifacts of a given repository and ** writes all artifacts to the file system. The DESTINATION directory ** will be populated with subdirectories AA and files AA/BBBBBBBBB.., where | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | ** ** Usage %fossil deconstruct ?OPTIONS? DESTINATION ** ** ** This command exports all artifacts of a given repository and ** writes all artifacts to the file system. The DESTINATION directory ** will be populated with subdirectories AA and files AA/BBBBBBBBB.., where ** AABBBBBBBBB.. is the 40+ character artifact ID, AA the first 2 characters. ** If -L|--prefixlength is given, the length (default 2) of the directory ** prefix can be set to 0,1,..,9 characters. ** ** Options: ** -R|--repository REPOSITORY deconstruct given REPOSITORY ** -L|--prefixlength N set the length of the names of the DESTINATION ** subdirectories to N |
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
77 78 79 80 81 82 83 | @ -- The blob and delta tables collectively hold the "global state" of @ -- a Fossil repository. @ -- @ CREATE TABLE blob( @ rid INTEGER PRIMARY KEY, -- Record ID @ rcvid INTEGER, -- Origin of this record @ size INTEGER, -- Size of content. -1 for a phantom. | | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | @ -- The blob and delta tables collectively hold the "global state" of @ -- a Fossil repository. @ -- @ CREATE TABLE blob( @ rid INTEGER PRIMARY KEY, -- Record ID @ rcvid INTEGER, -- Origin of this record @ size INTEGER, -- Size of content. -1 for a phantom. @ uuid TEXT UNIQUE NOT NULL, -- hash of the content @ content BLOB, -- Compressed content of this record @ CHECK( length(uuid)>=40 AND rid>0 ) @ ); @ CREATE TABLE delta( @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression @ ); @ CREATE INDEX delta_i1 ON delta(srcid); @ |
| ︙ | ︙ |
Changes to src/sha1.c.
1 2 3 4 5 6 7 | /* ** This implementation of SHA1. */ #include "config.h" #include <sys/types.h> #include "sha1.h" | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > < | 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 |
/*
** Copyright (c) 2006 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This implementation of SHA1.
*/
#include "config.h"
#include <sys/types.h>
#include <stdint.h>
#include "sha1.h"
/*
** SHA1 Implementation #1 is the hardened SHA1 implementation by
** Marc Stevens. Code obtained from GitHub
**
** https://github.com/cr-marcstevens/sha1collisiondetection
**
** Downloaded on 2017-03-01 then repackaged to work with Fossil
** and makeheaders.
*/
#if FOSSIL_HARDENED_SHA1
#if INTERFACE
typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
struct SHA1_CTX {
uint64_t total;
uint32_t ihv[5];
unsigned char buffer[64];
int bigendian;
int found_collision;
int safe_hash;
int detect_coll;
int ubc_check;
int reduced_round_coll;
collision_block_callback callback;
uint32_t ihv1[5];
uint32_t ihv2[5];
uint32_t m1[80];
uint32_t m2[80];
uint32_t states[80][5];
};
#endif
void SHA1DCInit(SHA1_CTX*);
void SHA1DCUpdate(SHA1_CTX*, const unsigned char*, unsigned);
int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
#define SHA1Context SHA1_CTX
#define SHA1Init SHA1DCInit
#define SHA1Update SHA1DCUpdate
#define SHA1Final SHA1DCFinal
/*
** SHA1 Implementation #2: use the SHA1 algorithm built into SSL
*/
#elif defined(FOSSIL_ENABLE_SSL)
# include <openssl/sha.h>
# define SHA1Context SHA_CTX
# define SHA1Init SHA1_Init
# define SHA1Update SHA1_Update
# define SHA1Final SHA1_Final
/*
** SHA1 Implementation #3: If none of the previous two SHA1
** algorithms work, there is this built-in. This built-in was the
** original implementation used by Fossil.
*/
#else
/*
** The SHA1 implementation below is adapted from:
**
** $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $
** $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $
**
** SHA-1 in C
|
| ︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
#else
/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
#endif
#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
|(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
^block[(i+2)&15]^block[i&15],1))
| > > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
#else
/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
#endif
#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
|(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
^block[(i+2)&15]^block[i&15],1))
|
| ︙ | ︙ | |||
186 187 188 189 190 191 192 |
(void)memcpy(&context->buffer[j], &data[i], len - i);
}
/*
* Add padding and return the message digest.
*/
| | | < | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
(void)memcpy(&context->buffer[j], &data[i], len - i);
}
/*
* Add padding and return the message digest.
*/
static void SHA1Final(unsigned char *digest, SHA1Context *context){
unsigned int i;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (const unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448)
SHA1Update(context, (const unsigned char *)"\0", 1);
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
if (digest) {
for (i = 0; i < 20; i++)
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
}
#endif /* Built-in SHA1 implemenation */
/*
** Convert a digest into base-16. digest should be declared as
** "unsigned char digest[20]" in the calling function. The SHA1
** digest is stored in the first 20 bytes. zBuf should
** be "char zBuf[41]".
*/
|
| ︙ | ︙ | |||
266 267 268 269 270 271 272 |
** of computation. The return pointer points to a static buffer that
** is overwritten by subsequent calls to this function.
*/
char *sha1sum_finish(Blob *pOut){
unsigned char zResult[20];
static char zOut[41];
sha1sum_step_text(0,0);
| | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
** of computation. The return pointer points to a static buffer that
** is overwritten by subsequent calls to this function.
*/
char *sha1sum_finish(Blob *pOut){
unsigned char zResult[20];
static char zOut[41];
sha1sum_step_text(0,0);
SHA1Final(zResult, &incrCtx);
incrInit = 0;
DigestToBase16(zResult, zOut);
if( pOut ){
blob_zero(pOut);
blob_append(pOut, zOut, 40);
}
return zOut;
|
| ︙ | ︙ | |||
314 315 316 317 318 319 320 |
n = fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
fclose(in);
blob_zero(pCksum);
blob_resize(pCksum, 40);
| | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
n = fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
fclose(in);
blob_zero(pCksum);
blob_resize(pCksum, 40);
SHA1Final(zResult, &ctx);
DigestToBase16(zResult, blob_buffer(pCksum));
return 0;
}
/*
** Compute the SHA1 checksum of a blob in memory. Store the resulting
** checksum in the blob pCksum. pCksum is assumed to be either
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 |
SHA1Update(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn));
if( pIn==pCksum ){
blob_reset(pCksum);
}else{
blob_zero(pCksum);
}
blob_resize(pCksum, 40);
| | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
SHA1Update(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn));
if( pIn==pCksum ){
blob_reset(pCksum);
}else{
blob_zero(pCksum);
}
blob_resize(pCksum, 40);
SHA1Final(zResult, &ctx);
DigestToBase16(zResult, blob_buffer(pCksum));
return 0;
}
/*
** Compute the SHA1 checksum of a zero-terminated string. The
** result is held in memory obtained from mprintf().
*/
char *sha1sum(const char *zIn){
SHA1Context ctx;
unsigned char zResult[20];
char zDigest[41];
SHA1Init(&ctx);
SHA1Update(&ctx, (unsigned const char*)zIn, strlen(zIn));
SHA1Final(zResult, &ctx);
DigestToBase16(zResult, zDigest);
return mprintf("%s", zDigest);
}
/*
** Convert a cleartext password for a specific user into a SHA1 hash.
**
|
| ︙ | ︙ | |||
405 406 407 408 409 410 411 |
zProjCode = zProjectId;
}
SHA1Update(&ctx, (unsigned char*)zProjCode, strlen(zProjCode));
SHA1Update(&ctx, (unsigned char*)"/", 1);
SHA1Update(&ctx, (unsigned char*)zLogin, strlen(zLogin));
SHA1Update(&ctx, (unsigned char*)"/", 1);
SHA1Update(&ctx, (unsigned const char*)zPw, strlen(zPw));
| | | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
zProjCode = zProjectId;
}
SHA1Update(&ctx, (unsigned char*)zProjCode, strlen(zProjCode));
SHA1Update(&ctx, (unsigned char*)"/", 1);
SHA1Update(&ctx, (unsigned char*)zLogin, strlen(zLogin));
SHA1Update(&ctx, (unsigned char*)"/", 1);
SHA1Update(&ctx, (unsigned const char*)zPw, strlen(zPw));
SHA1Final(zResult, &ctx);
DigestToBase16(zResult, zDigest);
return mprintf("%s", zDigest);
}
/*
** Implement the shared_secret() SQL function. shared_secret() takes two or
** three arguments; the third argument is optional.
|
| ︙ | ︙ |
Added src/sha1hard.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 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 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 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 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 |
/*
** The code in this file is the concatenation of several files
** copied out of
**
** https://github.com/cr-marcstevens/sha1collisiondetection
**
** The copy was made on 2017-03-01. Some minor formatting changes
** were made but otherwise the code is unchanged. All
** original copyright claims are preserved.
**
** The code here implements a version of the SHA1 hash function that
** is not vulnerable to crypto-analysis based attacks. If an input
** is detected that looks like it might have been the result of a
** crypto-analysis attack, then the hash is perturbed to generate a
** completely different hash. The authors claim that the chance of
** a false-positive is vanishingly small.
*/
/*MAKEHEADERS-STOP*/
#include "config.h"
#if FOSSIL_HARDENED_SHA1 /* Only do this code if requested */
/*************** File: lib/sha1.c ****************/
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow (danshu@microsoft.com)
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/
/*************** File: LICENSE.txt ***************/
/*
** MIT License
**
** Copyright (c) 2017:
** Marc Stevens
** Cryptology Group
** Centrum Wiskunde & Informatica
** P.O. Box 94079, 1090 GB Amsterdam, Netherlands
** marc@marc-stevens.nl
**
** Dan Shumow
** Microsoft Research
** danshu@microsoft.com
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/
#include <string.h>
#include <memory.h>
#include <stdio.h>
#define DVMASKSIZE 1
typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
#define DOSTORESTATE58
#define DOSTORESTATE65
typedef void(*sha1_recompression_type)(uint32_t*, uint32_t*, const uint32_t*, const uint32_t*);
void sha1_message_expansion(uint32_t W[80]);
void sha1_compression(uint32_t ihv[5], const uint32_t m[16]);
void sha1_compression_W(uint32_t ihv[5], const uint32_t W[80]);
void sha1_compression_states(uint32_t ihv[5], const uint32_t W[80], uint32_t states[80][5]);
extern sha1_recompression_type sha1_recompression_step[80];
typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
typedef struct {
uint64_t total;
uint32_t ihv[5];
unsigned char buffer[64];
int bigendian;
int found_collision;
int safe_hash;
int detect_coll;
int ubc_check;
int reduced_round_coll;
collision_block_callback callback;
uint32_t ihv1[5];
uint32_t ihv2[5];
uint32_t m1[80];
uint32_t m2[80];
uint32_t states[80][5];
} SHA1_CTX;
/******************** File: lib/ubc_check.c **************************/
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/
/*
** this file was generated by the 'parse_bitrel' program in the tools section
** using the data files from directory 'tools/data/3565'
**
** sha1_dvs contains a list of SHA-1 Disturbance Vectors (DV) to check
** dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper)
** dm[80] is the expanded message block XOR-difference defined by the DV
** testt is the step to do the recompression from for collision detection
** maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check
**
** ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
** it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
** thus one needs to do the recompression check for each DV that has its bit set
**
** ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded
** a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c
** ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
*/
static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
static const uint32_t DV_I_44_0_bit = (uint32_t)(1) << 1;
static const uint32_t DV_I_45_0_bit = (uint32_t)(1) << 2;
static const uint32_t DV_I_46_0_bit = (uint32_t)(1) << 3;
static const uint32_t DV_I_46_2_bit = (uint32_t)(1) << 4;
static const uint32_t DV_I_47_0_bit = (uint32_t)(1) << 5;
static const uint32_t DV_I_47_2_bit = (uint32_t)(1) << 6;
static const uint32_t DV_I_48_0_bit = (uint32_t)(1) << 7;
static const uint32_t DV_I_48_2_bit = (uint32_t)(1) << 8;
static const uint32_t DV_I_49_0_bit = (uint32_t)(1) << 9;
static const uint32_t DV_I_49_2_bit = (uint32_t)(1) << 10;
static const uint32_t DV_I_50_0_bit = (uint32_t)(1) << 11;
static const uint32_t DV_I_50_2_bit = (uint32_t)(1) << 12;
static const uint32_t DV_I_51_0_bit = (uint32_t)(1) << 13;
static const uint32_t DV_I_51_2_bit = (uint32_t)(1) << 14;
static const uint32_t DV_I_52_0_bit = (uint32_t)(1) << 15;
static const uint32_t DV_II_45_0_bit = (uint32_t)(1) << 16;
static const uint32_t DV_II_46_0_bit = (uint32_t)(1) << 17;
static const uint32_t DV_II_46_2_bit = (uint32_t)(1) << 18;
static const uint32_t DV_II_47_0_bit = (uint32_t)(1) << 19;
static const uint32_t DV_II_48_0_bit = (uint32_t)(1) << 20;
static const uint32_t DV_II_49_0_bit = (uint32_t)(1) << 21;
static const uint32_t DV_II_49_2_bit = (uint32_t)(1) << 22;
static const uint32_t DV_II_50_0_bit = (uint32_t)(1) << 23;
static const uint32_t DV_II_50_2_bit = (uint32_t)(1) << 24;
static const uint32_t DV_II_51_0_bit = (uint32_t)(1) << 25;
static const uint32_t DV_II_51_2_bit = (uint32_t)(1) << 26;
static const uint32_t DV_II_52_0_bit = (uint32_t)(1) << 27;
static const uint32_t DV_II_53_0_bit = (uint32_t)(1) << 28;
static const uint32_t DV_II_54_0_bit = (uint32_t)(1) << 29;
static const uint32_t DV_II_55_0_bit = (uint32_t)(1) << 30;
static const uint32_t DV_II_56_0_bit = (uint32_t)(1) << 31;
dv_info_t sha1_dvs[] =
{
{1,43,0,58,0,0, { 0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161,0x80000599 } }
, {1,44,0,58,0,1, { 0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161 } }
, {1,45,0,58,0,2, { 0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803 } }
, {1,46,0,58,0,3, { 0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c } }
, {1,46,2,58,0,4, { 0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020,0x0000039a,0x00000132 } }
, {1,47,0,58,0,5, { 0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6 } }
, {1,47,2,58,0,6, { 0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020,0x0000039a } }
, {1,48,0,58,0,7, { 0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408 } }
, {1,48,2,58,0,8, { 0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020 } }
, {1,49,0,58,0,9, { 0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164 } }
, {1,49,2,58,0,10, { 0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590 } }
, {1,50,0,65,0,11, { 0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018 } }
, {1,50,2,65,0,12, { 0x20000030,0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060 } }
, {1,51,0,65,0,13, { 0xe8000000,0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202 } }
, {1,51,2,65,0,14, { 0xa0000003,0x20000030,0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a } }
, {1,52,0,65,0,15, { 0x04000010,0xe8000000,0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012 } }
, {2,45,0,58,0,16, { 0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4,0x80000054,0x00000967 } }
, {2,46,0,58,0,17, { 0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4,0x80000054 } }
, {2,46,2,58,0,18, { 0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c,0x000005b6,0x0000106a,0x00000b90,0x00000152 } }
, {2,47,0,58,0,19, { 0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4 } }
, {2,48,0,58,0,20, { 0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a } }
, {2,49,0,58,0,21, { 0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d } }
, {2,49,2,58,0,22, { 0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c,0x000005b6 } }
, {2,50,0,65,0,23, { 0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b } }
, {2,50,2,65,0,24, { 0xd0000072,0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c } }
, {2,51,0,65,0,25, { 0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b } }
, {2,51,2,65,0,26, { 0x00000043,0xd0000072,0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e } }
, {2,52,0,65,0,27, { 0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014 } }
, {2,53,0,65,0,28, { 0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089 } }
, {2,54,0,65,0,29, { 0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107 } }
, {2,55,0,65,0,30, { 0x00000010,0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b } }
, {2,56,0,65,0,31, { 0x2600001a,0x00000010,0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046 } }
, {0,0,0,0,0,0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
};
void ubc_check(const uint32_t W[80], uint32_t dvmask[1])
{
uint32_t mask = ~((uint32_t)(0));
mask &= (((((W[44]^W[45])>>29)&1)-1) | ~(DV_I_48_0_bit|DV_I_51_0_bit|DV_I_52_0_bit|DV_II_45_0_bit|DV_II_46_0_bit|DV_II_50_0_bit|DV_II_51_0_bit));
mask &= (((((W[49]^W[50])>>29)&1)-1) | ~(DV_I_46_0_bit|DV_II_45_0_bit|DV_II_50_0_bit|DV_II_51_0_bit|DV_II_55_0_bit|DV_II_56_0_bit));
mask &= (((((W[48]^W[49])>>29)&1)-1) | ~(DV_I_45_0_bit|DV_I_52_0_bit|DV_II_49_0_bit|DV_II_50_0_bit|DV_II_54_0_bit|DV_II_55_0_bit));
mask &= ((((W[47]^(W[50]>>25))&(1<<4))-(1<<4)) | ~(DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_51_0_bit|DV_II_56_0_bit));
mask &= (((((W[47]^W[48])>>29)&1)-1) | ~(DV_I_44_0_bit|DV_I_51_0_bit|DV_II_48_0_bit|DV_II_49_0_bit|DV_II_53_0_bit|DV_II_54_0_bit));
mask &= (((((W[46]>>4)^(W[49]>>29))&1)-1) | ~(DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit|DV_II_50_0_bit|DV_II_55_0_bit));
mask &= (((((W[46]^W[47])>>29)&1)-1) | ~(DV_I_43_0_bit|DV_I_50_0_bit|DV_II_47_0_bit|DV_II_48_0_bit|DV_II_52_0_bit|DV_II_53_0_bit));
mask &= (((((W[45]>>4)^(W[48]>>29))&1)-1) | ~(DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit|DV_II_49_0_bit|DV_II_54_0_bit));
mask &= (((((W[45]^W[46])>>29)&1)-1) | ~(DV_I_49_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_47_0_bit|DV_II_51_0_bit|DV_II_52_0_bit));
mask &= (((((W[44]>>4)^(W[47]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit|DV_II_48_0_bit|DV_II_53_0_bit));
mask &= (((((W[43]>>4)^(W[46]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit|DV_II_47_0_bit|DV_II_52_0_bit));
mask &= (((((W[43]^W[44])>>29)&1)-1) | ~(DV_I_47_0_bit|DV_I_50_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_49_0_bit|DV_II_50_0_bit));
mask &= (((((W[42]>>4)^(W[45]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_51_0_bit));
mask &= (((((W[41]>>4)^(W[44]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_50_0_bit));
mask &= (((((W[40]^W[41])>>29)&1)-1) | ~(DV_I_44_0_bit|DV_I_47_0_bit|DV_I_48_0_bit|DV_II_46_0_bit|DV_II_47_0_bit|DV_II_56_0_bit));
mask &= (((((W[54]^W[55])>>29)&1)-1) | ~(DV_I_51_0_bit|DV_II_47_0_bit|DV_II_50_0_bit|DV_II_55_0_bit|DV_II_56_0_bit));
mask &= (((((W[53]^W[54])>>29)&1)-1) | ~(DV_I_50_0_bit|DV_II_46_0_bit|DV_II_49_0_bit|DV_II_54_0_bit|DV_II_55_0_bit));
mask &= (((((W[52]^W[53])>>29)&1)-1) | ~(DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit|DV_II_53_0_bit|DV_II_54_0_bit));
mask &= ((((W[50]^(W[53]>>25))&(1<<4))-(1<<4)) | ~(DV_I_50_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_48_0_bit|DV_II_54_0_bit));
mask &= (((((W[50]^W[51])>>29)&1)-1) | ~(DV_I_47_0_bit|DV_II_46_0_bit|DV_II_51_0_bit|DV_II_52_0_bit|DV_II_56_0_bit));
mask &= ((((W[49]^(W[52]>>25))&(1<<4))-(1<<4)) | ~(DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_47_0_bit|DV_II_53_0_bit));
mask &= ((((W[48]^(W[51]>>25))&(1<<4))-(1<<4)) | ~(DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_52_0_bit));
mask &= (((((W[42]^W[43])>>29)&1)-1) | ~(DV_I_46_0_bit|DV_I_49_0_bit|DV_I_50_0_bit|DV_II_48_0_bit|DV_II_49_0_bit));
mask &= (((((W[41]^W[42])>>29)&1)-1) | ~(DV_I_45_0_bit|DV_I_48_0_bit|DV_I_49_0_bit|DV_II_47_0_bit|DV_II_48_0_bit));
mask &= (((((W[40]>>4)^(W[43]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_50_0_bit|DV_II_49_0_bit|DV_II_56_0_bit));
mask &= (((((W[39]>>4)^(W[42]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_49_0_bit|DV_II_48_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_44_0_bit|DV_I_48_0_bit|DV_II_47_0_bit|DV_II_54_0_bit|DV_II_56_0_bit))
mask &= (((((W[38]>>4)^(W[41]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_48_0_bit|DV_II_47_0_bit|DV_II_54_0_bit|DV_II_56_0_bit));
mask &= (((((W[37]>>4)^(W[40]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_47_0_bit|DV_II_46_0_bit|DV_II_53_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_51_0_bit|DV_II_56_0_bit))
mask &= (((((W[55]^W[56])>>29)&1)-1) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_51_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_50_0_bit|DV_II_56_0_bit))
mask &= ((((W[52]^(W[55]>>25))&(1<<4))-(1<<4)) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_50_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_51_0_bit|DV_II_47_0_bit|DV_II_49_0_bit|DV_II_55_0_bit))
mask &= ((((W[51]^(W[54]>>25))&(1<<4))-(1<<4)) | ~(DV_I_51_0_bit|DV_II_47_0_bit|DV_II_49_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_48_0_bit|DV_II_47_0_bit|DV_II_52_0_bit|DV_II_53_0_bit))
mask &= (((((W[51]^W[52])>>29)&1)-1) | ~(DV_I_48_0_bit|DV_II_47_0_bit|DV_II_52_0_bit|DV_II_53_0_bit));
if (mask & (DV_I_46_0_bit|DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit))
mask &= (((((W[36]>>4)^(W[40]>>29))&1)-1) | ~(DV_I_46_0_bit|DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_49_0_bit))
mask &= ((0-(((W[53]^W[56])>>29)&1)) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_49_0_bit));
if (mask & (DV_I_50_0_bit|DV_II_46_0_bit|DV_II_47_0_bit))
mask &= ((0-(((W[51]^W[54])>>29)&1)) | ~(DV_I_50_0_bit|DV_II_46_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit))
mask &= ((0-(((W[50]^W[52])>>29)&1)) | ~(DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit));
if (mask & (DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit))
mask &= ((0-(((W[49]^W[51])>>29)&1)) | ~(DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit));
if (mask & (DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit))
mask &= ((0-(((W[48]^W[50])>>29)&1)) | ~(DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit));
if (mask & (DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit))
mask &= ((0-(((W[47]^W[49])>>29)&1)) | ~(DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit));
if (mask & (DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit))
mask &= ((0-(((W[46]^W[48])>>29)&1)) | ~(DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit));
mask &= ((((W[45]^W[47])&(1<<6))-(1<<6)) | ~(DV_I_47_2_bit|DV_I_49_2_bit|DV_I_51_2_bit));
if (mask & (DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit))
mask &= ((0-(((W[45]^W[47])>>29)&1)) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit));
mask &= (((((W[44]^W[46])>>6)&1)-1) | ~(DV_I_46_2_bit|DV_I_48_2_bit|DV_I_50_2_bit));
if (mask & (DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit))
mask &= ((0-(((W[44]^W[46])>>29)&1)) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit));
mask &= ((0-((W[41]^(W[42]>>5))&(1<<1))) | ~(DV_I_48_2_bit|DV_II_46_2_bit|DV_II_51_2_bit));
mask &= ((0-((W[40]^(W[41]>>5))&(1<<1))) | ~(DV_I_47_2_bit|DV_I_51_2_bit|DV_II_50_2_bit));
if (mask & (DV_I_44_0_bit|DV_I_46_0_bit|DV_II_56_0_bit))
mask &= ((0-(((W[40]^W[42])>>4)&1)) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_II_56_0_bit));
mask &= ((0-((W[39]^(W[40]>>5))&(1<<1))) | ~(DV_I_46_2_bit|DV_I_50_2_bit|DV_II_49_2_bit));
if (mask & (DV_I_43_0_bit|DV_I_45_0_bit|DV_II_55_0_bit))
mask &= ((0-(((W[39]^W[41])>>4)&1)) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_44_0_bit|DV_II_54_0_bit|DV_II_56_0_bit))
mask &= ((0-(((W[38]^W[40])>>4)&1)) | ~(DV_I_44_0_bit|DV_II_54_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_43_0_bit|DV_II_53_0_bit|DV_II_55_0_bit))
mask &= ((0-(((W[37]^W[39])>>4)&1)) | ~(DV_I_43_0_bit|DV_II_53_0_bit|DV_II_55_0_bit));
mask &= ((0-((W[36]^(W[37]>>5))&(1<<1))) | ~(DV_I_47_2_bit|DV_I_50_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_45_0_bit|DV_I_48_0_bit|DV_II_47_0_bit))
mask &= (((((W[35]>>4)^(W[39]>>29))&1)-1) | ~(DV_I_45_0_bit|DV_I_48_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_48_0_bit|DV_II_48_0_bit))
mask &= ((0-((W[63]^(W[64]>>5))&(1<<0))) | ~(DV_I_48_0_bit|DV_II_48_0_bit));
if (mask & (DV_I_45_0_bit|DV_II_45_0_bit))
mask &= ((0-((W[63]^(W[64]>>5))&(1<<1))) | ~(DV_I_45_0_bit|DV_II_45_0_bit));
if (mask & (DV_I_47_0_bit|DV_II_47_0_bit))
mask &= ((0-((W[62]^(W[63]>>5))&(1<<0))) | ~(DV_I_47_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_46_0_bit|DV_II_46_0_bit))
mask &= ((0-((W[61]^(W[62]>>5))&(1<<0))) | ~(DV_I_46_0_bit|DV_II_46_0_bit));
mask &= ((0-((W[61]^(W[62]>>5))&(1<<2))) | ~(DV_I_46_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_45_0_bit|DV_II_45_0_bit))
mask &= ((0-((W[60]^(W[61]>>5))&(1<<0))) | ~(DV_I_45_0_bit|DV_II_45_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_54_0_bit))
mask &= (((((W[58]^W[59])>>29)&1)-1) | ~(DV_II_51_0_bit|DV_II_54_0_bit));
if (mask & (DV_II_50_0_bit|DV_II_53_0_bit))
mask &= (((((W[57]^W[58])>>29)&1)-1) | ~(DV_II_50_0_bit|DV_II_53_0_bit));
if (mask & (DV_II_52_0_bit|DV_II_54_0_bit))
mask &= ((((W[56]^(W[59]>>25))&(1<<4))-(1<<4)) | ~(DV_II_52_0_bit|DV_II_54_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_52_0_bit))
mask &= ((0-(((W[56]^W[59])>>29)&1)) | ~(DV_II_51_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_49_0_bit|DV_II_52_0_bit))
mask &= (((((W[56]^W[57])>>29)&1)-1) | ~(DV_II_49_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_53_0_bit))
mask &= ((((W[55]^(W[58]>>25))&(1<<4))-(1<<4)) | ~(DV_II_51_0_bit|DV_II_53_0_bit));
if (mask & (DV_II_50_0_bit|DV_II_52_0_bit))
mask &= ((((W[54]^(W[57]>>25))&(1<<4))-(1<<4)) | ~(DV_II_50_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_49_0_bit|DV_II_51_0_bit))
mask &= ((((W[53]^(W[56]>>25))&(1<<4))-(1<<4)) | ~(DV_II_49_0_bit|DV_II_51_0_bit));
mask &= ((((W[51]^(W[50]>>5))&(1<<1))-(1<<1)) | ~(DV_I_50_2_bit|DV_II_46_2_bit));
mask &= ((((W[48]^W[50])&(1<<6))-(1<<6)) | ~(DV_I_50_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_51_0_bit|DV_I_52_0_bit))
mask &= ((0-(((W[48]^W[55])>>29)&1)) | ~(DV_I_51_0_bit|DV_I_52_0_bit));
mask &= ((((W[47]^W[49])&(1<<6))-(1<<6)) | ~(DV_I_49_2_bit|DV_I_51_2_bit));
mask &= ((((W[48]^(W[47]>>5))&(1<<1))-(1<<1)) | ~(DV_I_47_2_bit|DV_II_51_2_bit));
mask &= ((((W[46]^W[48])&(1<<6))-(1<<6)) | ~(DV_I_48_2_bit|DV_I_50_2_bit));
mask &= ((((W[47]^(W[46]>>5))&(1<<1))-(1<<1)) | ~(DV_I_46_2_bit|DV_II_50_2_bit));
mask &= ((0-((W[44]^(W[45]>>5))&(1<<1))) | ~(DV_I_51_2_bit|DV_II_49_2_bit));
mask &= ((((W[43]^W[45])&(1<<6))-(1<<6)) | ~(DV_I_47_2_bit|DV_I_49_2_bit));
mask &= (((((W[42]^W[44])>>6)&1)-1) | ~(DV_I_46_2_bit|DV_I_48_2_bit));
mask &= ((((W[43]^(W[42]>>5))&(1<<1))-(1<<1)) | ~(DV_II_46_2_bit|DV_II_51_2_bit));
mask &= ((((W[42]^(W[41]>>5))&(1<<1))-(1<<1)) | ~(DV_I_51_2_bit|DV_II_50_2_bit));
mask &= ((((W[41]^(W[40]>>5))&(1<<1))-(1<<1)) | ~(DV_I_50_2_bit|DV_II_49_2_bit));
if (mask & (DV_I_52_0_bit|DV_II_51_0_bit))
mask &= ((((W[39]^(W[43]>>25))&(1<<4))-(1<<4)) | ~(DV_I_52_0_bit|DV_II_51_0_bit));
if (mask & (DV_I_51_0_bit|DV_II_50_0_bit))
mask &= ((((W[38]^(W[42]>>25))&(1<<4))-(1<<4)) | ~(DV_I_51_0_bit|DV_II_50_0_bit));
if (mask & (DV_I_48_2_bit|DV_I_51_2_bit))
mask &= ((0-((W[37]^(W[38]>>5))&(1<<1))) | ~(DV_I_48_2_bit|DV_I_51_2_bit));
if (mask & (DV_I_50_0_bit|DV_II_49_0_bit))
mask &= ((((W[37]^(W[41]>>25))&(1<<4))-(1<<4)) | ~(DV_I_50_0_bit|DV_II_49_0_bit));
if (mask & (DV_II_52_0_bit|DV_II_54_0_bit))
mask &= ((0-((W[36]^W[38])&(1<<4))) | ~(DV_II_52_0_bit|DV_II_54_0_bit));
mask &= ((0-((W[35]^(W[36]>>5))&(1<<1))) | ~(DV_I_46_2_bit|DV_I_49_2_bit));
if (mask & (DV_I_51_0_bit|DV_II_47_0_bit))
mask &= ((((W[35]^(W[39]>>25))&(1<<3))-(1<<3)) | ~(DV_I_51_0_bit|DV_II_47_0_bit));
if (mask) {
if (mask & DV_I_43_0_bit)
if (
!((W[61]^(W[62]>>5)) & (1<<1))
|| !(!((W[59]^(W[63]>>25)) & (1<<5)))
|| !((W[58]^(W[63]>>30)) & (1<<0))
) mask &= ~DV_I_43_0_bit;
if (mask & DV_I_44_0_bit)
if (
!((W[62]^(W[63]>>5)) & (1<<1))
|| !(!((W[60]^(W[64]>>25)) & (1<<5)))
|| !((W[59]^(W[64]>>30)) & (1<<0))
) mask &= ~DV_I_44_0_bit;
if (mask & DV_I_46_2_bit)
mask &= ((~((W[40]^W[42])>>2)) | ~DV_I_46_2_bit);
if (mask & DV_I_47_2_bit)
if (
!((W[62]^(W[63]>>5)) & (1<<2))
|| !(!((W[41]^W[43]) & (1<<6)))
) mask &= ~DV_I_47_2_bit;
if (mask & DV_I_48_2_bit)
if (
!((W[63]^(W[64]>>5)) & (1<<2))
|| !(!((W[48]^(W[49]<<5)) & (1<<6)))
) mask &= ~DV_I_48_2_bit;
if (mask & DV_I_49_2_bit)
if (
!(!((W[49]^(W[50]<<5)) & (1<<6)))
|| !((W[42]^W[50]) & (1<<1))
|| !(!((W[39]^(W[40]<<5)) & (1<<6)))
|| !((W[38]^W[40]) & (1<<1))
) mask &= ~DV_I_49_2_bit;
if (mask & DV_I_50_0_bit)
mask &= ((((W[36]^W[37])<<7)) | ~DV_I_50_0_bit);
if (mask & DV_I_50_2_bit)
mask &= ((((W[43]^W[51])<<11)) | ~DV_I_50_2_bit);
if (mask & DV_I_51_0_bit)
mask &= ((((W[37]^W[38])<<9)) | ~DV_I_51_0_bit);
if (mask & DV_I_51_2_bit)
if (
!(!((W[51]^(W[52]<<5)) & (1<<6)))
|| !(!((W[49]^W[51]) & (1<<6)))
|| !(!((W[37]^(W[37]>>5)) & (1<<1)))
|| !(!((W[35]^(W[39]>>25)) & (1<<5)))
) mask &= ~DV_I_51_2_bit;
if (mask & DV_I_52_0_bit)
mask &= ((((W[38]^W[39])<<11)) | ~DV_I_52_0_bit);
if (mask & DV_II_46_2_bit)
mask &= ((((W[47]^W[51])<<17)) | ~DV_II_46_2_bit);
if (mask & DV_II_48_0_bit)
if (
!(!((W[36]^(W[40]>>25)) & (1<<3)))
|| !((W[35]^(W[40]<<2)) & (1<<30))
) mask &= ~DV_II_48_0_bit;
if (mask & DV_II_49_0_bit)
if (
!(!((W[37]^(W[41]>>25)) & (1<<3)))
|| !((W[36]^(W[41]<<2)) & (1<<30))
) mask &= ~DV_II_49_0_bit;
if (mask & DV_II_49_2_bit)
if (
!(!((W[53]^(W[54]<<5)) & (1<<6)))
|| !(!((W[51]^W[53]) & (1<<6)))
|| !((W[50]^W[54]) & (1<<1))
|| !(!((W[45]^(W[46]<<5)) & (1<<6)))
|| !(!((W[37]^(W[41]>>25)) & (1<<5)))
|| !((W[36]^(W[41]>>30)) & (1<<0))
) mask &= ~DV_II_49_2_bit;
if (mask & DV_II_50_0_bit)
if (
!((W[55]^W[58]) & (1<<29))
|| !(!((W[38]^(W[42]>>25)) & (1<<3)))
|| !((W[37]^(W[42]<<2)) & (1<<30))
) mask &= ~DV_II_50_0_bit;
if (mask & DV_II_50_2_bit)
if (
!(!((W[54]^(W[55]<<5)) & (1<<6)))
|| !(!((W[52]^W[54]) & (1<<6)))
|| !((W[51]^W[55]) & (1<<1))
|| !((W[45]^W[47]) & (1<<1))
|| !(!((W[38]^(W[42]>>25)) & (1<<5)))
|| !((W[37]^(W[42]>>30)) & (1<<0))
) mask &= ~DV_II_50_2_bit;
if (mask & DV_II_51_0_bit)
if (
!(!((W[39]^(W[43]>>25)) & (1<<3)))
|| !((W[38]^(W[43]<<2)) & (1<<30))
) mask &= ~DV_II_51_0_bit;
if (mask & DV_II_51_2_bit)
if (
!(!((W[55]^(W[56]<<5)) & (1<<6)))
|| !(!((W[53]^W[55]) & (1<<6)))
|| !((W[52]^W[56]) & (1<<1))
|| !((W[46]^W[48]) & (1<<1))
|| !(!((W[39]^(W[43]>>25)) & (1<<5)))
|| !((W[38]^(W[43]>>30)) & (1<<0))
) mask &= ~DV_II_51_2_bit;
if (mask & DV_II_52_0_bit)
if (
!(!((W[59]^W[60]) & (1<<29)))
|| !(!((W[40]^(W[44]>>25)) & (1<<3)))
|| !(!((W[40]^(W[44]>>25)) & (1<<4)))
|| !((W[39]^(W[44]<<2)) & (1<<30))
) mask &= ~DV_II_52_0_bit;
if (mask & DV_II_53_0_bit)
if (
!((W[58]^W[61]) & (1<<29))
|| !(!((W[57]^(W[61]>>25)) & (1<<4)))
|| !(!((W[41]^(W[45]>>25)) & (1<<3)))
|| !(!((W[41]^(W[45]>>25)) & (1<<4)))
) mask &= ~DV_II_53_0_bit;
if (mask & DV_II_54_0_bit)
if (
!(!((W[58]^(W[62]>>25)) & (1<<4)))
|| !(!((W[42]^(W[46]>>25)) & (1<<3)))
|| !(!((W[42]^(W[46]>>25)) & (1<<4)))
) mask &= ~DV_II_54_0_bit;
if (mask & DV_II_55_0_bit)
if (
!(!((W[59]^(W[63]>>25)) & (1<<4)))
|| !(!((W[57]^(W[59]>>25)) & (1<<4)))
|| !(!((W[43]^(W[47]>>25)) & (1<<3)))
|| !(!((W[43]^(W[47]>>25)) & (1<<4)))
) mask &= ~DV_II_55_0_bit;
if (mask & DV_II_56_0_bit)
if (
!(!((W[60]^(W[64]>>25)) & (1<<4)))
|| !(!((W[44]^(W[48]>>25)) & (1<<3)))
|| !(!((W[44]^(W[48]>>25)) & (1<<4)))
) mask &= ~DV_II_56_0_bit;
}
dvmask[0]=mask;
}
/******************** End Of File: lib/ubc_check.c *******************/
/******************** Continue with: lib/sha1.c **********************/
#define rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
#define rotate_left(x,n) (((x)<<(n))|((x)>>(32-(n))))
#define sha1_f1(b,c,d) ((d)^((b)&((c)^(d))))
#define sha1_f2(b,c,d) ((b)^(c)^(d))
#define sha1_f3(b,c,d) (((b) & ((c)|(d))) | ((c)&(d)))
#define sha1_f4(b,c,d) ((b)^(c)^(d))
#define HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, m, t) \
{ e += rotate_left(a, 5) + sha1_f1(b,c,d) + 0x5A827999 + m[t]; b = rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, m, t) \
{ e += rotate_left(a, 5) + sha1_f2(b,c,d) + 0x6ED9EBA1 + m[t]; b = rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, m, t) \
{ e += rotate_left(a, 5) + sha1_f3(b,c,d) + 0x8F1BBCDC + m[t]; b = rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, m, t) \
{ e += rotate_left(a, 5) + sha1_f4(b,c,d) + 0xCA62C1D6 + m[t]; b = rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, m, t) \
{ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f1(b,c,d) + 0x5A827999 + m[t]; }
#define HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, m, t) \
{ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f2(b,c,d) + 0x6ED9EBA1 + m[t]; }
#define HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, m, t) \
{ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f3(b,c,d) + 0x8F1BBCDC + m[t]; }
#define HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, m, t) \
{ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f4(b,c,d) + 0xCA62C1D6 + m[t]; }
#define SHA1_STORE_STATE(i) states[i][0] = a; states[i][1] = b; states[i][2] = c; states[i][3] = d; states[i][4] = e;
void sha1_message_expansion(uint32_t W[80])
{
unsigned i;
for (i = 16; i < 80; ++i)
W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
}
void sha1_compression(uint32_t ihv[5], const uint32_t m[16])
{
uint32_t W[80];
uint32_t a,b,c,d,e;
unsigned i;
memcpy(W, m, 16 * 4);
for (i = 16; i < 80; ++i)
W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
a = ihv[0]; b = ihv[1]; c = ihv[2]; d = ihv[3]; e = ihv[4];
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 0);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 1);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 2);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 3);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 4);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 5);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 6);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 7);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 8);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 9);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 10);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 11);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 12);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 13);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 14);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 15);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 16);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 17);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 18);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 19);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 20);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 21);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 22);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 23);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 24);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 25);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 26);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 27);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 28);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 29);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 30);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 31);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 32);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 33);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 34);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 35);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 36);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 37);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 38);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 39);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 40);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 41);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 42);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 43);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 44);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 45);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 46);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 47);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 48);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 49);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 50);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 51);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 52);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 53);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 54);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 55);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 56);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 57);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 58);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 59);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 60);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 61);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 62);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 63);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 64);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 65);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 66);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 67);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 68);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 69);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 70);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 71);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 72);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 73);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 74);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 75);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 76);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 77);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 78);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 79);
ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
}
void sha1_compression_W(uint32_t ihv[5], const uint32_t W[80])
{
uint32_t a = ihv[0], b = ihv[1], c = ihv[2], d = ihv[3], e = ihv[4];
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 0);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 1);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 2);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 3);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 4);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 5);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 6);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 7);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 8);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 9);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 10);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 11);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 12);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 13);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 14);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 15);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 16);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 17);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 18);
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 19);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 20);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 21);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 22);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 23);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 24);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 25);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 26);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 27);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 28);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 29);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 30);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 31);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 32);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 33);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 34);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 35);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 36);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 37);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 38);
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 39);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 40);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 41);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 42);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 43);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 44);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 45);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 46);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 47);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 48);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 49);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 50);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 51);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 52);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 53);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 54);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 55);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 56);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 57);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 58);
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 59);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 60);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 61);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 62);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 63);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 64);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 65);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 66);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 67);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 68);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 69);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 70);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 71);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 72);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 73);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 74);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 75);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 76);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 77);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 78);
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 79);
ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
}
void sha1_compression_states(uint32_t ihv[5], const uint32_t W[80], uint32_t states[80][5])
{
uint32_t a = ihv[0], b = ihv[1], c = ihv[2], d = ihv[3], e = ihv[4];
#ifdef DOSTORESTATE00
SHA1_STORE_STATE(0)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 0);
#ifdef DOSTORESTATE01
SHA1_STORE_STATE(1)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 1);
#ifdef DOSTORESTATE02
SHA1_STORE_STATE(2)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 2);
#ifdef DOSTORESTATE03
SHA1_STORE_STATE(3)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 3);
#ifdef DOSTORESTATE04
SHA1_STORE_STATE(4)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 4);
#ifdef DOSTORESTATE05
SHA1_STORE_STATE(5)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 5);
#ifdef DOSTORESTATE06
SHA1_STORE_STATE(6)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 6);
#ifdef DOSTORESTATE07
SHA1_STORE_STATE(7)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 7);
#ifdef DOSTORESTATE08
SHA1_STORE_STATE(8)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 8);
#ifdef DOSTORESTATE09
SHA1_STORE_STATE(9)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 9);
#ifdef DOSTORESTATE10
SHA1_STORE_STATE(10)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 10);
#ifdef DOSTORESTATE11
SHA1_STORE_STATE(11)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 11);
#ifdef DOSTORESTATE12
SHA1_STORE_STATE(12)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 12);
#ifdef DOSTORESTATE13
SHA1_STORE_STATE(13)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 13);
#ifdef DOSTORESTATE14
SHA1_STORE_STATE(14)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 14);
#ifdef DOSTORESTATE15
SHA1_STORE_STATE(15)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 15);
#ifdef DOSTORESTATE16
SHA1_STORE_STATE(16)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 16);
#ifdef DOSTORESTATE17
SHA1_STORE_STATE(17)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 17);
#ifdef DOSTORESTATE18
SHA1_STORE_STATE(18)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 18);
#ifdef DOSTORESTATE19
SHA1_STORE_STATE(19)
#endif
HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 19);
#ifdef DOSTORESTATE20
SHA1_STORE_STATE(20)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 20);
#ifdef DOSTORESTATE21
SHA1_STORE_STATE(21)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 21);
#ifdef DOSTORESTATE22
SHA1_STORE_STATE(22)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 22);
#ifdef DOSTORESTATE23
SHA1_STORE_STATE(23)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 23);
#ifdef DOSTORESTATE24
SHA1_STORE_STATE(24)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 24);
#ifdef DOSTORESTATE25
SHA1_STORE_STATE(25)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 25);
#ifdef DOSTORESTATE26
SHA1_STORE_STATE(26)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 26);
#ifdef DOSTORESTATE27
SHA1_STORE_STATE(27)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 27);
#ifdef DOSTORESTATE28
SHA1_STORE_STATE(28)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 28);
#ifdef DOSTORESTATE29
SHA1_STORE_STATE(29)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 29);
#ifdef DOSTORESTATE30
SHA1_STORE_STATE(30)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 30);
#ifdef DOSTORESTATE31
SHA1_STORE_STATE(31)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 31);
#ifdef DOSTORESTATE32
SHA1_STORE_STATE(32)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 32);
#ifdef DOSTORESTATE33
SHA1_STORE_STATE(33)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 33);
#ifdef DOSTORESTATE34
SHA1_STORE_STATE(34)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 34);
#ifdef DOSTORESTATE35
SHA1_STORE_STATE(35)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 35);
#ifdef DOSTORESTATE36
SHA1_STORE_STATE(36)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 36);
#ifdef DOSTORESTATE37
SHA1_STORE_STATE(37)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 37);
#ifdef DOSTORESTATE38
SHA1_STORE_STATE(38)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 38);
#ifdef DOSTORESTATE39
SHA1_STORE_STATE(39)
#endif
HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 39);
#ifdef DOSTORESTATE40
SHA1_STORE_STATE(40)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 40);
#ifdef DOSTORESTATE41
SHA1_STORE_STATE(41)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 41);
#ifdef DOSTORESTATE42
SHA1_STORE_STATE(42)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 42);
#ifdef DOSTORESTATE43
SHA1_STORE_STATE(43)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 43);
#ifdef DOSTORESTATE44
SHA1_STORE_STATE(44)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 44);
#ifdef DOSTORESTATE45
SHA1_STORE_STATE(45)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 45);
#ifdef DOSTORESTATE46
SHA1_STORE_STATE(46)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 46);
#ifdef DOSTORESTATE47
SHA1_STORE_STATE(47)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 47);
#ifdef DOSTORESTATE48
SHA1_STORE_STATE(48)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 48);
#ifdef DOSTORESTATE49
SHA1_STORE_STATE(49)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 49);
#ifdef DOSTORESTATE50
SHA1_STORE_STATE(50)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 50);
#ifdef DOSTORESTATE51
SHA1_STORE_STATE(51)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 51);
#ifdef DOSTORESTATE52
SHA1_STORE_STATE(52)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 52);
#ifdef DOSTORESTATE53
SHA1_STORE_STATE(53)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 53);
#ifdef DOSTORESTATE54
SHA1_STORE_STATE(54)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 54);
#ifdef DOSTORESTATE55
SHA1_STORE_STATE(55)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 55);
#ifdef DOSTORESTATE56
SHA1_STORE_STATE(56)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 56);
#ifdef DOSTORESTATE57
SHA1_STORE_STATE(57)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 57);
#ifdef DOSTORESTATE58
SHA1_STORE_STATE(58)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 58);
#ifdef DOSTORESTATE59
SHA1_STORE_STATE(59)
#endif
HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 59);
#ifdef DOSTORESTATE60
SHA1_STORE_STATE(60)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 60);
#ifdef DOSTORESTATE61
SHA1_STORE_STATE(61)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 61);
#ifdef DOSTORESTATE62
SHA1_STORE_STATE(62)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 62);
#ifdef DOSTORESTATE63
SHA1_STORE_STATE(63)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 63);
#ifdef DOSTORESTATE64
SHA1_STORE_STATE(64)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 64);
#ifdef DOSTORESTATE65
SHA1_STORE_STATE(65)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 65);
#ifdef DOSTORESTATE66
SHA1_STORE_STATE(66)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 66);
#ifdef DOSTORESTATE67
SHA1_STORE_STATE(67)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 67);
#ifdef DOSTORESTATE68
SHA1_STORE_STATE(68)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 68);
#ifdef DOSTORESTATE69
SHA1_STORE_STATE(69)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 69);
#ifdef DOSTORESTATE70
SHA1_STORE_STATE(70)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 70);
#ifdef DOSTORESTATE71
SHA1_STORE_STATE(71)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 71);
#ifdef DOSTORESTATE72
SHA1_STORE_STATE(72)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 72);
#ifdef DOSTORESTATE73
SHA1_STORE_STATE(73)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 73);
#ifdef DOSTORESTATE74
SHA1_STORE_STATE(74)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 74);
#ifdef DOSTORESTATE75
SHA1_STORE_STATE(75)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 75);
#ifdef DOSTORESTATE76
SHA1_STORE_STATE(76)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 76);
#ifdef DOSTORESTATE77
SHA1_STORE_STATE(77)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 77);
#ifdef DOSTORESTATE78
SHA1_STORE_STATE(78)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 78);
#ifdef DOSTORESTATE79
SHA1_STORE_STATE(79)
#endif
HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 79);
ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
}
#define SHA1_RECOMPRESS(t) \
void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5]) \
{ \
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; \
if (t > 79) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(b, c, d, e, a, me2, 79); \
if (t > 78) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(c, d, e, a, b, me2, 78); \
if (t > 77) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(d, e, a, b, c, me2, 77); \
if (t > 76) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(e, a, b, c, d, me2, 76); \
if (t > 75) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, me2, 75); \
if (t > 74) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(b, c, d, e, a, me2, 74); \
if (t > 73) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(c, d, e, a, b, me2, 73); \
if (t > 72) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(d, e, a, b, c, me2, 72); \
if (t > 71) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(e, a, b, c, d, me2, 71); \
if (t > 70) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, me2, 70); \
if (t > 69) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(b, c, d, e, a, me2, 69); \
if (t > 68) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(c, d, e, a, b, me2, 68); \
if (t > 67) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(d, e, a, b, c, me2, 67); \
if (t > 66) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(e, a, b, c, d, me2, 66); \
if (t > 65) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, me2, 65); \
if (t > 64) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(b, c, d, e, a, me2, 64); \
if (t > 63) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(c, d, e, a, b, me2, 63); \
if (t > 62) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(d, e, a, b, c, me2, 62); \
if (t > 61) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(e, a, b, c, d, me2, 61); \
if (t > 60) HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, me2, 60); \
if (t > 59) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(b, c, d, e, a, me2, 59); \
if (t > 58) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(c, d, e, a, b, me2, 58); \
if (t > 57) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(d, e, a, b, c, me2, 57); \
if (t > 56) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(e, a, b, c, d, me2, 56); \
if (t > 55) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, me2, 55); \
if (t > 54) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(b, c, d, e, a, me2, 54); \
if (t > 53) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(c, d, e, a, b, me2, 53); \
if (t > 52) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(d, e, a, b, c, me2, 52); \
if (t > 51) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(e, a, b, c, d, me2, 51); \
if (t > 50) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, me2, 50); \
if (t > 49) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(b, c, d, e, a, me2, 49); \
if (t > 48) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(c, d, e, a, b, me2, 48); \
if (t > 47) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(d, e, a, b, c, me2, 47); \
if (t > 46) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(e, a, b, c, d, me2, 46); \
if (t > 45) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, me2, 45); \
if (t > 44) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(b, c, d, e, a, me2, 44); \
if (t > 43) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(c, d, e, a, b, me2, 43); \
if (t > 42) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(d, e, a, b, c, me2, 42); \
if (t > 41) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(e, a, b, c, d, me2, 41); \
if (t > 40) HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, me2, 40); \
if (t > 39) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(b, c, d, e, a, me2, 39); \
if (t > 38) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(c, d, e, a, b, me2, 38); \
if (t > 37) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(d, e, a, b, c, me2, 37); \
if (t > 36) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(e, a, b, c, d, me2, 36); \
if (t > 35) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, me2, 35); \
if (t > 34) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(b, c, d, e, a, me2, 34); \
if (t > 33) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(c, d, e, a, b, me2, 33); \
if (t > 32) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(d, e, a, b, c, me2, 32); \
if (t > 31) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(e, a, b, c, d, me2, 31); \
if (t > 30) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, me2, 30); \
if (t > 29) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(b, c, d, e, a, me2, 29); \
if (t > 28) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(c, d, e, a, b, me2, 28); \
if (t > 27) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(d, e, a, b, c, me2, 27); \
if (t > 26) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(e, a, b, c, d, me2, 26); \
if (t > 25) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, me2, 25); \
if (t > 24) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(b, c, d, e, a, me2, 24); \
if (t > 23) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(c, d, e, a, b, me2, 23); \
if (t > 22) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(d, e, a, b, c, me2, 22); \
if (t > 21) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(e, a, b, c, d, me2, 21); \
if (t > 20) HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, me2, 20); \
if (t > 19) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(b, c, d, e, a, me2, 19); \
if (t > 18) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(c, d, e, a, b, me2, 18); \
if (t > 17) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(d, e, a, b, c, me2, 17); \
if (t > 16) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(e, a, b, c, d, me2, 16); \
if (t > 15) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, me2, 15); \
if (t > 14) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(b, c, d, e, a, me2, 14); \
if (t > 13) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(c, d, e, a, b, me2, 13); \
if (t > 12) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(d, e, a, b, c, me2, 12); \
if (t > 11) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(e, a, b, c, d, me2, 11); \
if (t > 10) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, me2, 10); \
if (t > 9) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(b, c, d, e, a, me2, 9); \
if (t > 8) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(c, d, e, a, b, me2, 8); \
if (t > 7) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(d, e, a, b, c, me2, 7); \
if (t > 6) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(e, a, b, c, d, me2, 6); \
if (t > 5) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, me2, 5); \
if (t > 4) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(b, c, d, e, a, me2, 4); \
if (t > 3) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(c, d, e, a, b, me2, 3); \
if (t > 2) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(d, e, a, b, c, me2, 2); \
if (t > 1) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(e, a, b, c, d, me2, 1); \
if (t > 0) HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, me2, 0); \
ihvin[0] = a; ihvin[1] = b; ihvin[2] = c; ihvin[3] = d; ihvin[4] = e; \
a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; \
if (t <= 0) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, me2, 0); \
if (t <= 1) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, me2, 1); \
if (t <= 2) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, me2, 2); \
if (t <= 3) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, me2, 3); \
if (t <= 4) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, me2, 4); \
if (t <= 5) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, me2, 5); \
if (t <= 6) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, me2, 6); \
if (t <= 7) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, me2, 7); \
if (t <= 8) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, me2, 8); \
if (t <= 9) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, me2, 9); \
if (t <= 10) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, me2, 10); \
if (t <= 11) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, me2, 11); \
if (t <= 12) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, me2, 12); \
if (t <= 13) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, me2, 13); \
if (t <= 14) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, me2, 14); \
if (t <= 15) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, me2, 15); \
if (t <= 16) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, me2, 16); \
if (t <= 17) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, me2, 17); \
if (t <= 18) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, me2, 18); \
if (t <= 19) HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, me2, 19); \
if (t <= 20) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, me2, 20); \
if (t <= 21) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, me2, 21); \
if (t <= 22) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, me2, 22); \
if (t <= 23) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, me2, 23); \
if (t <= 24) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, me2, 24); \
if (t <= 25) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, me2, 25); \
if (t <= 26) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, me2, 26); \
if (t <= 27) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, me2, 27); \
if (t <= 28) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, me2, 28); \
if (t <= 29) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, me2, 29); \
if (t <= 30) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, me2, 30); \
if (t <= 31) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, me2, 31); \
if (t <= 32) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, me2, 32); \
if (t <= 33) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, me2, 33); \
if (t <= 34) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, me2, 34); \
if (t <= 35) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, me2, 35); \
if (t <= 36) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, me2, 36); \
if (t <= 37) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, me2, 37); \
if (t <= 38) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, me2, 38); \
if (t <= 39) HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, me2, 39); \
if (t <= 40) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, me2, 40); \
if (t <= 41) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, me2, 41); \
if (t <= 42) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, me2, 42); \
if (t <= 43) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, me2, 43); \
if (t <= 44) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, me2, 44); \
if (t <= 45) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, me2, 45); \
if (t <= 46) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, me2, 46); \
if (t <= 47) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, me2, 47); \
if (t <= 48) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, me2, 48); \
if (t <= 49) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, me2, 49); \
if (t <= 50) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, me2, 50); \
if (t <= 51) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, me2, 51); \
if (t <= 52) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, me2, 52); \
if (t <= 53) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, me2, 53); \
if (t <= 54) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, me2, 54); \
if (t <= 55) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, me2, 55); \
if (t <= 56) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, me2, 56); \
if (t <= 57) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, me2, 57); \
if (t <= 58) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, me2, 58); \
if (t <= 59) HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, me2, 59); \
if (t <= 60) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, me2, 60); \
if (t <= 61) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, me2, 61); \
if (t <= 62) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, me2, 62); \
if (t <= 63) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, me2, 63); \
if (t <= 64) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, me2, 64); \
if (t <= 65) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, me2, 65); \
if (t <= 66) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, me2, 66); \
if (t <= 67) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, me2, 67); \
if (t <= 68) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, me2, 68); \
if (t <= 69) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, me2, 69); \
if (t <= 70) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, me2, 70); \
if (t <= 71) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, me2, 71); \
if (t <= 72) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, me2, 72); \
if (t <= 73) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, me2, 73); \
if (t <= 74) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, me2, 74); \
if (t <= 75) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, me2, 75); \
if (t <= 76) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, me2, 76); \
if (t <= 77) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, me2, 77); \
if (t <= 78) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, me2, 78); \
if (t <= 79) HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, me2, 79); \
ihvout[0] = ihvin[0] + a; ihvout[1] = ihvin[1] + b; ihvout[2] = ihvin[2] + c; ihvout[3] = ihvin[3] + d; ihvout[4] = ihvin[4] + e; \
}
SHA1_RECOMPRESS(0)
SHA1_RECOMPRESS(1)
SHA1_RECOMPRESS(2)
SHA1_RECOMPRESS(3)
SHA1_RECOMPRESS(4)
SHA1_RECOMPRESS(5)
SHA1_RECOMPRESS(6)
SHA1_RECOMPRESS(7)
SHA1_RECOMPRESS(8)
SHA1_RECOMPRESS(9)
SHA1_RECOMPRESS(10)
SHA1_RECOMPRESS(11)
SHA1_RECOMPRESS(12)
SHA1_RECOMPRESS(13)
SHA1_RECOMPRESS(14)
SHA1_RECOMPRESS(15)
SHA1_RECOMPRESS(16)
SHA1_RECOMPRESS(17)
SHA1_RECOMPRESS(18)
SHA1_RECOMPRESS(19)
SHA1_RECOMPRESS(20)
SHA1_RECOMPRESS(21)
SHA1_RECOMPRESS(22)
SHA1_RECOMPRESS(23)
SHA1_RECOMPRESS(24)
SHA1_RECOMPRESS(25)
SHA1_RECOMPRESS(26)
SHA1_RECOMPRESS(27)
SHA1_RECOMPRESS(28)
SHA1_RECOMPRESS(29)
SHA1_RECOMPRESS(30)
SHA1_RECOMPRESS(31)
SHA1_RECOMPRESS(32)
SHA1_RECOMPRESS(33)
SHA1_RECOMPRESS(34)
SHA1_RECOMPRESS(35)
SHA1_RECOMPRESS(36)
SHA1_RECOMPRESS(37)
SHA1_RECOMPRESS(38)
SHA1_RECOMPRESS(39)
SHA1_RECOMPRESS(40)
SHA1_RECOMPRESS(41)
SHA1_RECOMPRESS(42)
SHA1_RECOMPRESS(43)
SHA1_RECOMPRESS(44)
SHA1_RECOMPRESS(45)
SHA1_RECOMPRESS(46)
SHA1_RECOMPRESS(47)
SHA1_RECOMPRESS(48)
SHA1_RECOMPRESS(49)
SHA1_RECOMPRESS(50)
SHA1_RECOMPRESS(51)
SHA1_RECOMPRESS(52)
SHA1_RECOMPRESS(53)
SHA1_RECOMPRESS(54)
SHA1_RECOMPRESS(55)
SHA1_RECOMPRESS(56)
SHA1_RECOMPRESS(57)
SHA1_RECOMPRESS(58)
SHA1_RECOMPRESS(59)
SHA1_RECOMPRESS(60)
SHA1_RECOMPRESS(61)
SHA1_RECOMPRESS(62)
SHA1_RECOMPRESS(63)
SHA1_RECOMPRESS(64)
SHA1_RECOMPRESS(65)
SHA1_RECOMPRESS(66)
SHA1_RECOMPRESS(67)
SHA1_RECOMPRESS(68)
SHA1_RECOMPRESS(69)
SHA1_RECOMPRESS(70)
SHA1_RECOMPRESS(71)
SHA1_RECOMPRESS(72)
SHA1_RECOMPRESS(73)
SHA1_RECOMPRESS(74)
SHA1_RECOMPRESS(75)
SHA1_RECOMPRESS(76)
SHA1_RECOMPRESS(77)
SHA1_RECOMPRESS(78)
SHA1_RECOMPRESS(79)
sha1_recompression_type sha1_recompression_step[80] =
{
sha1recompress_fast_0, sha1recompress_fast_1, sha1recompress_fast_2, sha1recompress_fast_3, sha1recompress_fast_4, sha1recompress_fast_5, sha1recompress_fast_6, sha1recompress_fast_7, sha1recompress_fast_8, sha1recompress_fast_9,
sha1recompress_fast_10, sha1recompress_fast_11, sha1recompress_fast_12, sha1recompress_fast_13, sha1recompress_fast_14, sha1recompress_fast_15, sha1recompress_fast_16, sha1recompress_fast_17, sha1recompress_fast_18, sha1recompress_fast_19,
sha1recompress_fast_20, sha1recompress_fast_21, sha1recompress_fast_22, sha1recompress_fast_23, sha1recompress_fast_24, sha1recompress_fast_25, sha1recompress_fast_26, sha1recompress_fast_27, sha1recompress_fast_28, sha1recompress_fast_29,
sha1recompress_fast_30, sha1recompress_fast_31, sha1recompress_fast_32, sha1recompress_fast_33, sha1recompress_fast_34, sha1recompress_fast_35, sha1recompress_fast_36, sha1recompress_fast_37, sha1recompress_fast_38, sha1recompress_fast_39,
sha1recompress_fast_40, sha1recompress_fast_41, sha1recompress_fast_42, sha1recompress_fast_43, sha1recompress_fast_44, sha1recompress_fast_45, sha1recompress_fast_46, sha1recompress_fast_47, sha1recompress_fast_48, sha1recompress_fast_49,
sha1recompress_fast_50, sha1recompress_fast_51, sha1recompress_fast_52, sha1recompress_fast_53, sha1recompress_fast_54, sha1recompress_fast_55, sha1recompress_fast_56, sha1recompress_fast_57, sha1recompress_fast_58, sha1recompress_fast_59,
sha1recompress_fast_60, sha1recompress_fast_61, sha1recompress_fast_62, sha1recompress_fast_63, sha1recompress_fast_64, sha1recompress_fast_65, sha1recompress_fast_66, sha1recompress_fast_67, sha1recompress_fast_68, sha1recompress_fast_69,
sha1recompress_fast_70, sha1recompress_fast_71, sha1recompress_fast_72, sha1recompress_fast_73, sha1recompress_fast_74, sha1recompress_fast_75, sha1recompress_fast_76, sha1recompress_fast_77, sha1recompress_fast_78, sha1recompress_fast_79,
};
void sha1_process(SHA1_CTX* ctx, const uint32_t block[16])
{
unsigned i, j;
uint32_t ubc_dv_mask[DVMASKSIZE];
uint32_t ihvtmp[5];
for (i=0; i < DVMASKSIZE; ++i)
ubc_dv_mask[i]=0;
ctx->ihv1[0] = ctx->ihv[0];
ctx->ihv1[1] = ctx->ihv[1];
ctx->ihv1[2] = ctx->ihv[2];
ctx->ihv1[3] = ctx->ihv[3];
ctx->ihv1[4] = ctx->ihv[4];
memcpy(ctx->m1, block, 64);
sha1_message_expansion(ctx->m1);
if (ctx->detect_coll && ctx->ubc_check)
{
ubc_check(ctx->m1, ubc_dv_mask);
}
sha1_compression_states(ctx->ihv, ctx->m1, ctx->states);
if (ctx->detect_coll)
{
for (i = 0; sha1_dvs[i].dvType != 0; ++i)
{
if ((0 == ctx->ubc_check) || (((uint32_t)(1) << sha1_dvs[i].maskb) & ubc_dv_mask[sha1_dvs[i].maski]))
{
for (j = 0; j < 80; ++j)
ctx->m2[j] = ctx->m1[j] ^ sha1_dvs[i].dm[j];
(sha1_recompression_step[sha1_dvs[i].testt])(ctx->ihv2, ihvtmp, ctx->m2, ctx->states[sha1_dvs[i].testt]);
/* to verify SHA-1 collision detection code with collisions for reduced-step SHA-1 */
if ((ihvtmp[0] == ctx->ihv[0] && ihvtmp[1] == ctx->ihv[1] && ihvtmp[2] == ctx->ihv[2] && ihvtmp[3] == ctx->ihv[3] && ihvtmp[4] == ctx->ihv[4])
|| (ctx->reduced_round_coll && ctx->ihv1[0] == ctx->ihv2[0] && ctx->ihv1[1] == ctx->ihv2[1] && ctx->ihv1[2] == ctx->ihv2[2] && ctx->ihv1[3] == ctx->ihv2[3] && ctx->ihv1[4] == ctx->ihv2[4]))
{
ctx->found_collision = 1;
/* TODO: call callback */
if (ctx->callback != NULL)
ctx->callback(ctx->total - 64, ctx->ihv1, ctx->ihv2, ctx->m1, ctx->m2);
if (ctx->safe_hash)
{
sha1_compression_W(ctx->ihv, ctx->m1);
sha1_compression_W(ctx->ihv, ctx->m1);
}
break;
}
}
}
}
}
void swap_bytes(uint32_t val[16])
{
unsigned i;
for (i = 0; i < 16; ++i)
{
val[i] = ((val[i] << 8) & 0xFF00FF00) | ((val[i] >> 8) & 0xFF00FF);
val[i] = (val[i] << 16) | (val[i] >> 16);
}
}
void SHA1DCInit(SHA1_CTX* ctx)
{
static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
static const uint32_t littleendian = 0x03020100;
ctx->total = 0;
ctx->ihv[0] = 0x67452301;
ctx->ihv[1] = 0xEFCDAB89;
ctx->ihv[2] = 0x98BADCFE;
ctx->ihv[3] = 0x10325476;
ctx->ihv[4] = 0xC3D2E1F0;
ctx->found_collision = 0;
ctx->safe_hash = 1;
ctx->ubc_check = 1;
ctx->detect_coll = 1;
ctx->reduced_round_coll = 0;
ctx->bigendian = (endianness.value != littleendian);
ctx->callback = NULL;
}
void SHA1DCSetSafeHash(SHA1_CTX* ctx, int safehash)
{
if (safehash)
ctx->safe_hash = 1;
else
ctx->safe_hash = 0;
}
void SHA1DCSetUseUBC(SHA1_CTX* ctx, int ubc_check)
{
if (ubc_check)
ctx->ubc_check = 1;
else
ctx->ubc_check = 0;
}
void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll)
{
if (detect_coll)
ctx->detect_coll = 1;
else
ctx->detect_coll = 0;
}
void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX* ctx, int reduced_round_coll)
{
if (reduced_round_coll)
ctx->reduced_round_coll = 1;
else
ctx->reduced_round_coll = 0;
}
void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback)
{
ctx->callback = callback;
}
void SHA1DCUpdate(SHA1_CTX* ctx, const unsigned char* buf, unsigned len)
{
unsigned left, fill;
if (len == 0)
return;
left = ctx->total & 63;
fill = 64 - left;
if (left && len >= fill)
{
ctx->total += fill;
memcpy(ctx->buffer + left, buf, fill);
if (!ctx->bigendian)
swap_bytes((uint32_t*)(ctx->buffer));
sha1_process(ctx, (uint32_t*)(ctx->buffer));
buf += fill;
len -= fill;
left = 0;
}
while (len >= 64)
{
ctx->total += 64;
if (!ctx->bigendian)
{
memcpy(ctx->buffer, buf, 64);
swap_bytes((uint32_t*)(ctx->buffer));
sha1_process(ctx, (uint32_t*)(ctx->buffer));
}
else
sha1_process(ctx, (uint32_t*)(buf));
buf += 64;
len -= 64;
}
if (len > 0)
{
ctx->total += len;
memcpy(ctx->buffer + left, buf, len);
}
}
static const unsigned char sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int SHA1DCFinal(unsigned char output[20], SHA1_CTX *ctx)
{
uint32_t last = ctx->total & 63;
uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
uint64_t total;
SHA1DCUpdate(ctx, sha1_padding, padn);
total = ctx->total - padn;
total <<= 3;
ctx->buffer[56] = (unsigned char)(total >> 56);
ctx->buffer[57] = (unsigned char)(total >> 48);
ctx->buffer[58] = (unsigned char)(total >> 40);
ctx->buffer[59] = (unsigned char)(total >> 32);
ctx->buffer[60] = (unsigned char)(total >> 24);
ctx->buffer[61] = (unsigned char)(total >> 16);
ctx->buffer[62] = (unsigned char)(total >> 8);
ctx->buffer[63] = (unsigned char)(total);
if (!ctx->bigendian)
swap_bytes((uint32_t*)(ctx->buffer));
sha1_process(ctx, (uint32_t*)(ctx->buffer));
output[0] = (unsigned char)(ctx->ihv[0] >> 24);
output[1] = (unsigned char)(ctx->ihv[0] >> 16);
output[2] = (unsigned char)(ctx->ihv[0] >> 8);
output[3] = (unsigned char)(ctx->ihv[0]);
output[4] = (unsigned char)(ctx->ihv[1] >> 24);
output[5] = (unsigned char)(ctx->ihv[1] >> 16);
output[6] = (unsigned char)(ctx->ihv[1] >> 8);
output[7] = (unsigned char)(ctx->ihv[1]);
output[8] = (unsigned char)(ctx->ihv[2] >> 24);
output[9] = (unsigned char)(ctx->ihv[2] >> 16);
output[10] = (unsigned char)(ctx->ihv[2] >> 8);
output[11] = (unsigned char)(ctx->ihv[2]);
output[12] = (unsigned char)(ctx->ihv[3] >> 24);
output[13] = (unsigned char)(ctx->ihv[3] >> 16);
output[14] = (unsigned char)(ctx->ihv[3] >> 8);
output[15] = (unsigned char)(ctx->ihv[3]);
output[16] = (unsigned char)(ctx->ihv[4] >> 24);
output[17] = (unsigned char)(ctx->ihv[4] >> 16);
output[18] = (unsigned char)(ctx->ihv[4] >> 8);
output[19] = (unsigned char)(ctx->ihv[4]);
return ctx->found_collision;
}
#endif /* FOSSIL_HARDENED_SHA1 */
|
Added src/sha3.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
/*
** Copyright (c) 2017 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains an implementation of SHA3 (Keccak) hashing.
*/
#include "config.h"
#include "sha3.h"
/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
#ifndef SHA3_BYTEORDER
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__)
# define SHA3_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__)
# define SHA3_BYTEORDER 4321
# else
# define SHA3_BYTEORDER 0
# endif
#endif
/*
** State structure for a SHA3 hash in progress
*/
typedef struct SHA3Context SHA3Context;
struct SHA3Context {
union {
u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
unsigned char x[1600]; /* ... or 1600 bytes */
} u;
unsigned nRate; /* Bytes of input accepted per Keccak iteration */
unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
};
/*
** A single step of the Keccak mixing function for a 1600-bit state
*/
static void KeccakF1600Step(SHA3Context *p){
int i;
u64 B0, B1, B2, B3, B4;
u64 C0, C1, C2, C3, C4;
u64 D0, D1, D2, D3, D4;
static const u64 RC[] = {
0x0000000000000001ULL, 0x0000000000008082ULL,
0x800000000000808aULL, 0x8000000080008000ULL,
0x000000000000808bULL, 0x0000000080000001ULL,
0x8000000080008081ULL, 0x8000000000008009ULL,
0x000000000000008aULL, 0x0000000000000088ULL,
0x0000000080008009ULL, 0x000000008000000aULL,
0x000000008000808bULL, 0x800000000000008bULL,
0x8000000000008089ULL, 0x8000000000008003ULL,
0x8000000000008002ULL, 0x8000000000000080ULL,
0x000000000000800aULL, 0x800000008000000aULL,
0x8000000080008081ULL, 0x8000000000008080ULL,
0x0000000080000001ULL, 0x8000000080008008ULL
};
# define A00 (p->u.s[0])
# define A01 (p->u.s[1])
# define A02 (p->u.s[2])
# define A03 (p->u.s[3])
# define A04 (p->u.s[4])
# define A10 (p->u.s[5])
# define A11 (p->u.s[6])
# define A12 (p->u.s[7])
# define A13 (p->u.s[8])
# define A14 (p->u.s[9])
# define A20 (p->u.s[10])
# define A21 (p->u.s[11])
# define A22 (p->u.s[12])
# define A23 (p->u.s[13])
# define A24 (p->u.s[14])
# define A30 (p->u.s[15])
# define A31 (p->u.s[16])
# define A32 (p->u.s[17])
# define A33 (p->u.s[18])
# define A34 (p->u.s[19])
# define A40 (p->u.s[20])
# define A41 (p->u.s[21])
# define A42 (p->u.s[22])
# define A43 (p->u.s[23])
# define A44 (p->u.s[24])
# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
for(i=0; i<24; i+=4){
C0 = A00^A10^A20^A30^A40;
C1 = A01^A11^A21^A31^A41;
C2 = A02^A12^A22^A32^A42;
C3 = A03^A13^A23^A33^A43;
C4 = A04^A14^A24^A34^A44;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A11^D1), 44);
B2 = ROL64((A22^D2), 43);
B3 = ROL64((A33^D3), 21);
B4 = ROL64((A44^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i];
A11 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B2 = ROL64((A20^D0), 3);
B3 = ROL64((A31^D1), 45);
B4 = ROL64((A42^D2), 61);
B0 = ROL64((A03^D3), 28);
B1 = ROL64((A14^D4), 20);
A20 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A40^D0), 18);
B0 = ROL64((A01^D1), 1);
B1 = ROL64((A12^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A34^D4), 8);
A40 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B1 = ROL64((A10^D0), 36);
B2 = ROL64((A21^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A43^D3), 56);
B0 = ROL64((A04^D4), 27);
A10 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B3 = ROL64((A30^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A02^D2), 62);
B1 = ROL64((A13^D3), 55);
B2 = ROL64((A24^D4), 39);
A30 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
C0 = A00^A20^A40^A10^A30;
C1 = A11^A31^A01^A21^A41;
C2 = A22^A42^A12^A32^A02;
C3 = A33^A03^A23^A43^A13;
C4 = A44^A14^A34^A04^A24;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A31^D1), 44);
B2 = ROL64((A12^D2), 43);
B3 = ROL64((A43^D3), 21);
B4 = ROL64((A24^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+1];
A31 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B2 = ROL64((A40^D0), 3);
B3 = ROL64((A21^D1), 45);
B4 = ROL64((A02^D2), 61);
B0 = ROL64((A33^D3), 28);
B1 = ROL64((A14^D4), 20);
A40 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A30^D0), 18);
B0 = ROL64((A11^D1), 1);
B1 = ROL64((A42^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A04^D4), 8);
A30 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B1 = ROL64((A20^D0), 36);
B2 = ROL64((A01^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A13^D3), 56);
B0 = ROL64((A44^D4), 27);
A20 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B3 = ROL64((A10^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A22^D2), 62);
B1 = ROL64((A03^D3), 55);
B2 = ROL64((A34^D4), 39);
A10 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
C0 = A00^A40^A30^A20^A10;
C1 = A31^A21^A11^A01^A41;
C2 = A12^A02^A42^A32^A22;
C3 = A43^A33^A23^A13^A03;
C4 = A24^A14^A04^A44^A34;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A21^D1), 44);
B2 = ROL64((A42^D2), 43);
B3 = ROL64((A13^D3), 21);
B4 = ROL64((A34^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+2];
A21 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B2 = ROL64((A30^D0), 3);
B3 = ROL64((A01^D1), 45);
B4 = ROL64((A22^D2), 61);
B0 = ROL64((A43^D3), 28);
B1 = ROL64((A14^D4), 20);
A30 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A10^D0), 18);
B0 = ROL64((A31^D1), 1);
B1 = ROL64((A02^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A44^D4), 8);
A10 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B1 = ROL64((A40^D0), 36);
B2 = ROL64((A11^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A03^D3), 56);
B0 = ROL64((A24^D4), 27);
A40 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B3 = ROL64((A20^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A12^D2), 62);
B1 = ROL64((A33^D3), 55);
B2 = ROL64((A04^D4), 39);
A20 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
C0 = A00^A30^A10^A40^A20;
C1 = A21^A01^A31^A11^A41;
C2 = A42^A22^A02^A32^A12;
C3 = A13^A43^A23^A03^A33;
C4 = A34^A14^A44^A24^A04;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A01^D1), 44);
B2 = ROL64((A02^D2), 43);
B3 = ROL64((A03^D3), 21);
B4 = ROL64((A04^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+3];
A01 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B2 = ROL64((A10^D0), 3);
B3 = ROL64((A11^D1), 45);
B4 = ROL64((A12^D2), 61);
B0 = ROL64((A13^D3), 28);
B1 = ROL64((A14^D4), 20);
A10 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A20^D0), 18);
B0 = ROL64((A21^D1), 1);
B1 = ROL64((A22^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A24^D4), 8);
A20 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B1 = ROL64((A30^D0), 36);
B2 = ROL64((A31^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A33^D3), 56);
B0 = ROL64((A34^D4), 27);
A30 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B3 = ROL64((A40^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A42^D2), 62);
B1 = ROL64((A43^D3), 55);
B2 = ROL64((A44^D4), 39);
A40 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
}
}
/*
** Initialize a new hash. iSize determines the size of the hash
** in bits and should be one of 224, 256, 384, or 512. Or iSize
** can be zero to use the default hash size of 224 bits.
*/
static void SHA3Init(SHA3Context *p, int iSize){
memset(p, 0, sizeof(*p));
if( iSize>=128 && iSize<=512 ){
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
}else{
p->nRate = 144;
}
#if SHA3_BYTEORDER==1234
/* Known to be little-endian at compile-time. No-op */
#elif SHA3_BYTEORDER==4321
p->ixMask = 7; /* Big-endian */
#else
{
static unsigned int one = 1;
if( 1==*(unsigned char*)&one ){
/* Little endian. No byte swapping. */
p->ixMask = 0;
}else{
/* Big endian. Byte swap. */
p->ixMask = 7;
}
}
#endif
}
/*
** Make consecutive calls to the SHA3Update function to add new content
** to the hash
*/
static void SHA3Update(
SHA3Context *p,
const unsigned char *aData,
unsigned int nData
){
unsigned int i = 0;
#if SHA3_BYTEORDER==1234
if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
for(; i+7<nData; i+=8){
p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
p->nLoaded += 8;
if( p->nLoaded>=p->nRate ){
KeccakF1600Step(p);
p->nLoaded = 0;
}
}
}
#endif
for(; i<nData; i++){
#if SHA1_BYTEORDER==1234
p->u.x[p->nLoaded] ^= aData[i];
#elif SHA3_BYTEORDER==4321
p->u.x[p->nLoaded^0x07] ^= aData[i];
#else
p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
#endif
p->nLoaded++;
if( p->nLoaded==p->nRate ){
KeccakF1600Step(p);
p->nLoaded = 0;
}
}
}
/*
** After all content has been added, invoke SHA3Final() to compute
** the final hash. The function returns a pointer to the binary
** hash value.
*/
static unsigned char *SHA3Final(SHA3Context *p){
unsigned int i;
if( p->nLoaded==p->nRate-1 ){
const unsigned char c1 = 0x86;
SHA3Update(p, &c1, 1);
}else{
const unsigned char c2 = 0x06;
const unsigned char c3 = 0x80;
SHA3Update(p, &c2, 1);
p->nLoaded = p->nRate - 1;
SHA3Update(p, &c3, 1);
}
for(i=0; i<p->nRate; i++){
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
}
return &p->u.x[p->nRate];
}
/*
** Convert a digest into base-16. digest should be declared as
** "unsigned char digest[20]" in the calling function. The SHA3
** digest is stored in the first 20 bytes. zBuf should
** be "char zBuf[41]".
*/
static void DigestToBase16(unsigned char *digest, char *zBuf, int nByte){
static const char zEncode[] = "0123456789abcdef";
int ix;
for(ix=0; ix<nByte; ix++){
*zBuf++ = zEncode[(*digest>>4)&0xf];
*zBuf++ = zEncode[*digest++ & 0xf];
}
*zBuf = '\0';
}
/*
** The state of a incremental SHA3 checksum computation. Only one
** such computation can be underway at a time, of course.
*/
static SHA3Context incrCtx;
static int incrInit = 0;
/*
** Initialize a new global SHA3 hash.
*/
void sha3sum_init(int iSize){
assert( incrInit==0 );
incrInit = iSize;
SHA3Init(&incrCtx, incrInit);
}
/*
** Add more text to the incremental SHA3 checksum.
*/
void sha3sum_step_text(const char *zText, int nBytes){
assert( incrInit );
if( nBytes<=0 ){
if( nBytes==0 ) return;
nBytes = strlen(zText);
}
SHA3Update(&incrCtx, (unsigned char*)zText, nBytes);
}
/*
** Add the content of a blob to the incremental SHA3 checksum.
*/
void sha3sum_step_blob(Blob *p){
assert( incrInit );
SHA3Update(&incrCtx, (unsigned char*)blob_buffer(p), blob_size(p));
}
/*
** Finish the incremental SHA3 checksum. Store the result in blob pOut
** if pOut!=0. Also return a pointer to the result.
**
** This resets the incremental checksum preparing for the next round
** of computation. The return pointer points to a static buffer that
** is overwritten by subsequent calls to this function.
*/
char *sha3sum_finish(Blob *pOut){
static char zOut[132];
DigestToBase16(SHA3Final(&incrCtx), zOut, incrInit/8);
if( pOut ){
blob_zero(pOut);
blob_append(pOut, zOut, incrInit/4);
}
incrInit = 0;
return zOut;
}
/*
** Compute the SHA3 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 sha3sum_file(const char *zFilename, int iSize, Blob *pCksum){
FILE *in;
SHA3Context ctx;
char zBuf[10240];
if( file_wd_islink(zFilename) ){
/* Instead of file content, return sha3 of link destination path */
Blob destinationPath;
int rc;
blob_read_link(&destinationPath, zFilename);
rc = sha3sum_blob(&destinationPath, iSize, pCksum);
blob_reset(&destinationPath);
return rc;
}
in = fossil_fopen(zFilename,"rb");
if( in==0 ){
return 1;
}
SHA3Init(&ctx, iSize);
for(;;){
int n;
n = fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
SHA3Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
fclose(in);
blob_zero(pCksum);
blob_resize(pCksum, iSize/4);
DigestToBase16(SHA3Final(&ctx), blob_buffer(pCksum), iSize/8);
return 0;
}
/*
** Compute the SHA3 checksum of a blob in memory. Store the resulting
** checksum in the blob pCksum. pCksum is assumed to be either
** uninitialized or the same blob as pIn.
**
** Return the number of errors.
*/
int sha3sum_blob(const Blob *pIn, int iSize, Blob *pCksum){
SHA3Context ctx;
SHA3Init(&ctx, iSize);
SHA3Update(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn));
if( pIn==pCksum ){
blob_reset(pCksum);
}else{
blob_zero(pCksum);
}
blob_resize(pCksum, iSize/4);
DigestToBase16(SHA3Final(&ctx), blob_buffer(pCksum), iSize/8);
return 0;
}
/*
** Compute the SHA3 checksum of a zero-terminated string. The
** result is held in memory obtained from mprintf().
*/
char *sha3sum(const char *zIn, int iSize){
SHA3Context ctx;
char zDigest[132];
SHA3Init(&ctx, iSize);
SHA3Update(&ctx, (unsigned const char*)zIn, strlen(zIn));
DigestToBase16(SHA3Final(&ctx), zDigest, iSize/4);
return mprintf("%s", zDigest);
}
/*
** COMMAND: sha3sum*
**
** Usage: %fossil sha3sum FILE...
**
** Compute an SHA3 checksum of all files named on the command-line.
** If a file is named "-" then take its content from standard input.
**
** Options:
**
** --224 Compute a SHA3-224 hash
** --256 Compute a SHA3-256 hash (the default)
** --384 Compute a SHA3-384 hash
** --512 Compute a SHA3-512 hash
** --size N An N-bit hash. N must be a multiple of 32 between 128
** and 512.
*/
void sha3sum_test(void){
int i;
Blob in;
Blob cksum;
int iSize = 256;
if( find_option("224",0,0)!=0 ) iSize = 224;
else if( find_option("256",0,0)!=0 ) iSize = 256;
else if( find_option("384",0,0)!=0 ) iSize = 384;
else if( find_option("512",0,0)!=0 ) iSize = 512;
else{
const char *zN = find_option("size",0,1);
if( zN!=0 ){
int n = atoi(zN);
if( n%32!=0 || n<128 || n>512 ){
fossil_fatal("--size must be a multiple of 64 between 128 and 512");
}
iSize = n;
}
}
verify_all_options();
for(i=2; i<g.argc; i++){
blob_init(&cksum, "************** not found ***************", -1);
if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){
blob_read_from_channel(&in, stdin, -1);
sha3sum_blob(&in, iSize, &cksum);
}else{
sha3sum_file(g.argv[i], iSize, &cksum);
}
fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]);
blob_reset(&cksum);
}
}
|
Changes to src/shell.c.
| ︙ | ︙ | |||
2208 2209 2210 2211 2212 2213 2214 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " ascii Columns/rows delimited by 0x1F and 0x1E\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" " html HTML <table> code\n" " insert SQL insert statements for TABLE\n" " line One value per line\n" | | | 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " ascii Columns/rows delimited by 0x1F and 0x1E\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" " html HTML <table> code\n" " insert SQL insert statements for TABLE\n" " line One value per line\n" " list Values delimited by \"|\"\n" " quote Escape answers as for SQL\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" ".nullvalue STRING Use STRING in place of NULL values\n" ".once FILENAME Output for the next SQL command only to FILENAME\n" ".open ?--new? ?FILE? Close existing database and reopen FILE\n" " The --new starts with an empty file\n" |
| ︙ | ︙ | |||
4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 |
char *zNewFilename; /* Name of the database file to open */
int iName = 1; /* Index in azArg[] of the filename */
int newFlag = 0; /* True to delete file before opening */
/* Close the existing database */
session_close_all(p);
sqlite3_close(p->db);
p->db = 0;
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = 0;
/* Check for command-line arguments */
for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
const char *z = azArg[iName];
if( optionMatch(z,"new") ){
newFlag = 1;
| > | 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 |
char *zNewFilename; /* Name of the database file to open */
int iName = 1; /* Index in azArg[] of the filename */
int newFlag = 0; /* True to delete file before opening */
/* Close the existing database */
session_close_all(p);
sqlite3_close(p->db);
p->db = 0;
p->zDbFilename = 0;
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = 0;
/* Check for command-line arguments */
for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
const char *z = azArg[iName];
if( optionMatch(z,"new") ){
newFlag = 1;
|
| ︙ | ︙ | |||
4610 4611 4612 4613 4614 4615 4616 |
}else{
rc = 0;
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
| | | 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 |
}else{
rc = 0;
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
sqlite3SelectTrace = (int)integerValue(azArg[1]);
}else
#endif
#if defined(SQLITE_ENABLE_SESSION)
if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
OpenSession *pSession = &p->aSession[0];
char **azCmd = &azArg[1];
|
| ︙ | ︙ | |||
5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 |
utf8_printf(stderr,
"Error: CLI support for testctrl %s not implemented\n",
azArg[1]);
break;
}
}
}else
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
open_db(p, 0);
sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
}else
if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
| > | 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 |
utf8_printf(stderr,
"Error: CLI support for testctrl %s not implemented\n",
azArg[1]);
break;
}
}
}else
#endif /* !defined(SQLITE_UNTESTABLE) */
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
open_db(p, 0);
sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
}else
if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
|
| ︙ | ︙ | |||
5224 5225 5226 5227 5228 5229 5230 |
if( p->traceOut==0 ){
sqlite3_trace_v2(p->db, 0, 0, 0);
}else{
sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
}
#endif
}else
| < | 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 |
if( p->traceOut==0 ){
sqlite3_trace_v2(p->db, 0, 0, 0);
}else{
sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
}
#endif
}else
#if SQLITE_USER_AUTHENTICATION
if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
if( nArg<2 ){
raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
rc = 1;
goto meta_command_exit;
|
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
/*
** Return true if the given artifact ID should be shunned.
*/
int uuid_is_shunned(const char *zUuid){
static Stmt q;
int rc;
if( zUuid==0 || zUuid[0]==0 ) return 0;
db_static_prepare(&q, "SELECT 1 FROM shun WHERE uuid=:uuid");
db_bind_text(&q, ":uuid", zUuid);
rc = db_step(&q);
db_reset(&q);
return rc==SQLITE_ROW;
}
/*
** WEBPAGE: shun
**
| > | | 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 |
/*
** Return true if the given artifact ID should be shunned.
*/
int uuid_is_shunned(const char *zUuid){
static Stmt q;
int rc;
if( zUuid==0 || zUuid[0]==0 ) return 0;
if( g.eHashPolicy==HPOLICY_SHUN_SHA1 && zUuid[HNAME_LEN_SHA1]==0 ) return 1;
db_static_prepare(&q, "SELECT 1 FROM shun WHERE uuid=:uuid");
db_bind_text(&q, ":uuid", zUuid);
rc = db_step(&q);
db_reset(&q);
return rc==SQLITE_ROW;
}
/*
** WEBPAGE: shun
**
** View the hashes of all shunned artifacts. Add new hashes
** to the shun set. Requires Admin privilege.
*/
void shun_page(void){
Stmt q;
int cnt = 0;
const char *zUuid = P("uuid");
const char *zShun = P("shun");
|
| ︙ | ︙ | |||
82 83 84 85 86 87 88 |
}
i++;
}
zCanonical[j+1] = zCanonical[j] = 0;
p = zCanonical;
while( *p ){
int nUuid = strlen(p);
| | | | | | | | 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 |
}
i++;
}
zCanonical[j+1] = zCanonical[j] = 0;
p = zCanonical;
while( *p ){
int nUuid = strlen(p);
if( !hname_validate(p, nUuid) ){
@ <p class="generalError">Error: Bad artifact IDs.</p>
fossil_free(zCanonical);
zCanonical = 0;
break;
}else{
canonical16(p, nUuid);
p += nUuid+1;
}
}
zUuid = zCanonical;
}
style_header("Shunned Artifacts");
if( zUuid && P("sub") ){
const char *p = zUuid;
int allExist = 1;
login_verify_csrf_secret();
while( *p ){
db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
allExist = 0;
}
admin_log("Unshunned %Q", p);
p += strlen(p)+1;
}
if( allExist ){
@ <p class="noMoreShun">Artifact(s)<br />
for( p = zUuid ; *p ; p += strlen(p)+1 ){
@ <a href="%R/artifact/%s(p)">%s(p)</a><br />
}
@ are no longer being shunned.</p>
}else{
@ <p class="noMoreShun">Artifact(s)<br />
for( p = zUuid ; *p ; p += strlen(p)+1 ){
@ %s(p)<br />
}
@ will no longer be shunned. But they may not exist in the repository.
@ It may be necessary to rebuild the repository using the
@ <b>fossil rebuild</b> command-line before the artifact content
@ can pulled in from other repositories.</p>
}
|
| ︙ | ︙ | |||
144 145 146 147 148 149 150 |
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
if( tagid ){
db_multi_exec("DELETE FROM ticket WHERE tkt_uuid=%Q", p);
db_multi_exec("DELETE FROM tag WHERE tagid=%d", tagid);
db_multi_exec("DELETE FROM tagxref WHERE tagid=%d", tagid);
}
admin_log("Shunned %Q", p);
| | | | | | | | 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 |
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
if( tagid ){
db_multi_exec("DELETE FROM ticket WHERE tkt_uuid=%Q", p);
db_multi_exec("DELETE FROM tag WHERE tagid=%d", tagid);
db_multi_exec("DELETE FROM tagxref WHERE tagid=%d", tagid);
}
admin_log("Shunned %Q", p);
p += strlen(p)+1;
}
@ <p class="shunned">Artifact(s)<br />
for( p = zUuid ; *p ; p += strlen(p)+1 ){
@ <a href="%R/artifact/%s(p)">%s(p)</a><br />
}
@ have been shunned. They will no longer be pushed.
@ They will be removed from the repository the next time the repository
@ is rebuilt using the <b>fossil rebuild</b> command-line</p>
}
if( zRcvid ){
nRcvid = atoi(zRcvid);
numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
nRcvid);
}
@ <p>A shunned artifact will not be pushed nor accepted in a pull and the
@ artifact content will be purged from the repository the next time the
@ repository is rebuilt. A list of shunned artifacts can be seen at the
@ bottom of this page.</p>
@
@ <a name="addshun"></a>
@ <p>To shun artifacts, enter their artifact hashes (the 40- or
@ 64-character lowercase hexadecimal hash of the artifact content) in the
@ following box and press the "Shun" button. This will cause the artifacts
@ to be removed from the repository and will prevent the artifacts from being
@ readded to the repository by subsequent sync operation.</p>
@
@ <p>Note that you must enter the full 40- or 64-character artifact hashes,
@ not an abbreviation or a symbolic tag.</p>
@
@ <p>Warning: Shunning should only be used to remove inappropriate content
@ from the repository. Inappropriate content includes such things as
@ spam added to Wiki, files that violate copyright or patent agreements,
@ or artifacts that by design or accident interfere with the processing
@ of the repository. Do not shun artifacts merely to remove them from
@ sight - set the "hidden" tag on such artifacts instead.</p>
|
| ︙ | ︙ |
Changes to src/sitemap.c.
| ︙ | ︙ | |||
109 110 111 112 113 114 115 |
if( srchFlags ){
@ <li>%z(href("%R/search"))Full-Text Search</a></li>
}
@ <li>%z(href("%R/login"))Login/Logout/Change Password</a></li>
if( g.perm.Read ){
@ <li>%z(href("%R/stat"))Repository Status</a>
@ <ul>
| | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
if( srchFlags ){
@ <li>%z(href("%R/search"))Full-Text Search</a></li>
}
@ <li>%z(href("%R/login"))Login/Logout/Change Password</a></li>
if( g.perm.Read ){
@ <li>%z(href("%R/stat"))Repository Status</a>
@ <ul>
@ <li>%z(href("%R/hash-collisions"))Collisions on hash prefixes</a></li>
if( g.perm.Admin ){
@ <li>%z(href("%R/urllist"))List of URLs used to access
@ this repository</a></li>
}
@ <li>%z(href("%R/bloblist"))List of Artifacts</a></li>
@ <li>%z(href("%R/timewarps"))List of "Timewarp" Check-ins</a></li>
@ </ul>
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
183 184 185 186 187 188 189 | ** ** WARNING: Careless use of this command can corrupt a Fossil repository ** in ways that are unrecoverable. Be sure you know what you are doing before ** running any SQL commands that modify the repository database. ** ** The following extensions to the usual SQLite commands are provided: ** | | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | ** ** WARNING: Careless use of this command can corrupt a Fossil repository ** in ways that are unrecoverable. Be sure you know what you are doing before ** running any SQL commands that modify the repository database. ** ** The following extensions to the usual SQLite commands are provided: ** ** content(X) Return the content of artifact X. X can be an ** artifact hash or prefix or a tag. ** ** compress(X) Compress text X. ** ** decompress(X) Decompress text X. Undoes the work of ** compress(X). ** ** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID) |
| ︙ | ︙ |
Changes to src/stash.c.
| ︙ | ︙ | |||
330 331 332 333 334 335 336 |
diff_print_index(zNew, diffFlags);
isBin1 = 0;
isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd,
zBinGlob, fIncludeBinary, diffFlags);
}else if( isRemoved ){
fossil_print("DELETE %s\n", zOrig);
| > > | < < < < < < < < | < | | | > > | < < < < < < < < | > | | > > > > > > < | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
diff_print_index(zNew, diffFlags);
isBin1 = 0;
isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd,
zBinGlob, fIncludeBinary, diffFlags);
}else if( isRemoved ){
fossil_print("DELETE %s\n", zOrig);
diff_print_index(zNew, diffFlags);
isBin2 = 0;
if( fBaseline ){
content_get(rid, &a);
isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
zBinGlob, fIncludeBinary, diffFlags);
}else{
}
}else{
Blob delta;
int isOrigLink = file_wd_islink(zOPath);
db_ephemeral_blob(&q, 6, &delta);
fossil_print("CHANGED %s\n", zNew);
if( !isOrigLink != !isLink ){
diff_print_index(zNew, diffFlags);
diff_print_filenames(zOrig, zNew, diffFlags);
printf(DIFF_CANNOT_COMPUTE_SYMLINK);
}else{
content_get(rid, &a);
blob_delta_apply(&a, &delta, &b);
isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
isBin2 = fIncludeBinary ? 0 : looks_like_binary(&b);
if( fBaseline ){
diff_file_mem(&a, &b, isBin1, isBin2, zNew,
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
}else{
/*Diff with file on disk using fSwapDiff=1 to show the diff in the
same direction as if fBaseline=1.*/
diff_file(&b, isBin2, zOPath, zNew, zDiffCmd,
zBinGlob, fIncludeBinary, diffFlags, 1);
}
blob_reset(&a);
blob_reset(&b);
}
blob_reset(&delta);
}
}
db_finalize(&q);
}
/*
|
| ︙ | ︙ | |||
431 432 433 434 435 436 437 438 | ** ** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>? ** ** List all changes sets currently stashed. Show information about ** individual files in each changeset if -v or --verbose is used. ** ** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS? ** | > | > > | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | ** ** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>? ** ** List all changes sets currently stashed. Show information about ** individual files in each changeset if -v or --verbose is used. ** ** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS? ** fossil stash gshow|gcat ?STASHID? ?DIFF-OPTIONS? ** ** Show the contents of a stash as a diff against it's baseline. ** With gshow and gcat, gdiff-command is used instead of internal ** diff logic. ** ** fossil stash pop ** fossil stash apply ?STASHID? ** ** Apply STASHID or the most recently create stash to the current ** working checkout. The "pop" command deletes that changeset from ** the stash after applying it but the "apply" command retains the |
| ︙ | ︙ | |||
458 459 460 461 462 463 464 | ** -a|--all flag is used. Individual drops are undoable but -a|--all ** is not. ** ** fossil stash diff ?STASHID? ?DIFF-OPTIONS? ** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS? ** ** Show diffs of the current working directory and what that | | > > | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
** -a|--all flag is used. Individual drops are undoable but -a|--all
** is not.
**
** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
**
** Show diffs of the current working directory and what that
** directory would be if STASHID were applied. With gdiff,
** gdiff-command is used instead of internal diff logic.
**
** SUMMARY:
** fossil stash
** fossil stash save ?-m|--comment COMMENT? ?FILES...?
** fossil stash snapshot ?-m|--comment COMMENT? ?FILES...?
** fossil stash list|ls ?-v|--verbose? ?-W|--width <num>?
** fossil stash show|cat ?STASHID? ?DIFF-OPTIONS?
** fossil stash gshow|gcat ?STASHID? ?DIFF-OPTIONS?
** fossil stash pop
** fossil stash apply|goto ?STASHID?
** fossil stash drop|rm ?STASHID? ?-a|--all?
** fossil stash diff ?STASHID? ?DIFF-OPTIONS?
** fossil stash gdiff ?STASHID? ?DIFF-OPTIONS?
*/
void stash_cmd(void){
|
| ︙ | ︙ | |||
652 653 654 655 656 657 658 659 660 661 662 663 |
"(SELECT origname FROM stashfile WHERE stashid=%d)",
stashid);
undo_finish();
}else
if( memcmp(zCmd, "diff", nCmd)==0
|| memcmp(zCmd, "gdiff", nCmd)==0
|| memcmp(zCmd, "show", nCmd)==0
|| memcmp(zCmd, "cat", nCmd)==0
){
const char *zDiffCmd = 0;
const char *zBinGlob = 0;
int fIncludeBinary = 0;
| > > | > > > | | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 |
"(SELECT origname FROM stashfile WHERE stashid=%d)",
stashid);
undo_finish();
}else
if( memcmp(zCmd, "diff", nCmd)==0
|| memcmp(zCmd, "gdiff", nCmd)==0
|| memcmp(zCmd, "show", nCmd)==0
|| memcmp(zCmd, "gshow", nCmd)==0
|| memcmp(zCmd, "cat", nCmd)==0
|| memcmp(zCmd, "gcat", nCmd)==0
){
const char *zDiffCmd = 0;
const char *zBinGlob = 0;
int fIncludeBinary = 0;
int fBaseline = 0;
u64 diffFlags;
if( strstr(zCmd,"show")!=0 || strstr(zCmd,"cat")!=0 ){
fBaseline = 1;
}
if( find_option("tk",0,0)!=0 ){
db_close(0);
diff_tk(fBaseline ? "stash show" : "stash diff", 3);
return;
}
if( find_option("internal","i",0)==0 ){
zDiffCmd = diff_command_external(zCmd[0]=='g');
}
diffFlags = diff_options();
if( find_option("verbose","v",0)!=0 ) diffFlags |= DIFF_VERBOSE;
if( g.argc>4 ) usage(mprintf("%s ?STASHID? ?DIFF-OPTIONS?", zCmd));
if( zDiffCmd ){
zBinGlob = diff_get_binary_glob();
fIncludeBinary = diff_include_binary_files();
|
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
74 75 76 77 78 79 80 |
style_adunit_config(ADUNIT_RIGHT_OK);
if( g.perm.Admin ){
style_submenu_element("URLs", "urllist");
style_submenu_element("Schema", "repo_schema");
style_submenu_element("Web-Cache", "cachestat");
}
style_submenu_element("Activity Reports", "reports");
| | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
style_adunit_config(ADUNIT_RIGHT_OK);
if( g.perm.Admin ){
style_submenu_element("URLs", "urllist");
style_submenu_element("Schema", "repo_schema");
style_submenu_element("Web-Cache", "cachestat");
}
style_submenu_element("Activity Reports", "reports");
style_submenu_element("Hash Collisions", "hash-collisions");
if( sqlite3_compileoption_used("ENABLE_DBSTAT_VTAB") ){
style_submenu_element("Table Sizes", "repo-tabsize");
}
if( g.perm.Admin || g.perm.Setup || db_get_boolean("test_env_enable",0) ){
style_submenu_element("Environment", "test_env");
}
@ <table class="label-value">
|
| ︙ | ︙ | |||
181 182 183 184 185 186 187 | @ <tr><th>Fossil Version:</th><td> @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) @ (%h(RELEASE_VERSION)) <a href='version?verbose=1'>(details)</a> @ </td></tr> @ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid()) @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion())) @ <a href='version?verbose=2'>(details)</a></td></tr> | > > > > | > | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
@ <tr><th>Fossil Version:</th><td>
@ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
@ (%h(RELEASE_VERSION)) <a href='version?verbose=1'>(details)</a>
@ </td></tr>
@ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid())
@ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))
@ <a href='version?verbose=2'>(details)</a></td></tr>
if( g.eHashPolicy!=HPOLICY_AUTO ){
@ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema),
@ %s(hpolicy_name())</td></tr>
}else{
@ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema)</td></tr>
}
@ <tr><th>Repository Rebuilt:</th><td>
@ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
@ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
@ <tr><th>Database Stats:</th><td>
@ %d(db_int(0, "PRAGMA repository.page_count")) pages,
@ %d(db_int(0, "PRAGMA repository.page_size")) bytes/page,
@ %d(db_int(0, "PRAGMA repository.freelist_count")) free pages,
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
625 626 627 628 629 630 631 |
}
rid = name_to_typed_rid(g.argv[2], "ci");
blob_init(&value, 0, 0);
for(i=3; i<g.argc; i++){
int pid = name_to_typed_rid(g.argv[i], "ci");
if( i>3 ) blob_append(&value, " ", 1);
zUuid = rid_to_uuid(pid);
| | | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
}
rid = name_to_typed_rid(g.argv[2], "ci");
blob_init(&value, 0, 0);
for(i=3; i<g.argc; i++){
int pid = name_to_typed_rid(g.argv[i], "ci");
if( i>3 ) blob_append(&value, " ", 1);
zUuid = rid_to_uuid(pid);
blob_append(&value, zUuid, strlen(zUuid));
fossil_free(zUuid);
}
if( bTest && !dryRun ){
tag_insert("parent", 1, blob_str(&value), -1, 0.0, rid);
}else{
zUuid = rid_to_uuid(rid);
tag_add_artifact("","parent",zUuid,blob_str(&value),1|dryRun,0,0);
|
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
481 482 483 484 485 486 487 |
unsigned int mTime;
content_get(rid, &mfile);
if( blob_size(&mfile)==0 ){
blob_zero(pTar);
return;
}
| | | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
unsigned int mTime;
content_get(rid, &mfile);
if( blob_size(&mfile)==0 ){
blob_zero(pTar);
return;
}
blob_set_dynamic(&hash, rid_to_uuid(rid));
blob_zero(&filename);
if( zDir && zDir[0] ){
blob_appendf(&filename, "%s/", zDir);
}
nPrefix = blob_size(&filename);
|
| ︙ | ︙ | |||
518 519 520 521 522 523 524 |
}
if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
if( eflg & MFESTFLG_RAW ){
blob_append(&filename, "manifest", -1);
zName = blob_str(&filename);
}
| < < < < | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
}
if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
if( eflg & MFESTFLG_RAW ){
blob_append(&filename, "manifest", -1);
zName = blob_str(&filename);
}
if( eflg & MFESTFLG_RAW ) {
sterilize_manifest(&mfile);
tar_add_file(zName, &mfile, 0, mTime);
}
}
blob_reset(&mfile);
if( eflg & MFESTFLG_UUID ){
blob_append(&hash, "\n", 1);
blob_resize(&filename, nPrefix);
blob_append(&filename, "manifest.uuid", -1);
zName = blob_str(&filename);
tar_add_file(zName, &hash, 0, mTime);
}
if( eflg & MFESTFLG_TAGS ){
Blob tagslist;
blob_zero(&tagslist);
get_checkin_taglist(rid, &tagslist);
blob_resize(&filename, nPrefix);
blob_append(&filename, "manifest.tags", -1);
|
| ︙ | ︙ | |||
562 563 564 565 566 567 568 |
blob_append(&filename, pFile->zName, -1);
zName = blob_str(&filename);
tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
blob_reset(&file);
}
}
}else{
| < > | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
blob_append(&filename, pFile->zName, -1);
zName = blob_str(&filename);
tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
blob_reset(&file);
}
}
}else{
blob_append(&filename, blob_str(&hash), 16);
zName = blob_str(&filename);
mTime = db_int64(0, "SELECT (julianday('now') - 2440587.5)*86400.0;");
tar_begin(mTime);
tar_add_file(zName, &mfile, 0, mTime);
}
manifest_destroy(pManifest);
blob_reset(&mfile);
blob_reset(&hash);
blob_reset(&filename);
tar_finish(pTar);
}
/*
** COMMAND: tarball*
**
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
721 722 723 724 725 726 727 |
** is the rail on which the riser should run and the second integer
** is the id of the node upto which the riser should run.
** mi: "merge-in". An array of integer rail positions from which
** merge arrows should be drawn into this node. If the value is
** negative, then the rail position is the absolute value of mi[]
** and a thin merge-arrow descender is drawn to the bottom of
** the screen.
| | | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 |
** is the rail on which the riser should run and the second integer
** is the id of the node upto which the riser should run.
** mi: "merge-in". An array of integer rail positions from which
** merge arrows should be drawn into this node. If the value is
** negative, then the rail position is the absolute value of mi[]
** and a thin merge-arrow descender is drawn to the bottom of
** the screen.
** h: The artifact hash of the object being graphed
*/
cgi_printf("var rowinfo = [\n");
for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
cgi_printf("{id:%d,bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,f:%d,au:",
pRow->idx, /* id */
pRow->zBgClr, /* bg */
pRow->iRail, /* r */
|
| ︙ | ︙ | |||
1459 1460 1461 1462 1463 1464 1465 | ** ng No Graph. ** nd Do not highlight the focus check-in ** v Show details of files changed ** f=CHECKIN Show family (immediate parents and children) of CHECKIN ** from=CHECKIN Path from... ** to=CHECKIN ... to this ** shortest ... show only the shortest path | | | 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 | ** ng No Graph. ** nd Do not highlight the focus check-in ** v Show details of files changed ** f=CHECKIN Show family (immediate parents and children) of CHECKIN ** from=CHECKIN Path from... ** to=CHECKIN ... to this ** shortest ... show only the shortest path ** uf=FILE_HASH Show only check-ins that contain the given file version ** chng=GLOBLIST Show only check-ins that involve changes to a file whose ** name matches one of the comma-separate GLOBLIST ** brbg Background color from branch name ** ubg Background color from user ** namechng Show only check-ins that have filename changes ** forks Show only forks and their children ** ym=YYYY-MM Show only events for the given year/month |
| ︙ | ︙ |
Changes to src/unversioned.c.
| ︙ | ︙ | |||
454 455 456 457 458 459 460 | ** ** Display a list of all unversioned files in the repository. ** Query parameters: ** ** byage=1 Order the initial display be decreasing age ** showdel=0 Show deleted files */ | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
**
** Display a list of all unversioned files in the repository.
** Query parameters:
**
** byage=1 Order the initial display be decreasing age
** showdel=0 Show deleted files
*/
void uvlist_page(void){
Stmt q;
sqlite3_int64 iNow;
sqlite3_int64 iTotalSz = 0;
int cnt = 0;
int n = 0;
const char *zOrderBy = "name";
int showDel = 0;
|
| ︙ | ︙ | |||
552 553 554 555 556 557 558 |
@ </table></div>
output_table_sorting_javascript("uvtab","tkKttN",1);
}else{
@ No unversioned files on this server.
}
style_footer();
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 |
@ </table></div>
output_table_sorting_javascript("uvtab","tkKttN",1);
}else{
@ No unversioned files on this server.
}
style_footer();
}
/*
** WEBPAGE: juvlist
**
** Return a complete list of unversioned files as JSON. The JSON
** looks like this:
**
** [{"name":NAME,
** "mtime":MTIME,
** "hash":HASH,
** "size":SIZE,
** "user":USER}]
*/
void uvlist_json_page(void){
Stmt q;
char *zSep = "[";
Blob json;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cgi_set_content_type("text/json");
if( !db_table_exists("repository","unversioned") ){
blob_init(&json, "[]", -1);
cgi_set_content(&json);
return;
}
blob_init(&json, 0, 0);
db_prepare(&q,
"SELECT"
" name,"
" mtime,"
" hash,"
" sz,"
" (SELECT login FROM rcvfrom, user"
" WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid)"
" FROM unversioned WHERE hash IS NOT NULL"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
sqlite3_int64 mtime = db_column_int(&q, 1);
const char *zHash = db_column_text(&q, 2);
int fullSize = db_column_int(&q, 3);
const char *zLogin = db_column_text(&q, 4);
if( zLogin==0 ) zLogin = "";
blob_appendf(&json, "%s{\"name\":\"", zSep);
zSep = ",\n ";
blob_append_json_string(&json, zName);
blob_appendf(&json, "\",\n \"mtime\":%lld,\n \"hash\":\"", mtime);
blob_append_json_string(&json, zHash);
blob_appendf(&json, "\",\n \"size\":%d,\n \"user\":\"", fullSize);
blob_append_json_string(&json, zLogin);
blob_appendf(&json, "\"}");
}
db_finalize(&q);
blob_appendf(&json,"]\n");
cgi_set_content(&json);
}
|
Changes to src/verify.c.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 |
** Load the record identify by rid. Make sure we can reproduce it
** without error.
**
** Panic if anything goes wrong. If this procedure returns it means
** that everything is OK.
*/
static void verify_rid(int rid){
| | | | < < | | | | 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 |
** Load the record identify by rid. Make sure we can reproduce it
** without error.
**
** Panic if anything goes wrong. If this procedure returns it means
** that everything is OK.
*/
static void verify_rid(int rid){
Blob uuid, content;
if( content_size(rid, 0)<0 ){
return; /* No way to verify phantoms */
}
blob_zero(&uuid);
db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( !hname_validate(blob_buffer(&uuid), blob_size(&uuid)) ){
fossil_fatal("not a valid rid: %d", rid);
}
if( content_get(rid, &content) ){
if( !hname_verify_hash(&content, blob_buffer(&uuid), blob_size(&uuid)) ){
fossil_fatal("hash of rid %d does not match its uuid (%b)",
rid, &uuid);
}
blob_reset(&content);
}
blob_reset(&uuid);
}
/*
** The following bag holds the rid for every record that needs
** to be verified.
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | */ #include "config.h" #include "vfile.h" #include <assert.h> #include <sys/types.h> /* | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
*/
#include "config.h"
#include "vfile.h"
#include <assert.h>
#include <sys/types.h>
/*
** The input is guaranteed to be a 40- or 64-character well-formed
** artifact hash. Find its rid.
*/
int fast_uuid_to_rid(const char *zUuid){
static Stmt q;
int rid;
db_static_prepare(&q, "SELECT rid FROM blob WHERE uuid=:uuid");
db_bind_text(&q, ":uuid", zUuid);
if( db_step(&q)==SQLITE_ROW ){
|
| ︙ | ︙ | |||
49 50 51 52 53 54 55 |
**
** If the UUID is not found and phantomize is 1 or 2, then attempt to
** create a phantom record. A private phantom is created for 2 and
** a public phantom is created for 1.
*/
int uuid_to_rid(const char *zUuid, int phantomize){
int rid, sz;
| | | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
**
** If the UUID is not found and phantomize is 1 or 2, then attempt to
** create a phantom record. A private phantom is created for 2 and
** a public phantom is created for 1.
*/
int uuid_to_rid(const char *zUuid, int phantomize){
int rid, sz;
char z[HNAME_MAX+1];
sz = strlen(zUuid);
if( !hname_validate(zUuid, sz) ){
return 0; /* Not a valid hash */
}
memcpy(z, zUuid, sz+1);
canonical16(z, sz);
rid = fast_uuid_to_rid(z);
if( rid==0 && phantomize ){
rid = content_new(zUuid, phantomize-1);
}
return rid;
}
|
| ︙ | ︙ | |||
128 129 130 131 132 133 134 | #if INTERFACE /* ** The cksigFlags parameter to vfile_check_signature() is an OR-ed ** combination of the following bits: */ #define CKSIG_ENOTFILE 0x001 /* non-file FS objects throw an error */ | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #if INTERFACE /* ** The cksigFlags parameter to vfile_check_signature() is an OR-ed ** combination of the following bits: */ #define CKSIG_ENOTFILE 0x001 /* non-file FS objects throw an error */ #define CKSIG_HASH 0x002 /* Verify file content using hashing */ #define CKSIG_SETMTIME 0x004 /* Set mtime to last check-out time */ #endif /* INTERFACE */ /* ** Look at every VFILE entry with the given vid and update VFILE.CHNGED field ** according to whether or not the file has changed. |
| ︙ | ︙ | |||
157 158 159 160 161 162 163 | ** the file has changed without having the check the size, mtime, ** or on-disk content. ** ** If the size of the file has changed, then we always know that the file ** changed without having to look at the mtime or on-disk content. ** ** The mtime of the file is only a factor if the mtime-changes setting | | | < | | 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 |
** the file has changed without having the check the size, mtime,
** or on-disk content.
**
** If the size of the file has changed, then we always know that the file
** changed without having to look at the mtime or on-disk content.
**
** The mtime of the file is only a factor if the mtime-changes setting
** is false and the CKSIG_HASH flag is false. If the mtime-changes
** setting is true (or undefined - it defaults to true) or if CKSIG_HASH
** is true, then we do not trust the mtime and will examine the on-disk
** content to determine if a file really is the same.
**
** If the mtime is used, it is used only to determine if files are the same.
** If the mtime of a file has changed, we still examine the on-disk content
** to see whether or not the edit was a null-edit.
*/
void vfile_check_signature(int vid, unsigned int cksigFlags){
int nErr = 0;
Stmt q;
int useMtime = (cksigFlags & CKSIG_HASH)==0
&& db_get_boolean("mtime-changes", 1);
db_begin_transaction();
db_prepare(&q, "SELECT id, %Q || pathname,"
" vfile.mrid, deleted, chnged, uuid, size, mtime,"
" CASE WHEN isexe THEN %d WHEN islink THEN %d ELSE %d END"
" FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
|
| ︙ | ︙ | |||
220 221 222 223 224 225 226 |
nErr++;
}
chnged = 1;
}
if( origSize!=currentSize ){
if( chnged!=1 ){
/* A file size change is definitive - the file has changed. No
| | > > < < < < | < < | | > > < < < < < | < < < | 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 |
nErr++;
}
chnged = 1;
}
if( origSize!=currentSize ){
if( chnged!=1 ){
/* A file size change is definitive - the file has changed. No
** need to check the mtime or hash */
chnged = 1;
}
}else if( chnged==1 && rid!=0 && !isDeleted ){
/* File is believed to have changed but it is the same size.
** Double check that it really has changed by looking at content. */
const char *zUuid = db_column_text(&q, 5);
int nUuid = db_column_bytes(&q, 5);
assert( origSize==currentSize );
if( hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 0;
}else if( (chnged==0 || chnged==2 || chnged==4)
&& (useMtime==0 || currentMtime!=oldMtime) ){
/* For files that were formerly believed to be unchanged or that were
** changed by merging, if their mtime changes, or unconditionally
** if --hash is used, check to see if they have been edited by
** looking at their artifact hashes */
const char *zUuid = db_column_text(&q, 5);
int nUuid = db_column_bytes(&q, 5);
assert( origSize==currentSize );
if( !hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 1;
}
if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){
i64 desiredMtime;
if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
if( currentMtime!=desiredMtime ){
file_set_mtime(zName, desiredMtime);
currentMtime = file_wd_mtime(zName);
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 |
** timestamp. Returns 0 if there is no such item and -1 if the details
** are ambiguous and could refer to multiple items.
*/
int wiki_technote_to_rid(const char *zETime) {
int rid=0; /* Artifact ID of the tech note */
int nETime = strlen(zETime);
Stmt q;
| | | | 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 |
** timestamp. Returns 0 if there is no such item and -1 if the details
** are ambiguous and could refer to multiple items.
*/
int wiki_technote_to_rid(const char *zETime) {
int rid=0; /* Artifact ID of the tech note */
int nETime = strlen(zETime);
Stmt q;
if( nETime>=4 && hname_validate(zETime, nETime) ){
char zUuid[HNAME_MAX+1];
memcpy(zUuid, zETime, nETime+1);
canonical16(zUuid, nETime);
db_prepare(&q,
"SELECT e.objid"
" FROM event e, tag t"
" WHERE e.type='e' AND e.tagid IS NOT NULL AND t.tagid=e.tagid"
" AND t.tagname GLOB 'event-%q*'",
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
1065 1066 1067 1068 1069 1070 1071 |
/*
** If the input string corresponds to an existing baseline,
** return true.
*/
static int is_valid_uuid(const char *z){
int n = strlen(z);
| | | 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 |
/*
** If the input string corresponds to an existing baseline,
** return true.
*/
static int is_valid_uuid(const char *z){
int n = strlen(z);
if( n<4 || n>HNAME_MAX ) return 0;
if( !validate16(z, n) ) return 0;
return 1;
}
/*
** Return TRUE if a UUID corresponds to an artifact in this
** repository.
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 | int nFileRcvd; /* Number of files received */ int nDeltaRcvd; /* Number of deltas received */ int nDanglingFile; /* Number of dangling deltas received */ int mxSend; /* Stop sending "file" when pOut reaches this size */ int resync; /* Send igot cards for all holdings */ u8 syncPrivate; /* True to enable syncing private content */ u8 nextIsPrivate; /* If true, next "file" received is a private */ time_t maxTime; /* Time when this transfer should be finished */ }; /* | > | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
int nFileRcvd; /* Number of files received */
int nDeltaRcvd; /* Number of deltas received */
int nDanglingFile; /* Number of dangling deltas received */
int mxSend; /* Stop sending "file" when pOut reaches this size */
int resync; /* Send igot cards for all holdings */
u8 syncPrivate; /* True to enable syncing private content */
u8 nextIsPrivate; /* If true, next "file" received is a private */
u32 clientVersion; /* Version of the client software */
time_t maxTime; /* Time when this transfer should be finished */
};
/*
** The input blob contains an artifact. Convert it into a record ID.
** Create a phantom record if no prior record exists and
** phantomize is true.
**
** Compare to uuid_to_rid(). This routine takes a blob argument
** and does less error checking.
*/
static int rid_from_uuid(Blob *pUuid, int phantomize, int isPrivate){
|
| ︙ | ︙ | |||
98 99 100 101 102 103 104 | /* ** The aToken[0..nToken-1] blob array is a parse of a "file" line ** message. This routine finishes parsing that message and does ** a record insert of the file. ** ** The file line is in one of the following two forms: ** | | | | > | | < > | | | | | | | | < | < < | | < | | | | 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 |
/*
** The aToken[0..nToken-1] blob array is a parse of a "file" line
** message. This routine finishes parsing that message and does
** a record insert of the file.
**
** The file line is in one of the following two forms:
**
** file HASH SIZE \n CONTENT
** file HASH DELTASRC SIZE \n CONTENT
**
** The content is SIZE bytes immediately following the newline.
** If DELTASRC exists, then the CONTENT is a delta against the
** content of DELTASRC.
**
** If any error occurs, write a message into pErr which has already
** be initialized to an empty string.
**
** Any artifact successfully received by this routine is considered to
** be public and is therefore removed from the "private" table.
*/
static void xfer_accept_file(
Xfer *pXfer,
int cloneFlag,
char **pzUuidList,
int *pnUuidList
){
int n;
int rid;
int srcid = 0;
Blob content;
int isPriv;
Blob *pUuid;
isPriv = pXfer->nextIsPrivate;
pXfer->nextIsPrivate = 0;
if( pXfer->nToken<3
|| pXfer->nToken>4
|| !blob_is_hname(&pXfer->aToken[1])
|| !blob_is_int(&pXfer->aToken[pXfer->nToken-1], &n)
|| n<0
|| (pXfer->nToken==4 && !blob_is_hname(&pXfer->aToken[2]))
){
blob_appendf(&pXfer->err, "malformed file line");
return;
}
blob_zero(&content);
blob_extract(pXfer->pIn, n, &content);
pUuid = &pXfer->aToken[1];
if( !cloneFlag && uuid_is_shunned(blob_str(pUuid)) ){
/* Ignore files that have been shunned */
blob_reset(&content);
return;
}
if( isPriv && !g.perm.Private ){
/* Do not accept private files if not authorized */
blob_reset(&content);
return;
}
if( cloneFlag ){
if( pXfer->nToken==4 ){
srcid = rid_from_uuid(&pXfer->aToken[2], 1, isPriv);
pXfer->nDeltaRcvd++;
}else{
srcid = 0;
pXfer->nFileRcvd++;
}
rid = content_put_ex(&content, blob_str(pUuid), srcid,
0, isPriv);
Th_AppendToList(pzUuidList, pnUuidList, blob_str(pUuid),
blob_size(pUuid));
remote_has(rid);
blob_reset(&content);
return;
}
if( pXfer->nToken==4 ){
Blob src, next;
srcid = rid_from_uuid(&pXfer->aToken[2], 1, isPriv);
if( content_get(srcid, &src)==0 ){
rid = content_put_ex(&content, blob_str(pUuid), srcid,
0, isPriv);
Th_AppendToList(pzUuidList, pnUuidList, blob_str(pUuid),
blob_size(pUuid));
pXfer->nDanglingFile++;
db_multi_exec("DELETE FROM phantom WHERE rid=%d", rid);
if( !isPriv ) content_make_public(rid);
blob_reset(&src);
blob_reset(&content);
return;
}
pXfer->nDeltaRcvd++;
blob_delta_apply(&src, &content, &next);
blob_reset(&src);
blob_reset(&content);
content = next;
}else{
pXfer->nFileRcvd++;
}
if( hname_verify_hash(&content, blob_buffer(pUuid), blob_size(pUuid))==0 ){
blob_appendf(&pXfer->err, "wrong hash on received artifact: %b", pUuid);
}
rid = content_put_ex(&content, blob_str(pUuid), 0, 0, isPriv);
Th_AppendToList(pzUuidList, pnUuidList, blob_str(pUuid), blob_size(pUuid));
if( rid==0 ){
blob_appendf(&pXfer->err, "%s", g.zErrMsg);
blob_reset(&content);
}else{
if( !isPriv ) content_make_public(rid);
manifest_crosslink(rid, &content, MC_NO_ERRORS);
}
assert( blob_is_reset(&content) );
remote_has(rid);
}
/*
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
** message. This routine finishes parsing that message and does
** a record insert of the file. The difference between "file" and
** "cfile" is that with "cfile" the content is already compressed.
**
** The file line is in one of the following two forms:
**
** cfile HASH USIZE CSIZE \n CONTENT
** cfile HASH DELTASRC USIZE CSIZE \n CONTENT
**
** The content is CSIZE bytes immediately following the newline.
** If DELTASRC exists, then the CONTENT is a delta against the
** content of DELTASRC.
**
** The original size of the HASH artifact is USIZE.
**
** If any error occurs, write a message into pErr which has already
** be initialized to an empty string.
**
** Any artifact successfully received by this routine is considered to
** be public and is therefore removed from the "private" table.
*/
|
| ︙ | ︙ | |||
246 247 248 249 250 251 252 | Blob content; int isPriv; isPriv = pXfer->nextIsPrivate; pXfer->nextIsPrivate = 0; if( pXfer->nToken<4 || pXfer->nToken>5 | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
Blob content;
int isPriv;
isPriv = pXfer->nextIsPrivate;
pXfer->nextIsPrivate = 0;
if( pXfer->nToken<4
|| pXfer->nToken>5
|| !blob_is_hname(&pXfer->aToken[1])
|| !blob_is_int(&pXfer->aToken[pXfer->nToken-2], &szU)
|| !blob_is_int(&pXfer->aToken[pXfer->nToken-1], &szC)
|| szC<0 || szU<0
|| (pXfer->nToken==5 && !blob_is_hname(&pXfer->aToken[2]))
){
blob_appendf(&pXfer->err, "malformed cfile line");
return;
}
if( isPriv && !g.perm.Private ){
/* Do not accept private files if not authorized */
return;
|
| ︙ | ︙ | |||
295 296 297 298 299 300 301 | ** uvfile NAME MTIME HASH SIZE FLAGS ** uvfile NAME MTIME HASH SIZE FLAGS \n CONTENT ** ** If the 0x0001 bit of FLAGS is set, that means the file has been ** deleted, SIZE is zero, the HASH is "-", and the "\n CONTENT" is omitted. ** ** SIZE is the number of bytes of CONTENT. The CONTENT is uncompressed. | | < | < | < | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
** uvfile NAME MTIME HASH SIZE FLAGS
** uvfile NAME MTIME HASH SIZE FLAGS \n CONTENT
**
** If the 0x0001 bit of FLAGS is set, that means the file has been
** deleted, SIZE is zero, the HASH is "-", and the "\n CONTENT" is omitted.
**
** SIZE is the number of bytes of CONTENT. The CONTENT is uncompressed.
** HASH is the artifact hash of CONTENT.
**
** If the 0x0004 bit of FLAGS is set, that means the CONTENT is omitted.
** The sender might have omitted the content because it is too big to
** transmit, or because it is unchanged and this record exists purely
** to update the MTIME.
*/
static void xfer_accept_unversioned_file(Xfer *pXfer, int isWriter){
sqlite3_int64 mtime; /* The MTIME */
Blob *pHash; /* The HASH value */
int sz; /* The SIZE */
int flags; /* The FLAGS */
Blob content; /* The CONTENT */
Blob x; /* Compressed content */
Stmt q; /* SQL statements for comparison and insert */
int isDelete; /* HASH is "-" indicating this is a delete */
int nullContent; /* True of CONTENT is NULL */
int iStatus; /* Result from unversioned_status() */
pHash = &pXfer->aToken[3];
if( pXfer->nToken==5
|| !blob_is_filename(&pXfer->aToken[1])
|| !blob_is_int64(&pXfer->aToken[2], &mtime)
|| (!blob_eq(pHash,"-") && !blob_is_hname(pHash))
|| !blob_is_int(&pXfer->aToken[4], &sz)
|| !blob_is_int(&pXfer->aToken[5], &flags)
){
blob_appendf(&pXfer->err, "malformed uvfile line");
return;
}
blob_init(&content, 0, 0);
blob_init(&x, 0, 0);
if( sz>0 && (flags & 0x0005)==0 ){
blob_extract(pXfer->pIn, sz, &content);
nullContent = 0;
if( hname_verify_hash(&content, blob_buffer(pHash), blob_size(pHash))==0 ){
blob_appendf(&pXfer->err, "in uvfile line, HASH does not match CONTENT");
goto end_accept_unversioned_file;
}
}else{
nullContent = 1;
}
|
| ︙ | ︙ | |||
397 398 399 400 401 402 403 |
db_step(&q);
db_finalize(&q);
db_unset("uv-hash", 0);
end_accept_unversioned_file:
blob_reset(&x);
blob_reset(&content);
| < | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
db_step(&q);
db_finalize(&q);
db_unset("uv-hash", 0);
end_accept_unversioned_file:
blob_reset(&x);
blob_reset(&content);
}
/*
** Try to send a file as a delta against its parent.
** If successful, return the number of bytes in the delta.
** If we cannot generate an appropriate delta, then send
** nothing and return zero.
**
** Never send a delta against a private artifact.
*/
static int send_delta_parent(
Xfer *pXfer, /* The transfer context */
int rid, /* record id of the file to send */
int isPrivate, /* True if rid is a private artifact */
Blob *pContent, /* The content of the file to send */
Blob *pUuid /* The HASH of the file to send */
){
static const char *const azQuery[] = {
"SELECT pid FROM plink x"
" WHERE cid=%d"
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)",
"SELECT pid, min(mtime) FROM mlink, event ON mlink.mid=event.objid"
|
| ︙ | ︙ | |||
467 468 469 470 471 472 473 | ** ** Never send a delta against a private artifact. */ static int send_delta_native( Xfer *pXfer, /* The transfer context */ int rid, /* record id of the file to send */ int isPrivate, /* True if rid is a private artifact */ | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
**
** Never send a delta against a private artifact.
*/
static int send_delta_native(
Xfer *pXfer, /* The transfer context */
int rid, /* record id of the file to send */
int isPrivate, /* True if rid is a private artifact */
Blob *pUuid /* The HASH of the file to send */
){
Blob src, delta;
int size = 0;
int srcId;
srcId = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", rid);
if( srcId>0
|
| ︙ | ︙ | |||
498 499 500 501 502 503 504 505 506 507 508 |
blob_reset(&delta);
blob_reset(&src);
}else{
size = 0;
}
return size;
}
/*
** Send the file identified by rid.
**
| > > > > > > > > > > > | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
blob_reset(&delta);
blob_reset(&src);
}else{
size = 0;
}
return size;
}
/*
** Push an error message to alert the older client that the repository
** has SHA3 content and cannot be synced or cloned.
*/
static void xfer_cannot_send_sha3_error(Xfer *pXfer){
blob_appendf(pXfer->pOut,
"error Fossil\\sversion\\s2.0\\sor\\slater\\srequired.\n"
);
}
/*
** Send the file identified by rid.
**
** The pUuid can be NULL in which case the correct hash is computed
** from the rid.
**
** Try to send the file as a native delta if nativeDelta is true, or
** as a parent delta if nativeDelta is false.
**
** It should never be the case that rid is a private artifact. But
** as a precaution, this routine does check on rid and if it is private
|
| ︙ | ︙ | |||
525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){
return;
}
blob_zero(&uuid);
db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid);
if( blob_size(&uuid)==0 ){
return;
}
if( pUuid ){
if( blob_compare(pUuid, &uuid)!=0 ){
blob_reset(&uuid);
return;
}
}else{
| > > > > | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){
return;
}
blob_zero(&uuid);
db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid);
if( blob_size(&uuid)==0 ){
return;
}
if( blob_size(&uuid)>HNAME_LEN_SHA1 && pXfer->clientVersion<20000 ){
xfer_cannot_send_sha3_error(pXfer);
return;
}
if( pUuid ){
if( blob_compare(pUuid, &uuid)!=0 ){
blob_reset(&uuid);
return;
}
}else{
|
| ︙ | ︙ | |||
615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
zUuid = db_column_text(&q1, 0);
szU = db_column_int(&q1, 1);
szC = db_column_bytes(&q1, 2);
zContent = db_column_raw(&q1, 2);
srcIsPrivate = db_column_int(&q1, 3);
zDelta = db_column_text(&q1, 4);
if( isPrivate ) blob_append(pXfer->pOut, "private\n", -1);
blob_appendf(pXfer->pOut, "cfile %s ", zUuid);
if( !isPrivate && srcIsPrivate ){
content_get(rid, &fullContent);
szU = blob_size(&fullContent);
blob_compress(&fullContent, &fullContent);
szC = blob_size(&fullContent);
zContent = blob_buffer(&fullContent);
| > > > > > | 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 |
zUuid = db_column_text(&q1, 0);
szU = db_column_int(&q1, 1);
szC = db_column_bytes(&q1, 2);
zContent = db_column_raw(&q1, 2);
srcIsPrivate = db_column_int(&q1, 3);
zDelta = db_column_text(&q1, 4);
if( isPrivate ) blob_append(pXfer->pOut, "private\n", -1);
if( pXfer->clientVersion<20000 && db_column_bytes(&q1,0)!=HNAME_LEN_SHA1 ){
xfer_cannot_send_sha3_error(pXfer);
db_reset(&q1);
return;
}
blob_appendf(pXfer->pOut, "cfile %s ", zUuid);
if( !isPrivate && srcIsPrivate ){
content_get(rid, &fullContent);
szU = blob_size(&fullContent);
blob_compress(&fullContent, &fullContent);
szC = blob_size(&fullContent);
zContent = blob_buffer(&fullContent);
|
| ︙ | ︙ | |||
674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
" WHERE name=%Q",
zName
);
}
if( db_step(&q1)==SQLITE_ROW ){
sqlite3_int64 mtime = db_column_int64(&q1, 0);
const char *zHash = db_column_text(&q1, 1);
if( blob_size(pXfer->pOut)>=pXfer->mxSend ){
/* If we have already reached the send size limit, send a (short)
** uvigot card rather than a uvfile card. This only happens on the
** server side. The uvigot card will provoke the client to resend
** another uvgimme on the next cycle. */
blob_appendf(pXfer->pOut, "uvigot %s %lld %s %d\n",
zName, mtime, zHash, db_column_int(&q1,3));
| > > > > > | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 |
" WHERE name=%Q",
zName
);
}
if( db_step(&q1)==SQLITE_ROW ){
sqlite3_int64 mtime = db_column_int64(&q1, 0);
const char *zHash = db_column_text(&q1, 1);
if( pXfer->clientVersion<20000 && db_column_bytes(&q1,1)>HNAME_LEN_SHA1 ){
xfer_cannot_send_sha3_error(pXfer);
db_reset(&q1);
return;
}
if( blob_size(pXfer->pOut)>=pXfer->mxSend ){
/* If we have already reached the send size limit, send a (short)
** uvigot card rather than a uvfile card. This only happens on the
** server side. The uvigot card will provoke the client to resend
** another uvgimme on the next cycle. */
blob_appendf(pXfer->pOut, "uvigot %s %lld %s %d\n",
zName, mtime, zHash, db_column_int(&q1,3));
|
| ︙ | ︙ | |||
726 727 728 729 730 731 732 |
blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);
pXfer->nGimmeSent++;
}
db_finalize(&q);
}
/*
| | > > > < | < < | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 |
blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);
pXfer->nGimmeSent++;
}
db_finalize(&q);
}
/*
** Compute an hash on the tail of pMsg. Verify that it matches the
** the hash given in pHash. Return non-zero for an error and 0 on success.
**
** The type of hash computed (SHA1, SHA3-256) is determined by
** the length of the input hash in pHash.
*/
static int check_tail_hash(Blob *pHash, Blob *pMsg){
Blob tail;
int rc;
blob_tail(pMsg, &tail);
rc = hname_verify_hash(&tail, blob_buffer(pHash), blob_size(pHash));
blob_reset(&tail);
return rc==HNAME_ERROR;
}
/*
** Check the signature on an application/x-fossil payload received by
** the HTTP server. The signature is a line of the following form:
**
** login LOGIN NONCE SIGNATURE
|
| ︙ | ︙ | |||
1196 1197 1198 1199 1200 1201 1202 |
pnUuidList = &nUuidList;
}
while( blob_line(xfer.pIn, &xfer.line) ){
if( blob_buffer(&xfer.line)[0]=='#' ) continue;
if( blob_size(&xfer.line)==0 ) continue;
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
| | | | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 |
pnUuidList = &nUuidList;
}
while( blob_line(xfer.pIn, &xfer.line) ){
if( blob_buffer(&xfer.line)[0]=='#' ) continue;
if( blob_size(&xfer.line)==0 ) continue;
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
/* file HASH SIZE \n CONTENT
** file HASH DELTASRC SIZE \n CONTENT
**
** Accept a file from the client.
*/
if( blob_eq(&xfer.aToken[0], "file") ){
if( !isPush ){
cgi_reset_content();
@ error not\sauthorized\sto\swrite
nErr++;
break;
}
xfer_accept_file(&xfer, 0, pzUuidList, pnUuidList);
if( blob_size(&xfer.err) ){
cgi_reset_content();
@ error %T(blob_str(&xfer.err))
nErr++;
break;
}
}else
/* cfile HASH USIZE CSIZE \n CONTENT
** cfile HASH DELTASRC USIZE CSIZE \n CONTENT
**
** Accept a file from the client.
*/
if( blob_eq(&xfer.aToken[0], "cfile") ){
if( !isPush ){
cgi_reset_content();
@ error not\sauthorized\sto\swrite
|
| ︙ | ︙ | |||
1252 1253 1254 1255 1256 1257 1258 |
cgi_reset_content();
@ error %T(blob_str(&xfer.err))
nErr++;
break;
}
}else
| | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 |
cgi_reset_content();
@ error %T(blob_str(&xfer.err))
nErr++;
break;
}
}else
/* gimme HASH
**
** Client is requesting a file. Send it.
*/
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_hname(&xfer.aToken[1])
){
nGimme++;
if( isPull ){
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
if( rid ){
send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
}
|
| ︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 |
if( blob_eq(&xfer.aToken[0], "uvgimme")
&& xfer.nToken==2
&& blob_is_filename(&xfer.aToken[1])
){
send_unversioned_file(&xfer, blob_str(&xfer.aToken[1]), 0);
}else
| | | | < | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 |
if( blob_eq(&xfer.aToken[0], "uvgimme")
&& xfer.nToken==2
&& blob_is_filename(&xfer.aToken[1])
){
send_unversioned_file(&xfer, blob_str(&xfer.aToken[1]), 0);
}else
/* igot HASH ?ISPRIVATE?
**
** Client announces that it has a particular file. If the ISPRIVATE
** argument exists and is non-zero, then the file is a private file.
*/
if( xfer.nToken>=2
&& blob_eq(&xfer.aToken[0], "igot")
&& blob_is_hname(&xfer.aToken[1])
){
if( isPush ){
if( xfer.nToken==2 || blob_eq(&xfer.aToken[2],"1")==0 ){
rid_from_uuid(&xfer.aToken[1], 1, 0);
}else if( g.perm.Private ){
rid_from_uuid(&xfer.aToken[1], 1, 1);
}else{
server_private_xfer_not_authorized();
}
}
}else
/* pull SERVERCODE PROJECTCODE
** push SERVERCODE PROJECTCODE
**
** The client wants either send or receive. The server should
** verify that the project code matches. The server code is ignored.
*/
if( xfer.nToken==3
&& (blob_eq(&xfer.aToken[0], "pull") || blob_eq(&xfer.aToken[0], "push"))
&& blob_is_hname(&xfer.aToken[2])
){
const char *zPCode;
zPCode = db_get("project-code", 0);
if( zPCode==0 ){
fossil_panic("missing project code");
}
if( !blob_eq_str(&xfer.aToken[2], zPCode, -1) ){
|
| ︙ | ︙ | |||
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 |
/* pragma send-catalog
**
** Send igot cards for all known artifacts.
*/
if( blob_eq(&xfer.aToken[1], "send-catalog") ){
xfer.resync = 0x7fffffff;
}
/* pragma uv-hash HASH
**
** The client wants to make sure that unversioned files are all synced.
** If the HASH does not match, send a complete catalog of
** "uvigot" cards.
*/
if( blob_eq(&xfer.aToken[1], "uv-hash")
| > > > > > > > > | | 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 |
/* pragma send-catalog
**
** Send igot cards for all known artifacts.
*/
if( blob_eq(&xfer.aToken[1], "send-catalog") ){
xfer.resync = 0x7fffffff;
}
/* pragma client-version VERSION
**
** Let the server know what version of Fossil is running on the client.
*/
if( xfer.nToken>=3 && blob_eq(&xfer.aToken[1], "client-version") ){
xfer.clientVersion = atoi(blob_str(&xfer.aToken[2]));
}
/* pragma uv-hash HASH
**
** The client wants to make sure that unversioned files are all synced.
** If the HASH does not match, send a complete catalog of
** "uvigot" cards.
*/
if( blob_eq(&xfer.aToken[1], "uv-hash")
&& blob_is_hname(&xfer.aToken[2])
){
if( !uvCatalogSent ){
if( g.perm.Read && g.perm.WrUnver ){
@ pragma uv-push-ok
send_unversioned_catalog(&xfer);
}else if( g.perm.Read ){
@ pragma uv-pull-only
|
| ︙ | ︙ | |||
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 |
transport_stats(0, 0, 1);
socket_global_init();
memset(&xfer, 0, sizeof(xfer));
xfer.pIn = &recv;
xfer.pOut = &send;
xfer.mxSend = db_get_int("max-upload", 250000);
xfer.maxTime = -1;
if( syncFlags & SYNC_PRIVATE ){
g.perm.Private = 1;
xfer.syncPrivate = 1;
}
blobarray_zero(xfer.aToken, count(xfer.aToken));
blob_zero(&send);
| > | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 |
transport_stats(0, 0, 1);
socket_global_init();
memset(&xfer, 0, sizeof(xfer));
xfer.pIn = &recv;
xfer.pOut = &send;
xfer.mxSend = db_get_int("max-upload", 250000);
xfer.maxTime = -1;
xfer.clientVersion = RELEASE_VERSION_NUMBER;
if( syncFlags & SYNC_PRIVATE ){
g.perm.Private = 1;
xfer.syncPrivate = 1;
}
blobarray_zero(xfer.aToken, count(xfer.aToken));
blob_zero(&send);
|
| ︙ | ︙ | |||
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 |
" SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
);
}
/*
** Always begin with a clone, pull, or push message
*/
if( syncFlags & SYNC_CLONE ){
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
nCardSent++;
/* TBD: Request all transferable configuration values */
content_enable_dephantomize(0);
zOpType = "Clone";
| > | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 |
" SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
);
}
/*
** Always begin with a clone, pull, or push message
*/
blob_appendf(&send, "pragma client-version %d\n", RELEASE_VERSION_NUMBER);
if( syncFlags & SYNC_CLONE ){
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
nCardSent++;
/* TBD: Request all transferable configuration values */
content_enable_dephantomize(0);
zOpType = "Clone";
|
| ︙ | ︙ | |||
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 |
char *zRandomness;
db_begin_transaction();
db_record_repository_filename(0);
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
);
manifest_crosslink_begin();
/* Send back the most recently received cookie. Let the server
** figure out if this is a cookie that it cares about.
*/
zCookie = db_get("cookie", 0);
if( zCookie ){
blob_appendf(&send, "cookie %s\n", zCookie);
| > | 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 |
char *zRandomness;
db_begin_transaction();
db_record_repository_filename(0);
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
);
manifest_crosslink_begin();
/* Send back the most recently received cookie. Let the server
** figure out if this is a cookie that it cares about.
*/
zCookie = db_get("cookie", 0);
if( zCookie ){
blob_appendf(&send, "cookie %s\n", zCookie);
|
| ︙ | ︙ | |||
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 |
xfer.nFileSent = 0;
xfer.nDeltaSent = 0;
xfer.nGimmeSent = 0;
xfer.nIGotSent = 0;
lastPctDone = -1;
blob_reset(&send);
rArrivalTime = db_double(0.0, "SELECT julianday('now')");
/* Send the send-private pragma if we are trying to sync private data */
if( syncFlags & SYNC_PRIVATE ){
blob_append(&send, "pragma send-private\n", -1);
}
| > | 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 |
xfer.nFileSent = 0;
xfer.nDeltaSent = 0;
xfer.nGimmeSent = 0;
xfer.nIGotSent = 0;
lastPctDone = -1;
blob_reset(&send);
blob_appendf(&send, "pragma client-version %d\n", RELEASE_VERSION_NUMBER);
rArrivalTime = db_double(0.0, "SELECT julianday('now')");
/* Send the send-private pragma if we are trying to sync private data */
if( syncFlags & SYNC_PRIVATE ){
blob_append(&send, "pragma send-private\n", -1);
}
|
| ︙ | ︙ | |||
2026 2027 2028 2029 2030 2031 2032 |
if( pctDone!=lastPctDone ){
fossil_print("\rprocessed: %d%% ", pctDone);
lastPctDone = pctDone;
fflush(stdout);
}
}
| | | | | | 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 |
if( pctDone!=lastPctDone ){
fossil_print("\rprocessed: %d%% ", pctDone);
lastPctDone = pctDone;
fflush(stdout);
}
}
/* file HASH SIZE \n CONTENT
** file HASH DELTASRC SIZE \n CONTENT
**
** Receive a file transmitted from the server.
*/
if( blob_eq(&xfer.aToken[0],"file") ){
xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0, 0, 0);
nArtifactRcvd++;
}else
/* cfile HASH USIZE CSIZE \n CONTENT
** cfile HASH DELTASRC USIZE CSIZE \n CONTENT
**
** Receive a compressed file transmitted from the server.
*/
if( blob_eq(&xfer.aToken[0],"cfile") ){
xfer_accept_compressed_file(&xfer, 0, 0);
nArtifactRcvd++;
}else
|
| ︙ | ︙ | |||
2060 2061 2062 2063 2064 2065 2066 |
nUvFileRcvd++;
if( syncFlags & SYNC_VERBOSE ){
fossil_print("\rUnversioned-file received: %s\n",
blob_str(&xfer.aToken[1]));
}
}else
| | | | | | 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 |
nUvFileRcvd++;
if( syncFlags & SYNC_VERBOSE ){
fossil_print("\rUnversioned-file received: %s\n",
blob_str(&xfer.aToken[1]));
}
}else
/* gimme HASH
**
** Server is requesting a file. If the file is a manifest, assume
** that the server will also want to know all of the content files
** associated with the manifest and send those too.
*/
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_hname(&xfer.aToken[1])
){
if( syncFlags & SYNC_PUSH ){
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
}
}else
/* igot HASH ?PRIVATEFLAG?
**
** Server announces that it has a particular file. If this is
** not a file that we have and we are pulling, then create a
** phantom to cause this file to be requested on the next cycle.
** Always remember that the server has this file so that we do
** not transmit it by accident.
**
** If the PRIVATE argument exists and is 1, then the file is
** private. Pretend it does not exists if we are not pulling
** private files.
*/
if( xfer.nToken>=2
&& blob_eq(&xfer.aToken[0], "igot")
&& blob_is_hname(&xfer.aToken[1])
){
int rid;
int isPriv = xfer.nToken>=3 && blob_eq(&xfer.aToken[2],"1");
rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
if( rid>0 ){
if( !isPriv ) content_make_public(rid);
}else if( isPriv && !g.perm.Private ){
|
| ︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 |
** then do the deletion.
*/
if( xfer.nToken==5
&& blob_eq(&xfer.aToken[0], "uvigot")
&& blob_is_filename(&xfer.aToken[1])
&& blob_is_int64(&xfer.aToken[2], &mtime)
&& blob_is_int(&xfer.aToken[4], &size)
| | | 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 |
** then do the deletion.
*/
if( xfer.nToken==5
&& blob_eq(&xfer.aToken[0], "uvigot")
&& blob_is_filename(&xfer.aToken[1])
&& blob_is_int64(&xfer.aToken[2], &mtime)
&& blob_is_int(&xfer.aToken[4], &size)
&& (blob_eq(&xfer.aToken[3],"-") || blob_is_hname(&xfer.aToken[3]))
){
const char *zName = blob_str(&xfer.aToken[1]);
const char *zHash = blob_str(&xfer.aToken[3]);
int iStatus;
iStatus = unversioned_status(zName, mtime, zHash);
if( (syncFlags & SYNC_UV_REVERT)!=0 ){
if( iStatus==4 ) iStatus = 2;
|
| ︙ | ︙ | |||
2186 2187 2188 2189 2190 2191 2192 |
**
** Should only happen in response to a clone. This message tells
** the client what product to use for the new database.
*/
if( blob_eq(&xfer.aToken[0],"push")
&& xfer.nToken==3
&& (syncFlags & SYNC_CLONE)!=0
| | | 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 |
**
** Should only happen in response to a clone. This message tells
** the client what product to use for the new database.
*/
if( blob_eq(&xfer.aToken[0],"push")
&& xfer.nToken==3
&& (syncFlags & SYNC_CLONE)!=0
&& blob_is_hname(&xfer.aToken[2])
){
if( zPCode==0 ){
zPCode = mprintf("%b", &xfer.aToken[2]);
db_set("project-code", zPCode, 0);
}
if( cloneSeqno>0 ) blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
nCardSent++;
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
337 338 339 340 341 342 343 |
int nPrefix;
content_get(rid, &mfile);
if( blob_size(&mfile)==0 ){
blob_zero(pZip);
return;
}
| | | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
int nPrefix;
content_get(rid, &mfile);
if( blob_size(&mfile)==0 ){
blob_zero(pZip);
return;
}
blob_set_dynamic(&hash, rid_to_uuid(rid));
blob_zero(&filename);
zip_open();
if( zDir && zDir[0] ){
blob_appendf(&filename, "%s/", zDir);
}
nPrefix = blob_size(&filename);
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 |
if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
if( eflg & MFESTFLG_RAW ){
blob_append(&filename, "manifest", -1);
zName = blob_str(&filename);
zip_add_folders(zName);
}
| < < < < | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
if( eflg & MFESTFLG_RAW ){
blob_append(&filename, "manifest", -1);
zName = blob_str(&filename);
zip_add_folders(zName);
}
if( eflg & MFESTFLG_RAW ){
sterilize_manifest(&mfile);
zip_add_file(zName, &mfile, 0);
}
}
blob_reset(&mfile);
if( eflg & MFESTFLG_UUID ){
blob_append(&hash, "\n", 1);
blob_resize(&filename, nPrefix);
blob_append(&filename, "manifest.uuid", -1);
zName = blob_str(&filename);
zip_add_folders(zName);
zip_add_file(zName, &hash, 0);
}
if( eflg & MFESTFLG_TAGS ){
Blob tagslist;
blob_zero(&tagslist);
get_checkin_taglist(rid, &tagslist);
blob_resize(&filename, nPrefix);
blob_append(&filename, "manifest.tags", -1);
|
| ︙ | ︙ | |||
427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
}
}
}else{
blob_reset(&mfile);
}
manifest_destroy(pManifest);
blob_reset(&filename);
zip_close(pZip);
}
/*
** COMMAND: zip*
**
** Usage: %fossil zip VERSION OUTPUTFILE [OPTIONS]
| > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
}
}
}else{
blob_reset(&mfile);
}
manifest_destroy(pManifest);
blob_reset(&filename);
blob_reset(&hash);
zip_close(pZip);
}
/*
** COMMAND: zip*
**
** Usage: %fossil zip VERSION OUTPUTFILE [OPTIONS]
|
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | | | | | 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 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd dispatch doc encode event export file finfo foci fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 sha1hard sha3 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR)\translate.c |
| ︙ | ︙ | |||
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | +translate$E $** > $@ $(OBJDIR)\gzip$O : gzip_.c gzip.h $(TCC) -o$@ -c gzip_.c gzip_.c : $(SRCDIR)\gzip.c +translate$E $** > $@ $(OBJDIR)\http$O : http_.c http.h $(TCC) -o$@ -c http_.c http_.c : $(SRCDIR)\http.c +translate$E $** > $@ | > > > > > > | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | +translate$E $** > $@ $(OBJDIR)\gzip$O : gzip_.c gzip.h $(TCC) -o$@ -c gzip_.c gzip_.c : $(SRCDIR)\gzip.c +translate$E $** > $@ $(OBJDIR)\hname$O : hname_.c hname.h $(TCC) -o$@ -c hname_.c hname_.c : $(SRCDIR)\hname.c +translate$E $** > $@ $(OBJDIR)\http$O : http_.c http.h $(TCC) -o$@ -c http_.c http_.c : $(SRCDIR)\http.c +translate$E $** > $@ |
| ︙ | ︙ | |||
654 655 656 657 658 659 660 661 662 663 664 665 666 667 | +translate$E $** > $@ $(OBJDIR)\sha1$O : sha1_.c sha1.h $(TCC) -o$@ -c sha1_.c sha1_.c : $(SRCDIR)\sha1.c +translate$E $** > $@ $(OBJDIR)\shun$O : shun_.c shun.h $(TCC) -o$@ -c shun_.c shun_.c : $(SRCDIR)\shun.c +translate$E $** > $@ | > > > > > > > > > > > > | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | +translate$E $** > $@ $(OBJDIR)\sha1$O : sha1_.c sha1.h $(TCC) -o$@ -c sha1_.c sha1_.c : $(SRCDIR)\sha1.c +translate$E $** > $@ $(OBJDIR)\sha1hard$O : sha1hard_.c sha1hard.h $(TCC) -o$@ -c sha1hard_.c sha1hard_.c : $(SRCDIR)\sha1hard.c +translate$E $** > $@ $(OBJDIR)\sha3$O : sha3_.c sha3.h $(TCC) -o$@ -c sha3_.c sha3_.c : $(SRCDIR)\sha3.c +translate$E $** > $@ $(OBJDIR)\shun$O : shun_.c shun.h $(TCC) -o$@ -c shun_.c shun_.c : $(SRCDIR)\shun.c +translate$E $** > $@ |
| ︙ | ︙ | |||
854 855 856 857 858 859 860 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h | | | 872 873 874 875 876 877 878 879 880 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
459 460 461 462 463 464 465 466 467 468 469 470 471 472 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ | > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/hname.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ |
| ︙ | ︙ | |||
509 510 511 512 513 514 515 516 517 518 519 520 521 522 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ | > > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/sha1hard.c \ $(SRCDIR)/sha3.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ |
| ︙ | ︙ | |||
634 635 636 637 638 639 640 641 642 643 644 645 646 647 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ | > | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/hname_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ |
| ︙ | ︙ | |||
684 685 686 687 688 689 690 691 692 693 694 695 696 697 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ | > > | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/sha1hard_.c \ $(OBJDIR)/sha3_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ |
| ︙ | ︙ | |||
758 759 760 761 762 763 764 765 766 767 768 769 770 771 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ | > | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/hname.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ |
| ︙ | ︙ | |||
808 809 810 811 812 813 814 815 816 817 818 819 820 821 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ | > > | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/sha1hard.o \ $(OBJDIR)/sha3.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ |
| ︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ | > | 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/hname_.c:$(OBJDIR)/hname.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ |
| ︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | > > | 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/sha1hard_.c:$(OBJDIR)/sha1hard.h \ $(OBJDIR)/sha3_.c:$(OBJDIR)/sha3.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| ︙ | ︙ | |||
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c | > > > > > > > > | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/hname_.c: $(SRCDIR)/hname.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/hname.c >$@ $(OBJDIR)/hname.o: $(OBJDIR)/hname_.c $(OBJDIR)/hname.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/hname.o -c $(OBJDIR)/hname_.c $(OBJDIR)/hname.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c |
| ︙ | ︙ | |||
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c | > > > > > > > > > > > > > > > > | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/sha1hard_.c: $(SRCDIR)/sha1hard.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1hard.c >$@ $(OBJDIR)/sha1hard.o: $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1hard.o -c $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h: $(OBJDIR)/headers $(OBJDIR)/sha3_.c: $(SRCDIR)/sha3.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha3.c >$@ $(OBJDIR)/sha3.o: $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha3.o -c $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c |
| ︙ | ︙ |
Changes to win/Makefile.mingw.mistachkin.
| ︙ | ︙ | |||
459 460 461 462 463 464 465 466 467 468 469 470 471 472 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ | > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ $(SRCDIR)/fshell.c \ $(SRCDIR)/fusefs.c \ $(SRCDIR)/glob.c \ $(SRCDIR)/graph.c \ $(SRCDIR)/gzip.c \ $(SRCDIR)/hname.c \ $(SRCDIR)/http.c \ $(SRCDIR)/http_socket.c \ $(SRCDIR)/http_ssl.c \ $(SRCDIR)/http_transport.c \ $(SRCDIR)/import.c \ $(SRCDIR)/info.c \ $(SRCDIR)/json.c \ |
| ︙ | ︙ | |||
509 510 511 512 513 514 515 516 517 518 519 520 521 522 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ | > > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/sha1hard.c \ $(SRCDIR)/sha3.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/sqlcmd.c \ $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ |
| ︙ | ︙ | |||
634 635 636 637 638 639 640 641 642 643 644 645 646 647 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ | > | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ $(OBJDIR)/fshell_.c \ $(OBJDIR)/fusefs_.c \ $(OBJDIR)/glob_.c \ $(OBJDIR)/graph_.c \ $(OBJDIR)/gzip_.c \ $(OBJDIR)/hname_.c \ $(OBJDIR)/http_.c \ $(OBJDIR)/http_socket_.c \ $(OBJDIR)/http_ssl_.c \ $(OBJDIR)/http_transport_.c \ $(OBJDIR)/import_.c \ $(OBJDIR)/info_.c \ $(OBJDIR)/json_.c \ |
| ︙ | ︙ | |||
684 685 686 687 688 689 690 691 692 693 694 695 696 697 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ | > > | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/sha1hard_.c \ $(OBJDIR)/sha3_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/sqlcmd_.c \ $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ |
| ︙ | ︙ | |||
758 759 760 761 762 763 764 765 766 767 768 769 770 771 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ | > | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ $(OBJDIR)/fshell.o \ $(OBJDIR)/fusefs.o \ $(OBJDIR)/glob.o \ $(OBJDIR)/graph.o \ $(OBJDIR)/gzip.o \ $(OBJDIR)/hname.o \ $(OBJDIR)/http.o \ $(OBJDIR)/http_socket.o \ $(OBJDIR)/http_ssl.o \ $(OBJDIR)/http_transport.o \ $(OBJDIR)/import.o \ $(OBJDIR)/info.o \ $(OBJDIR)/json.o \ |
| ︙ | ︙ | |||
808 809 810 811 812 813 814 815 816 817 818 819 820 821 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ | > > | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/sha1hard.o \ $(OBJDIR)/sha3.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/sqlcmd.o \ $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ |
| ︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ | > | 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 | $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ $(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \ $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \ $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \ $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \ $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \ $(OBJDIR)/hname_.c:$(OBJDIR)/hname.h \ $(OBJDIR)/http_.c:$(OBJDIR)/http.h \ $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \ $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \ $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h \ $(OBJDIR)/import_.c:$(OBJDIR)/import.h \ $(OBJDIR)/info_.c:$(OBJDIR)/info.h \ $(OBJDIR)/json_.c:$(OBJDIR)/json.h \ |
| ︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | > > | 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/sha1hard_.c:$(OBJDIR)/sha1hard.h \ $(OBJDIR)/sha3_.c:$(OBJDIR)/sha3.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| ︙ | ︙ | |||
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c | > > > > > > > > | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 | $(OBJDIR)/gzip_.c: $(SRCDIR)/gzip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/gzip.c >$@ $(OBJDIR)/gzip.o: $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h: $(OBJDIR)/headers $(OBJDIR)/hname_.c: $(SRCDIR)/hname.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/hname.c >$@ $(OBJDIR)/hname.o: $(OBJDIR)/hname_.c $(OBJDIR)/hname.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/hname.o -c $(OBJDIR)/hname_.c $(OBJDIR)/hname.h: $(OBJDIR)/headers $(OBJDIR)/http_.c: $(SRCDIR)/http.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/http.c >$@ $(OBJDIR)/http.o: $(OBJDIR)/http_.c $(OBJDIR)/http.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c |
| ︙ | ︙ | |||
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c | > > > > > > > > > > > > > > > > | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 | $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h: $(OBJDIR)/headers $(OBJDIR)/sha1hard_.c: $(SRCDIR)/sha1hard.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1hard.c >$@ $(OBJDIR)/sha1hard.o: $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1hard.o -c $(OBJDIR)/sha1hard_.c $(OBJDIR)/sha1hard.h: $(OBJDIR)/headers $(OBJDIR)/sha3_.c: $(SRCDIR)/sha3.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha3.c >$@ $(OBJDIR)/sha3.o: $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha3.o -c $(OBJDIR)/sha3_.c $(OBJDIR)/sha3.h: $(OBJDIR)/headers $(OBJDIR)/shun_.c: $(SRCDIR)/shun.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/shun.c >$@ $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c |
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
finfo_.c \
foci_.c \
fshell_.c \
fusefs_.c \
glob_.c \
graph_.c \
gzip_.c \
http_.c \
http_socket_.c \
http_ssl_.c \
http_transport_.c \
import_.c \
info_.c \
json_.c \
| > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
finfo_.c \
foci_.c \
fshell_.c \
fusefs_.c \
glob_.c \
graph_.c \
gzip_.c \
hname_.c \
http_.c \
http_socket_.c \
http_ssl_.c \
http_transport_.c \
import_.c \
info_.c \
json_.c \
|
| ︙ | ︙ | |||
434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
regexp_.c \
report_.c \
rss_.c \
schema_.c \
search_.c \
setup_.c \
sha1_.c \
shun_.c \
sitemap_.c \
skins_.c \
sqlcmd_.c \
stash_.c \
stat_.c \
statrep_.c \
| > > | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
regexp_.c \
report_.c \
rss_.c \
schema_.c \
search_.c \
setup_.c \
sha1_.c \
sha1hard_.c \
sha3_.c \
shun_.c \
sitemap_.c \
skins_.c \
sqlcmd_.c \
stash_.c \
stat_.c \
statrep_.c \
|
| ︙ | ︙ | |||
558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
$(OX)\finfo$O \
$(OX)\foci$O \
$(OX)\fshell$O \
$(OX)\fusefs$O \
$(OX)\glob$O \
$(OX)\graph$O \
$(OX)\gzip$O \
$(OX)\http$O \
$(OX)\http_socket$O \
$(OX)\http_ssl$O \
$(OX)\http_transport$O \
$(OX)\import$O \
$(OX)\info$O \
$(OX)\json$O \
| > | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
$(OX)\finfo$O \
$(OX)\foci$O \
$(OX)\fshell$O \
$(OX)\fusefs$O \
$(OX)\glob$O \
$(OX)\graph$O \
$(OX)\gzip$O \
$(OX)\hname$O \
$(OX)\http$O \
$(OX)\http_socket$O \
$(OX)\http_ssl$O \
$(OX)\http_transport$O \
$(OX)\import$O \
$(OX)\info$O \
$(OX)\json$O \
|
| ︙ | ︙ | |||
608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
$(OX)\regexp$O \
$(OX)\report$O \
$(OX)\rss$O \
$(OX)\schema$O \
$(OX)\search$O \
$(OX)\setup$O \
$(OX)\sha1$O \
$(OX)\shell$O \
$(OX)\shun$O \
$(OX)\sitemap$O \
$(OX)\skins$O \
$(OX)\sqlcmd$O \
$(OX)\sqlite3$O \
$(OX)\stash$O \
| > > | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
$(OX)\regexp$O \
$(OX)\report$O \
$(OX)\rss$O \
$(OX)\schema$O \
$(OX)\search$O \
$(OX)\setup$O \
$(OX)\sha1$O \
$(OX)\sha1hard$O \
$(OX)\sha3$O \
$(OX)\shell$O \
$(OX)\shun$O \
$(OX)\sitemap$O \
$(OX)\skins$O \
$(OX)\sqlcmd$O \
$(OX)\sqlite3$O \
$(OX)\stash$O \
|
| ︙ | ︙ | |||
741 742 743 744 745 746 747 748 749 750 751 752 753 754 | echo $(OX)\finfo.obj >> $@ echo $(OX)\foci.obj >> $@ echo $(OX)\fshell.obj >> $@ echo $(OX)\fusefs.obj >> $@ echo $(OX)\glob.obj >> $@ echo $(OX)\graph.obj >> $@ echo $(OX)\gzip.obj >> $@ echo $(OX)\http.obj >> $@ echo $(OX)\http_socket.obj >> $@ echo $(OX)\http_ssl.obj >> $@ echo $(OX)\http_transport.obj >> $@ echo $(OX)\import.obj >> $@ echo $(OX)\info.obj >> $@ echo $(OX)\json.obj >> $@ | > | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | echo $(OX)\finfo.obj >> $@ echo $(OX)\foci.obj >> $@ echo $(OX)\fshell.obj >> $@ echo $(OX)\fusefs.obj >> $@ echo $(OX)\glob.obj >> $@ echo $(OX)\graph.obj >> $@ echo $(OX)\gzip.obj >> $@ echo $(OX)\hname.obj >> $@ echo $(OX)\http.obj >> $@ echo $(OX)\http_socket.obj >> $@ echo $(OX)\http_ssl.obj >> $@ echo $(OX)\http_transport.obj >> $@ echo $(OX)\import.obj >> $@ echo $(OX)\info.obj >> $@ echo $(OX)\json.obj >> $@ |
| ︙ | ︙ | |||
791 792 793 794 795 796 797 798 799 800 801 802 803 804 | echo $(OX)\regexp.obj >> $@ echo $(OX)\report.obj >> $@ echo $(OX)\rss.obj >> $@ echo $(OX)\schema.obj >> $@ echo $(OX)\search.obj >> $@ echo $(OX)\setup.obj >> $@ echo $(OX)\sha1.obj >> $@ echo $(OX)\shell.obj >> $@ echo $(OX)\shun.obj >> $@ echo $(OX)\sitemap.obj >> $@ echo $(OX)\skins.obj >> $@ echo $(OX)\sqlcmd.obj >> $@ echo $(OX)\sqlite3.obj >> $@ echo $(OX)\stash.obj >> $@ | > > | 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 | echo $(OX)\regexp.obj >> $@ echo $(OX)\report.obj >> $@ echo $(OX)\rss.obj >> $@ echo $(OX)\schema.obj >> $@ echo $(OX)\search.obj >> $@ echo $(OX)\setup.obj >> $@ echo $(OX)\sha1.obj >> $@ echo $(OX)\sha1hard.obj >> $@ echo $(OX)\sha3.obj >> $@ echo $(OX)\shell.obj >> $@ echo $(OX)\shun.obj >> $@ echo $(OX)\sitemap.obj >> $@ echo $(OX)\skins.obj >> $@ echo $(OX)\sqlcmd.obj >> $@ echo $(OX)\sqlite3.obj >> $@ echo $(OX)\stash.obj >> $@ |
| ︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 | translate$E $** > $@ $(OX)\gzip$O : gzip_.c gzip.h $(TCC) /Fo$@ -c gzip_.c gzip_.c : $(SRCDIR)\gzip.c translate$E $** > $@ $(OX)\http$O : http_.c http.h $(TCC) /Fo$@ -c http_.c http_.c : $(SRCDIR)\http.c translate$E $** > $@ | > > > > > > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 | translate$E $** > $@ $(OX)\gzip$O : gzip_.c gzip.h $(TCC) /Fo$@ -c gzip_.c gzip_.c : $(SRCDIR)\gzip.c translate$E $** > $@ $(OX)\hname$O : hname_.c hname.h $(TCC) /Fo$@ -c hname_.c hname_.c : $(SRCDIR)\hname.c translate$E $** > $@ $(OX)\http$O : http_.c http.h $(TCC) /Fo$@ -c http_.c http_.c : $(SRCDIR)\http.c translate$E $** > $@ |
| ︙ | ︙ | |||
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 | translate$E $** > $@ $(OX)\sha1$O : sha1_.c sha1.h $(TCC) /Fo$@ -c sha1_.c sha1_.c : $(SRCDIR)\sha1.c translate$E $** > $@ $(OX)\shun$O : shun_.c shun.h $(TCC) /Fo$@ -c shun_.c shun_.c : $(SRCDIR)\shun.c translate$E $** > $@ | > > > > > > > > > > > > | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 | translate$E $** > $@ $(OX)\sha1$O : sha1_.c sha1.h $(TCC) /Fo$@ -c sha1_.c sha1_.c : $(SRCDIR)\sha1.c translate$E $** > $@ $(OX)\sha1hard$O : sha1hard_.c sha1hard.h $(TCC) /Fo$@ -c sha1hard_.c sha1hard_.c : $(SRCDIR)\sha1hard.c translate$E $** > $@ $(OX)\sha3$O : sha3_.c sha3.h $(TCC) /Fo$@ -c sha3_.c sha3_.c : $(SRCDIR)\sha3.c translate$E $** > $@ $(OX)\shun$O : shun_.c shun.h $(TCC) /Fo$@ -c shun_.c shun_.c : $(SRCDIR)\shun.c translate$E $** > $@ |
| ︙ | ︙ | |||
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 | finfo_.c:finfo.h \ foci_.c:foci.h \ fshell_.c:fshell.h \ fusefs_.c:fusefs.h \ glob_.c:glob.h \ graph_.c:graph.h \ gzip_.c:gzip.h \ http_.c:http.h \ http_socket_.c:http_socket.h \ http_ssl_.c:http_ssl.h \ http_transport_.c:http_transport.h \ import_.c:import.h \ info_.c:info.h \ json_.c:json.h \ | > | 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 | finfo_.c:finfo.h \ foci_.c:foci.h \ fshell_.c:fshell.h \ fusefs_.c:fusefs.h \ glob_.c:glob.h \ graph_.c:graph.h \ gzip_.c:gzip.h \ hname_.c:hname.h \ http_.c:http.h \ http_socket_.c:http_socket.h \ http_ssl_.c:http_ssl.h \ http_transport_.c:http_transport.h \ import_.c:import.h \ info_.c:info.h \ json_.c:json.h \ |
| ︙ | ︙ | |||
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 | regexp_.c:regexp.h \ report_.c:report.h \ rss_.c:rss.h \ schema_.c:schema.h \ search_.c:search.h \ setup_.c:setup.h \ sha1_.c:sha1.h \ shun_.c:shun.h \ sitemap_.c:sitemap.h \ skins_.c:skins.h \ sqlcmd_.c:sqlcmd.h \ stash_.c:stash.h \ stat_.c:stat.h \ statrep_.c:statrep.h \ | > > | 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 | regexp_.c:regexp.h \ report_.c:report.h \ rss_.c:rss.h \ schema_.c:schema.h \ search_.c:search.h \ setup_.c:setup.h \ sha1_.c:sha1.h \ sha1hard_.c:sha1hard.h \ sha3_.c:sha3.h \ shun_.c:shun.h \ sitemap_.c:sitemap.h \ skins_.c:skins.h \ sqlcmd_.c:sqlcmd.h \ stash_.c:stash.h \ stat_.c:stat.h \ statrep_.c:statrep.h \ |
| ︙ | ︙ |
Changes to www/branching.wiki.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | <tr><td align="center"> <img src="branch01.gif" width=280 height=68><br> Figure 1 </td></tr></table> Each circle represents a check-in. For the sake of clarity, the check-ins are given small consecutive numbers. In a real system, of course, the | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <tr><td align="center"> <img src="branch01.gif" width=280 height=68><br> Figure 1 </td></tr></table> Each circle represents a check-in. For the sake of clarity, the check-ins are given small consecutive numbers. In a real system, of course, the check-in numbers would be long hexadecimal hashes since it is not possible to allocate collision-free sequential numbers in a distributed system. But as sequential numbers are easier to read, we will substitute them for the long hashes in this document. The arrows in figure 1 show the evolution of a project. The initial check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 was created by making edits to check-in 1 and then committing those edits. We say that 2 is a <i>child</i> of 1 and that 1 is a <i>parent</i> of 2. Check-in 3 is derived from check-in 2, making |
| ︙ | ︙ | |||
191 192 193 194 195 196 197 | The initial check-in of every repository has two propagating tags. In figure 5, that initial check-in is check-in 1. The <b>branch</b> tag tells (by its value) what branch the check-in is a member of. The default branch is called "trunk." All tags that begin with "<b>sym-</b>" are symbolic name tags. When a symbolic name tag is attached to a check-in, that allows you to refer to that check-in by its symbolic | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | The initial check-in of every repository has two propagating tags. In figure 5, that initial check-in is check-in 1. The <b>branch</b> tag tells (by its value) what branch the check-in is a member of. The default branch is called "trunk." All tags that begin with "<b>sym-</b>" are symbolic name tags. When a symbolic name tag is attached to a check-in, that allows you to refer to that check-in by its symbolic name rather than by its hexadecimal hash name. When a symbolic name tag propagates (as does the <b>sym-trunk</b> tag) then referring to that name is the same as referring to the most recent check-in with that name. Thus the two tags on check-in 1 cause all descendants to be in the "trunk" branch and to have the symbolic name "trunk." Check-in 4 has a <b>branch</b> tag which changes the name of the branch to "test." The branch tag on check-in 4 propagates to check-ins 6 and 9. |
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 | <title>Change Log</title> | | | > > > > > > > > > > > > > > > > > > | 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 |
<title>Change Log</title>
<a name='v2_1'></a>
<h2>Changes for Version 2.1 (2017-03-??)</h2>
* Add support for [./hashpolicy.wiki|hash policies] that control which
of the Hardened-SHA1 or SHA3-256 algorithms is used to name new
artifacts.
* Add the "gshow" and "gcat" subcommands to [/help?cmd=stash|fossil stash].
* Add the [/help?cmd=/juvlist|/juvlist] web page and use it to construct
the [/uv/download.html|Download Page] of the Fossil self-hosting website
using Ajax.
<a name='v2_0'></a>
<h2>Changes for Version 2.0 (2017-03-03)</h2>
* Use the
[https://github.com/cr-marcstevens/sha1collisiondetection|hardened SHA1]
implemenation by Marc Stevens and Dan Shumow.
* Add the ability to read and understand
[./fileformat.wiki#names|artifact names] that are based on SHA3-256
rather than SHA1, but do not actually generate any such names.
* Added the [/help?cmd=sha3sum|sha3sum] command.
* Update the built-in SQLite to version 3.17.0.
<a name='v1_37'></a>
<h2>Changes for Version 1.37 (2017-01-16)</h2>
* Add checkbox widgets to various web pages. See [/technote/8d18bf27e9|
this technote] for more information. To get the checkboxes to look as
|
| ︙ | ︙ |
Changes to www/checkin_names.wiki.
1 2 3 4 5 6 7 8 | <title>Check-in Names</title> <table align="right" border="1" width="33%" cellpadding="10"> <tr><td> <h3>Executive Summary</h3> <p>A check-in can be identified using any of the following names: <ul> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <title>Check-in Names</title> <table align="right" border="1" width="33%" cellpadding="10"> <tr><td> <h3>Executive Summary</h3> <p>A check-in can be identified using any of the following names: <ul> <li> Cryptographic hash prefix <li> Tag or branchname <li> Timestamp: <i>YYYY-MM-DD HH:MM:SS</i> <li> <i>tag-name</i> <big><b>:</b></big> <i>timestamp</i> <li> <b>root :</b> <i>branchname</i> <li> Special names: <ul> <li> <b>tip</b> |
| ︙ | ︙ | |||
42 43 44 45 46 47 48 | determines which version of the documentation to display. Fossil provides a variety of ways to specify a check-in. This document describes the various methods. <h2>Canonical Check-in Name</h2> | | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | determines which version of the documentation to display. Fossil provides a variety of ways to specify a check-in. This document describes the various methods. <h2>Canonical Check-in Name</h2> The canonical name of a check-in is the hash of its [./fileformat.wiki#manifest | manifest] expressed as a 40-or-more character lowercase hexadecimal number. For example: <blockquote><pre> fossil info e5a734a19a9826973e1d073b49dc2a16aa2308f9 </pre></blockquote> The full 40+ character hash is unwieldy to remember and type, though, so Fossil also accepts a unique prefix of the hash, using any combination of upper and lower case letters, as long as the prefix is at least 4 characters long. Hence the following commands all accomplish the same thing as the above: <blockquote><pre> fossil info e5a734a19a9 |
| ︙ | ︙ |
Changes to www/customskin.md.
| ︙ | ︙ | |||
175 176 177 178 179 180 181 |
without the leading "/" and without query parameters.
Examples: "timeline", "doc/trunk/README.txt", "wiki".
* **csrf_token** - A token used to prevent cross-site request forgery.
* **release_version** - The release version of Fossil. Ex: "1.31"
| | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
without the leading "/" and without query parameters.
Examples: "timeline", "doc/trunk/README.txt", "wiki".
* **csrf_token** - A token used to prevent cross-site request forgery.
* **release_version** - The release version of Fossil. Ex: "1.31"
* **manifest_version** - A prefix on the check-in hash of the
specific version of fossil that is running. Ex: "\[47bb6432a1\]"
* **manifest_date** - The date of the source-code check-in for the
version of fossil that is running.
* **compiler_name** - The name and version of the compiler used to
build the fossil executable.
|
| ︙ | ︙ |
Changes to www/fileformat.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <title>Fossil File Formats</title> <h1 align="center"> Fossil File Formats </h1> The global state of a fossil repository is kept simple so that it can endure in useful form for decades or centuries. A fossil repository is intended to be readable, searchable, and extensible by people not yet born. The global state of a fossil repository is an unordered set of <i>artifacts</i>. An artifact might be a source code file, the text of a wiki page, | | > > > > | | > | > > > | | | > | > > > | > > > > > > > > | > > > > > > | > | > > > > > > > > > > > > | < < < | | | | < < < < < < < < < < < < < < < < < < < < | | | | 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 | <title>Fossil File Formats</title> <h1 align="center"> Fossil File Formats </h1> The global state of a fossil repository is kept simple so that it can endure in useful form for decades or centuries. A fossil repository is intended to be readable, searchable, and extensible by people not yet born. The global state of a fossil repository is an unordered set of <i>artifacts</i>. An artifact might be a source code file, the text of a wiki page, part of a trouble ticket, a description of a check-in including all the files in that check-in with the check-in comment and so forth. Artifacts are broadly grouped into two types: content artifacts and structural artifacts. Content artifacts are the raw project source-code files that are checked into the repository. Structural artifacts have special formatting rules and are used to show the relationships between other artifacts in the repository. It is possible for an artifact to be both a structure artifact and a content artifact, though this is rare. Artifacts can be text or binary. In addition to the global state, each fossil repository also contains local state. The local state consists of web-page formatting preferences, authorized users, ticket display and reporting formats, and so forth. The global state is shared in common among all repositories for the same project, whereas the local state is often different in separate repositories. The local state is not versioned and is not synchronized with the global state. The local state is not composed of artifacts and is not intended to be enduring. This document is concerned with global state only. Local state is only mentioned here in order to distinguish it from global state. <a name="names"></a> <h2>1.0 Artifact Names</h2> Each artifact in the repository is named by a hash of its content. No prefixes, suffixes, or other information is added to an artifact before the hash is computed. The artifact name is just the (lower-case hexadecimal) hash of the raw artifact. Fossil currently computes artifact names using either SHA1 or SHA3-256. It is relatively easy to add new algorithms in the future, but there are no plans to do so at this time. When referring to artifacts in using tty commands or webpage URLs, it is sufficient to specify a unique prefix for the artifact name. If the input prefix is not unique, Fossil will show an error. Within a structural artifact, however, all references to other artifacts must be the complete hash. Prior to Fossil version 2.0, all names were formed from the SHA1 hash of the artifact. The key innovation in Fossil 2.0 was adding support for alternative hash algorithms. <a name="structural"></a> <h2>2.0 Structural Artifacts</h2> A structural artifact is an artifact with a particular format that is used to define the relationships between other artifacts in the repository. Fossil recognizes the following kinds of structural artifacts: <ul> <li> [#manifest | Manifests] </li> <li> [#cluster | Clusters] </li> <li> [#ctrl | Control Artifacts] </li> <li> [#wikichng | Wiki Pages] </li> <li> [#tktchng | Ticket Changes] </li> <li> [#attachment | Attachments] </li> <li> [#event | TechNotes] </li> </ul> These seven structural artifact types are described in subsections below. Structural artifacts are ASCII text. The artifact may be PGP clearsigned. After removal of the PGP clearsign header and suffix (if any) a structural artifact consists of one or more "cards" separated by a single newline (ASCII: 0x0a) character. Each card begins with a single character "card type". Zero or more arguments may follow the card type. All arguments are separated from each other and from the card-type character by a single space character. There is no surplus white space between arguments and no leading or trailing whitespace except for the newline character that acts as the card separator. All cards must be in strict lexicographical order. There may not be any duplicate cards. In the current implementation (as of 2017-02-27) the artifacts that make up a fossil repository are stored as delta- and zlib-compressed blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This is an implementation detail and might change in a future release. For the purpose of this article "file format" means the format of the artifacts, not how the artifacts are stored on disk. It is the artifact format that is intended to be enduring. The specifics of how artifacts are stored on disk, though stable, is not intended to live as long as the artifact format. <a name="manifest"></a> <h3>2.1 The Manifest</h3> A manifest defines a check-in. A manifest contains a list of artifacts for each file in the project and the corresponding filenames, as well as information such as parent check-ins, the username of the programmer who created the check-in, the date and time when the check-in was created, and any check-in comments associated with the check-in. Allowed cards in the manifest are as follows: <blockquote> <b>B</b> <i>baseline-manifest</i><br> <b>C</b> <i>checkin-comment</i><br> <b>D</b> <i>time-and-date-stamp</i><br> <b>F</b> <i>filename</i> ?<i>hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br> <b>N</b> <i>mimetype</i><br> <b>P</b> <i>artifact-hash</i>+<br> <b>Q</b> (<b>+</b>|<b>-</b>)<i>artifact-hash</i> ?<i>artifact-hash</i>?<br> <b>R</b> <i>repository-checksum</i><br> <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br> <b>U</b> <i>user-login</i><br> <b>Z</b> <i>manifest-checksum</i> </blockquote> A manifest may optionally have a single B-card. The B-card specifies |
| ︙ | ︙ | |||
143 144 145 146 147 148 149 | that is part of the check-in. There are one, two, three, or four arguments. The first argument is the pathname of the file in the check-in relative to the root of the project file hierarchy. No ".." or "." directories are allowed within the filename. Space characters are escaped as in C-card comment text. Backslash characters and newlines are not allowed within filenames. The directory separator character is a forward slash (ASCII 0x2F). The second argument to the | | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | that is part of the check-in. There are one, two, three, or four arguments. The first argument is the pathname of the file in the check-in relative to the root of the project file hierarchy. No ".." or "." directories are allowed within the filename. Space characters are escaped as in C-card comment text. Backslash characters and newlines are not allowed within filenames. The directory separator character is a forward slash (ASCII 0x2F). The second argument to the F-card is the lower-case hexadecimal artifact hash of the content artifact. The second argument is required for baseline manifests but is optional for delta manifests. When the second argument to the F-card is omitted, it means that the file has been deleted relative to the baseline (files removed in baseline manifests versions are <em>not</em> added as F-cards). The optional 3rd argument defines any special access permissions associated with the file. This can be defined as "x" to mean that the file is executable or "l" |
| ︙ | ︙ | |||
165 166 167 168 169 170 171 | A manifest has zero or one N-cards. The N-card specifies the mimetype for the text in the comment of the C-card. If the N-card is omitted, a default mimetype is used. A manifest has zero or one P-cards. Most manifests have one P-card. The P-card has a varying number of arguments that define other manifests from which the current manifest | | | | | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | A manifest has zero or one N-cards. The N-card specifies the mimetype for the text in the comment of the C-card. If the N-card is omitted, a default mimetype is used. A manifest has zero or one P-cards. Most manifests have one P-card. The P-card has a varying number of arguments that define other manifests from which the current manifest is derived. Each argument is a lowercase hexadecimal artifact hash of a predecessor manifest. All arguments to the P-card must be unique within that card. The first argument is the artifact hash of the direct ancestor of the manifest. Other arguments define manifests with which the first was merged to yield the current manifest. Most manifests have a P-card with a single argument. The first manifest in the project has no ancestors and thus has no P-card or (depending on the Fossil version) an empty P-card (no arguments). A manifest has zero or more Q-cards. A Q-card is similar to a P-card |
| ︙ | ︙ | |||
227 228 229 230 231 232 233 | the login of the user who created the manifest. The login name is encoded using the same character escapes as is used for the check-in comment argument to the C-card. A manifest must have a single Z-card as its last line. The argument to the Z-card is a 32-character lowercase hexadecimal MD5 hash of all prior lines of the manifest up to and including the newline | | > | < < < < < < < < < < < < < < < | | < < < < < < | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | the login of the user who created the manifest. The login name is encoded using the same character escapes as is used for the check-in comment argument to the C-card. A manifest must have a single Z-card as its last line. The argument to the Z-card is a 32-character lowercase hexadecimal MD5 hash of all prior lines of the manifest up to and including the newline character that immediately precedes the "Z", excluding any PGP clear-signing prefix. The Z-card is a sanity check to prove that the manifest is well-formed and consistent. A sample manifest from Fossil itself can be seen [/artifact/28987096ac | here]. <a name="cluster"></a> <h3>2.2 Clusters</h3> A cluster is an artifact that declares the existence of other artifacts. Clusters are used during repository synchronization to help reduce network traffic. As such, clusters are an optimization and may be removed from a repository without loss or damage to the underlying project code. Allowed cards in the cluster are as follows: <blockquote> <b>M</b> <i>artifact-id</i><br /> <b>Z</b> <i>checksum</i> </blockquote> A cluster contains one or more "M" cards followed by a single "Z" card. Each M card has a single argument which is the artifact ID of another artifact in the repository. The Z card works exactly like the Z card of a manifest. The argument to the Z card is the lower-case hexadecimal representation of the MD5 checksum of all prior cards in the cluster. The Z-card is required. An example cluster from Fossil can be seen [/artifact/d03dbdd73a2a8 | here]. <a name="ctrl"></a> <h3>2.3 Control Artifacts</h3> Control artifacts are used to assign properties to other artifacts within the repository. Allowed cards in a control artifact are as follows: <blockquote> <b>D</b> <i>time-and-date-stamp</i><br /> <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <i>artifact-id</i> ?<i>value</i>?<br /> <b>U</b> <i>user-name</i><br /> <b>Z</b> <i>checksum</i><br /> |
| ︙ | ︙ | |||
336 337 338 339 340 341 342 | The U card is the name of the user that created the control artifact. The Z card is the usual required artifact checksum. An example control artifacts can be seen [/info/9d302ccda8 | here]. <a name="wikichng"></a> | | > | < < | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | The U card is the name of the user that created the control artifact. The Z card is the usual required artifact checksum. An example control artifacts can be seen [/info/9d302ccda8 | here]. <a name="wikichng"></a> <h3>2.4 Wiki Pages</h3> A wiki artifact defines a single version of a single wiki page. Wiki artifacts accept the following card types: <blockquote> <b>D</b> <i>time-and-date-stamp</i><br /> <b>L</b> <i>wiki-title</i><br /> <b>N</b> <i>mimetype</i><br /> <b>P</b> <i>parent-artifact-id</i>+<br /> |
| ︙ | ︙ | |||
373 374 375 376 377 378 379 | that terminates the W card. The wiki text is always followed by one extra newline. An example wiki artifact can be seen [/artifact?name=7b2f5fd0e0&txt=1 | here]. <a name="tktchng"></a> | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | that terminates the W card. The wiki text is always followed by one extra newline. An example wiki artifact can be seen [/artifact?name=7b2f5fd0e0&txt=1 | here]. <a name="tktchng"></a> <h3>2.5 Ticket Changes</h3> A ticket-change artifact represents a change to a trouble ticket. The following cards are allowed on a ticket change artifact: <blockquote> <b>D</b> <i>time-and-date-stamp</i><br /> <b>J</b> ?<b>+</b>?<i>name</i> ?<i>value</i>?<br /> |
| ︙ | ︙ | |||
419 420 421 422 423 424 425 | The field name and value are both encoded using the character escapes defined for the C card of a manifest. An example ticket-change artifact can be seen [/artifact/91f1ec6af053 | here]. <a name="attachment"></a> | | | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | The field name and value are both encoded using the character escapes defined for the C card of a manifest. An example ticket-change artifact can be seen [/artifact/91f1ec6af053 | here]. <a name="attachment"></a> <h3>2.6 Attachments</h3> An attachment artifact associates some other artifact that is the attachment (the source artifact) with a ticket or wiki page or technical note to which the attachment is connected (the target artifact). The following cards are allowed on an attachment artifact: |
| ︙ | ︙ | |||
461 462 463 464 465 466 467 | If an attachment is added anonymously, then the U card may be omitted. The Z card is the usual checksum over the rest of the attachment artifact. The Z card is required. <a name="event"></a> | | | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | If an attachment is added anonymously, then the U card may be omitted. The Z card is the usual checksum over the rest of the attachment artifact. The Z card is required. <a name="event"></a> <h3>2.7 Technical Notes</h3> A technical note or "technote" artifact (formerly known as an "event" artifact) associates a timeline comment and a page of text (similar to a wiki page) with a point in time. Technotes can be used to record project milestones, release notes, blog entries, process checkpoints, or news articles. The following cards are allowed on an technote artifact: |
| ︙ | ︙ | |||
530 531 532 533 534 535 536 | technote. The format of the W card is exactly the same as for a [#wikichng | wiki artifact]. The Z card is the required checksum over the rest of the artifact. <a name="summary"></a> | | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | technote. The format of the W card is exactly the same as for a [#wikichng | wiki artifact]. The Z card is the required checksum over the rest of the artifact. <a name="summary"></a> <h2>3.0 Card Summary</h2> The following table summarizes the various kinds of cards that appear on Fossil artifacts. A blank entry means that combination of card and artifact is not legal. A number or range of numbers indicates the number of times a card may (or must) appear in the corresponding artifact type. e.g. a value of 1 indicates a required unique card and 1+ indicates that one or more such cards are required. |
| ︙ | ︙ | |||
737 738 739 740 741 742 743 | <td align=center><b>1</b></td> <td align=center><b>1</b></td> </tr> </table> <a name="addenda"></a> | | | | 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | <td align=center><b>1</b></td> <td align=center><b>1</b></td> </tr> </table> <a name="addenda"></a> <h2>4.0 Addenda</h2> This section contains additional information which may be useful when implementing algorithms described above. <h3>4.1 R-Card Hash Calculation</h3> Given a manifest file named <tt>MF</tt>, the following Bash shell code demonstrates how to compute the value of the R card in that manifest. This example uses manifest [28987096ac]. Lines starting with <tt>#</tt> are shell input and other lines are output. This demonstration assumes that the file versions represented by the input manifest are checked out under the current directory. |
| ︙ | ︙ |
Changes to www/fossil-v-git.wiki.
| ︙ | ︙ | |||
65 66 67 68 69 70 71 | website using Fossil can be done in minutes, whereas doing the same using Git requires hours or days. <h3>3.2 Database</h3> The baseline data structures for Fossil and Git are the same (modulo formatting details). Both systems store check-ins as immutable | | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | website using Fossil can be done in minutes, whereas doing the same using Git requires hours or days. <h3>3.2 Database</h3> The baseline data structures for Fossil and Git are the same (modulo formatting details). Both systems store check-ins as immutable objects referencing their immediate ancestors and named by a cryptographic hash of the check-in content. The difference is that Git stores its objects as individual files in the ".git" folder or compressed into bespoke "pack-files", whereas Fossil stores its objects in a relational ([https://www.sqlite.org/|SQLite]) database file. To put it another way, Git uses an ad-hoc pile-of-files key/value database whereas Fossil uses a proven, general-purpose SQL database. This |
| ︙ | ︙ |
Added www/hashpolicy.wiki.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | <title>Hash Policy</title> <h2> Executive Summary, Or How To Avoid Reading This Article </h2> There is much angst over the [http://www.shattered.io|Shattered attack] against SHA1. If you are concerned about this and its implications for Fossil, simply upgrade to Fossil 2.0 or later and the problem will go away. Everything will continue to work as before. All of your legacy repositories will continue to work and all of your old check-ins will still have the same name. Your workflow will be unchanged. But if you are curious and want a deeper understanding of what is going on, read on... <h2> Introduction </h2> The first snapshot-based distributed version control system was [http://www.monotone.ca|Monotone]. Many of the ideas behind the design of Fossil were copied from Monotone, including the use of a SHA1 hash to assign names to artifacts. Git and Mercurial did the same thing. The SHA1 hash algorithm is used only to create names for artifacts in Fossil (and in Git, Mercurial, and Monotone). It is not used for security. Nevertheless, when the [http://www.shattered.io|Shattered attack] found two different PDF files with the same SHA1 hash, many users learned that "SHA1 is broken". They see that Fossil (and Git, Mercurial, and Monotone) use SHA1 and they therefore conclude that "Fossil is broken". This is not true, but it is a public relations problem. So the decision was made to migrate Fossil away from SHA1. This article describes how that migration is occurring. <h2>Use Of Hardened SHA1</h2> In Fossil version 2.0 ([/timeline?c=version-2.0|2017-03-03]), the internal SHA1 implementation was changed from a generic FIPS PUB 180-4 SHA1 implementation to a "Hardened SHA1" [[https://github.com/cr-marcstevens/sha1collisiondetection|1]] [[https://marc-stevens.nl/research/papers/C13-S.pdf|2]]. The Hardened SHA1 implement automatically detects when the artifact being hashed is specifically designed to exploit the known weaknesses in the SHA1 algorithm, and when it detects such an attack it changes the hash algorithm (by increasing the number of rounds in the compression function) to make the algorithm secure again. If the attack detection gets a false possible, that means that Hardened SHA1 will get a different answer than the standard FIPS PUB 180-4 SHA1, but the creators of Hardened SHA1 (see the second paper [[https://marc-stevens.nl/research/papers/C13-S.pdf|2]]) report that the probability of a false positive is vanishingly small - less than 1 false positive out of 10<sup><font size=1>27</font></sup> hashes. Hardened SHA1 is slower (and a lot bigger) but Fossil does not do that much hashing, so performance is not really an issue. All versions of Fossil moving forward will use Hardened SHA1. So if someone says "SHA1 is broken, and Fossil uses SHA1, therefore Fossil is broken", you can rebut the argument by pointing out that Fossil uses <em>Hardened SHA1</em> not generic SHA1 and Hardened SHA1 is <em>not</em> broken. <h2>Support For SHA3-256</h2> Prior to Fossil version 2.0 ([/timeline?c=version-2.0|2017-03-03]), all artifacts in all Fossil repositories were named by only a SHA1 hash. Version 2.0 extended the [./fileformat.wiki|Fossil file format] to allow artifacts to be named by either SHA1 or SHA3-256 hashes. (SHA3-256 is the only variant of SHA3 that Fossil uses for artifact naming, so for the remainder of this article it will be called simply "SHA3". Similarly, "Hardened SHA1" will shortened to "SHA1" in the sequel.) Other than permitting the use of SHA3 in addition to SHA1, there were no file format changes in Fossil version 2.0 relative to the previous version 1.37. Both Fossil 2.0 and Fossil 1.37 read and write all the same repositories and sync with one another, as long as none of the repositories contain artifacts named using SHA3. If a repository does contain artifacts named using SHA3, Fossil 1.37 will not know how to interpret those artifacts and will generate various warnings and errors. <h2>How Fossil Decides Which Hash Algorithm To Use</h2> If newer versions of Fossil are able to use either SHA1 or SHA3 to name artifacts, which hash algorithm is actually used? That question is answered by the "hash policy". These are the supported hash policies: <table cellpadding=10> <tr> <td valign='top'>sha1</td> <td>Name all new artifacts using the (Hardened) SHA1 hash algorithm.</td> </tr> <tr> <td valign='top'>auto</td> <td>Name new artifacts using the SHA1 hash algorithm. But if any artifacts are encountered which are already named using SHA3, then automatically switch the hash policy to "sha3"</td> </tr> <tr> <td valign='top'>sha3</td> <td>Name new artifacts using the SHA3 hash algorithm if the artifact does not already have a SHA1 name. If the artifact already has a SHA1 name, then continue to use the older SHA1 name. Use SHA3 for new artifacts that have never before been encountered.</td> </tr> <tr> <td valign='top'>sha3-only</td> <td>Name new artifacts using the SHA3 hash algorithm even if the artifact already has a SHA1 name. In other words, force the use of SHA3. This can cause some artifacts to be added to the respository twice, once under their SHA1 name and again under their SHA3 name. But delta compression will prevent that from causing repository size problems.</td> </tr> <tr> <td valign='top'>shun-sha1</td> <td>Like "sha3-only" but at this level do not accept a push of SHA1-named artifacts. If another Fossil instance tries to push a SHA1-named artifact, that artifact is discarded and ignored. </tr> </table> For Fossil 2.0, and obviously also for Fossil 1.37 and before, the only hash policy supported was "sha1". All new artifacts were named using their SHA1 hash. Even though Fossil 2.0 was capable of understanding SHA3 hashes, it never actually generates any SHA3 hashes. Beginning with Fossil 2.1, the default hash policy for legacy repositories changed to "auto". That means Fossil 2.1 will continue to generate only SHA1 hashes until it encounters one artifact with a SHA3 hash. Once a single SHA3 hash is seen, Fossil automatically switches to "sha3" mode and thereafter generates only SHA3 hashes. When a new repository is created by cloning, the hash policy is copied from the parent. For new repositories created using the [/help?cmd=new|fossil new] command the default hash policy is "sha3". That means new repositories will normally hold nothing except SHA3 hashes. The hash policy for new repositories can be overridden using the "--sha1" option to the "fossil new" command. Even after upgrading to Fossil 2.1, Fossil will continue to use nothing but SHA1 hashes on legacy repositories, thus preserving complete compatibility with Fossil 1.37 and before. If you want Fossil to go ahead and start using SHA3 hashes, change the hash policy to "sha3" using a command like this: <blockquote><verbatim> fossil hash-policy sha3 </verbatim></blockquote> The next check-in will use a SHA3 hash. And when that check-in is pushed to colleagues, their copies of Fossil will see the new SHA3-named artifact and automatically convert to SHA3 as well. Of course, if some members of your team stubbornly refuse to upgrade past Fossil 1.37, you should avoid changing the hash policy and creating artifacts with SHA3 names, because once you do that your recalcitrant coworkers will no longer be able to collaborate. <h2>A Pure SHA3 Future</h2> At some point in the future, years from now, after everybody has finally upgraded to Fossil 2.0 or later, the default hash policy will probably change to "sha3", or maybe even "shun-sha1". By the time that happens, you will probably already be using SHA3 on all your projects and so you are unlikely to notice. |
Changes to www/mkdownload.tcl.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 42 |
if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
set filehash($fn) [lindex $line 1]
set avers($version) 1
}
}
close $in
set vdate(1.37) 2017-01-15
| > < | | 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 |
if {[regexp -- {-(\d\.\d+)\.(tar\.gz|zip)$} $fn all version]} {
set filehash($fn) [lindex $line 1]
set avers($version) 1
}
}
close $in
set vdate(2.0) 2017-03-03
set vdate(1.37) 2017-01-15
# Do all versions from newest to oldest
#
foreach vers [lsort -decr -real [array names avers]] {
# set hr "../timeline?c=version-$vers;y=ci"
set v2 v[string map {. _} $vers]
set hr "../doc/trunk/www/changes.wiki#$v2"
puts $out "<tr><td colspan=6 align=left><hr>"
puts $out "<center><b><a href=\"$hr\">Version $vers</a>"
if {[info exists vdate($vers)]} {
set hr2 "../timeline?c=version-$vers&y=ci"
puts $out " (<a href='$hr2'>$vdate($vers)</a>)"
}
puts $out "</b></center>"
puts $out "</td></tr>"
puts $out "<tr>"
foreach {prefix img desc} {
fossil-linux linux.gif {Linux 3.x x64}
fossil-macosx mac.gif {Mac 10.x x86}
fossil-openbsd-x86 openbsd.gif {OpenBSD 5.x x86}
fossil-w32 win32.gif {Windows}
fossil-src src.gif {Source Tarball}
} {
set glob download/$prefix*-$vers*
set filename [array names filesize $glob]
|
| ︙ | ︙ |
Changes to www/mkindex.tcl.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
faq.wiki {Frequently Asked Questions}
fileformat.wiki {Fossil File Format}
fiveminutes.wiki {Update and Running in 5 Minutes as a Single User}
foss-cklist.wiki {Checklist For Successful Open-Source Projects}
fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
fossil-v-git.wiki {Fossil Versus Git}
hacker-howto.wiki {Hacker How-To}
/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}
makefile.wiki {The Fossil Build Process}
/md_rules {Markdown Formatting Rules}
newrepo.wiki {How To Create A New Fossil Repository}
| > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
faq.wiki {Frequently Asked Questions}
fileformat.wiki {Fossil File Format}
fiveminutes.wiki {Update and Running in 5 Minutes as a Single User}
foss-cklist.wiki {Checklist For Successful Open-Source Projects}
fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
fossil-v-git.wiki {Fossil Versus Git}
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}
makefile.wiki {The Fossil Build Process}
/md_rules {Markdown Formatting Rules}
newrepo.wiki {How To Create A New Fossil Repository}
|
| ︙ | ︙ |
Changes to www/permutedindex.html.
| ︙ | ︙ | |||
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 | <li><a href="delta_encoder_algorithm.wiki">Algorithm — Fossil Delta Encoding</a></li> <li><a href="blame.wiki">Algorithm Of Fossil — The Annotate/Blame</a></li> <li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil — The</a></li> <li><a href="customskin.md">Appearance of Web Pages — Theming: Customizing The</a></li> <li><a href="faq.wiki">Asked Questions — Frequently</a></li> <li><a href="password.wiki">Authentication — Password Management And</a></li> <li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li> <li><a href="antibot.wiki">Bots — Defense against Spiders and</a></li> <li><a href="private.wiki">Branches — 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 — The Fossil</a></li> <li><a href="aboutcgi.wiki">CGI Works In Fossil — How</a></li> <li><a href="changes.wiki">Changelog — Fossil</a></li> <li><a href="checkin_names.wiki"><b>Check-in And Version Names</b></a></li> <li><a href="checkin.wiki"><b>Check-in Checklist</b></a></li> <li><a href="checkin.wiki">Checklist — Check-in</a></li> <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> <li><a href="foss-cklist.wiki"><b>Checklist For Successful Open-Source Projects</b></a></li> <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> <li><a href="childprojects.wiki"><b>Child Projects</b></a></li> <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> <li><a href="style.wiki">Code Style Guidelines — Source</a></li> <li><a href="../../../help">Commands and Webpages — Lists of</a></li> <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> | > > | 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 | <li><a href="delta_encoder_algorithm.wiki">Algorithm — Fossil Delta Encoding</a></li> <li><a href="blame.wiki">Algorithm Of Fossil — The Annotate/Blame</a></li> <li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil — The</a></li> <li><a href="customskin.md">Appearance of Web Pages — Theming: Customizing The</a></li> <li><a href="faq.wiki">Asked Questions — Frequently</a></li> <li><a href="password.wiki">Authentication — Password Management And</a></li> <li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li> <li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 — Hash Policy: Choosing</a></li> <li><a href="antibot.wiki">Bots — Defense against Spiders and</a></li> <li><a href="private.wiki">Branches — 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 — The Fossil</a></li> <li><a href="aboutcgi.wiki">CGI Works In Fossil — How</a></li> <li><a href="changes.wiki">Changelog — Fossil</a></li> <li><a href="checkin_names.wiki"><b>Check-in And Version Names</b></a></li> <li><a href="checkin.wiki"><b>Check-in Checklist</b></a></li> <li><a href="checkin.wiki">Checklist — Check-in</a></li> <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> <li><a href="foss-cklist.wiki"><b>Checklist For Successful Open-Source Projects</b></a></li> <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> <li><a href="childprojects.wiki"><b>Child Projects</b></a></li> <li><a href="hashpolicy.wiki">Choosing Between SHA1 and SHA3-256 — Hash Policy:</a></li> <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> <li><a href="style.wiki">Code Style Guidelines — Source</a></li> <li><a href="../../../help">Commands and Webpages — Lists of</a></li> <li><a href="build.wiki"><b>Compiling and Installing Fossil</b></a></li> <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> |
| ︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 | <li><a href="quotes.wiki">Git, and DVCSes in General — Quotes: What People Are Saying About Fossil,</a></li> <li><a href="env-opts.md">Global Options — Environment Variables and</a></li> <li><a href="customgraph.md">Graph — Theming: Customizing the Timeline</a></li> <li><a href="quickstart.wiki">Guide — Fossil Quick Start</a></li> <li><a href="style.wiki">Guidelines — Source Code Style</a></li> <li><a href="hacker-howto.wiki"><b>Hacker How-To</b></a></li> <li><a href="adding_code.wiki"><b>Hacking Fossil</b></a></li> <li><a href="hints.wiki">Hints — Fossil Tips And Usage</a></li> <li><a href="index.wiki"><b>Home Page</b></a></li> <li><a href="selfhost.wiki">Hosting Repositories — Fossil Self</a></li> <li><a href="aboutcgi.wiki"><b>How CGI Works In Fossil</b></a></li> <li><a href="server.wiki"><b>How To Configure A Fossil Server</b></a></li> <li><a href="newrepo.wiki"><b>How To Create A New Fossil Repository</b></a></li> <li><a href="encryptedrepos.wiki"><b>How To Use Encrypted Repositories</b></a></li> | > | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | <li><a href="quotes.wiki">Git, and DVCSes in General — Quotes: What People Are Saying About Fossil,</a></li> <li><a href="env-opts.md">Global Options — Environment Variables and</a></li> <li><a href="customgraph.md">Graph — Theming: Customizing the Timeline</a></li> <li><a href="quickstart.wiki">Guide — Fossil Quick Start</a></li> <li><a href="style.wiki">Guidelines — Source Code Style</a></li> <li><a href="hacker-howto.wiki"><b>Hacker How-To</b></a></li> <li><a href="adding_code.wiki"><b>Hacking Fossil</b></a></li> <li><a href="hashpolicy.wiki"><b>Hash Policy: Choosing Between SHA1 and SHA3-256</b></a></li> <li><a href="hints.wiki">Hints — Fossil Tips And Usage</a></li> <li><a href="index.wiki"><b>Home Page</b></a></li> <li><a href="selfhost.wiki">Hosting Repositories — Fossil Self</a></li> <li><a href="aboutcgi.wiki"><b>How CGI Works In Fossil</b></a></li> <li><a href="server.wiki"><b>How To Configure A Fossil Server</b></a></li> <li><a href="newrepo.wiki"><b>How To Create A New Fossil Repository</b></a></li> <li><a href="encryptedrepos.wiki"><b>How To Use Encrypted Repositories</b></a></li> |
| ︙ | ︙ | |||
145 146 147 148 149 150 151 152 153 154 155 156 157 158 | <li><a href="env-opts.md">Options — Environment Variables and Global</a></li> <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil — A Technical</a></li> <li><a href="index.wiki">Page — Home</a></li> <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> <li><a href="makefile.wiki">Process — The Fossil Build</a></li> <li><a href="contribute.wiki">Project — Contributing Code or Documentation To The Fossil</a></li> <li><a href="embeddeddoc.wiki">Project Documentation — Embedded</a></li> <li><a href="foss-cklist.wiki">Projects — Checklist For Successful Open-Source</a></li> | > | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | <li><a href="env-opts.md">Options — Environment Variables and Global</a></li> <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil — A Technical</a></li> <li><a href="index.wiki">Page — Home</a></li> <li><a href="customskin.md">Pages — Theming: Customizing The Appearance of Web</a></li> <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li> <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General — Quotes: What</a></li> <li><a href="stats.wiki"><b>Performance Statistics</b></a></li> <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 — Hash</a></li> <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li> <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li> <li><a href="private.wiki">Private Branches — Creating, Syncing, and Deleting</a></li> <li><a href="makefile.wiki">Process — The Fossil Build</a></li> <li><a href="contribute.wiki">Project — Contributing Code or Documentation To The Fossil</a></li> <li><a href="embeddeddoc.wiki">Project Documentation — Embedded</a></li> <li><a href="foss-cklist.wiki">Projects — Checklist For Successful Open-Source</a></li> |
| ︙ | ︙ | |||
172 173 174 175 176 177 178 179 180 181 182 183 184 185 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Update and</a></li> <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> <li><a href="th1.md">Scripting Language — The TH1</a></li> <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> <li><a href="server.wiki">Server — How To Configure A Fossil</a></li> <li><a href="settings.wiki">Settings — Fossil</a></li> <li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li> <li><a href="fiveminutes.wiki">Single User — Update and Running in 5 Minutes as a</a></li> <li><a href="../../../sitemap"><b>Site Map</b></a></li> <li><a href="style.wiki"><b>Source Code Style Guidelines</b></a></li> <li><a href="antibot.wiki">Spiders and Bots — Defense against</a></li> <li><a href="tech_overview.wiki"><b>SQLite Databases Used By Fossil</b></a></li> <li><a href="ssl.wiki">SSL with Fossil — Using</a></li> | > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | <li><a href="fiveminutes.wiki">Running in 5 Minutes as a Single User — Update and</a></li> <li><a href="quotes.wiki">Saying About Fossil, Git, and DVCSes in General — Quotes: What People Are</a></li> <li><a href="th1.md">Scripting Language — The TH1</a></li> <li><a href="selfcheck.wiki">Self Checks — Fossil Repository Integrity</a></li> <li><a href="selfhost.wiki">Self Hosting Repositories — Fossil</a></li> <li><a href="server.wiki">Server — How To Configure A Fossil</a></li> <li><a href="settings.wiki">Settings — Fossil</a></li> <li><a href="hashpolicy.wiki">SHA1 and SHA3-256 — Hash Policy: Choosing Between</a></li> <li><a href="hashpolicy.wiki">SHA3-256 — 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 — Update and Running in 5 Minutes as a</a></li> <li><a href="../../../sitemap"><b>Site Map</b></a></li> <li><a href="style.wiki"><b>Source Code Style Guidelines</b></a></li> <li><a href="antibot.wiki">Spiders and Bots — Defense against</a></li> <li><a href="tech_overview.wiki"><b>SQLite Databases Used By Fossil</b></a></li> <li><a href="ssl.wiki">SSL with Fossil — Using</a></li> |
| ︙ | ︙ |
Changes to www/pop.wiki.
| ︙ | ︙ | |||
23 24 25 26 27 28 29 | repositories are fully synchronized). The local state for each repository is private to that repository. The global state represents the content of the project. The local state identifies the authorized users and access policies for a particular repository.</p></li> <li><p>The global state of a repository is an unordered | | > | | | | | | 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 | repositories are fully synchronized). The local state for each repository is private to that repository. The global state represents the content of the project. The local state identifies the authorized users and access policies for a particular repository.</p></li> <li><p>The global state of a repository is an unordered collection of artifacts. Each artifact is named by a cryptographic hash (SHA1 or SHA3-256) encoded in lowercase hexadecimal. In many contexts, the name can be abbreviated to a unique prefix. A five- or six-character prefix usually suffices to uniquely identify a file.</p></li> <li><p>Because artifacts are named by a cryptographic hash, all artifacts are immutable. Any change to the content of an artifact also changes the hash that forms the artifacts name, thus creating a new artifact. Both the old original version of the artifact and the new change are preserved under different names.</p></li> <li><p>It is theoretically possible for two artifacts with different content to share the same hash. But finding two such artifacts is so incredibly difficult and unlikely that we consider it to be an impossibility.</p></li> <li><p>The signature of an artifact is the cryptographic hash of the artifact itself, exactly as it would appear in a disk file. No prefix or meta-information about the artifact is added before computing the hash. So you can always find the signature of a file by using the "sha1sum" or "sha3sum" or similar command-line utilities.</p></li> <li><p>The artifacts that comprise the global state of a repository are the complete global state of that repository. The SQLite database that holds the repository contains additional information about linkages between artifacts, but all of that added information can be discarded and reconstructed by rescanning the content artifacts.</p></li> |
| ︙ | ︙ |
Changes to www/selfcheck.wiki.
| ︙ | ︙ | |||
49 50 51 52 53 54 55 | recoverable, fossil makes sure it can extract an exact replica of every content file that it changes just prior to transaction commit. So during the course of check-in (or other repository operation) many different files in the repository might be modified. Some files are simply compressed. Other files are delta encoded and then compressed. While all this is going on, fossil makes a record of every file | | | | | | | 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 | recoverable, fossil makes sure it can extract an exact replica of every content file that it changes just prior to transaction commit. So during the course of check-in (or other repository operation) many different files in the repository might be modified. Some files are simply compressed. Other files are delta encoded and then compressed. While all this is going on, fossil makes a record of every file and the SHA1 or SHA3-256 hash of the original content of that file. Then just before transaction commit, fossil re-extracts the original content of all files that were written, recomputes the hash, and verifies that the recomputed hash still matches. If anything does not match up, an error message is printed and the transaction rolls back. So, in other words, fossil always checks to make sure it can re-extract a file before it commits a change to that file. Hence bugs in fossil are unlikely to corrupt the repository in a way that prevents us from extracting historical versions of files. <h2>Checksum Over All Files In A Check-in</h2> Manifest artifacts that define a check-in have two fields (the R-card and Z-card) that record MD5 hashes of the manifest itself and of all other files in the manifest. Prior to any check-in commit, these checksums are verified to ensure that the check-in agrees exactly with what is on disk. Similarly, the repository checksum is verified after a checkout to make sure that the entire repository was checked out correctly. Note that these added checks use a different hash algorithm (MD5) in order to avoid common-mode failures in the hash algorithm implementation. <h2>Checksums On Control Artifacts And Deltas</h2> Every [./fileformat.wiki | control artifact] in a fossil repository contains a "Z-card" bearing an MD5 checksum over the rest of the |
| ︙ | ︙ |
Changes to www/shunning.wiki.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 |
disrupting the operation of Fossil.
<h2>Shunning</h2>
Fossil provides a mechanism called "shunning" for removing content from
a repository.
| | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
disrupting the operation of Fossil.
<h2>Shunning</h2>
Fossil provides a mechanism called "shunning" for removing content from
a repository.
Every Fossil repository maintains a list of the hash names of
"shunned" artifacts.
Fossil will refuse to push or pull any shunned artifact.
Furthermore, all shunned artifacts (but not the shunning list
itself) are removed from the
repository whenever the repository is reconstructed using the
"rebuild" command.
|
| ︙ | ︙ |
Changes to www/sync.wiki.
1 2 3 4 5 6 7 8 | <title>The Fossil Sync Protocol</title> <p>This document describes the wire protocol used to synchronize content between two Fossil repositories.</p> <h2>1.0 Overview</h2> <p>The global state of a fossil repository consists of an unordered | | | | | | | | | | | 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 | <title>The Fossil Sync Protocol</title> <p>This document describes the wire protocol used to synchronize content between two Fossil repositories.</p> <h2>1.0 Overview</h2> <p>The global state of a fossil repository consists of an unordered collection of artifacts. Each artifact is identified by a cryptographic hash of its content, expressed as a lower-case hexadecimal string. Synchronization is the process of sharing artifacts between servers so that all servers have copies of all artifacts. Because artifacts are unordered, the order in which artifacts are received at a server is inconsequential. It is assumed that the hash names of artifacts are unique - that every artifact has a different hash. To a first approximation, synchronization proceeds by sharing lists hash values for available artifacts, then sharing the content of artifacts whose names are missing from one side or the other of the connection. In practice, a repository might contain millions of artifacts. The list of hash names for this many artifacts can be large. So optimizations are employed that usually reduce the number of hashes that need to be shared to a few hundred.</p> <p>Each repository also has local state. The local state determines the web-page formatting preferences, authorized users, ticket formats, and similar information that varies from one repository to another. The local state is not using transferred during a sync. Except, some local state is transferred during a [/help?cmd=clone|clone] |
| ︙ | ︙ | |||
196 197 198 199 200 201 202 | or the artifact delta is the first <i>size</i> bytes of the x-fossil content that immediately follow the newline that terminates the file card. </p> <p>The first argument of a file card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | or the artifact delta is the first <i>size</i> bytes of the x-fossil content that immediately follow the newline that terminates the file card. </p> <p>The first argument of a file card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal representation of the name hash for the artifact. The last argument of the file card is the number of bytes of payload that immediately follow the file card. If the file card has only two arguments, that means the payload is the complete content of the artifact. If the file card has three arguments, then the payload is a delta and second argument is the ID of another artifact that is the source of the delta.</p> |
| ︙ | ︙ | |||
229 230 231 232 233 234 235 | <blockquote> <b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br> <b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br> </blockquote> <p>The first argument of the cfile card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | <blockquote> <b>cfile</b> <i>artifact-id usize csize</i> <b>\n</b> <i>content</i><br> <b>cfile</b> <i>artifact-id delta-artifact-id usize csize</i> <b>\n</b> <i>content</i><br> </blockquote> <p>The first argument of the cfile card is the ID of the artifact that is being transferred. The artifact ID is the lower-case hexadecimal representation of the name hash for the artifact. The second argument of the cfile card is the original size in bytes of the artifact. The last argument of the cfile card is the number of compressed bytes of payload that immediately follow the cfile card. If the cfile card has only three arguments, that means the payload is the complete content of the artifact. If the cfile card has four arguments, then the payload is a delta and the second argument is the ID of another artifact that is the source of the delta and the third argument is the original size of the |
| ︙ | ︙ | |||
269 270 271 272 273 274 275 | <blockquote> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i> </blockquote> <p>The <i>name</i> field is the name of the unversioned file. The <i>mtime</i> is the last modification time of the file in seconds | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | <blockquote> <b>uvfile</b> <i>name mtime hash size flags</i> <b>\n</b> <i>content</i> </blockquote> <p>The <i>name</i> field is the name of the unversioned file. The <i>mtime</i> is the last modification time of the file in seconds since 1970. The <i>hash</i> field is the hash of the content for the unversioned file, or "<b>-</b>" for deleted content. The <i>size</i> field is the (uncompressed) size of the content in bytes. The <i>flags</i> field is an integer which is interpreted as an array of bits. The 0x0004 bit of <i>flags</i> indicates that the <i>content</i> is to be omitted. The content might be omitted if it is too large to transmit, or if the sender merely wants to update the modification time of the file without changing the files content. |
| ︙ | ︙ | |||
407 408 409 410 411 412 413 | <blockquote> <b>uvigot</b> <i>name mtime hash size</i> </blockquote> <p>The <i>name</i> argument is the name of an unversioned file. The <i>mtime</i> is the last modification time of the unversioned file in seconds since 1970. | | | | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | <blockquote> <b>uvigot</b> <i>name mtime hash size</i> </blockquote> <p>The <i>name</i> argument is the name of an unversioned file. The <i>mtime</i> is the last modification time of the unversioned file in seconds since 1970. The <i>hash</i> is the SHA1 or SHA3-256 hash of the unversioned file content, or "<b>-</b>" if the file has been deleted. The <i>size</i> is the uncompressed size of the file in bytes. <p>When the server sees a "pragma uv-hash" card for which the hash does not match, it sends uvigot cards for every unversioned file that it holds. The client will use this information to figure out which unversioned files need to be synchronized. The server might also send a uvigot card when it receives a uvgimme card |
| ︙ | ︙ |
Changes to www/tech_overview.wiki.
| ︙ | ︙ | |||
171 172 173 174 175 176 177 | All of the original uncompressed and undeltaed artifacts can be extracted from a Fossil repository database using the [/help/deconstruct | fossil deconstruct] command. Individual artifacts can be extracted using the [/help/artifact | fossil artifact] command. When accessing the repository database using raw SQL and the [/help/sqlite3 | fossil sql] command, the extension function | | > | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | All of the original uncompressed and undeltaed artifacts can be extracted from a Fossil repository database using the [/help/deconstruct | fossil deconstruct] command. Individual artifacts can be extracted using the [/help/artifact | fossil artifact] command. When accessing the repository database using raw SQL and the [/help/sqlite3 | fossil sql] command, the extension function "<tt>content()</tt>" with a single argument which is the SHA1 or SHA3-256 hash of an artifact will return the complete undeleted and uncompressed content of that artifact. Going the other way, the [/help/reconstruct | fossil reconstruct] command will scan a directory hierarchy and add all files found to a new repository database. The [/help/import | fossil import] command works by reading the input git-fast-export stream and using it to construct |
| ︙ | ︙ | |||
276 277 278 279 280 281 282 | The set of canonical artifacts for a project - the global state for the project - is intended to be an append-only database. In other words, new artifacts can be added but artifacts can never be removed. But it sometimes happens that inappropriate content is mistakenly or maliciously added to a repository. The only way to get rid of the undesired content is to [./shunning.wiki | "shun"] it. | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | The set of canonical artifacts for a project - the global state for the project - is intended to be an append-only database. In other words, new artifacts can be added but artifacts can never be removed. But it sometimes happens that inappropriate content is mistakenly or maliciously added to a repository. The only way to get rid of the undesired content is to [./shunning.wiki | "shun"] it. The "shun" table in the repository database records the hash values for all shunned artifacts. The shun table can be pushed or pulled using the [/help/config | fossil config] command with the "shun" AREA argument. The shun table is also copied during a [/help/clone | clone]. <a name='localdb'></a> |
| ︙ | ︙ |
Changes to www/theory1.wiki.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 | An artifact is a list of bytes - a "file" in the usual manner of thinking. Many artifacts are simply the content of source files that have been checked into the Fossil repository. Call these "content artifacts". Other artifacts, known as "control artifacts", contain ASCII text in a particular format that defines relationships between other artifacts, such as which content artifacts that go together to form a particular version of the | | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | An artifact is a list of bytes - a "file" in the usual manner of thinking. Many artifacts are simply the content of source files that have been checked into the Fossil repository. Call these "content artifacts". Other artifacts, known as "control artifacts", contain ASCII text in a particular format that defines relationships between other artifacts, such as which content artifacts that go together to form a particular version of the project. Each artifact is named by its SHA1 or SHA3-256 hash and is thus immutable. Artifacts can be added to the database but not removed (if we ignore the exceptional case of [./shunning.wiki | shunning].) Repositories synchronize by computing the union of their artifact sets. SQL and relation theory play no role in any of this. SQL enters the picture only in the implementation details. The current implementation of Fossil stores each artifact as a BLOB in an SQLite |
| ︙ | ︙ |
Changes to www/webpage-ex.md.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 |
* <a target='_blank' class='exbtn'
href='$ROOT/bigbloblist'>Example</a>
The largest objects in the repository.
* <a target='_blank' class='exbtn'
href='$ROOT/hash-collisions'>Example</a>
| | | 121 122 123 124 125 126 127 128 129 130 131 132 |
* <a target='_blank' class='exbtn'
href='$ROOT/bigbloblist'>Example</a>
The largest objects in the repository.
* <a target='_blank' class='exbtn'
href='$ROOT/hash-collisions'>Example</a>
Hash prefix collisions
* <a target='_blank' class='exbtn'
href='$ROOT/sitemap'>Example</a>
The "sitemap" containing links to many other pages
|
Changes to www/whyusefossil.wiki.
| ︙ | ︙ | |||
230 231 232 233 234 235 236 |
to the first check-in of a branch. The name assigned by this
special tag automatically propagates to all direct children.
</ul>
</ul>
<li><p><b>Why version control is important (reprise)</b>
<ol type="A">
<li><p>Every check-in and every individual file has a unique name - its
| | > | | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
to the first check-in of a branch. The name assigned by this
special tag automatically propagates to all direct children.
</ul>
</ul>
<li><p><b>Why version control is important (reprise)</b>
<ol type="A">
<li><p>Every check-in and every individual file has a unique name - its
SHA1 or SHA3-256 hash. Team members can unambiguously identify
any specific
version of the overall project or any specific version of an
individual file.
<li><p>Any historical version of the whole project or of any individual
file can be easily recreated at any time and by any team member.
<li><p>Accidental changes to files can be detected by recomputing their
cryptographic hash.
<li><p>Files of unknown origin can be identified using their hash.
<li><p>Developers are able to work in parallel, review each others work,
and easily merge their changes together. External revisions to
the baseline can be easily incorporated into the latest changes.
<li><p>Developers can follow experimental lines of development, then
revert back to an earlier stable version if the experiment does
not work out. Creativity is enhanced by allowing crazy ideas to
be investigated without destabilizing the project.
|
| ︙ | ︙ |