Fossil SCM
Add the db_fingerprint() interface for computing a repository fingerprint.
Commit
f5043617c0f725a2c88084f923def46e52693c64ec372085533e3e527dcccc11
Parent
1e3cfc1e9eaa2bc…
1 file changed
+65
M
src/db.c
+65
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -3704,5 +3704,70 @@ | ||
| 3704 | 3704 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 3705 | 3705 | fossil_print("Repository database: %s\n", g.zRepositoryName); |
| 3706 | 3706 | fossil_print("Local database: %s\n", g.zLocalDbName); |
| 3707 | 3707 | fossil_print("Config database: %s\n", g.zConfigDbName); |
| 3708 | 3708 | } |
| 3709 | + | |
| 3710 | +/* | |
| 3711 | +** Compute a "fingerprint" on the repository. A fingerprint is used | |
| 3712 | +** to verify that that the repository has not been replaced by a clone | |
| 3713 | +** of the same repository. More precisely, a fingerprint are used to | |
| 3714 | +** verify that the mapping between SHA3 hashes and RID values is unchanged. | |
| 3715 | +** | |
| 3716 | +** The checkout database ("localdb") stores RID values. When associating | |
| 3717 | +** a checkout database against a repository database, it is useful to verify | |
| 3718 | +** the fingerprint so that we know tha the RID values in the checkout | |
| 3719 | +** database still correspond to the correct entries in the BLOB table of | |
| 3720 | +** the repository. | |
| 3721 | +** | |
| 3722 | +** The fingerprint is based on the RCVFROM table. When constructing a | |
| 3723 | +** new fingerprint, use the most recent RCVFROM entry. (Set rcvid==0 to | |
| 3724 | +** accomplish this.) When verifying an old fingerprint, use the same | |
| 3725 | +** RCVFROM entry that generated the fingerprint in the first place. | |
| 3726 | +** | |
| 3727 | +** The fingerprint consists of the rcvid, a "/", and the MD5 checksum of | |
| 3728 | +** the remaining fields of the RCVFROM table entry. | |
| 3729 | +*/ | |
| 3730 | +char *db_fingerprint(int rcvid){ | |
| 3731 | + char *z = 0; | |
| 3732 | + Blob sql = BLOB_INITIALIZER; | |
| 3733 | + Stmt q; | |
| 3734 | + blob_append_sql(&sql, | |
| 3735 | + "SELECT rcvid, quote(uid), quote(mtime), quote(nonce), quote(ipaddr)" | |
| 3736 | + " FROM rcvfrom" | |
| 3737 | + ); | |
| 3738 | + if( rcvid<=0 ){ | |
| 3739 | + blob_append_sql(&sql, " ORDER BY rcvid DESC LIMIT 1"); | |
| 3740 | + }else{ | |
| 3741 | + blob_append_sql(&sql, " WHERE rcvid=%d", rcvid); | |
| 3742 | + } | |
| 3743 | + db_prepare_blob(&q, &sql); | |
| 3744 | + blob_reset(&sql); | |
| 3745 | + if( db_step(&q)==SQLITE_ROW ){ | |
| 3746 | + int i; | |
| 3747 | + md5sum_init(); | |
| 3748 | + for(i=1; i<=4; i++){ | |
| 3749 | + md5sum_step_text(db_column_text(&q,i),-1); | |
| 3750 | + } | |
| 3751 | + z = mprintf("%d/%s",db_column_int(&q,0),md5sum_finish(0)); | |
| 3752 | + } | |
| 3753 | + db_finalize(&q); | |
| 3754 | + return z; | |
| 3755 | +} | |
| 3756 | + | |
| 3757 | +/* | |
| 3758 | +** COMMAND: test-fingerprint | |
| 3759 | +** | |
| 3760 | +** Usage: %fossil test-fingerprint ?RCVID? | |
| 3761 | +** | |
| 3762 | +** Display the repository fingerprint. | |
| 3763 | +*/ | |
| 3764 | +void test_fingerprint(void){ | |
| 3765 | + int rcvid = 0; | |
| 3766 | + db_find_and_open_repository(OPEN_ANY_SCHEMA,0); | |
| 3767 | + if( g.argc==3 ){ | |
| 3768 | + rcvid = atoi(g.argv[2]); | |
| 3769 | + }else if( g.argc!=2 ){ | |
| 3770 | + fossil_fatal("wrong number of arguments"); | |
| 3771 | + } | |
| 3772 | + fossil_print("%z\n", db_fingerprint(rcvid)); | |
| 3773 | +} | |
| 3709 | 3774 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -3704,5 +3704,70 @@ | |
| 3704 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 3705 | fossil_print("Repository database: %s\n", g.zRepositoryName); |
| 3706 | fossil_print("Local database: %s\n", g.zLocalDbName); |
| 3707 | fossil_print("Config database: %s\n", g.zConfigDbName); |
| 3708 | } |
| 3709 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -3704,5 +3704,70 @@ | |
| 3704 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 3705 | fossil_print("Repository database: %s\n", g.zRepositoryName); |
| 3706 | fossil_print("Local database: %s\n", g.zLocalDbName); |
| 3707 | fossil_print("Config database: %s\n", g.zConfigDbName); |
| 3708 | } |
| 3709 | |
| 3710 | /* |
| 3711 | ** Compute a "fingerprint" on the repository. A fingerprint is used |
| 3712 | ** to verify that that the repository has not been replaced by a clone |
| 3713 | ** of the same repository. More precisely, a fingerprint are used to |
| 3714 | ** verify that the mapping between SHA3 hashes and RID values is unchanged. |
| 3715 | ** |
| 3716 | ** The checkout database ("localdb") stores RID values. When associating |
| 3717 | ** a checkout database against a repository database, it is useful to verify |
| 3718 | ** the fingerprint so that we know tha the RID values in the checkout |
| 3719 | ** database still correspond to the correct entries in the BLOB table of |
| 3720 | ** the repository. |
| 3721 | ** |
| 3722 | ** The fingerprint is based on the RCVFROM table. When constructing a |
| 3723 | ** new fingerprint, use the most recent RCVFROM entry. (Set rcvid==0 to |
| 3724 | ** accomplish this.) When verifying an old fingerprint, use the same |
| 3725 | ** RCVFROM entry that generated the fingerprint in the first place. |
| 3726 | ** |
| 3727 | ** The fingerprint consists of the rcvid, a "/", and the MD5 checksum of |
| 3728 | ** the remaining fields of the RCVFROM table entry. |
| 3729 | */ |
| 3730 | char *db_fingerprint(int rcvid){ |
| 3731 | char *z = 0; |
| 3732 | Blob sql = BLOB_INITIALIZER; |
| 3733 | Stmt q; |
| 3734 | blob_append_sql(&sql, |
| 3735 | "SELECT rcvid, quote(uid), quote(mtime), quote(nonce), quote(ipaddr)" |
| 3736 | " FROM rcvfrom" |
| 3737 | ); |
| 3738 | if( rcvid<=0 ){ |
| 3739 | blob_append_sql(&sql, " ORDER BY rcvid DESC LIMIT 1"); |
| 3740 | }else{ |
| 3741 | blob_append_sql(&sql, " WHERE rcvid=%d", rcvid); |
| 3742 | } |
| 3743 | db_prepare_blob(&q, &sql); |
| 3744 | blob_reset(&sql); |
| 3745 | if( db_step(&q)==SQLITE_ROW ){ |
| 3746 | int i; |
| 3747 | md5sum_init(); |
| 3748 | for(i=1; i<=4; i++){ |
| 3749 | md5sum_step_text(db_column_text(&q,i),-1); |
| 3750 | } |
| 3751 | z = mprintf("%d/%s",db_column_int(&q,0),md5sum_finish(0)); |
| 3752 | } |
| 3753 | db_finalize(&q); |
| 3754 | return z; |
| 3755 | } |
| 3756 | |
| 3757 | /* |
| 3758 | ** COMMAND: test-fingerprint |
| 3759 | ** |
| 3760 | ** Usage: %fossil test-fingerprint ?RCVID? |
| 3761 | ** |
| 3762 | ** Display the repository fingerprint. |
| 3763 | */ |
| 3764 | void test_fingerprint(void){ |
| 3765 | int rcvid = 0; |
| 3766 | db_find_and_open_repository(OPEN_ANY_SCHEMA,0); |
| 3767 | if( g.argc==3 ){ |
| 3768 | rcvid = atoi(g.argv[2]); |
| 3769 | }else if( g.argc!=2 ){ |
| 3770 | fossil_fatal("wrong number of arguments"); |
| 3771 | } |
| 3772 | fossil_print("%z\n", db_fingerprint(rcvid)); |
| 3773 | } |
| 3774 |