@@ -1655,10 +1655,29 @@
1655 1655 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1656 1656 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Make a change to the CHECK constraint on the BLOB table for
1657 1657 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** version 2.0 and later.
1658 1658 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
1659 1659 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
1660 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
1661 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* If the checkout database was opened first, then check to make
1662 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** sure that the repository database that was just opened has not
1663 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** be replaced by a clone of the same project, with different RID
1664 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** values.
1665 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
1666 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( g.localOpen && !db_fingerprint_ok() ){
1667 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print(
1668 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "Oops. It looks like the repository database file located at\n"
1669 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " \"%s\"\n", zDbName
1670 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
1671 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print(
1672 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "has been swapped with a clone that may have different\n"
1673 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "integer keys for the various artifacts. As of 2019-01-11,\n"
1674 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "we are working on enhancing Fossil to be able to deal with\n"
1675 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "that automatically, but we are not there yet. Sorry.\n\n"
1676 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
1677 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_fatal("bad fingerprint");
1678 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
1660 1679 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1661 1680 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1662 1681 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
1663 1682 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Return true if there have been any changes to the repository
1664 1683 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** database since it was opened.
@@ -2872,11 +2891,11 @@
2872 2891 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
g.allowSymlinks = db_get_boolean("allow-symlinks",
2873 2892 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_allow_symlinks_by_default());
2874 2893 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
2875 2894 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_lset("repository", g.argv[2]);
2876 2895 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_record_repository_filename(g.argv[2]);
2877 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_lset_int("checkout", 0);
2896 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_set_checkout(0);
2878 2897 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
azNewArgv[0] = g.argv[0];
2879 2898 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
g.argv = azNewArgv;
2880 2899 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( !emptyFlag ){
2881 2900 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
g.argc = 3;
2882 2901 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( g.zOpenRevision ){
@@ -3704,5 +3723,120 @@
3704 3723 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
3705 3724 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_print("Repository database: %s\n", g.zRepositoryName);
3706 3725 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_print("Local database: %s\n", g.zLocalDbName);
3707 3726 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_print("Config database: %s\n", g.zConfigDbName);
3708 3727 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
3728 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3729 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
3730 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Compute a "fingerprint" on the repository. A fingerprint is used
3731 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** to verify that that the repository has not been replaced by a clone
3732 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** of the same repository. More precisely, a fingerprint are used to
3733 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** verify that the mapping between SHA3 hashes and RID values is unchanged.
3734 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3735 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** The checkout database ("localdb") stores RID values. When associating
3736 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** a checkout database against a repository database, it is useful to verify
3737 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** the fingerprint so that we know tha the RID values in the checkout
3738 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** database still correspond to the correct entries in the BLOB table of
3739 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** the repository.
3740 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3741 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** The fingerprint is based on the RCVFROM table. When constructing a
3742 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** new fingerprint, use the most recent RCVFROM entry. (Set rcvid==0 to
3743 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** accomplish this.) When verifying an old fingerprint, use the same
3744 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** RCVFROM entry that generated the fingerprint in the first place.
3745 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3746 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** The fingerprint consists of the rcvid, a "/", and the MD5 checksum of
3747 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** the remaining fields of the RCVFROM table entry. MD5 is used for this
3748 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** because it is 4x faster than SHA3 and 5x faster than SHA1, and there
3749 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** are no security concerns - this is just a checksum, not a security
3750 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** token.
3751 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
3752 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *db_fingerprint(int rcvid){
3753 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *z = 0;
3754 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Blob sql = BLOB_INITIALIZER;
3755 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Stmt q;
3756 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ blob_append_sql(&sql,
3757 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "SELECT rcvid, quote(uid), quote(mtime), quote(nonce), quote(ipaddr)"
3758 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " FROM rcvfrom"
3759 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
3760 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( rcvid<=0 ){
3761 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ blob_append_sql(&sql, " ORDER BY rcvid DESC LIMIT 1");
3762 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else{
3763 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ blob_append_sql(&sql, " WHERE rcvid=%d", rcvid);
3764 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3765 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_prepare_blob(&q, &sql);
3766 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ blob_reset(&sql);
3767 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( db_step(&q)==SQLITE_ROW ){
3768 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int i;
3769 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ md5sum_init();
3770 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(i=1; i<=4; i++){
3771 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ md5sum_step_text(db_column_text(&q,i),-1);
3772 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3773 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z = mprintf("%d/%s",db_column_int(&q,0),md5sum_finish(0));
3774 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3775 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_finalize(&q);
3776 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return z;
3777 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3778 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3779 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
3780 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** COMMAND: test-fingerprint
3781 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3782 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Usage: %fossil test-fingerprint ?RCVID? ?--check?
3783 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3784 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Display the repository fingerprint. Or if the --check option
3785 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** is provided and this command is run from a checkout, invoke the
3786 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** db_fingerprint_ok() method and print its result.
3787 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
3788 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ void test_fingerprint(void){
3789 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int rcvid = 0;
3790 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( find_option("check",0,0)!=0 ){
3791 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_must_be_within_tree();
3792 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print("db_fingerprint_ok() => %d\n", db_fingerprint_ok());
3793 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return;
3794 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3795 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_find_and_open_repository(OPEN_ANY_SCHEMA,0);
3796 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( g.argc==3 ){
3797 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ rcvid = atoi(g.argv[2]);
3798 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if( g.argc!=2 ){
3799 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_fatal("wrong number of arguments");
3800 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3801 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print("%z\n", db_fingerprint(rcvid));
3802 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3803 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3804 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
3805 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Set the value of the "checkout" entry in the VVAR table.
3806 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
3807 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Also set "fingerprint" and "checkout-hash".
3808 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
3809 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ void db_set_checkout(int rid){
3810 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *z;
3811 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_lset_int("checkout", rid);
3812 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid);
3813 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_lset("checkout-hash", z);
3814 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(z);
3815 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ z = db_fingerprint(0);
3816 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_lset("fingerprint", z);
3817 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(z);
3818 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3819 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3820 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
3821 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Verify that the fingerprint recorded in the "fingerprint" entry
3822 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** of the VVAR table matches the fingerprint on the currently
3823 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** connected repository. Return true if the fingerprint is ok, and
3824 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** return false if the fingerprint does not match.
3825 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
3826 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int db_fingerprint_ok(void){
3827 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *zCkout; /* The fingerprint recorded in the checkout database */
3828 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *zRepo; /* The fingerprint of the repository */
3829 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int rc; /* Result */
3830 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3831 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
3832 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( zCkout==0 ){
3833 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* This is an older checkout that does not record a fingerprint.
3834 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** We have to assume everything is ok */
3835 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return 2;
3836 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3837 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zRepo = db_fingerprint(atoi(zCkout));
3838 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ rc = fossil_strcmp(zCkout,zRepo)==0;
3839 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(zCkout);
3840 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(zRepo);
3841 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return rc;
3842 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
3709 3843 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!