1 /*
2 ** Copyright (c) 2006 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 **
12 ** Author contact information:
13 ** drh@hwaci.com
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** Code for interfacing to the various databases.
19 **
20 ** There are three separate database files that fossil interacts
21 ** with:
22 **
23 ** (1) The "configdb" database in ~/.fossil or ~/.config/fossil.db
24 ** or in %LOCALAPPDATA%/_fossil
25 **
26 ** (2) The "repository" database
27 **
28 ** (3) A local checkout database named "_FOSSIL_" or ".fslckout"
29 ** and located at the root of the local copy of the source tree.
30 **
31 */
32 #include "config.h"
33 #if defined(_WIN32)
34 # if USE_SEE
35 # include <windows.h>
36 # endif
37 #else
38 # include <pwd.h>
39 #endif
40 #if USE_SEE && !defined(SQLITE_HAS_CODEC)
41 # define SQLITE_HAS_CODEC
42 #endif
43 #include <sqlite3.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <time.h>
48 #include "db.h"
49
50 #if INTERFACE
51 /*
52 ** An single SQL statement is represented as an instance of the following
53 ** structure.
54 */
55 struct Stmt {
56 Blob sql; /* The SQL for this statement */
57 sqlite3_stmt *pStmt; /* The results of sqlite3_prepare_v2() */
58 Stmt *pNext, *pPrev; /* List of all unfinalized statements */
59 int nStep; /* Number of sqlite3_step() calls */
60 int rc; /* Error from db_vprepare() */
61 };
62
63 /*
64 ** Copy this to initialize a Stmt object to a clean/empty state. This
65 ** is useful to help avoid assertions when performing cleanup in some
66 ** error handling cases.
67 */
68 #define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0, 0}
69 #endif /* INTERFACE */
70 const struct Stmt empty_Stmt = empty_Stmt_m;
71
72 /*
73 ** Call this routine when a database error occurs.
74 ** This routine throws a fatal error. It does not return.
75 */
db_err(const char * zFormat,...)76 static void db_err(const char *zFormat, ...){
77 va_list ap;
78 char *z;
79 va_start(ap, zFormat);
80 z = vmprintf(zFormat, ap);
81 va_end(ap);
82 #ifdef FOSSIL_ENABLE_JSON
83 if( g.json.isJsonMode!=0 ){
84 /*
85 ** Avoid calling into the JSON support subsystem if it
86 ** has not yet been initialized, e.g. early SQLite log
87 ** messages, etc.
88 */
89 json_bootstrap_early();
90 json_err( 0, z, 1 );
91 }
92 else
93 #endif /* FOSSIL_ENABLE_JSON */
94 if( g.xferPanic && g.cgiOutput==1 ){
95 cgi_reset_content();
96 @ error Database\serror:\s%F(z)
97 cgi_reply();
98 }
99 fossil_fatal("Database error: %s", z);
100 }
101
102 /*
103 ** Check a result code. If it is not SQLITE_OK, print the
104 ** corresponding error message and exit.
105 */
db_check_result(int rc,Stmt * pStmt)106 static void db_check_result(int rc, Stmt *pStmt){
107 if( rc!=SQLITE_OK ){
108 db_err("SQL error (%d,%d: %s) while running [%s]",
109 rc, sqlite3_extended_errcode(g.db),
110 sqlite3_errmsg(g.db), blob_str(&pStmt->sql));
111 }
112 }
113
114 /*
115 ** All static variable that a used by only this file are gathered into
116 ** the following structure.
117 */
118 static struct DbLocalData {
119 unsigned protectMask; /* Prevent changes to database */
120 int nBegin; /* Nesting depth of BEGIN */
121 int doRollback; /* True to force a rollback */
122 int nCommitHook; /* Number of commit hooks */
123 int wrTxn; /* Outer-most TNX is a write */
124 Stmt *pAllStmt; /* List of all unfinalized statements */
125 int nPrepare; /* Number of calls to sqlite3_prepare_v2() */
126 int nDeleteOnFail; /* Number of entries in azDeleteOnFail[] */
127 struct sCommitHook {
128 int (*xHook)(void); /* Functions to call at db_end_transaction() */
129 int sequence; /* Call functions in sequence order */
130 } aHook[5];
131 char *azDeleteOnFail[3]; /* Files to delete on a failure */
132 char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
133 int nBeforeCommit; /* Number of entries in azBeforeCommit */
134 int nPriorChanges; /* sqlite3_total_changes() at transaction start */
135 const char *zStartFile; /* File in which transaction was started */
136 int iStartLine; /* Line of zStartFile where transaction started */
137 int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
138 void *pAuthArg; /* Argument to the authorizer */
139 const char *zAuthName; /* Name of the authorizer */
140 int bProtectTriggers; /* True if protection triggers already exist */
141 int nProtect; /* Slots of aProtect used */
142 unsigned aProtect[10]; /* Saved values of protectMask */
143 } db = {
144 PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
145 0, 0, 0, 0, 0, 0, };
146
147 /*
148 ** Arrange for the given file to be deleted on a failure.
149 */
db_delete_on_failure(const char * zFilename)150 void db_delete_on_failure(const char *zFilename){
151 assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
152 if( zFilename==0 ) return;
153 db.azDeleteOnFail[db.nDeleteOnFail++] = fossil_strdup(zFilename);
154 }
155
156 /*
157 ** Return the transaction nesting depth. 0 means we are currently
158 ** not in a transaction.
159 */
db_transaction_nesting_depth(void)160 int db_transaction_nesting_depth(void){
161 return db.nBegin;
162 }
163
164 /*
165 ** Return a pointer to a string that is the code point where the
166 ** current transaction was started.
167 */
db_transaction_start_point(void)168 char *db_transaction_start_point(void){
169 return mprintf("%s:%d", db.zStartFile, db.iStartLine);
170 }
171
172 /*
173 ** This routine is called by the SQLite commit-hook mechanism
174 ** just prior to each commit. All this routine does is verify
175 ** that nBegin really is zero. That insures that transactions
176 ** cannot commit by any means other than by calling db_end_transaction()
177 ** below.
178 **
179 ** This is just a safety and sanity check.
180 */
db_verify_at_commit(void * notUsed)181 static int db_verify_at_commit(void *notUsed){
182 if( db.nBegin ){
183 fossil_panic("illegal commit attempt");
184 return 1;
185 }
186 return 0;
187 }
188
189 /*
190 ** Silently add the filename and line number as parameter to each
191 ** db_begin_transaction call.
192 */
193 #if INTERFACE
194 #define db_begin_transaction() db_begin_transaction_real(__FILE__,__LINE__)
195 #define db_begin_write() db_begin_write_real(__FILE__,__LINE__)
196 #define db_commit_transaction() db_end_transaction(0)
197 #define db_rollback_transaction() db_end_transaction(1)
198 #endif
199
200 /*
201 ** Begin a nested transaction
202 */
db_begin_transaction_real(const char * zStartFile,int iStartLine)203 void db_begin_transaction_real(const char *zStartFile, int iStartLine){
204 if( db.nBegin==0 ){
205 db_multi_exec("BEGIN");
206 sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
207 db.nPriorChanges = sqlite3_total_changes(g.db);
208 db.doRollback = 0;
209 db.zStartFile = zStartFile;
210 db.iStartLine = iStartLine;
211 db.wrTxn = 0;
212 }
213 db.nBegin++;
214 }
215 /*
216 ** Begin a new transaction for writing.
217 */
db_begin_write_real(const char * zStartFile,int iStartLine)218 void db_begin_write_real(const char *zStartFile, int iStartLine){
219 if( db.nBegin==0 ){
220 if( !db_is_writeable("repository") ){
221 db_multi_exec("BEGIN");
222 }else{
223 db_multi_exec("BEGIN IMMEDIATE");
224 sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
225 db.nPriorChanges = sqlite3_total_changes(g.db);
226 db.doRollback = 0;
227 db.zStartFile = zStartFile;
228 db.iStartLine = iStartLine;
229 db.wrTxn = 1;
230 }
231 }else if( !db.wrTxn ){
232 fossil_warning("read txn at %s:%d might cause SQLITE_BUSY "
233 "for the write txn at %s:%d",
234 db.zStartFile, db.iStartLine, zStartFile, iStartLine);
235 }
236 db.nBegin++;
237 }
238
239 /* End a transaction previously started using db_begin_transaction()
240 ** or db_begin_write().
241 */
db_end_transaction(int rollbackFlag)242 void db_end_transaction(int rollbackFlag){
243 if( g.db==0 ) return;
244 if( db.nBegin<=0 ){
245 fossil_warning("Extra call to db_end_transaction");
246 return;
247 }
248 if( rollbackFlag ){
249 db.doRollback = 1;
250 if( g.fSqlTrace ) fossil_trace("-- ROLLBACK by request\n");
251 }
252 db.nBegin--;
253 if( db.nBegin==0 ){
254 int i;
255 if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){
256 i = 0;
257 db_protect_only(PROTECT_SENSITIVE);
258 while( db.nBeforeCommit ){
259 db.nBeforeCommit--;
260 sqlite3_exec(g.db, db.azBeforeCommit[i], 0, 0, 0);
261 sqlite3_free(db.azBeforeCommit[i]);
262 i++;
263 }
264 leaf_do_pending_checks();
265 db_protect_pop();
266 }
267 for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
268 int rc = db.aHook[i].xHook();
269 if( rc ){
270 db.doRollback = 1;
271 if( g.fSqlTrace ) fossil_trace("-- ROLLBACK due to aHook[%d]\n", i);
272 }
273 }
274 while( db.pAllStmt ){
275 db_finalize(db.pAllStmt);
276 }
277 db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
278 db.doRollback = 0;
279 }
280 }
281
282 /*
283 ** Force a rollback and shutdown the database
284 */
db_force_rollback(void)285 void db_force_rollback(void){
286 int i;
287 static int busy = 0;
288 sqlite3_stmt *pStmt = 0;
289 if( busy || g.db==0 ) return;
290 busy = 1;
291 undo_rollback();
292 while( (pStmt = sqlite3_next_stmt(g.db,pStmt))!=0 ){
293 sqlite3_reset(pStmt);
294 }
295 while( db.pAllStmt ){
296 db_finalize(db.pAllStmt);
297 }
298 if( db.nBegin ){
299 sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0);
300 db.nBegin = 0;
301 }
302 busy = 0;
303 db_close(0);
304 for(i=0; i<db.nDeleteOnFail; i++){
305 file_delete(db.azDeleteOnFail[i]);
306 }
307 }
308
309 /*
310 ** Install a commit hook. Hooks are installed in sequence order.
311 ** It is an error to install the same commit hook more than once.
312 **
313 ** Each commit hook is called (in order of ascending sequence) at
314 ** each commit operation. If any commit hook returns non-zero,
315 ** the subsequence commit hooks are omitted and the transaction
316 ** rolls back rather than commit. It is the responsibility of the
317 ** hooks themselves to issue any error messages.
318 */
db_commit_hook(int (* x)(void),int sequence)319 void db_commit_hook(int (*x)(void), int sequence){
320 int i;
321 assert( db.nCommitHook < count(db.aHook) );
322 for(i=0; i<db.nCommitHook; i++){
323 assert( x!=db.aHook[i].xHook );
324 if( db.aHook[i].sequence>sequence ){
325 int s = sequence;
326 int (*xS)(void) = x;
327 sequence = db.aHook[i].sequence;
328 x = db.aHook[i].xHook;
329 db.aHook[i].sequence = s;
330 db.aHook[i].xHook = xS;
331 }
332 }
333 db.aHook[db.nCommitHook].sequence = sequence;
334 db.aHook[db.nCommitHook].xHook = x;
335 db.nCommitHook++;
336 }
337
338 #if INTERFACE
339 /*
340 ** Flag bits for db_protect() and db_unprotect() indicating which parts
341 ** of the databases should be write protected or write enabled, respectively.
342 */
343 #define PROTECT_USER 0x01 /* USER table */
344 #define PROTECT_CONFIG 0x02 /* CONFIG and GLOBAL_CONFIG tables */
345 #define PROTECT_SENSITIVE 0x04 /* Sensitive and/or global settings */
346 #define PROTECT_READONLY 0x08 /* everything except TEMP tables */
347 #define PROTECT_BASELINE 0x10 /* protection system is working */
348 #define PROTECT_ALL 0x1f /* All of the above */
349 #define PROTECT_NONE 0x00 /* Nothing. Everything is open */
350 #endif /* INTERFACE */
351
352 /*
353 ** Enable or disable database write protections.
354 **
355 ** db_protext(X) Add protects on X
356 ** db_unprotect(X) Remove protections on X
357 ** db_protect_only(X) Remove all prior protections then set
358 ** protections to only X.
359 **
360 ** Each of these routines pushes the previous protection mask onto
361 ** a finite-size stack. Each should be followed by a call to
362 ** db_protect_pop() to pop the stack and restore the protections that
363 ** existed prior to the call. The protection mask stack has a limited
364 ** depth, so take care not to nest calls too deeply.
365 **
366 ** About Database Write Protection
367 ** -------------------------------
368 **
369 ** This is *not* a primary means of defending the application from
370 ** attack. Fossil should be secure even if this mechanism is disabled.
371 ** The purpose of database write protection is to provide an additional
372 ** layer of defense in case SQL injection bugs somehow slip into other
373 ** parts of the system. In other words, database write protection is
374 ** not primary defense but rather defense in depth.
375 **
376 ** This mechanism mostly focuses on the USER table, to prevent an
377 ** attacker from giving themselves Admin privilegs, and on the
378 ** CONFIG table and specially "sensitive" settings such as
379 ** "diff-command" or "editor" that if compromised by an attacker
380 ** could lead to an RCE.
381 **
382 ** By default, the USER and CONFIG tables are read-only. Various
383 ** subsystems that legitimately need to change those tables can
384 ** temporarily do so using:
385 **
386 ** db_unprotect(PROTECT_xxx);
387 ** // make the legitmate changes here
388 ** db_protect_pop();
389 **
390 ** Code that runs inside of reduced protections should be carefully
391 ** reviewed to ensure that it is harmless and not subject to SQL
392 ** injection.
393 **
394 ** Read-only operations (such as many web pages like /timeline)
395 ** can invoke db_protect(PROTECT_ALL) to effectively make the database
396 ** read-only. TEMP tables (which are often used for these kinds of
397 ** pages) are still writable, however.
398 **
399 ** The PROTECT_SENSITIVE protection is a subset of PROTECT_CONFIG
400 ** that blocks changes to all of the global_config table, but only
401 ** "sensitive" settings in the config table. PROTECT_SENSITIVE
402 ** relies on triggers and the protected_setting() SQL function to
403 ** prevent changes to sensitive settings.
404 **
405 ** Additional Notes
406 ** ----------------
407 **
408 ** Calls to routines like db_set() and db_unset() temporarily disable
409 ** the PROTECT_CONFIG protection. The assumption is that these calls
410 ** cannot be invoked by an SQL injection and are thus safe. Make sure
411 ** this is the case by always using a string literal as the name argument
412 ** to db_set() and db_unset() and friend, not a variable that might
413 ** be compromised by an attack.
414 */
db_protect_only(unsigned flags)415 void db_protect_only(unsigned flags){
416 if( db.nProtect>=count(db.aProtect)-2 ){
417 fossil_panic("too many db_protect() calls");
418 }
419 db.aProtect[db.nProtect++] = db.protectMask;
420 if( (flags & PROTECT_SENSITIVE)!=0
421 && db.bProtectTriggers==0
422 && g.repositoryOpen
423 ){
424 /* Create the triggers needed to protect sensitive settings from
425 ** being created or modified the first time that PROTECT_SENSITIVE
426 ** is enabled. Deleting a sensitive setting is harmless, so there
427 ** is not trigger to block deletes. After being created once, the
428 ** triggers persist for the life of the database connection. */
429 db_multi_exec(
430 "CREATE TEMP TRIGGER protect_1 BEFORE INSERT ON config"
431 " WHEN protected_setting(new.name) BEGIN"
432 " SELECT raise(abort,'not authorized');"
433 "END;\n"
434 "CREATE TEMP TRIGGER protect_2 BEFORE UPDATE ON config"
435 " WHEN protected_setting(new.name) BEGIN"
436 " SELECT raise(abort,'not authorized');"
437 "END;\n"
438 );
439 db.bProtectTriggers = 1;
440 }
441 db.protectMask = flags;
442 }
db_protect(unsigned flags)443 void db_protect(unsigned flags){
444 db_protect_only(db.protectMask | flags);
445 }
db_unprotect(unsigned flags)446 void db_unprotect(unsigned flags){
447 if( db.nProtect>=count(db.aProtect)-2 ){
448 fossil_panic("too many db_unprotect() calls");
449 }
450 db.aProtect[db.nProtect++] = db.protectMask;
451 db.protectMask &= ~flags;
452 }
db_protect_pop(void)453 void db_protect_pop(void){
454 if( db.nProtect<1 ){
455 fossil_panic("too many db_protect_pop() calls");
456 }
457 db.protectMask = db.aProtect[--db.nProtect];
458 }
459
460 /*
461 ** Verify that the desired database write protections are in place.
462 ** Throw a fatal error if not.
463 */
db_assert_protected(unsigned flags)464 void db_assert_protected(unsigned flags){
465 if( (flags & db.protectMask)!=flags ){
466 fossil_fatal("missing database write protection bits: %02x",
467 flags & ~db.protectMask);
468 }
469 }
470
471 /*
472 ** Assert that either all protections are off (including PROTECT_BASELINE
473 ** which is usually always enabled), or the setting named in the argument
474 ** is no a sensitive setting.
475 **
476 ** This assert() is used to verify that the db_set() and db_set_int()
477 ** interfaces do not modify a sensitive setting.
478 */
db_assert_protection_off_or_not_sensitive(const char * zName)479 void db_assert_protection_off_or_not_sensitive(const char *zName){
480 if( db.protectMask!=0 && db_setting_is_protected(zName) ){
481 fossil_panic("unauthorized change to protected setting \"%s\"", zName);
482 }
483 }
484
485 /*
486 ** Every Fossil database connection automatically registers the following
487 ** overarching authenticator callback, and leaves it registered for the
488 ** duration of the connection. This authenticator will call any
489 ** sub-authenticators that are registered using db_set_authorizer().
490 */
db_top_authorizer(void * pNotUsed,int eCode,const char * z0,const char * z1,const char * z2,const char * z3)491 int db_top_authorizer(
492 void *pNotUsed,
493 int eCode,
494 const char *z0,
495 const char *z1,
496 const char *z2,
497 const char *z3
498 ){
499 int rc = SQLITE_OK;
500 switch( eCode ){
501 case SQLITE_INSERT:
502 case SQLITE_UPDATE:
503 case SQLITE_DELETE: {
504 if( (db.protectMask & PROTECT_USER)!=0
505 && sqlite3_stricmp(z0,"user")==0 ){
506 rc = SQLITE_DENY;
507 }else if( (db.protectMask & PROTECT_CONFIG)!=0 &&
508 (sqlite3_stricmp(z0,"config")==0 ||
509 sqlite3_stricmp(z0,"global_config")==0) ){
510 rc = SQLITE_DENY;
511 }else if( (db.protectMask & PROTECT_SENSITIVE)!=0 &&
512 sqlite3_stricmp(z0,"global_config")==0 ){
513 rc = SQLITE_DENY;
514 }else if( (db.protectMask & PROTECT_READONLY)!=0
515 && sqlite3_stricmp(z2,"temp")!=0 ){
516 rc = SQLITE_DENY;
517 }
518 break;
519 }
520 case SQLITE_DROP_TEMP_TRIGGER: {
521 /* Do not allow the triggers that enforce PROTECT_SENSITIVE
522 ** to be dropped */
523 rc = SQLITE_DENY;
524 break;
525 }
526 }
527 if( db.xAuth && rc==SQLITE_OK ){
528 rc = db.xAuth(db.pAuthArg, eCode, z0, z1, z2, z3);
529 }
530 return rc;
531 }
532
533 /*
534 ** Set or unset the query authorizer callback function
535 */
db_set_authorizer(int (* xAuth)(void *,int,const char *,const char *,const char *,const char *),void * pArg,const char * zName)536 void db_set_authorizer(
537 int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
538 void *pArg,
539 const char *zName /* for tracing */
540 ){
541 if( db.xAuth ){
542 fossil_panic("multiple active db_set_authorizer() calls");
543 }
544 db.xAuth = xAuth;
545 db.pAuthArg = pArg;
546 db.zAuthName = zName;
547 if( g.fSqlTrace ) fossil_trace("-- set authorizer %s\n", zName);
548 }
db_clear_authorizer(void)549 void db_clear_authorizer(void){
550 if( db.zAuthName && g.fSqlTrace ){
551 fossil_trace("-- discontinue authorizer %s\n", db.zAuthName);
552 }
553 db.xAuth = 0;
554 db.pAuthArg = 0;
555 db.zAuthName = 0;
556 }
557
558 #if INTERFACE
559 /*
560 ** Possible flags to db_vprepare
561 */
562 #define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
563 #define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
564 #endif
565
566 /*
567 ** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
568 ** If the input string contains multiple SQL statements, only the first
569 ** one is processed. All statements beyond the first are silently ignored.
570 */
db_vprepare(Stmt * pStmt,int flags,const char * zFormat,va_list ap)571 int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){
572 int rc;
573 int prepFlags = 0;
574 char *zSql;
575 const char *zExtra = 0;
576 blob_zero(&pStmt->sql);
577 blob_vappendf(&pStmt->sql, zFormat, ap);
578 va_end(ap);
579 zSql = blob_str(&pStmt->sql);
580 db.nPrepare++;
581 if( flags & DB_PREPARE_PERSISTENT ){
582 prepFlags = SQLITE_PREPARE_PERSISTENT;
583 }
584 rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
585 if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
586 db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
587 }else if( zExtra && !fossil_all_whitespace(zExtra) ){
588 db_err("surplus text follows SQL: \"%s\"", zExtra);
589 }
590 pStmt->pNext = db.pAllStmt;
591 pStmt->pPrev = 0;
592 if( db.pAllStmt ) db.pAllStmt->pPrev = pStmt;
593 db.pAllStmt = pStmt;
594 pStmt->nStep = 0;
595 pStmt->rc = rc;
596 return rc;
597 }
db_prepare(Stmt * pStmt,const char * zFormat,...)598 int db_prepare(Stmt *pStmt, const char *zFormat, ...){
599 int rc;
600 va_list ap;
601 va_start(ap, zFormat);
602 rc = db_vprepare(pStmt, 0, zFormat, ap);
603 va_end(ap);
604 return rc;
605 }
db_prepare_ignore_error(Stmt * pStmt,const char * zFormat,...)606 int db_prepare_ignore_error(Stmt *pStmt, const char *zFormat, ...){
607 int rc;
608 va_list ap;
609 va_start(ap, zFormat);
610 rc = db_vprepare(pStmt, DB_PREPARE_IGNORE_ERROR, zFormat, ap);
611 va_end(ap);
612 return rc;
613 }
614
615 /* This variant of db_prepare() checks to see if the statement has
616 ** already been prepared, and if it has it becomes a no-op.
617 */
db_static_prepare(Stmt * pStmt,const char * zFormat,...)618 int db_static_prepare(Stmt *pStmt, const char *zFormat, ...){
619 int rc = SQLITE_OK;
620 if( blob_size(&pStmt->sql)==0 ){
621 va_list ap;
622 va_start(ap, zFormat);
623 rc = db_vprepare(pStmt, DB_PREPARE_PERSISTENT, zFormat, ap);
624 va_end(ap);
625 }
626 return rc;
627 }
628
629 /* Return TRUE if static Stmt object pStmt has been initialized.
630 */
db_static_stmt_is_init(Stmt * pStmt)631 int db_static_stmt_is_init(Stmt *pStmt){
632 return blob_size(&pStmt->sql)>0;
633 }
634
635 /* Prepare a statement using text placed inside a Blob
636 ** using blob_append_sql().
637 */
db_prepare_blob(Stmt * pStmt,Blob * pSql)638 int db_prepare_blob(Stmt *pStmt, Blob *pSql){
639 int rc;
640 char *zSql;
641 pStmt->sql = *pSql;
642 blob_init(pSql, 0, 0);
643 zSql = blob_sql_text(&pStmt->sql);
644 db.nPrepare++;
645 rc = sqlite3_prepare_v3(g.db, zSql, -1, 0, &pStmt->pStmt, 0);
646 if( rc!=0 ){
647 db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
648 }
649 pStmt->pNext = pStmt->pPrev = 0;
650 pStmt->nStep = 0;
651 pStmt->rc = rc;
652 return rc;
653 }
654
655
656 /*
657 ** Return the index of a bind parameter
658 */
paramIdx(Stmt * pStmt,const char * zParamName)659 static int paramIdx(Stmt *pStmt, const char *zParamName){
660 int i = sqlite3_bind_parameter_index(pStmt->pStmt, zParamName);
661 if( i==0 ){
662 db_err("no such bind parameter: %s\nSQL: %b", zParamName, &pStmt->sql);
663 }
664 return i;
665 }
666 /*
667 ** Bind an integer, string, or Blob value to a named parameter.
668 */
db_bind_int(Stmt * pStmt,const char * zParamName,int iValue)669 int db_bind_int(Stmt *pStmt, const char *zParamName, int iValue){
670 return sqlite3_bind_int(pStmt->pStmt, paramIdx(pStmt, zParamName), iValue);
671 }
db_bind_int64(Stmt * pStmt,const char * zParamName,i64 iValue)672 int db_bind_int64(Stmt *pStmt, const char *zParamName, i64 iValue){
673 return sqlite3_bind_int64(pStmt->pStmt, paramIdx(pStmt, zParamName), iValue);
674 }
db_bind_double(Stmt * pStmt,const char * zParamName,double rValue)675 int db_bind_double(Stmt *pStmt, const char *zParamName, double rValue){
676 return sqlite3_bind_double(pStmt->pStmt, paramIdx(pStmt, zParamName), rValue);
677 }
db_bind_text(Stmt * pStmt,const char * zParamName,const char * zValue)678 int db_bind_text(Stmt *pStmt, const char *zParamName, const char *zValue){
679 return sqlite3_bind_text(pStmt->pStmt, paramIdx(pStmt, zParamName), zValue,
680 -1, SQLITE_STATIC);
681 }
db_bind_text16(Stmt * pStmt,const char * zParamName,const char * zValue)682 int db_bind_text16(Stmt *pStmt, const char *zParamName, const char *zValue){
683 return sqlite3_bind_text16(pStmt->pStmt, paramIdx(pStmt, zParamName), zValue,
684 -1, SQLITE_STATIC);
685 }
db_bind_null(Stmt * pStmt,const char * zParamName)686 int db_bind_null(Stmt *pStmt, const char *zParamName){
687 return sqlite3_bind_null(pStmt->pStmt, paramIdx(pStmt, zParamName));
688 }
db_bind_blob(Stmt * pStmt,const char * zParamName,Blob * pBlob)689 int db_bind_blob(Stmt *pStmt, const char *zParamName, Blob *pBlob){
690 return sqlite3_bind_blob(pStmt->pStmt, paramIdx(pStmt, zParamName),
691 blob_buffer(pBlob), blob_size(pBlob), SQLITE_STATIC);
692 }
693
694 /* bind_str() treats a Blob object like a TEXT string and binds it
695 ** to the SQL variable. Contrast this to bind_blob() which treats
696 ** the Blob object like an SQL BLOB.
697 */
db_bind_str(Stmt * pStmt,const char * zParamName,Blob * pBlob)698 int db_bind_str(Stmt *pStmt, const char *zParamName, Blob *pBlob){
699 return sqlite3_bind_text(pStmt->pStmt, paramIdx(pStmt, zParamName),
700 blob_buffer(pBlob), blob_size(pBlob), SQLITE_STATIC);
701 }
702
703 /*
704 ** Step the SQL statement. Return either SQLITE_ROW or an error code
705 ** or SQLITE_OK if the statement finishes successfully.
706 */
db_step(Stmt * pStmt)707 int db_step(Stmt *pStmt){
708 int rc;
709 if( pStmt->pStmt==0 ) return pStmt->rc;
710 rc = sqlite3_step(pStmt->pStmt);
711 pStmt->nStep++;
712 return rc;
713 }
714
715 /*
716 ** Print warnings if a query is inefficient.
717 */
db_stats(Stmt * pStmt)718 static void db_stats(Stmt *pStmt){
719 #ifdef FOSSIL_DEBUG
720 int c1, c2, c3;
721 const char *zSql = sqlite3_sql(pStmt->pStmt);
722 if( zSql==0 ) return;
723 c1 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
724 c2 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, 1);
725 c3 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_SORT, 1);
726 if( c1>pStmt->nStep*4 && strstr(zSql,"/*scan*/")==0 ){
727 fossil_warning("%d scan steps for %d rows in [%s]", c1, pStmt->nStep, zSql);
728 }else if( c2 ){
729 fossil_warning("%d automatic index rows in [%s]", c2, zSql);
730 }else if( c3 && strstr(zSql,"/*sort*/")==0 && strstr(zSql,"/*scan*/")==0 ){
731 fossil_warning("sort w/o index in [%s]", zSql);
732 }
733 pStmt->nStep = 0;
734 #endif
735 }
736
737 /*
738 ** Reset or finalize a statement.
739 */
db_reset(Stmt * pStmt)740 int db_reset(Stmt *pStmt){
741 int rc;
742 if( g.fSqlStats ){ db_stats(pStmt); }
743 rc = sqlite3_reset(pStmt->pStmt);
744 db_check_result(rc, pStmt);
745 return rc;
746 }
db_finalize(Stmt * pStmt)747 int db_finalize(Stmt *pStmt){
748 int rc;
749 if( pStmt->pNext ){
750 pStmt->pNext->pPrev = pStmt->pPrev;
751 }
752 if( pStmt->pPrev ){
753 pStmt->pPrev->pNext = pStmt->pNext;
754 }else if( db.pAllStmt==pStmt ){
755 db.pAllStmt = pStmt->pNext;
756 }
757 pStmt->pNext = 0;
758 pStmt->pPrev = 0;
759 if( g.fSqlStats ){ db_stats(pStmt); }
760 blob_reset(&pStmt->sql);
761 rc = sqlite3_finalize(pStmt->pStmt);
762 db_check_result(rc, pStmt);
763 pStmt->pStmt = 0;
764 return rc;
765 }
766
767 /*
768 ** Return the rowid of the most recent insert
769 */
db_last_insert_rowid(void)770 int db_last_insert_rowid(void){
771 i64 x = sqlite3_last_insert_rowid(g.db);
772 if( x<0 || x>(i64)2147483647 ){
773 fossil_panic("rowid out of range (0..2147483647)");
774 }
775 return (int)x;
776 }
777
778 /*
779 ** Return the number of rows that were changed by the most recent
780 ** INSERT, UPDATE, or DELETE. Auxiliary changes caused by triggers
781 ** or other side effects are not counted.
782 */
db_changes(void)783 int db_changes(void){
784 return sqlite3_changes(g.db);
785 }
786
787 /*
788 ** Extract text, integer, or blob values from the N-th column of the
789 ** current row.
790 */
db_column_type(Stmt * pStmt,int N)791 int db_column_type(Stmt *pStmt, int N){
792 return sqlite3_column_type(pStmt->pStmt, N);
793 }
db_column_bytes(Stmt * pStmt,int N)794 int db_column_bytes(Stmt *pStmt, int N){
795 return sqlite3_column_bytes(pStmt->pStmt, N);
796 }
db_column_int(Stmt * pStmt,int N)797 int db_column_int(Stmt *pStmt, int N){
798 return sqlite3_column_int(pStmt->pStmt, N);
799 }
db_column_int64(Stmt * pStmt,int N)800 i64 db_column_int64(Stmt *pStmt, int N){
801 return sqlite3_column_int64(pStmt->pStmt, N);
802 }
db_column_double(Stmt * pStmt,int N)803 double db_column_double(Stmt *pStmt, int N){
804 return sqlite3_column_double(pStmt->pStmt, N);
805 }
db_column_text(Stmt * pStmt,int N)806 const char *db_column_text(Stmt *pStmt, int N){
807 return (char*)sqlite3_column_text(pStmt->pStmt, N);
808 }
db_column_raw(Stmt * pStmt,int N)809 const char *db_column_raw(Stmt *pStmt, int N){
810 return (const char*)sqlite3_column_blob(pStmt->pStmt, N);
811 }
db_column_name(Stmt * pStmt,int N)812 const char *db_column_name(Stmt *pStmt, int N){
813 return (char*)sqlite3_column_name(pStmt->pStmt, N);
814 }
db_column_count(Stmt * pStmt)815 int db_column_count(Stmt *pStmt){
816 return sqlite3_column_count(pStmt->pStmt);
817 }
db_column_malloc(Stmt * pStmt,int N)818 char *db_column_malloc(Stmt *pStmt, int N){
819 return mprintf("%s", db_column_text(pStmt, N));
820 }
db_column_blob(Stmt * pStmt,int N,Blob * pBlob)821 void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){
822 blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
823 sqlite3_column_bytes(pStmt->pStmt, N));
824 }
db_column_text_as_blob(Stmt * pStmt,int N)825 Blob db_column_text_as_blob(Stmt *pStmt, int N){
826 Blob x;
827 blob_init(&x, (char*)sqlite3_column_text(pStmt->pStmt,N),
828 sqlite3_column_bytes(pStmt->pStmt,N));
829 return x;
830 }
831
832 /*
833 ** Initialize a blob to an ephemeral copy of the content of a
834 ** column in the current row. The data in the blob will become
835 ** invalid when the statement is stepped or reset.
836 */
db_ephemeral_blob(Stmt * pStmt,int N,Blob * pBlob)837 void db_ephemeral_blob(Stmt *pStmt, int N, Blob *pBlob){
838 blob_init(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
839 sqlite3_column_bytes(pStmt->pStmt, N));
840 }
841
842 /*
843 ** Execute a single prepared statement until it finishes.
844 */
db_exec(Stmt * pStmt)845 int db_exec(Stmt *pStmt){
846 int rc;
847 while( (rc = db_step(pStmt))==SQLITE_ROW ){}
848 rc = db_reset(pStmt);
849 db_check_result(rc, pStmt);
850 return rc;
851 }
852
853 /*
854 ** COMMAND: test-db-exec-error
855 ** Usage: %fossil test-db-exec-error
856 **
857 ** Invoke the db_exec() interface with an erroneous SQL statement
858 ** in order to verify the error handling logic.
859 */
db_test_db_exec_cmd(void)860 void db_test_db_exec_cmd(void){
861 Stmt err;
862 db_find_and_open_repository(0,0);
863 db_prepare(&err, "INSERT INTO repository.config(name) VALUES(NULL);");
864 db_exec(&err);
865 }
866
867 /*
868 ** COMMAND: test-db-prepare
869 ** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
870 **
871 ** Options:
872 **
873 ** --auth-report Enable the ticket report query authorizer.
874 ** --auth-ticket Enable the ticket schema query authorizer.
875 **
876 ** Invoke db_prepare() on the SQL input. Report any errors encountered.
877 ** This command is used to verify error detection logic in the db_prepare()
878 ** utility routine.
879 */
db_test_db_prepare(void)880 void db_test_db_prepare(void){
881 const int fAuthReport = find_option("auth-report",0,0)!=0;
882 const int fAuthSchema = find_option("auth-ticket",0,0)!=0;
883 char * zReportErr = 0; /* auth-report error string. */
884 int nSchemaErr = 0; /* Number of auth-ticket errors. */
885 Stmt err;
886
887 if(fAuthReport + fAuthSchema > 1){
888 fossil_fatal("Only one of --auth-report or --auth-ticket "
889 "may be used.");
890 }
891 db_find_and_open_repository(0,0);
892 verify_all_options();
893 if( g.argc!=3 ) usage("?OPTIONS? SQL");
894 if(fAuthReport){
895 report_restrict_sql(&zReportErr);
896 }else if(fAuthSchema){
897 ticket_restrict_sql(&nSchemaErr);
898 }
899 db_prepare(&err, "%s", g.argv[2]/*safe-for-%s*/);
900 db_finalize(&err);
901 if(fAuthReport){
902 report_unrestrict_sql();
903 if(zReportErr){
904 fossil_warning("Report authorizer error: %s\n", zReportErr);
905 fossil_free(zReportErr);
906 }
907 }else if(fAuthSchema){
908 ticket_unrestrict_sql();
909 if(nSchemaErr){
910 fossil_warning("Ticket schema authorizer error count: %d\n",
911 nSchemaErr);
912 }
913 }
914 }
915
916 /*
917 ** Print the output of one or more SQL queries on standard output.
918 ** This routine is used for debugging purposes only.
919 */
db_debug(const char * zSql,...)920 int db_debug(const char *zSql, ...){
921 Blob sql;
922 int rc = SQLITE_OK;
923 va_list ap;
924 const char *z, *zEnd;
925 sqlite3_stmt *pStmt;
926 blob_init(&sql, 0, 0);
927 va_start(ap, zSql);
928 blob_vappendf(&sql, zSql, ap);
929 va_end(ap);
930 z = blob_str(&sql);
931 while( rc==SQLITE_OK && z[0] ){
932 pStmt = 0;
933 rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
934 if( rc!=SQLITE_OK ) break;
935 if( pStmt ){
936 int nRow = 0;
937 db.nPrepare++;
938 while( sqlite3_step(pStmt)==SQLITE_ROW ){
939 int i, n;
940 if( nRow++ > 0 ) fossil_print("\n");
941 n = sqlite3_column_count(pStmt);
942 for(i=0; i<n; i++){
943 fossil_print("%s = %s\n", sqlite3_column_name(pStmt, i),
944 sqlite3_column_text(pStmt,i));
945 }
946 }
947 rc = sqlite3_finalize(pStmt);
948 if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
949 }
950 z = zEnd;
951 }
952 blob_reset(&sql);
953 return rc;
954 }
955
956 /*
957 ** Execute multiple SQL statements. The input text is executed
958 ** directly without any formatting.
959 */
db_exec_sql(const char * z)960 int db_exec_sql(const char *z){
961 int rc = SQLITE_OK;
962 sqlite3_stmt *pStmt;
963 const char *zEnd;
964 while( rc==SQLITE_OK && z[0] ){
965 pStmt = 0;
966 rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
967 if( rc ){
968 db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
969 }else if( pStmt ){
970 db.nPrepare++;
971 while( sqlite3_step(pStmt)==SQLITE_ROW ){}
972 rc = sqlite3_finalize(pStmt);
973 if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
974 }
975 z = zEnd;
976 }
977 return rc;
978 }
979
980 /*
981 ** Execute multiple SQL statements using printf-style formatting.
982 */
db_multi_exec(const char * zSql,...)983 int db_multi_exec(const char *zSql, ...){
984 Blob sql;
985 int rc;
986 va_list ap;
987
988 blob_init(&sql, 0, 0);
989 va_start(ap, zSql);
990 blob_vappendf(&sql, zSql, ap);
991 va_end(ap);
992 rc = db_exec_sql(blob_str(&sql));
993 blob_reset(&sql);
994 return rc;
995 }
996
997 /*
998 ** Optionally make the following changes to the database if feasible and
999 ** convenient. Do not start a transaction for these changes, but only
1000 ** make these changes if other changes are also being made.
1001 */
db_optional_sql(const char * zDb,const char * zSql,...)1002 void db_optional_sql(const char *zDb, const char *zSql, ...){
1003 if( db_is_writeable(zDb) && db.nBeforeCommit < count(db.azBeforeCommit) ){
1004 va_list ap;
1005 va_start(ap, zSql);
1006 db.azBeforeCommit[db.nBeforeCommit++] = sqlite3_vmprintf(zSql, ap);
1007 va_end(ap);
1008 }
1009 }
1010
1011 /*
1012 ** Execute a query and return a single integer value.
1013 */
db_int64(i64 iDflt,const char * zSql,...)1014 i64 db_int64(i64 iDflt, const char *zSql, ...){
1015 va_list ap;
1016 Stmt s;
1017 i64 rc;
1018 va_start(ap, zSql);
1019 db_vprepare(&s, 0, zSql, ap);
1020 va_end(ap);
1021 if( db_step(&s)!=SQLITE_ROW ){
1022 rc = iDflt;
1023 }else{
1024 rc = db_column_int64(&s, 0);
1025 }
1026 db_finalize(&s);
1027 return rc;
1028 }
db_int(int iDflt,const char * zSql,...)1029 int db_int(int iDflt, const char *zSql, ...){
1030 va_list ap;
1031 Stmt s;
1032 int rc;
1033 va_start(ap, zSql);
1034 db_vprepare(&s, 0, zSql, ap);
1035 va_end(ap);
1036 if( db_step(&s)!=SQLITE_ROW ){
1037 rc = iDflt;
1038 }else{
1039 rc = db_column_int(&s, 0);
1040 }
1041 db_finalize(&s);
1042 return rc;
1043 }
1044
1045 /*
1046 ** Return TRUE if the query would return 1 or more rows. Return
1047 ** FALSE if the query result would be an empty set.
1048 */
db_exists(const char * zSql,...)1049 int db_exists(const char *zSql, ...){
1050 va_list ap;
1051 Stmt s;
1052 int rc;
1053 va_start(ap, zSql);
1054 db_vprepare(&s, 0, zSql, ap);
1055 va_end(ap);
1056 if( db_step(&s)!=SQLITE_ROW ){
1057 rc = 0;
1058 }else{
1059 rc = 1;
1060 }
1061 db_finalize(&s);
1062 return rc;
1063 }
1064
1065
1066 /*
1067 ** Execute a query and return a floating-point value.
1068 */
db_double(double rDflt,const char * zSql,...)1069 double db_double(double rDflt, const char *zSql, ...){
1070 va_list ap;
1071 Stmt s;
1072 double r;
1073 va_start(ap, zSql);
1074 db_vprepare(&s, 0, zSql, ap);
1075 va_end(ap);
1076 if( db_step(&s)!=SQLITE_ROW ){
1077 r = rDflt;
1078 }else{
1079 r = db_column_double(&s, 0);
1080 }
1081 db_finalize(&s);
1082 return r;
1083 }
1084
1085 /*
1086 ** Execute a query and append the first column of the first row
1087 ** of the result set to blob given in the first argument.
1088 */
db_blob(Blob * pResult,const char * zSql,...)1089 void db_blob(Blob *pResult, const char *zSql, ...){
1090 va_list ap;
1091 Stmt s;
1092 va_start(ap, zSql);
1093 db_vprepare(&s, 0, zSql, ap);
1094 va_end(ap);
1095 if( db_step(&s)==SQLITE_ROW ){
1096 blob_append(pResult, sqlite3_column_blob(s.pStmt, 0),
1097 sqlite3_column_bytes(s.pStmt, 0));
1098 }
1099 db_finalize(&s);
1100 }
1101
1102 /*
1103 ** Execute a query. Return the first column of the first row
1104 ** of the result set as a string. Space to hold the string is
1105 ** obtained from malloc(). If the result set is empty, return
1106 ** zDefault instead.
1107 */
db_text(const char * zDefault,const char * zSql,...)1108 char *db_text(const char *zDefault, const char *zSql, ...){
1109 va_list ap;
1110 Stmt s;
1111 char *z;
1112 va_start(ap, zSql);
1113 db_vprepare(&s, 0, zSql, ap);
1114 va_end(ap);
1115 if( db_step(&s)==SQLITE_ROW ){
1116 z = mprintf("%s", sqlite3_column_text(s.pStmt, 0));
1117 }else if( zDefault ){
1118 z = mprintf("%s", zDefault);
1119 }else{
1120 z = 0;
1121 }
1122 db_finalize(&s);
1123 return z;
1124 }
1125
1126 /*
1127 ** Initialize a new database file with the given schema. If anything
1128 ** goes wrong, call db_err() to exit.
1129 **
1130 ** If zFilename is NULL, then create an empty repository in an in-memory
1131 ** database.
1132 */
db_init_database(const char * zFileName,const char * zSchema,...)1133 void db_init_database(
1134 const char *zFileName, /* Name of database file to create */
1135 const char *zSchema, /* First part of schema */
1136 ... /* Additional SQL to run. Terminate with NULL. */
1137 ){
1138 sqlite3 *xdb;
1139 int rc;
1140 const char *zSql;
1141 va_list ap;
1142
1143 xdb = db_open(zFileName ? zFileName : ":memory:");
1144 sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0);
1145 rc = sqlite3_exec(xdb, zSchema, 0, 0, 0);
1146 if( rc!=SQLITE_OK ){
1147 db_err("%s", sqlite3_errmsg(xdb));
1148 }
1149 va_start(ap, zSchema);
1150 while( (zSql = va_arg(ap, const char*))!=0 ){
1151 rc = sqlite3_exec(xdb, zSql, 0, 0, 0);
1152 if( rc!=SQLITE_OK ){
1153 db_err("%s", sqlite3_errmsg(xdb));
1154 }
1155 }
1156 va_end(ap);
1157 sqlite3_exec(xdb, "COMMIT", 0, 0, 0);
1158 if( zFileName || g.db!=0 ){
1159 sqlite3_close(xdb);
1160 }else{
1161 g.db = xdb;
1162 }
1163 }
1164
1165 /*
1166 ** Function to return the number of seconds since 1970. This is
1167 ** the same as strftime('%s','now') but is more compact.
1168 */
db_now_function(sqlite3_context * context,int argc,sqlite3_value ** argv)1169 void db_now_function(
1170 sqlite3_context *context,
1171 int argc,
1172 sqlite3_value **argv
1173 ){
1174 sqlite3_result_int64(context, time(0));
1175 }
1176
1177 /*
1178 ** Function to return the check-in time for a file.
1179 **
1180 ** checkin_mtime(CKINID,RID)
1181 **
1182 ** CKINID: The RID for the manifest for a check-in.
1183 ** RID: The RID of a file in CKINID for which the check-in time
1184 ** is desired.
1185 **
1186 ** Returns: The check-in time in seconds since 1970.
1187 */
db_checkin_mtime_function(sqlite3_context * context,int argc,sqlite3_value ** argv)1188 void db_checkin_mtime_function(
1189 sqlite3_context *context,
1190 int argc,
1191 sqlite3_value **argv
1192 ){
1193 i64 mtime;
1194 int rc = mtime_of_manifest_file(sqlite3_value_int(argv[0]),
1195 sqlite3_value_int(argv[1]), &mtime);
1196 if( rc==0 ){
1197 sqlite3_result_int64(context, mtime);
1198 }
1199 }
1200
1201 /*
1202 ** SQL wrapper around the symbolic_name_to_rid() C-language API.
1203 ** Examples:
1204 **
1205 ** symbolic_name_to_rid('trunk');
1206 ** symbolic_name_to_rid('trunk','w');
1207 **
1208 */
db_sym2rid_function(sqlite3_context * context,int argc,sqlite3_value ** argv)1209 void db_sym2rid_function(
1210 sqlite3_context *context,
1211 int argc,
1212 sqlite3_value **argv
1213 ){
1214 const char *arg;
1215 const char *type;
1216 if(1 != argc && 2 != argc){
1217 sqlite3_result_error(context, "Expecting one or two arguments", -1);
1218 return;
1219 }
1220 arg = (const char*)sqlite3_value_text(argv[0]);
1221 if(!arg){
1222 sqlite3_result_error(context, "Expecting a STRING argument", -1);
1223 }else{
1224 int rid;
1225 type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0;
1226 if(!type) type = "ci";
1227 rid = symbolic_name_to_rid( arg, type );
1228 if(rid<0){
1229 sqlite3_result_error(context, "Symbolic name is ambiguous.", -1);
1230 }else if(0==rid){
1231 sqlite3_result_null(context);
1232 }else{
1233 sqlite3_result_int64(context, rid);
1234 }
1235 }
1236 }
1237
1238 /*
1239 ** The toLocal() SQL function returns a string that is an argument to a
1240 ** date/time function that is appropriate for modifying the time for display.
1241 ** If UTC time display is selected, no modification occurs. If local time
1242 ** display is selected, the time is adjusted appropriately.
1243 **
1244 ** Example usage:
1245 **
1246 ** SELECT datetime('now',toLocal());
1247 */
db_tolocal_function(sqlite3_context * context,int argc,sqlite3_value ** argv)1248 void db_tolocal_function(
1249 sqlite3_context *context,
1250 int argc,
1251 sqlite3_value **argv
1252 ){
1253 if( g.fTimeFormat==0 ){
1254 if( db_get_int("timeline-utc", 1) ){
1255 g.fTimeFormat = 1;
1256 }else{
1257 g.fTimeFormat = 2;
1258 }
1259 }
1260 if( g.fTimeFormat==1 ){
1261 sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
1262 }else{
1263 sqlite3_result_text(context, "localtime", -1, SQLITE_STATIC);
1264 }
1265 }
1266
1267 /*
1268 ** The fromLocal() SQL function returns a string that is an argument to a
1269 ** date/time function that is appropriate to convert an input time to UTC.
1270 ** If UTC time display is selected, no modification occurs. If local time
1271 ** display is selected, the time is adjusted from local to UTC.
1272 **
1273 ** Example usage:
1274 **
1275 ** SELECT julianday(:user_input,fromLocal());
1276 */
db_fromlocal_function(sqlite3_context * context,int argc,sqlite3_value ** argv)1277 void db_fromlocal_function(
1278 sqlite3_context *context,
1279 int argc,
1280 sqlite3_value **argv
1281 ){
1282 if( g.fTimeFormat==0 ){
1283 if( db_get_int("timeline-utc", 1) ){
1284 g.fTimeFormat = 1;
1285 }else{
1286 g.fTimeFormat = 2;
1287 }
1288 }
1289 if( g.fTimeFormat==1 ){
1290 sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
1291 }else{
1292 sqlite3_result_text(context, "utc", -1, SQLITE_STATIC);
1293 }
1294 }
1295
1296 /*
1297 ** If the input is a hexadecimal string, convert that string into a BLOB.
1298 ** If the input is not a hexadecimal string, return NULL.
1299 */
db_hextoblob(sqlite3_context * context,int argc,sqlite3_value ** argv)1300 void db_hextoblob(
1301 sqlite3_context *context,
1302 int argc,
1303 sqlite3_value **argv
1304 ){
1305 const unsigned char *zIn = sqlite3_value_text(argv[0]);
1306 int nIn = sqlite3_value_bytes(argv[0]);
1307 unsigned char *zOut;
1308 if( zIn==0 ) return;
1309 if( nIn&1 ) return;
1310 if( !validate16((const char*)zIn, nIn) ) return;
1311 zOut = sqlite3_malloc64( nIn/2 + 1 );
1312 if( zOut==0 ){
1313 sqlite3_result_error_nomem(context);
1314 return;
1315 }
1316 decode16(zIn, zOut, nIn);
1317 sqlite3_result_blob(context, zOut, nIn/2, sqlite3_free);
1318 }
1319
1320 /*
1321 ** Return the XOR-obscured version of the input text. Useful for
1322 ** updating authentication strings in Fossil settings. To change
1323 ** the password locally stored for sync, for instance:
1324 **
1325 ** echo "UPDATE config
1326 ** SET value = obscure('monkey123')
1327 ** WHERE name = 'last-sync-pw'" |
1328 ** fossil sql
1329 **
1330 ** Note that user.pw uses a different obscuration algorithm, but
1331 ** you don't need to use 'fossil sql' for that anyway. Just call
1332 **
1333 ** fossil user pass monkey123
1334 **
1335 ** to change the local user entry's password in the same way.
1336 */
db_obscure(sqlite3_context * context,int argc,sqlite3_value ** argv)1337 void db_obscure(
1338 sqlite3_context *context,
1339 int argc,
1340 sqlite3_value **argv
1341 ){
1342 const unsigned char *zIn = sqlite3_value_text(argv[0]);
1343 int nIn = sqlite3_value_bytes(argv[0]);
1344 char *zOut, *zTemp;
1345 if( 0==zIn ) return;
1346 if( 0==(zOut = sqlite3_malloc64( nIn * 2 + 3 )) ){
1347 sqlite3_result_error_nomem(context);
1348 return;
1349 }
1350 strcpy(zOut, zTemp = obscure((char*)zIn));
1351 fossil_free(zTemp);
1352 sqlite3_result_text(context, zOut, strlen(zOut), sqlite3_free);
1353 }
1354
1355 /*
1356 ** Return True if zName is a protected (a.k.a. "sensitive") setting.
1357 */
db_setting_is_protected(const char * zName)1358 int db_setting_is_protected(const char *zName){
1359 const Setting *pSetting = zName ? db_find_setting(zName,0) : 0;
1360 return pSetting!=0 && pSetting->sensitive!=0;
1361 }
1362
1363 /*
1364 ** Implement the protected_setting(X) SQL function. This function returns
1365 ** true if X is the name of a protected (security-sensitive) setting and
1366 ** the db.protectSensitive flag is enabled. It returns false otherwise.
1367 */
db_protected_setting_func(sqlite3_context * context,int argc,sqlite3_value ** argv)1368 LOCAL void db_protected_setting_func(
1369 sqlite3_context *context,
1370 int argc,
1371 sqlite3_value **argv
1372 ){
1373 const char *zSetting;
1374 if( (db.protectMask & PROTECT_SENSITIVE)==0 ){
1375 sqlite3_result_int(context, 0);
1376 return;
1377 }
1378 zSetting = (const char*)sqlite3_value_text(argv[0]);
1379 sqlite3_result_int(context, db_setting_is_protected(zSetting));
1380 }
1381
1382 /*
1383 ** Register the SQL functions that are useful both to the internal
1384 ** representation and to the "fossil sql" command.
1385 */
db_add_aux_functions(sqlite3 * db)1386 void db_add_aux_functions(sqlite3 *db){
1387 sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
1388 db_checkin_mtime_function, 0, 0);
1389 sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
1390 db_sym2rid_function, 0, 0);
1391 sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
1392 db_sym2rid_function, 0, 0);
1393 sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0,
1394 db_now_function, 0, 0);
1395 sqlite3_create_function(db, "toLocal", 0, SQLITE_UTF8, 0,
1396 db_tolocal_function, 0, 0);
1397 sqlite3_create_function(db, "fromLocal", 0, SQLITE_UTF8, 0,
1398 db_fromlocal_function, 0, 0);
1399 sqlite3_create_function(db, "hextoblob", 1, SQLITE_UTF8, 0,
1400 db_hextoblob, 0, 0);
1401 sqlite3_create_function(db, "capunion", 1, SQLITE_UTF8, 0,
1402 0, capability_union_step, capability_union_finalize);
1403 sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0,
1404 capability_fullcap, 0, 0);
1405 sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0,
1406 alert_find_emailaddr_func, 0, 0);
1407 sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
1408 alert_display_name_func, 0, 0);
1409 sqlite3_create_function(db, "obscure", 1, SQLITE_UTF8, 0,
1410 db_obscure, 0, 0);
1411 sqlite3_create_function(db, "protected_setting", 1, SQLITE_UTF8, 0,
1412 db_protected_setting_func, 0, 0);
1413 sqlite3_create_function(db, "win_reserved", 1, SQLITE_UTF8, 0,
1414 db_win_reserved_func,0,0
1415 );
1416 }
1417
1418 #if USE_SEE
1419 /*
1420 ** This is a pointer to the saved database encryption key string.
1421 */
1422 static char *zSavedKey = 0;
1423
1424 /*
1425 ** This is the size of the saved database encryption key, in bytes.
1426 */
1427 size_t savedKeySize = 0;
1428
1429 /*
1430 ** This function returns the saved database encryption key -OR- zero if
1431 ** no database encryption key is saved.
1432 */
db_get_saved_encryption_key()1433 char *db_get_saved_encryption_key(){
1434 return zSavedKey;
1435 }
1436
1437 /*
1438 ** This function returns the size of the saved database encryption key
1439 ** -OR- zero if no database encryption key is saved.
1440 */
db_get_saved_encryption_key_size()1441 size_t db_get_saved_encryption_key_size(){
1442 return savedKeySize;
1443 }
1444
1445 /*
1446 ** This function arranges for the database encryption key to be securely
1447 ** saved in non-pagable memory (on platforms where this is possible).
1448 */
db_save_encryption_key(Blob * pKey)1449 static void db_save_encryption_key(
1450 Blob *pKey
1451 ){
1452 void *p = NULL;
1453 size_t n = 0;
1454 size_t pageSize = 0;
1455 size_t blobSize = 0;
1456
1457 blobSize = blob_size(pKey);
1458 if( blobSize==0 ) return;
1459 fossil_get_page_size(&pageSize);
1460 assert( pageSize>0 );
1461 if( blobSize>pageSize ){
1462 fossil_panic("key blob too large: %u versus %u", blobSize, pageSize);
1463 }
1464 p = fossil_secure_alloc_page(&n);
1465 assert( p!=NULL );
1466 assert( n==pageSize );
1467 assert( n>=blobSize );
1468 memcpy(p, blob_str(pKey), blobSize);
1469 zSavedKey = p;
1470 savedKeySize = n;
1471 }
1472
1473 /*
1474 ** This function arranges for the saved database encryption key to be
1475 ** securely zeroed, unlocked (if necessary), and freed.
1476 */
db_unsave_encryption_key()1477 void db_unsave_encryption_key(){
1478 fossil_secure_free_page(zSavedKey, savedKeySize);
1479 zSavedKey = NULL;
1480 savedKeySize = 0;
1481 }
1482
1483 /*
1484 ** This function sets the saved database encryption key to the specified
1485 ** string value, allocating or freeing the underlying memory if needed.
1486 */
db_set_saved_encryption_key(Blob * pKey)1487 void db_set_saved_encryption_key(
1488 Blob *pKey
1489 ){
1490 if( zSavedKey!=NULL ){
1491 size_t blobSize = blob_size(pKey);
1492 if( blobSize==0 ){
1493 db_unsave_encryption_key();
1494 }else{
1495 if( blobSize>savedKeySize ){
1496 fossil_panic("key blob too large: %u versus %u",
1497 blobSize, savedKeySize);
1498 }
1499 fossil_secure_zero(zSavedKey, savedKeySize);
1500 memcpy(zSavedKey, blob_str(pKey), blobSize);
1501 }
1502 }else{
1503 db_save_encryption_key(pKey);
1504 }
1505 }
1506
1507 #if defined(_WIN32)
1508 /*
1509 ** This function sets the saved database encryption key to one that gets
1510 ** read from the specified Fossil parent process. This is only necessary
1511 ** (or functional) on Windows.
1512 */
db_read_saved_encryption_key_from_process(DWORD processId,LPVOID pAddress,SIZE_T nSize)1513 void db_read_saved_encryption_key_from_process(
1514 DWORD processId, /* Identifier for Fossil parent process. */
1515 LPVOID pAddress, /* Pointer to saved key buffer in the parent process. */
1516 SIZE_T nSize /* Size of saved key buffer in the parent process. */
1517 ){
1518 void *p = NULL;
1519 size_t n = 0;
1520 size_t pageSize = 0;
1521 HANDLE hProcess = NULL;
1522
1523 fossil_get_page_size(&pageSize);
1524 assert( pageSize>0 );
1525 if( nSize>pageSize ){
1526 fossil_panic("key too large: %u versus %u", nSize, pageSize);
1527 }
1528 p = fossil_secure_alloc_page(&n);
1529 assert( p!=NULL );
1530 assert( n==pageSize );
1531 assert( n>=nSize );
1532 hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processId);
1533 if( hProcess!=NULL ){
1534 SIZE_T nRead = 0;
1535 if( ReadProcessMemory(hProcess, pAddress, p, nSize, &nRead) ){
1536 CloseHandle(hProcess);
1537 if( nRead==nSize ){
1538 db_unsave_encryption_key();
1539 zSavedKey = p;
1540 savedKeySize = n;
1541 }else{
1542 fossil_panic("bad size read, %u out of %u bytes at %p from pid %lu",
1543 nRead, nSize, pAddress, processId);
1544 }
1545 }else{
1546 CloseHandle(hProcess);
1547 fossil_panic("failed read, %u bytes at %p from pid %lu: %lu", nSize,
1548 pAddress, processId, GetLastError());
1549 }
1550 }else{
1551 fossil_panic("failed to open pid %lu: %lu", processId, GetLastError());
1552 }
1553 }
1554
1555 /*
1556 ** This function evaluates the specified TH1 script and attempts to parse
1557 ** its result as a colon-delimited triplet containing a process identifier,
1558 ** address, and size (in bytes) of the database encryption key. This is
1559 ** only necessary (or functional) on Windows.
1560 */
db_read_saved_encryption_key_from_process_via_th1(const char * zConfig)1561 void db_read_saved_encryption_key_from_process_via_th1(
1562 const char *zConfig /* The TH1 script to evaluate. */
1563 ){
1564 int rc;
1565 char *zResult;
1566 Th_FossilInit(TH_INIT_DEFAULT | TH_INIT_NEED_CONFIG | TH_INIT_NO_REPO);
1567 rc = Th_Eval(g.interp, 0, zConfig, -1);
1568 zResult = (char*)Th_GetResult(g.interp, 0);
1569 if( rc!=TH_OK ){
1570 fossil_fatal("script for pid key failed: %s", zResult);
1571 }
1572 if( zResult ){
1573 DWORD processId = 0;
1574 LPVOID pAddress = NULL;
1575 SIZE_T nSize = 0;
1576 parse_pid_key_value(zResult, &processId, &pAddress, &nSize);
1577 db_read_saved_encryption_key_from_process(processId, pAddress, nSize);
1578 }
1579 }
1580 #endif /* defined(_WIN32) */
1581 #endif /* USE_SEE */
1582
1583 /*
1584 ** If the database file zDbFile has a name that suggests that it is
1585 ** encrypted, then prompt for the database encryption key and return it
1586 ** in the blob *pKey. Or, if the encryption key has previously been
1587 ** requested, just return a copy of the previous result. The blob in
1588 ** *pKey must be initialized.
1589 */
db_maybe_obtain_encryption_key(const char * zDbFile,Blob * pKey)1590 static void db_maybe_obtain_encryption_key(
1591 const char *zDbFile, /* Name of the database file */
1592 Blob *pKey /* Put the encryption key here */
1593 ){
1594 #if USE_SEE
1595 if( sqlite3_strglob("*.efossil", zDbFile)==0 ){
1596 char *zKey = db_get_saved_encryption_key();
1597 if( zKey ){
1598 blob_set(pKey, zKey);
1599 }else{
1600 char *zPrompt = mprintf("\rencryption key for '%s': ", zDbFile);
1601 prompt_for_password(zPrompt, pKey, 0);
1602 fossil_free(zPrompt);
1603 db_set_saved_encryption_key(pKey);
1604 }
1605 }
1606 #endif
1607 }
1608
1609
1610 /*
1611 ** Sets the encryption key for the database, if necessary.
1612 */
db_maybe_set_encryption_key(sqlite3 * db,const char * zDbName)1613 void db_maybe_set_encryption_key(sqlite3 *db, const char *zDbName){
1614 Blob key;
1615 blob_init(&key, 0, 0);
1616 db_maybe_obtain_encryption_key(zDbName, &key);
1617 if( blob_size(&key)>0 ){
1618 if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
1619 char *zCmd = sqlite3_mprintf("PRAGMA key(%Q)", blob_str(&key));
1620 sqlite3_exec(db, zCmd, 0, 0, 0);
1621 fossil_secure_zero(zCmd, strlen(zCmd));
1622 sqlite3_free(zCmd);
1623 #if USE_SEE
1624 }else{
1625 sqlite3_key(db, blob_str(&key), -1);
1626 #endif
1627 }
1628 }
1629 blob_reset(&key);
1630 }
1631
1632 /*
1633 ** Open a database file. Return a pointer to the new database
1634 ** connection. An error results in process abort.
1635 */
db_open(const char * zDbName)1636 LOCAL sqlite3 *db_open(const char *zDbName){
1637 int rc;
1638 sqlite3 *db;
1639
1640 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1641 if( strcmp(zDbName, g.nameOfExe)==0 ){
1642 extern int sqlite3_appendvfs_init(
1643 sqlite3 *, char **, const sqlite3_api_routines *
1644 );
1645 sqlite3_appendvfs_init(0,0,0);
1646 g.zVfsName = "apndvfs";
1647 }
1648 rc = sqlite3_open_v2(
1649 zDbName, &db,
1650 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1651 g.zVfsName
1652 );
1653 if( rc!=SQLITE_OK ){
1654 db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
1655 }
1656 db_maybe_set_encryption_key(db, zDbName);
1657 sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 0, &rc);
1658 sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_TRIGGER, 0, &rc);
1659 sqlite3_db_config(db, SQLITE_DBCONFIG_TRUSTED_SCHEMA, 0, &rc);
1660 sqlite3_db_config(db, SQLITE_DBCONFIG_DQS_DDL, 0, &rc);
1661 sqlite3_db_config(db, SQLITE_DBCONFIG_DQS_DML, 0, &rc);
1662 sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, &rc);
1663 sqlite3_busy_timeout(db, 15000);
1664 sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
1665 sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0);
1666 sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
1667 sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
1668 sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
1669 sqlite3_create_function(
1670 db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
1671 );
1672 sqlite3_create_function(
1673 db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
1674 );
1675 if( g.fSqlTrace ) sqlite3_trace_v2(db, SQLITE_TRACE_PROFILE, db_sql_trace, 0);
1676 db_add_aux_functions(db);
1677 re_add_sql_func(db); /* The REGEXP operator */
1678 foci_register(db); /* The "files_of_checkin" virtual table */
1679 sqlite3_set_authorizer(db, db_top_authorizer, db);
1680 return db;
1681 }
1682
1683
1684 /*
1685 ** Detaches the zLabel database.
1686 */
db_detach(const char * zLabel)1687 void db_detach(const char *zLabel){
1688 db_multi_exec("DETACH DATABASE %Q", zLabel);
1689 }
1690
1691 /*
1692 ** zDbName is the name of a database file. Attach zDbName using
1693 ** the name zLabel.
1694 */
db_attach(const char * zDbName,const char * zLabel)1695 void db_attach(const char *zDbName, const char *zLabel){
1696 Blob key;
1697 if( db_table_exists(zLabel,"sqlite_schema") ) return;
1698 blob_init(&key, 0, 0);
1699 db_maybe_obtain_encryption_key(zDbName, &key);
1700 if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
1701 char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
1702 zDbName, zLabel, blob_str(&key));
1703 db_exec_sql(zCmd);
1704 fossil_secure_zero(zCmd, strlen(zCmd));
1705 sqlite3_free(zCmd);
1706 }else{
1707 char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY ''",
1708 zDbName, zLabel);
1709 db_exec_sql(zCmd);
1710 sqlite3_free(zCmd);
1711 #if USE_SEE
1712 if( blob_size(&key)>0 ){
1713 sqlite3_key_v2(g.db, zLabel, blob_str(&key), -1);
1714 }
1715 #endif
1716 }
1717 blob_reset(&key);
1718 }
1719
1720 /*
1721 ** Change the schema name of the "main" database to zLabel.
1722 ** zLabel must be a static string that is unchanged for the life of
1723 ** the database connection.
1724 **
1725 ** After calling this routine, db_database_slot(zLabel) should
1726 ** return 0.
1727 */
db_set_main_schemaname(sqlite3 * db,const char * zLabel)1728 void db_set_main_schemaname(sqlite3 *db, const char *zLabel){
1729 if( sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, zLabel) ){
1730 fossil_panic("Fossil requires a version of SQLite that supports the "
1731 "SQLITE_DBCONFIG_MAINDBNAME interface.");
1732 }
1733 }
1734
1735 /*
1736 ** Return the slot number for database zLabel. The first database
1737 ** opened is slot 0. The "temp" database is slot 1. Attached databases
1738 ** are slots 2 and higher.
1739 **
1740 ** Return -1 if zLabel does not match any open database.
1741 */
db_database_slot(const char * zLabel)1742 int db_database_slot(const char *zLabel){
1743 int iSlot = -1;
1744 int rc;
1745 Stmt q;
1746 if( g.db==0 ) return iSlot;
1747 rc = db_prepare_ignore_error(&q, "PRAGMA database_list");
1748 if( rc==SQLITE_OK ){
1749 while( db_step(&q)==SQLITE_ROW ){
1750 if( fossil_strcmp(db_column_text(&q,1),zLabel)==0 ){
1751 iSlot = db_column_int(&q, 0);
1752 break;
1753 }
1754 }
1755 }
1756 db_finalize(&q);
1757 return iSlot;
1758 }
1759
1760 /*
1761 ** zDbName is the name of a database file. If no other database
1762 ** file is open, then open this one. If another database file is
1763 ** already open, then attach zDbName using the name zLabel.
1764 */
db_open_or_attach(const char * zDbName,const char * zLabel)1765 void db_open_or_attach(const char *zDbName, const char *zLabel){
1766 if( !g.db ){
1767 g.db = db_open(zDbName);
1768 db_set_main_schemaname(g.db, zLabel);
1769 }else{
1770 db_attach(zDbName, zLabel);
1771 }
1772 }
1773
1774 /*
1775 ** Close the per-user configuration database file
1776 */
db_close_config()1777 void db_close_config(){
1778 int iSlot = db_database_slot("configdb");
1779 if( iSlot>0 ){
1780 db_detach("configdb");
1781 }else if( g.dbConfig ){
1782 sqlite3_wal_checkpoint(g.dbConfig, 0);
1783 sqlite3_close(g.dbConfig);
1784 g.dbConfig = 0;
1785 }else if( g.db && 0==iSlot ){
1786 int rc;
1787 sqlite3_wal_checkpoint(g.db, 0);
1788 rc = sqlite3_close(g.db);
1789 if( g.fSqlTrace ) fossil_trace("-- db_close_config(%d)\n", rc);
1790 g.db = 0;
1791 g.repositoryOpen = 0;
1792 g.localOpen = 0;
1793 }else{
1794 return;
1795 }
1796 fossil_free(g.zConfigDbName);
1797 g.zConfigDbName = 0;
1798 }
1799
1800 /*
1801 ** Compute the name of the configuration database. If unable to find the
1802 ** database, return 0 if isOptional is true, or panic if isOptional is false.
1803 **
1804 ** Space to hold the result comes from fossil_malloc().
1805 */
db_configdb_name(int isOptional)1806 static char *db_configdb_name(int isOptional){
1807 char *zHome; /* Home directory */
1808 char *zDbName; /* Name of the database file */
1809
1810
1811 /* On Windows, look for these directories, in order:
1812 **
1813 ** FOSSIL_HOME
1814 ** LOCALAPPDATA
1815 ** APPDATA
1816 ** USERPROFILE
1817 ** HOMEDRIVE HOMEPATH
1818 */
1819 #if defined(_WIN32) || defined(__CYGWIN__)
1820 zHome = fossil_getenv("FOSSIL_HOME");
1821 if( zHome==0 ){
1822 zHome = fossil_getenv("LOCALAPPDATA");
1823 if( zHome==0 ){
1824 zHome = fossil_getenv("APPDATA");
1825 if( zHome==0 ){
1826 zHome = fossil_getenv("USERPROFILE");
1827 if( zHome==0 ){
1828 char *zDrive = fossil_getenv("HOMEDRIVE");
1829 char *zPath = fossil_getenv("HOMEPATH");
1830 if( zDrive && zPath ) zHome = mprintf("%s%s", zDrive, zPath);
1831 }
1832 }
1833 }
1834 }
1835 zDbName = mprintf("%//_fossil", zHome);
1836 fossil_free(zHome);
1837 return zDbName;
1838
1839 #else /* if unix */
1840 char *zXdgHome;
1841
1842 /* For unix. a 5-step algorithm is used.
1843 ** See ../www/tech_overview.wiki for discussion.
1844 **
1845 ** Step 1: If FOSSIL_HOME exists -> $FOSSIL_HOME/.fossil
1846 */
1847 zHome = fossil_getenv("FOSSIL_HOME");
1848 if( zHome!=0 ) return mprintf("%s/.fossil", zHome);
1849
1850 /* Step 2: If HOME exists and file $HOME/.fossil exists -> $HOME/.fossil
1851 */
1852 zHome = fossil_getenv("HOME");
1853 if( zHome ){
1854 zDbName = mprintf("%s/.fossil", zHome);
1855 if( file_size(zDbName, ExtFILE)>1024*3 ){
1856 return zDbName;
1857 }
1858 fossil_free(zDbName);
1859 }
1860
1861 /* Step 3: if XDG_CONFIG_HOME exists -> $XDG_CONFIG_HOME/fossil.db
1862 */
1863 zXdgHome = fossil_getenv("XDG_CONFIG_HOME");
1864 if( zXdgHome!=0 ){
1865 return mprintf("%s/fossil.db", zXdgHome);
1866 }
1867
1868 /* The HOME variable is required in order to continue.
1869 */
1870 if( zHome==0 ){
1871 if( isOptional ) return 0;
1872 fossil_fatal("cannot locate home directory - please set one of the "
1873 "FOSSIL_HOME, XDG_CONFIG_HOME, or HOME environment "
1874 "variables");
1875 }
1876
1877 /* Step 4: If $HOME/.config is a directory -> $HOME/.config/fossil.db
1878 */
1879 zXdgHome = mprintf("%s/.config", zHome);
1880 if( file_isdir(zXdgHome, ExtFILE)==1 ){
1881 fossil_free(zXdgHome);
1882 return mprintf("%s/.config/fossil.db", zHome);
1883 }
1884
1885 /* Step 5: Otherwise -> $HOME/.fossil
1886 */
1887 return mprintf("%s/.fossil", zHome);
1888 #endif /* unix */
1889 }
1890
1891 /*
1892 ** Open the configuration database. Create the database anew if
1893 ** it does not already exist.
1894 **
1895 ** If the useAttach flag is 0 (the usual case) then the configuration
1896 ** database is opened on a separate database connection g.dbConfig.
1897 ** This prevents the database from becoming locked on long check-in or sync
1898 ** operations which hold an exclusive transaction. In a few cases, though,
1899 ** it is convenient for the database to be attached to the main database
1900 ** connection so that we can join between the various databases. In that
1901 ** case, invoke this routine with useAttach as 1.
1902 */
db_open_config(int useAttach,int isOptional)1903 int db_open_config(int useAttach, int isOptional){
1904 char *zDbName;
1905 if( g.zConfigDbName ){
1906 int alreadyAttached = db_database_slot("configdb")>0;
1907 if( useAttach==alreadyAttached ) return 1; /* Already open. */
1908 db_close_config();
1909 }
1910 zDbName = db_configdb_name(isOptional);
1911 if( zDbName==0 ) return 0;
1912 if( file_size(zDbName, ExtFILE)<1024*3 ){
1913 char *zHome = file_dirname(zDbName);
1914 int rc;
1915 if( file_isdir(zHome, ExtFILE)==0 ){
1916 file_mkdir(zHome, ExtFILE, 0);
1917 }
1918 rc = file_access(zHome, W_OK);
1919 if( rc ){
1920 if( isOptional ) return 0;
1921 fossil_fatal("home directory \"%s\" must be writeable", zHome);
1922 }
1923 db_init_database(zDbName, zConfigSchema, (char*)0);
1924 fossil_free(zHome);
1925 }
1926 if( file_access(zDbName, W_OK) ){
1927 if( isOptional ) return 0;
1928 fossil_fatal("configuration file %s must be writeable", zDbName);
1929 }
1930 if( useAttach ){
1931 db_open_or_attach(zDbName, "configdb");
1932 g.dbConfig = 0;
1933 }else{
1934 g.dbConfig = db_open(zDbName);
1935 db_set_main_schemaname(g.dbConfig, "configdb");
1936 }
1937 g.zConfigDbName = zDbName;
1938 return 1;
1939 }
1940
1941 /*
1942 ** Return TRUE if zTable exists.
1943 */
db_table_exists(const char * zDb,const char * zTable)1944 int db_table_exists(
1945 const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
1946 const char *zTable /* Name of table */
1947 ){
1948 return sqlite3_table_column_metadata(g.db, zDb, zTable, 0,
1949 0, 0, 0, 0, 0)==SQLITE_OK;
1950 }
1951
1952 /*
1953 ** Return TRUE if zTable exists and contains column zColumn.
1954 ** Return FALSE if zTable does not exist or if zTable exists
1955 ** but lacks zColumn.
1956 */
db_table_has_column(const char * zDb,const char * zTable,const char * zColumn)1957 int db_table_has_column(
1958 const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
1959 const char *zTable, /* Name of table */
1960 const char *zColumn /* Name of column in table */
1961 ){
1962 return sqlite3_table_column_metadata(g.db, zDb, zTable, zColumn,
1963 0, 0, 0, 0, 0)==SQLITE_OK;
1964 }
1965
1966 /*
1967 ** Returns TRUE if zTable exists in the local database but lacks column
1968 ** zColumn
1969 */
db_local_table_exists_but_lacks_column(const char * zTable,const char * zColumn)1970 static int db_local_table_exists_but_lacks_column(
1971 const char *zTable,
1972 const char *zColumn
1973 ){
1974 return db_table_exists("localdb", zTable)
1975 && !db_table_has_column("localdb", zTable, zColumn);
1976 }
1977
1978 /*
1979 ** If zDbName is a valid local database file, open it and return
1980 ** true. If it is not a valid local database file, return 0.
1981 */
isValidLocalDb(const char * zDbName)1982 static int isValidLocalDb(const char *zDbName){
1983 i64 lsize;
1984
1985 if( file_access(zDbName, F_OK) ) return 0;
1986 lsize = file_size(zDbName, ExtFILE);
1987 if( lsize%1024!=0 || lsize<4096 ) return 0;
1988 db_open_or_attach(zDbName, "localdb");
1989
1990 /* Check to see if the checkout database has the lastest schema changes.
1991 ** The most recent schema change (2019-01-19) is the addition of the
1992 ** vmerge.mhash and vfile.mhash fields. If the schema has the vmerge.mhash
1993 ** column, assume everything else is up-to-date.
1994 */
1995 if( db_table_has_column("localdb","vmerge","mhash") ){
1996 return 1; /* This is a checkout database with the latest schema */
1997 }
1998
1999 /* If there is no vfile table, then assume we have picked up something
2000 ** that is not even close to being a valid checkout database */
2001 if( !db_table_exists("localdb","vfile") ){
2002 return 0; /* Not a DB */
2003 }
2004
2005 /* If the "isexe" column is missing from the vfile table, then
2006 ** add it now. This code added on 2010-03-06. After all users have
2007 ** upgraded, this code can be safely deleted.
2008 */
2009 if( !db_table_has_column("localdb","vfile","isexe") ){
2010 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
2011 }
2012
2013 /* If "islink"/"isLink" columns are missing from tables, then
2014 ** add them now. This code added on 2011-01-17 and 2011-08-27.
2015 ** After all users have upgraded, this code can be safely deleted.
2016 */
2017 if( !db_table_has_column("localdb","vfile","isLink") ){
2018 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
2019 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
2020 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
2021 }
2022 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
2023 db_multi_exec("ALTER TABLE undo ADD COLUMN isLink BOOLEAN DEFAULT 0");
2024 }
2025 if( db_local_table_exists_but_lacks_column("undo_vfile", "islink") ){
2026 db_multi_exec("ALTER TABLE undo_vfile ADD COLUMN islink BOOL DEFAULT 0");
2027 }
2028 }
2029
2030 /* The design of the checkout database changed on 2019-01-19, adding the mhash
2031 ** column to vfile and vmerge and changing the UNIQUE index on vmerge into
2032 ** a PRIMARY KEY that includes the new mhash column. However, we must have
2033 ** the repository database at hand in order to do the migration, so that
2034 ** step is deferred. */
2035 return 1;
2036 }
2037
2038 /*
2039 ** Locate the root directory of the local repository tree. The root
2040 ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
2041 ** that contains a valid repository database.
2042 **
2043 ** For legacy, also look for ".fos". The use of ".fos" is deprecated
2044 ** since "fos" has negative connotations in Hungarian, we are told.
2045 **
2046 ** If no valid _FOSSIL_ or .fslckout file is found, we move up one level and
2047 ** try again. Once the file is found, the g.zLocalRoot variable is set
2048 ** to the root of the repository tree and this routine returns 1. If
2049 ** no database is found, then this routine return 0.
2050 **
2051 ** In db_open_local_v2(), if the bRootOnly flag is true, then only
2052 ** look in the CWD for the checkout database. Do not scan upwards in
2053 ** the file hierarchy.
2054 **
2055 ** This routine always opens the user database regardless of whether or
2056 ** not the repository database is found. If the _FOSSIL_ or .fslckout file
2057 ** is found, it is attached to the open database connection too.
2058 */
db_open_local_v2(const char * zDbName,int bRootOnly)2059 int db_open_local_v2(const char *zDbName, int bRootOnly){
2060 int i, n;
2061 char zPwd[2000];
2062 static const char *(aDbName[]) = { "_FOSSIL_", ".fslckout", ".fos" };
2063
2064 if( g.localOpen ) return 1;
2065 file_getcwd(zPwd, sizeof(zPwd)-20);
2066 n = strlen(zPwd);
2067 while( n>0 ){
2068 for(i=0; i<count(aDbName); i++){
2069 sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "/%s", aDbName[i]);
2070 if( isValidLocalDb(zPwd) ){
2071 if( db_open_config(0, 1)==0 ){
2072 return 0; /* Configuration could not be opened */
2073 }
2074 /* Found a valid checkout database file */
2075 g.zLocalDbName = mprintf("%s", zPwd);
2076 zPwd[n] = 0;
2077 while( n>0 && zPwd[n-1]=='/' ){
2078 n--;
2079 zPwd[n] = 0;
2080 }
2081 g.zLocalRoot = mprintf("%s/", zPwd);
2082 g.localOpen = 1;
2083 db_open_repository(zDbName);
2084 return 1;
2085 }
2086 }
2087 if( bRootOnly ) break;
2088 n--;
2089 while( n>1 && zPwd[n]!='/' ){ n--; }
2090 while( n>1 && zPwd[n-1]=='/' ){ n--; }
2091 zPwd[n] = 0;
2092 }
2093
2094 /* A checkout database file could not be found */
2095 return 0;
2096 }
db_open_local(const char * zDbName)2097 int db_open_local(const char *zDbName){
2098 return db_open_local_v2(zDbName, 0);
2099 }
2100
2101 /*
2102 ** Get the full pathname to the repository database file. The
2103 ** local database (the _FOSSIL_ or .fslckout database) must have already
2104 ** been opened before this routine is called.
2105 */
db_repository_filename(void)2106 const char *db_repository_filename(void){
2107 static char *zRepo = 0;
2108 assert( g.localOpen );
2109 assert( g.zLocalRoot );
2110 if( zRepo==0 ){
2111 zRepo = db_lget("repository", 0);
2112 if( zRepo && !file_is_absolute_path(zRepo) ){
2113 char * zFree = zRepo;
2114 zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
2115 fossil_free(zFree);
2116 zFree = zRepo;
2117 zRepo = file_canonical_name_dup(zFree);
2118 fossil_free(zFree);
2119 }
2120 }
2121 return zRepo;
2122 }
2123
2124 /*
2125 ** Returns non-zero if support for symlinks is currently enabled.
2126 */
db_allow_symlinks(void)2127 int db_allow_symlinks(void){
2128 return g.allowSymlinks;
2129 }
2130
2131 /*
2132 ** Open the repository database given by zDbName. If zDbName==NULL then
2133 ** get the name from the already open local database.
2134 */
db_open_repository(const char * zDbName)2135 void db_open_repository(const char *zDbName){
2136 if( g.repositoryOpen ) return;
2137 if( zDbName==0 ){
2138 if( g.localOpen ){
2139 zDbName = db_repository_filename();
2140 }
2141 if( zDbName==0 ){
2142 db_err("unable to find the name of a repository database");
2143 }
2144 }
2145 if( file_access(zDbName, R_OK) || file_size(zDbName, ExtFILE)<1024 ){
2146 if( file_access(zDbName, F_OK) ){
2147 #ifdef FOSSIL_ENABLE_JSON
2148 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2149 #endif
2150 fossil_fatal("repository does not exist or"
2151 " is in an unreadable directory: %s", zDbName);
2152 }else if( file_access(zDbName, R_OK) ){
2153 #ifdef FOSSIL_ENABLE_JSON
2154 g.json.resultCode = FSL_JSON_E_DENIED;
2155 #endif
2156 fossil_fatal("read permission denied for repository %s", zDbName);
2157 }else{
2158 #ifdef FOSSIL_ENABLE_JSON
2159 g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
2160 #endif
2161 fossil_fatal("not a valid repository: %s", zDbName);
2162 }
2163 }
2164 g.zRepositoryName = mprintf("%s", zDbName);
2165 db_open_or_attach(g.zRepositoryName, "repository");
2166 g.repositoryOpen = 1;
2167 sqlite3_file_control(g.db, "repository", SQLITE_FCNTL_DATA_VERSION,
2168 &g.iRepoDataVers);
2169
2170 /* Cache "allow-symlinks" option, because we'll need it on every stat call */
2171 g.allowSymlinks = db_get_boolean("allow-symlinks",0);
2172
2173 g.zAuxSchema = db_get("aux-schema","");
2174 g.eHashPolicy = db_get_int("hash-policy",-1);
2175 if( g.eHashPolicy<0 ){
2176 g.eHashPolicy = hname_default_policy();
2177 db_set_int("hash-policy", g.eHashPolicy, 0);
2178 }
2179
2180 /* Make a change to the CHECK constraint on the BLOB table for
2181 ** version 2.0 and later.
2182 */
2183 rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
2184
2185 /* Additional checks that occur when opening the checkout database */
2186 if( g.localOpen ){
2187
2188 /* If the repository database that was just opened has been
2189 ** eplaced by a clone of the same project, with different RID
2190 ** values, then renumber the RID values stored in various tables
2191 ** of the checkout database, so that the repository and checkout
2192 ** databases align.
2193 */
2194 if( !db_fingerprint_ok() ){
2195 if( find_option("no-rid-adjust",0,0)!=0 ){
2196 /* The --no-rid-adjust command-line option bypasses the RID value
2197 ** updates. Intended for use during debugging, especially to be
2198 ** able to run "fossil sql" after a database swap. */
2199 fossil_print(
2200 "WARNING: repository change detected, but no adjust made.\n"
2201 );
2202 }else if( find_option("rid-renumber-dryrun",0,0)!=0 ){
2203 /* the --rid-renumber-dryrun option shows how RID values would be
2204 ** renumbered, but does not actually perform the renumbering.
2205 ** This is a debugging-only option. */
2206 vfile_rid_renumbering_event(1);
2207 exit(0);
2208 }else{
2209 char *z;
2210 stash_rid_renumbering_event();
2211 vfile_rid_renumbering_event(0);
2212 undo_reset();
2213 bisect_reset();
2214 z = db_fingerprint(0, 1);
2215 db_lset("fingerprint", z);
2216 fossil_free(z);
2217 fossil_print(
2218 "WARNING: The repository database has been replaced by a clone.\n"
2219 "Bisect history and undo have been lost.\n"
2220 );
2221 }
2222 }
2223
2224 /* Make sure the checkout database schema migration of 2019-01-20
2225 ** has occurred.
2226 **
2227 ** The 2019-01-19 migration is the addition of the vmerge.mhash and
2228 ** vfile.mhash columns and making the vmerge.mhash column part of the
2229 ** PRIMARY KEY for vmerge.
2230 */
2231 if( !db_table_has_column("localdb", "vfile", "mhash") ){
2232 db_multi_exec("ALTER TABLE vfile ADD COLUMN mhash;");
2233 db_multi_exec(
2234 "UPDATE vfile"
2235 " SET mhash=(SELECT uuid FROM blob WHERE blob.rid=vfile.mrid)"
2236 " WHERE mrid!=rid;"
2237 );
2238 if( !db_table_has_column("localdb", "vmerge", "mhash") ){
2239 db_exec_sql("ALTER TABLE vmerge RENAME TO old_vmerge;");
2240 db_exec_sql(zLocalSchemaVmerge);
2241 db_exec_sql(
2242 "INSERT OR IGNORE INTO vmerge(id,merge,mhash)"
2243 " SELECT id, merge, blob.uuid FROM old_vmerge, blob"
2244 " WHERE old_vmerge.merge=blob.rid;"
2245 "DROP TABLE old_vmerge;"
2246 );
2247 }
2248 }
2249 }
2250 }
2251
2252 /*
2253 ** Return true if there have been any changes to the repository
2254 ** database since it was opened.
2255 **
2256 ** Changes to "config" and "localdb" and "temp" do not count.
2257 ** This routine only returns true if there have been changes
2258 ** to "repository".
2259 */
db_repository_has_changed(void)2260 int db_repository_has_changed(void){
2261 unsigned int v;
2262 if( !g.repositoryOpen ) return 0;
2263 sqlite3_file_control(g.db, "repository", SQLITE_FCNTL_DATA_VERSION, &v);
2264 return g.iRepoDataVers != v;
2265 }
2266
2267 /*
2268 ** Flags for the db_find_and_open_repository() function.
2269 */
2270 #if INTERFACE
2271 #define OPEN_OK_NOT_FOUND 0x001 /* Do not error out if not found */
2272 #define OPEN_ANY_SCHEMA 0x002 /* Do not error if schema is wrong */
2273 #define OPEN_SUBSTITUTE 0x004 /* Fake in-memory repo if not found */
2274 #endif
2275
2276 /*
2277 ** Try to find the repository and open it. Use the -R or --repository
2278 ** option to locate the repository. If no such option is available, then
2279 ** use the repository of the open checkout if there is one.
2280 **
2281 ** Error out if the repository cannot be opened.
2282 */
db_find_and_open_repository(int bFlags,int nArgUsed)2283 void db_find_and_open_repository(int bFlags, int nArgUsed){
2284 const char *zRep = find_repository_option();
2285 if( zRep && file_isdir(zRep, ExtFILE)==1 ){
2286 goto rep_not_found;
2287 }
2288 if( zRep==0 && nArgUsed && g.argc==nArgUsed+1 ){
2289 zRep = g.argv[nArgUsed];
2290 }
2291 if( zRep==0 ){
2292 if( db_open_local(0)==0 ){
2293 goto rep_not_found;
2294 }
2295 zRep = db_repository_filename();
2296 if( zRep==0 ){
2297 goto rep_not_found;
2298 }
2299 }
2300 db_open_repository(zRep);
2301 if( g.repositoryOpen ){
2302 if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema();
2303 return;
2304 }
2305 rep_not_found:
2306 if( bFlags & OPEN_OK_NOT_FOUND ){
2307 /* No errors if the database is not found */
2308 if( bFlags & OPEN_SUBSTITUTE ){
2309 db_create_repository(0);
2310 }
2311 }else{
2312 #ifdef FOSSIL_ENABLE_JSON
2313 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2314 #endif
2315 if( nArgUsed==0 ){
2316 fossil_fatal("use --repository or -R to specify the repository database");
2317 }else{
2318 fossil_fatal("specify the repository name as a command-line argument");
2319 }
2320 }
2321 }
2322
2323 /*
2324 ** Return TRUE if the schema is out-of-date
2325 */
db_schema_is_outofdate(void)2326 int db_schema_is_outofdate(void){
2327 return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0
2328 || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0;
2329 }
2330
2331 /*
2332 ** Return true if the database is writeable
2333 */
db_is_writeable(const char * zName)2334 int db_is_writeable(const char *zName){
2335 return g.db!=0 && !sqlite3_db_readonly(g.db, zName);
2336 }
2337
2338 /*
2339 ** Verify that the repository schema is correct. If it is not correct,
2340 ** issue a fatal error and die.
2341 */
db_verify_schema(void)2342 void db_verify_schema(void){
2343 if( db_schema_is_outofdate() ){
2344 #ifdef FOSSIL_ENABLE_JSON
2345 g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD;
2346 #endif
2347 fossil_warning("incorrect repository schema version: "
2348 "current repository schema version is \"%s\" "
2349 "but need versions between \"%s\" and \"%s\".",
2350 g.zAuxSchema, AUX_SCHEMA_MIN, AUX_SCHEMA_MAX);
2351 fossil_fatal("run \"fossil rebuild\" to fix this problem");
2352 }
2353 }
2354
2355
2356 /*
2357 ** COMMAND: test-move-repository
2358 **
2359 ** Usage: %fossil test-move-repository PATHNAME
2360 **
2361 ** Change the location of the repository database on a local check-out.
2362 ** Use this command to avoid having to close and reopen a checkout
2363 ** when relocating the repository database.
2364 */
move_repo_cmd(void)2365 void move_repo_cmd(void){
2366 Blob repo;
2367 char *zRepo;
2368 if( g.argc!=3 ){
2369 usage("PATHNAME");
2370 }
2371 file_canonical_name(g.argv[2], &repo, 0);
2372 zRepo = blob_str(&repo);
2373 if( file_access(zRepo, F_OK) ){
2374 fossil_fatal("no such file: %s", zRepo);
2375 }
2376 if( db_open_local(zRepo)==0 ){
2377 fossil_fatal("not in a local checkout");
2378 return;
2379 }
2380 db_open_or_attach(zRepo, "test_repo");
2381 db_lset("repository", blob_str(&repo));
2382 db_record_repository_filename(blob_str(&repo));
2383 db_close(1);
2384 }
2385
2386
2387 /*
2388 ** Open the local database. If unable, exit with an error.
2389 */
db_must_be_within_tree(void)2390 void db_must_be_within_tree(void){
2391 if( find_repository_option() ){
2392 fossil_fatal("the \"%s\" command only works from within an open check-out",
2393 g.argv[1]);
2394 }
2395 if( db_open_local(0)==0 ){
2396 fossil_fatal("current directory is not within an open checkout");
2397 }
2398 db_open_repository(0);
2399 db_verify_schema();
2400 }
2401
2402 /*
2403 ** Close the database connection.
2404 **
2405 ** Check for unfinalized statements and report errors if the reportErrors
2406 ** argument is true. Ignore unfinalized statements when false.
2407 */
db_close(int reportErrors)2408 void db_close(int reportErrors){
2409 sqlite3_stmt *pStmt;
2410 if( g.db==0 ) return;
2411 sqlite3_set_authorizer(g.db, 0, 0);
2412 if( g.fSqlStats ){
2413 int cur, hiwtr;
2414 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
2415 fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
2416 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
2417 fprintf(stderr, "-- LOOKASIDE_HIT %10d\n", hiwtr);
2418 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &cur,&hiwtr,0);
2419 fprintf(stderr, "-- LOOKASIDE_MISS_SIZE %10d\n", hiwtr);
2420 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &cur,&hiwtr,0);
2421 fprintf(stderr, "-- LOOKASIDE_MISS_FULL %10d\n", hiwtr);
2422 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_USED, &cur, &hiwtr, 0);
2423 fprintf(stderr, "-- CACHE_USED %10d\n", cur);
2424 sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &cur, &hiwtr, 0);
2425 fprintf(stderr, "-- SCHEMA_USED %10d\n", cur);
2426 sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &cur, &hiwtr, 0);
2427 fprintf(stderr, "-- STMT_USED %10d\n", cur);
2428 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &cur, &hiwtr, 0);
2429 fprintf(stderr, "-- MEMORY_USED %10d %10d\n", cur, hiwtr);
2430 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &cur, &hiwtr, 0);
2431 fprintf(stderr, "-- MALLOC_SIZE %10d\n", hiwtr);
2432 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &cur, &hiwtr, 0);
2433 fprintf(stderr, "-- MALLOC_COUNT %10d %10d\n", cur, hiwtr);
2434 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &cur, &hiwtr, 0);
2435 fprintf(stderr, "-- PCACHE_OVFLOW %10d %10d\n", cur, hiwtr);
2436 fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
2437 }
2438 while( db.pAllStmt ){
2439 db_finalize(db.pAllStmt);
2440 }
2441 if( db.nBegin ){
2442 if( reportErrors ){
2443 fossil_warning("Transaction started at %s:%d never commits",
2444 db.zStartFile, db.iStartLine);
2445 }
2446 db_end_transaction(1);
2447 }
2448 pStmt = 0;
2449 sqlite3_busy_timeout(g.db, 0);
2450 g.dbIgnoreErrors++; /* Stop "database locked" warnings */
2451 sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
2452 g.dbIgnoreErrors--;
2453 db_close_config();
2454
2455 /* If the localdb has a lot of unused free space,
2456 ** then VACUUM it as we shut down.
2457 */
2458 if( db_database_slot("localdb")>=0 ){
2459 int nFree = db_int(0, "PRAGMA localdb.freelist_count");
2460 int nTotal = db_int(0, "PRAGMA localdb.page_count");
2461 if( nFree>nTotal/4 ){
2462 db_unprotect(PROTECT_ALL);
2463 db_multi_exec("VACUUM localdb;");
2464 db_protect_pop();
2465 }
2466 }
2467
2468 if( g.db ){
2469 int rc;
2470 sqlite3_wal_checkpoint(g.db, 0);
2471 rc = sqlite3_close(g.db);
2472 if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
2473 if( rc==SQLITE_BUSY && reportErrors ){
2474 while( (pStmt = sqlite3_next_stmt(g.db, pStmt))!=0 ){
2475 fossil_warning("unfinalized SQL statement: [%s]", sqlite3_sql(pStmt));
2476 }
2477 }
2478 g.db = 0;
2479 }
2480 g.repositoryOpen = 0;
2481 g.localOpen = 0;
2482 db.bProtectTriggers = 0;
2483 assert( g.dbConfig==0 );
2484 assert( g.zConfigDbName==0 );
2485 backoffice_run_if_needed();
2486 }
2487
2488 /*
2489 ** Close the database as quickly as possible without unnecessary processing.
2490 */
db_panic_close(void)2491 void db_panic_close(void){
2492 if( g.db ){
2493 int rc;
2494 sqlite3_wal_checkpoint(g.db, 0);
2495 rc = sqlite3_close(g.db);
2496 if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
2497 db_clear_authorizer();
2498 }
2499 g.db = 0;
2500 g.repositoryOpen = 0;
2501 g.localOpen = 0;
2502 }
2503
2504 /*
2505 ** Create a new empty repository database with the given name.
2506 **
2507 ** Only the schema is initialized. The required VAR tables entries
2508 ** are not set by this routine and must be set separately in order
2509 ** to make the new file a valid database.
2510 */
db_create_repository(const char * zFilename)2511 void db_create_repository(const char *zFilename){
2512 db_init_database(
2513 zFilename,
2514 zRepositorySchema1,
2515 zRepositorySchemaDefaultReports,
2516 zRepositorySchema2,
2517 (char*)0
2518 );
2519 db_delete_on_failure(zFilename);
2520 }
2521
2522 /*
2523 ** Create the default user accounts in the USER table.
2524 */
db_create_default_users(int setupUserOnly,const char * zDefaultUser)2525 void db_create_default_users(int setupUserOnly, const char *zDefaultUser){
2526 const char *zUser = zDefaultUser;
2527 if( zUser==0 ){
2528 zUser = db_get("default-user", 0);
2529 }
2530 if( zUser==0 ){
2531 zUser = fossil_getenv("FOSSIL_USER");
2532 }
2533 if( zUser==0 ){
2534 zUser = fossil_getenv("USER");
2535 }
2536 if( zUser==0 ){
2537 zUser = fossil_getenv("LOGNAME");
2538 }
2539 if( zUser==0 ){
2540 zUser = fossil_getenv("USERNAME");
2541 }
2542 if( zUser==0 ){
2543 zUser = "root";
2544 }
2545 db_unprotect(PROTECT_USER);
2546 db_multi_exec(
2547 "INSERT OR IGNORE INTO user(login, info) VALUES(%Q,'')", zUser
2548 );
2549 db_multi_exec(
2550 "UPDATE user SET cap='s', pw=%Q"
2551 " WHERE login=%Q", fossil_random_password(10), zUser
2552 );
2553 if( !setupUserOnly ){
2554 db_multi_exec(
2555 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2556 " VALUES('anonymous',hex(randomblob(8)),'hmnc','Anon');"
2557 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2558 " VALUES('nobody','','gjorz','Nobody');"
2559 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2560 " VALUES('developer','','ei','Dev');"
2561 "INSERT OR IGNORE INTO user(login,pw,cap,info)"
2562 " VALUES('reader','','kptw','Reader');"
2563 );
2564 }
2565 db_protect_pop();
2566 }
2567
2568 /*
2569 ** Return a pointer to a string that contains the RHS of an IN operator
2570 ** that will select CONFIG table names that are in the list of control
2571 ** settings.
2572 */
db_setting_inop_rhs()2573 const char *db_setting_inop_rhs(){
2574 Blob x;
2575 int i;
2576 int nSetting;
2577 const Setting *aSetting = setting_info(&nSetting);
2578 const char *zSep = "";
2579
2580 blob_zero(&x);
2581 blob_append_sql(&x, "(");
2582 for(i=0; i<nSetting; i++){
2583 blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, aSetting[i].name);
2584 zSep = ",";
2585 }
2586 blob_append_sql(&x, ")");
2587 return blob_sql_text(&x);
2588 }
2589
2590 /*
2591 ** Fill an empty repository database with the basic information for a
2592 ** repository. This function is shared between 'create_repository_cmd'
2593 ** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create
2594 ** new repositories.
2595 **
2596 ** The zTemplate parameter determines if the settings for the repository
2597 ** should be copied from another repository. If zTemplate is 0 then the
2598 ** settings will have their normal default values. If zTemplate is
2599 ** non-zero, it is assumed that the caller of this function has already
2600 ** attached a database using the label "settingSrc". If not, the call to
2601 ** this function will fail.
2602 **
2603 ** The zInitialDate parameter determines the date of the initial check-in
2604 ** that is automatically created. If zInitialDate is 0 then no initial
2605 ** check-in is created. The makeServerCodes flag determines whether or
2606 ** not server and project codes are invented for this repository.
2607 */
db_initial_setup(const char * zTemplate,const char * zInitialDate,const char * zDefaultUser)2608 void db_initial_setup(
2609 const char *zTemplate, /* Repository from which to copy settings. */
2610 const char *zInitialDate, /* Initial date of repository. (ex: "now") */
2611 const char *zDefaultUser /* Default user for the repository */
2612 ){
2613 char *zDate;
2614 Blob hash;
2615 Blob manifest;
2616
2617 db_unprotect(PROTECT_ALL);
2618 db_set("content-schema", CONTENT_SCHEMA, 0);
2619 db_set("aux-schema", AUX_SCHEMA_MAX, 0);
2620 db_set("rebuilt", get_version(), 0);
2621 db_set("admin-log", "1", 0);
2622 db_set("access-log", "1", 0);
2623 db_multi_exec(
2624 "INSERT INTO config(name,value,mtime)"
2625 " VALUES('server-code', lower(hex(randomblob(20))),now());"
2626 "INSERT INTO config(name,value,mtime)"
2627 " VALUES('project-code', lower(hex(randomblob(20))),now());"
2628 );
2629 if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0);
2630 if( !db_is_global("localauth") ) db_set_int("localauth", 0, 0);
2631 if( !db_is_global("timeline-plaintext") ){
2632 db_set_int("timeline-plaintext", 1, 0);
2633 }
2634 db_create_default_users(0, zDefaultUser);
2635 if( zDefaultUser ) g.zLogin = zDefaultUser;
2636 user_select();
2637
2638 if( zTemplate ){
2639 /*
2640 ** Copy all settings from the supplied template repository.
2641 */
2642 db_multi_exec(
2643 "INSERT OR REPLACE INTO config"
2644 " SELECT name,value,mtime FROM settingSrc.config"
2645 " WHERE (name IN %s OR name IN %s OR name GLOB 'walias:/*')"
2646 " AND name NOT GLOB 'project-*'"
2647 " AND name NOT GLOB 'short-project-*';",
2648 configure_inop_rhs(CONFIGSET_ALL),
2649 db_setting_inop_rhs()
2650 );
2651 g.eHashPolicy = db_get_int("hash-policy", g.eHashPolicy);
2652 db_multi_exec(
2653 "REPLACE INTO reportfmt SELECT * FROM settingSrc.reportfmt;"
2654 );
2655
2656 /*
2657 ** Copy the user permissions, contact information, last modified
2658 ** time, and photo for all the "system" users from the supplied
2659 ** template repository into the one being setup. The other columns
2660 ** are not copied because they contain security information or other
2661 ** data specific to the other repository. The list of columns copied
2662 ** by this SQL statement may need to be revised in the future.
2663 */
2664 db_multi_exec("UPDATE user SET"
2665 " cap = (SELECT u2.cap FROM settingSrc.user u2"
2666 " WHERE u2.login = user.login),"
2667 " info = (SELECT u2.info FROM settingSrc.user u2"
2668 " WHERE u2.login = user.login),"
2669 " mtime = (SELECT u2.mtime FROM settingSrc.user u2"
2670 " WHERE u2.login = user.login),"
2671 " photo = (SELECT u2.photo FROM settingSrc.user u2"
2672 " WHERE u2.login = user.login)"
2673 " WHERE user.login IN ('anonymous','nobody','developer','reader');"
2674 );
2675 }
2676 db_protect_pop();
2677
2678 if( zInitialDate ){
2679 int rid;
2680 blob_zero(&manifest);
2681 blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n");
2682 zDate = date_in_standard_format(zInitialDate);
2683 blob_appendf(&manifest, "D %s\n", zDate);
2684 md5sum_init();
2685 /* The R-card is necessary here because without it
2686 * fossil versions earlier than versions 1.27 would
2687 * interpret this artifact as a "control". */
2688 blob_appendf(&manifest, "R %s\n", md5sum_finish(0));
2689 blob_appendf(&manifest, "T *branch * trunk\n");
2690 blob_appendf(&manifest, "T *sym-trunk *\n");
2691 blob_appendf(&manifest, "U %F\n", g.zLogin);
2692 md5sum_blob(&manifest, &hash);
2693 blob_appendf(&manifest, "Z %b\n", &hash);
2694 blob_reset(&hash);
2695 rid = content_put(&manifest);
2696 manifest_crosslink(rid, &manifest, MC_NONE);
2697 }
2698 }
2699
2700 /*
2701 ** COMMAND: new*
2702 ** COMMAND: init
2703 **
2704 ** Usage: %fossil new ?OPTIONS? FILENAME
2705 ** or: %fossil init ?OPTIONS? FILENAME
2706 **
2707 ** Create a repository for a new project in the file named FILENAME.
2708 ** This command is distinct from "clone". The "clone" command makes
2709 ** a copy of an existing project. This command starts a new project.
2710 **
2711 ** By default, your current login name is used to create the default
2712 ** admin user. This can be overridden using the -A|--admin-user
2713 ** parameter.
2714 **
2715 ** By default, all settings will be initialized to their default values.
2716 ** This can be overridden using the --template parameter to specify a
2717 ** repository file from which to copy the initial settings. When a template
2718 ** repository is used, almost all of the settings accessible from the setup
2719 ** page, either directly or indirectly, will be copied. Normal users and
2720 ** their associated permissions will not be copied; however, the system
2721 ** default users "anonymous", "nobody", "reader", "developer", and their
2722 ** associated permissions will be copied.
2723 **
2724 ** Options:
2725 ** --template FILE Copy settings from repository file
2726 ** -A|--admin-user USERNAME Select given USERNAME as admin user
2727 ** --date-override DATETIME Use DATETIME as time of the initial check-in
2728 ** --sha1 Use an initial hash policy of "sha1"
2729 **
2730 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
2731 ** year-month-day form, it may be truncated, the "T" may be replaced by
2732 ** a space, and it may also name a timezone offset from UTC as "-HH:MM"
2733 ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
2734 ** means UTC.
2735 **
2736 ** See also: [[clone]]
2737 */
create_repository_cmd(void)2738 void create_repository_cmd(void){
2739 char *zPassword;
2740 const char *zTemplate; /* Repository from which to copy settings */
2741 const char *zDate; /* Date of the initial check-in */
2742 const char *zDefaultUser; /* Optional name of the default user */
2743 int bUseSha1 = 0; /* True to set the hash-policy to sha1 */
2744
2745
2746 zTemplate = find_option("template",0,1);
2747 zDate = find_option("date-override",0,1);
2748 zDefaultUser = find_option("admin-user","A",1);
2749 bUseSha1 = find_option("sha1",0,0)!=0;
2750 /* We should be done with options.. */
2751 verify_all_options();
2752
2753 if( g.argc!=3 ){
2754 usage("REPOSITORY-NAME");
2755 }
2756
2757 if( -1 != file_size(g.argv[2], ExtFILE) ){
2758 fossil_fatal("file already exists: %s", g.argv[2]);
2759 }
2760
2761 db_create_repository(g.argv[2]);
2762 db_open_repository(g.argv[2]);
2763 db_open_config(0, 0);
2764 if( zTemplate ) db_attach(zTemplate, "settingSrc");
2765 db_begin_transaction();
2766 if( bUseSha1 ){
2767 g.eHashPolicy = HPOLICY_SHA1;
2768 db_set_int("hash-policy", HPOLICY_SHA1, 0);
2769 }
2770 if( zDate==0 ) zDate = "now";
2771 db_initial_setup(zTemplate, zDate, zDefaultUser);
2772 db_end_transaction(0);
2773 if( zTemplate ) db_detach("settingSrc");
2774 fossil_print("project-id: %s\n", db_get("project-code", 0));
2775 fossil_print("server-id: %s\n", db_get("server-code", 0));
2776 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
2777 fossil_print("admin-user: %s (initial password is \"%s\")\n",
2778 g.zLogin, zPassword);
2779 }
2780
2781 /*
2782 ** SQL functions for debugging.
2783 **
2784 ** The print() function writes its arguments on stdout, but only
2785 ** if the -sqlprint command-line option is turned on.
2786 */
db_sql_print(sqlite3_context * context,int argc,sqlite3_value ** argv)2787 void db_sql_print(
2788 sqlite3_context *context,
2789 int argc,
2790 sqlite3_value **argv
2791 ){
2792 int i;
2793 if( g.fSqlPrint ){
2794 for(i=0; i<argc; i++){
2795 char c = i==argc-1 ? '\n' : ' ';
2796 fossil_print("%s%c", sqlite3_value_text(argv[i]), c);
2797 }
2798 }
2799 }
2800
2801 /*
2802 ** Callback for sqlite3_trace_v2();
2803 */
db_sql_trace(unsigned m,void * notUsed,void * pP,void * pX)2804 int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){
2805 sqlite3_stmt *pStmt = (sqlite3_stmt*)pP;
2806 char *zSql;
2807 int n;
2808 const char *zArg = (const char*)pX;
2809 char zEnd[100];
2810 if( m & SQLITE_TRACE_CLOSE ){
2811 /* If we are tracking closes, that means we want to clean up static
2812 ** prepared statements. */
2813 while( db.pAllStmt ){
2814 db_finalize(db.pAllStmt);
2815 }
2816 return 0;
2817 }
2818 if( zArg[0]=='-' ) return 0;
2819 if( m & SQLITE_TRACE_PROFILE ){
2820 sqlite3_int64 nNano = *(sqlite3_int64*)pX;
2821 double rMillisec = 0.000001 * nNano;
2822 int nRun = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_RUN, 0);
2823 int nVmStep = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_VM_STEP, 1);
2824 sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms, %r run, %d vm-steps */\n",
2825 rMillisec, nRun, nVmStep);
2826 }else{
2827 zEnd[0] = '\n';
2828 zEnd[1] = 0;
2829 }
2830 zSql = sqlite3_expanded_sql(pStmt);
2831 n = (int)strlen(zSql);
2832 fossil_trace("%s%s%s", zSql, (n>0 && zSql[n-1]==';') ? "" : ";", zEnd);
2833 sqlite3_free(zSql);
2834 return 0;
2835 }
2836
2837 /*
2838 ** Implement the user() SQL function. user() takes no arguments and
2839 ** returns the user ID of the current user.
2840 */
db_sql_user(sqlite3_context * context,int argc,sqlite3_value ** argv)2841 LOCAL void db_sql_user(
2842 sqlite3_context *context,
2843 int argc,
2844 sqlite3_value **argv
2845 ){
2846 if( g.zLogin!=0 ){
2847 sqlite3_result_text(context, g.zLogin, -1, SQLITE_STATIC);
2848 }
2849 }
2850
2851 /*
2852 ** Implement the cgi() SQL function. cgi() takes an argument which is
2853 ** a name of CGI query parameter. The value of that parameter is returned,
2854 ** if available. Optional second argument will be returned if the first
2855 ** doesn't exist as a CGI parameter.
2856 */
db_sql_cgi(sqlite3_context * context,int argc,sqlite3_value ** argv)2857 LOCAL void db_sql_cgi(sqlite3_context *context, int argc, sqlite3_value **argv){
2858 const char* zP;
2859 if( argc!=1 && argc!=2 ) return;
2860 zP = P((const char*)sqlite3_value_text(argv[0]));
2861 if( zP ){
2862 sqlite3_result_text(context, zP, -1, SQLITE_STATIC);
2863 }else if( argc==2 ){
2864 zP = (const char*)sqlite3_value_text(argv[1]);
2865 if( zP ) sqlite3_result_text(context, zP, -1, SQLITE_TRANSIENT);
2866 }
2867 }
2868
2869 /*
2870 ** SQL function:
2871 **
2872 ** is_selected(id)
2873 ** if_selected(id, X, Y)
2874 **
2875 ** On the commit command, when filenames are specified (in order to do
2876 ** a partial commit) the vfile.id values for the named files are loaded
2877 ** into the g.aCommitFile[] array. This function looks at that array
2878 ** to see if a file is named on the command-line.
2879 **
2880 ** In the first form (1 argument) return TRUE if either no files are
2881 ** named on the command line (g.aCommitFile is NULL meaning that all
2882 ** changes are to be committed) or if id is found in g.aCommitFile[]
2883 ** (meaning that id was named on the command-line).
2884 **
2885 ** In the second form (3 arguments) return argument X if true and Y
2886 ** if false. Except if Y is NULL then always return X.
2887 */
file_is_selected(sqlite3_context * context,int argc,sqlite3_value ** argv)2888 LOCAL void file_is_selected(
2889 sqlite3_context *context,
2890 int argc,
2891 sqlite3_value **argv
2892 ){
2893 int rc = 0;
2894
2895 assert(argc==1 || argc==3);
2896 if( g.aCommitFile ){
2897 int iId = sqlite3_value_int(argv[0]);
2898 int ii;
2899 for(ii=0; g.aCommitFile[ii]; ii++){
2900 if( iId==g.aCommitFile[ii] ){
2901 rc = 1;
2902 break;
2903 }
2904 }
2905 }else{
2906 rc = 1;
2907 }
2908 if( argc==1 ){
2909 sqlite3_result_int(context, rc);
2910 }else{
2911 assert( argc==3 );
2912 assert( rc==0 || rc==1 );
2913 if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
2914 sqlite3_result_value(context, argv[2-rc]);
2915 }
2916 }
2917
2918 /*
2919 ** Implementation of the "win_reserved(X)" SQL function, a wrapper
2920 ** for file_is_win_reserved(X) which returns true if X is
2921 ** a Windows-reserved filename.
2922 */
db_win_reserved_func(sqlite3_context * context,int argc,sqlite3_value ** argv)2923 LOCAL void db_win_reserved_func(
2924 sqlite3_context *context,
2925 int argc,
2926 sqlite3_value **argv
2927 ){
2928 const char * zName = (const char *)sqlite3_value_text(argv[0]);
2929 if( zName!=0 ){
2930 sqlite3_result_int(context, file_is_win_reserved(zName)!=0);
2931 }
2932 }
2933
2934 /*
2935 ** Convert the input string into a artifact hash. Make a notation in the
2936 ** CONCEALED table so that the hash can be undo using the db_reveal()
2937 ** function at some later time.
2938 **
2939 ** The value returned is stored in static space and will be overwritten
2940 ** on subsequent calls.
2941 **
2942 ** If zContent is already a well-formed artifact hash, then return a copy
2943 ** of that hash, not a hash of the hash.
2944 **
2945 ** The CONCEALED table is meant to obscure email addresses. Every valid
2946 ** email address will contain a "@" character and "@" is not valid within
2947 ** a SHA1 hash so there is no chance that a valid email address will go
2948 ** unconcealed.
2949 */
db_conceal(const char * zContent,int n)2950 char *db_conceal(const char *zContent, int n){
2951 static char zHash[HNAME_MAX+1];
2952 Blob out;
2953 if( hname_validate(zContent, n) ){
2954 memcpy(zHash, zContent, n);
2955 zHash[n] = 0;
2956 }else{
2957 sha1sum_step_text(zContent, n);
2958 sha1sum_finish(&out);
2959 sqlite3_snprintf(sizeof(zHash), zHash, "%s", blob_str(&out));
2960 blob_reset(&out);
2961 db_multi_exec(
2962 "INSERT OR IGNORE INTO concealed(hash,content,mtime)"
2963 " VALUES(%Q,%#Q,now())",
2964 zHash, n, zContent
2965 );
2966 }
2967 return zHash;
2968 }
2969
2970 /*
2971 ** Attempt to look up the input in the CONCEALED table. If found,
2972 ** and if the okRdAddr permission is enabled then return the
2973 ** original value for which the input is a hash. If okRdAddr is
2974 ** false or if the lookup fails, return the original string content.
2975 **
2976 ** In either case, the string returned is stored in space obtained
2977 ** from malloc and should be freed by the calling function.
2978 */
db_reveal(const char * zKey)2979 char *db_reveal(const char *zKey){
2980 char *zOut;
2981 if( g.perm.RdAddr ){
2982 zOut = db_text(0, "SELECT content FROM concealed WHERE hash=%Q", zKey);
2983 }else{
2984 zOut = 0;
2985 }
2986 if( zOut==0 ){
2987 zOut = mprintf("%s", zKey);
2988 }
2989 return zOut;
2990 }
2991
2992 /*
2993 ** Return true if the string zVal represents "true" (or "false").
2994 */
is_truth(const char * zVal)2995 int is_truth(const char *zVal){
2996 static const char *const azOn[] = { "on", "yes", "true", "1" };
2997 int i;
2998 for(i=0; i<count(azOn); i++){
2999 if( fossil_stricmp(zVal,azOn[i])==0 ) return 1;
3000 }
3001 return 0;
3002 }
is_false(const char * zVal)3003 int is_false(const char *zVal){
3004 static const char *const azOff[] = { "off", "no", "false", "0" };
3005 int i;
3006 for(i=0; i<count(azOff); i++){
3007 if( fossil_stricmp(zVal,azOff[i])==0 ) return 1;
3008 }
3009 return 0;
3010 }
3011
3012 /*
3013 ** Swap the g.db and g.dbConfig connections so that the various db_* routines
3014 ** work on the configuration database instead of on the repository database.
3015 ** Be sure to swap them back after doing the operation.
3016 **
3017 ** If the configuration database has already been opened as the main database
3018 ** or is attached to the main database, no connection swaps are required so
3019 ** this routine is a no-op.
3020 */
db_swap_connections(void)3021 void db_swap_connections(void){
3022 /*
3023 ** When swapping the main database connection with the config database
3024 ** connection, the config database connection must be open (not simply
3025 ** attached); otherwise, the swap would end up leaving the main database
3026 ** connection invalid, defeating the very purpose of this routine. This
3027 ** same constraint also holds true when restoring the previously swapped
3028 ** database connection; otherwise, it means that no swap was performed
3029 ** because the main database connection was already pointing to the config
3030 ** database.
3031 */
3032 if( g.dbConfig ){
3033 sqlite3 *dbTemp = g.db;
3034 g.db = g.dbConfig;
3035 g.dbConfig = dbTemp;
3036 }
3037 }
3038
3039 /*
3040 ** Try to read a versioned setting string from .fossil-settings/<name>.
3041 **
3042 ** Return the text of the string if it is found. Return NULL if not
3043 ** found.
3044 **
3045 ** If the zNonVersionedSetting parameter is not NULL then it holds the
3046 ** non-versioned value for this setting. If both a versioned and a
3047 ** non-versioned value exist and are not equal, then a warning message
3048 ** might be generated.
3049 */
db_get_versioned(const char * zName,char * zNonVersionedSetting)3050 char *db_get_versioned(const char *zName, char *zNonVersionedSetting){
3051 char *zVersionedSetting = 0;
3052 int noWarn = 0;
3053 int found = 0;
3054 struct _cacheEntry {
3055 struct _cacheEntry *next;
3056 const char *zName, *zValue;
3057 } *cacheEntry = 0;
3058 static struct _cacheEntry *cache = 0;
3059
3060 if( !g.localOpen && g.zOpenRevision==0 ) return zNonVersionedSetting;
3061 /* Look up name in cache */
3062 cacheEntry = cache;
3063 while( cacheEntry!=0 ){
3064 if( fossil_strcmp(cacheEntry->zName, zName)==0 ){
3065 zVersionedSetting = fossil_strdup(cacheEntry->zValue);
3066 break;
3067 }
3068 cacheEntry = cacheEntry->next;
3069 }
3070 /* Attempt to read value from file in checkout if there wasn't a cache hit. */
3071 if( cacheEntry==0 ){
3072 Blob versionedPathname;
3073 Blob setting;
3074 blob_zero(&versionedPathname);
3075 blob_zero(&setting);
3076 blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
3077 g.zLocalRoot, zName);
3078 if( !g.localOpen ){
3079 /* Repository is in the process of being opened, but files have not been
3080 * written to disk. Load from the database. */
3081 Blob noWarnFile;
3082 if( historical_blob(g.zOpenRevision, blob_str(&versionedPathname),
3083 &setting, 0) ){
3084 found = 1;
3085 }
3086 /* See if there's a no-warn flag */
3087 blob_append(&versionedPathname, ".no-warn", -1);
3088 blob_zero(&noWarnFile);
3089 if( historical_blob(g.zOpenRevision, blob_str(&versionedPathname),
3090 &noWarnFile, 0) ){
3091 noWarn = 1;
3092 }
3093 blob_reset(&noWarnFile);
3094 }else if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
3095 /* File exists, and contains the value for this setting. Load from
3096 ** the file. */
3097 const char *zFile = blob_str(&versionedPathname);
3098 if( blob_read_from_file(&setting, zFile, ExtFILE)>=0 ){
3099 found = 1;
3100 }
3101 /* See if there's a no-warn flag */
3102 blob_append(&versionedPathname, ".no-warn", -1);
3103 if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
3104 noWarn = 1;
3105 }
3106 }
3107 blob_reset(&versionedPathname);
3108 if( found ){
3109 blob_trim(&setting); /* Avoid non-obvious problems with line endings
3110 ** on boolean properties */
3111 zVersionedSetting = fossil_strdup(blob_str(&setting));
3112 }
3113 blob_reset(&setting);
3114 /* Store result in cache, which can be the value or 0 if not found */
3115 cacheEntry = (struct _cacheEntry*)fossil_malloc(sizeof(struct _cacheEntry));
3116 cacheEntry->next = cache;
3117 cacheEntry->zName = zName;
3118 cacheEntry->zValue = fossil_strdup(zVersionedSetting);
3119 cache = cacheEntry;
3120 }
3121 /* Display a warning? */
3122 if( zVersionedSetting!=0 && zNonVersionedSetting!=0
3123 && zNonVersionedSetting[0]!='\0' && !noWarn
3124 ){
3125 /* There's a versioned setting, and a non-versioned setting. Tell
3126 ** the user about the conflict */
3127 fossil_warning(
3128 "setting %s has both versioned and non-versioned values: using "
3129 "versioned value from file \"%/.fossil-settings/%s\" (to silence "
3130 "this warning, either create an empty file named "
3131 "\"%/.fossil-settings/%s.no-warn\" in the check-out root, or delete "
3132 "the non-versioned setting with \"fossil unset %s\")", zName,
3133 g.zLocalRoot, zName, g.zLocalRoot, zName, zName
3134 );
3135 }
3136 /* Prefer the versioned setting */
3137 return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting;
3138 }
3139
3140
3141 /*
3142 ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
3143 ** repository and local databases.
3144 **
3145 ** If no such variable exists, return zDefault. Or, if zName is the name
3146 ** of a setting, then the zDefault is ignored and the default value of the
3147 ** setting is returned instead. If zName is a versioned setting, then
3148 ** versioned value takes priority.
3149 */
db_get(const char * zName,const char * zDefault)3150 char *db_get(const char *zName, const char *zDefault){
3151 char *z = 0;
3152 const Setting *pSetting = db_find_setting(zName, 0);
3153 if( g.repositoryOpen ){
3154 static Stmt q1;
3155 const char *zRes;
3156 db_static_prepare(&q1, "SELECT value FROM config WHERE name=$n");
3157 db_bind_text(&q1, "$n", zName);
3158 if( db_step(&q1)==SQLITE_ROW && (zRes = db_column_text(&q1,0))!=0 ){
3159 z = fossil_strdup(zRes);
3160 }
3161 db_reset(&q1);
3162 }
3163 if( z==0 && g.zConfigDbName ){
3164 static Stmt q2;
3165 const char *zRes;
3166 db_swap_connections();
3167 db_static_prepare(&q2, "SELECT value FROM global_config WHERE name=$n");
3168 db_swap_connections();
3169 db_bind_text(&q2, "$n", zName);
3170 if( db_step(&q2)==SQLITE_ROW && (zRes = db_column_text(&q2,0))!=0 ){
3171 z = fossil_strdup(zRes);
3172 }
3173 db_reset(&q2);
3174 }
3175 if( pSetting!=0 && pSetting->versionable ){
3176 /* This is a versionable setting, try and get the info from a
3177 ** checked out file */
3178 char * zZ = z;
3179 z = db_get_versioned(zName, z);
3180 if(zZ != z){
3181 fossil_free(zZ);
3182 }
3183 }
3184 if( z==0 ){
3185 if( zDefault==0 && pSetting && pSetting->def[0] ){
3186 z = fossil_strdup(pSetting->def);
3187 }else{
3188 z = fossil_strdup(zDefault);
3189 }
3190 }
3191 return z;
3192 }
db_get_mtime(const char * zName,const char * zFormat,const char * zDefault)3193 char *db_get_mtime(const char *zName, const char *zFormat, const char *zDefault){
3194 char *z = 0;
3195 if( g.repositoryOpen ){
3196 z = db_text(0, "SELECT mtime FROM config WHERE name=%Q", zName);
3197 }
3198 if( z==0 ){
3199 z = fossil_strdup(zDefault);
3200 }else if( zFormat!=0 ){
3201 z = db_text(0, "SELECT strftime(%Q,%Q,'unixepoch');", zFormat, z);
3202 }
3203 return z;
3204 }
db_set(const char * zName,const char * zValue,int globalFlag)3205 void db_set(const char *zName, const char *zValue, int globalFlag){
3206 db_assert_protection_off_or_not_sensitive(zName);
3207 db_unprotect(PROTECT_CONFIG);
3208 db_begin_transaction();
3209 if( globalFlag ){
3210 db_swap_connections();
3211 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%Q)",
3212 zName, zValue);
3213 db_swap_connections();
3214 }else{
3215 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
3216 zName, zValue);
3217 }
3218 if( globalFlag && g.repositoryOpen ){
3219 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3220 }
3221 db_end_transaction(0);
3222 db_protect_pop();
3223 }
db_unset(const char * zName,int globalFlag)3224 void db_unset(const char *zName, int globalFlag){
3225 db_begin_transaction();
3226 db_unprotect(PROTECT_CONFIG);
3227 if( globalFlag ){
3228 db_swap_connections();
3229 db_multi_exec("DELETE FROM global_config WHERE name=%Q", zName);
3230 db_swap_connections();
3231 }else{
3232 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3233 }
3234 if( globalFlag && g.repositoryOpen ){
3235 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3236 }
3237 db_protect_pop();
3238 db_end_transaction(0);
3239 }
db_is_global(const char * zName)3240 int db_is_global(const char *zName){
3241 int rc = 0;
3242 if( g.zConfigDbName ){
3243 db_swap_connections();
3244 rc = db_exists("SELECT 1 FROM global_config WHERE name=%Q", zName);
3245 db_swap_connections();
3246 }
3247 return rc;
3248 }
db_get_int(const char * zName,int dflt)3249 int db_get_int(const char *zName, int dflt){
3250 int v = dflt;
3251 int rc;
3252 if( g.repositoryOpen ){
3253 static Stmt q;
3254 db_static_prepare(&q, "SELECT value FROM config WHERE name=$n");
3255 db_bind_text(&q, "$n", zName);
3256 rc = db_step(&q);
3257 if( rc==SQLITE_ROW ){
3258 v = db_column_int(&q, 0);
3259 }
3260 db_reset(&q);
3261 }else{
3262 rc = SQLITE_DONE;
3263 }
3264 if( rc==SQLITE_DONE && g.zConfigDbName ){
3265 static Stmt q2;
3266 db_swap_connections();
3267 db_static_prepare(&q2, "SELECT value FROM global_config WHERE name=$n");
3268 db_swap_connections();
3269 db_bind_text(&q2, "$n", zName);
3270 if( db_step(&q2)==SQLITE_ROW ){
3271 v = db_column_int(&q2, 0);
3272 }
3273 db_reset(&q2);
3274 }
3275 return v;
3276 }
db_set_int(const char * zName,int value,int globalFlag)3277 void db_set_int(const char *zName, int value, int globalFlag){
3278 db_assert_protection_off_or_not_sensitive(zName);
3279 db_unprotect(PROTECT_CONFIG);
3280 if( globalFlag ){
3281 db_swap_connections();
3282 db_multi_exec("REPLACE INTO global_config(name,value) VALUES(%Q,%d)",
3283 zName, value);
3284 db_swap_connections();
3285 }else{
3286 db_multi_exec("REPLACE INTO config(name,value,mtime) VALUES(%Q,%d,now())",
3287 zName, value);
3288 }
3289 if( globalFlag && g.repositoryOpen ){
3290 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3291 }
3292 db_protect_pop();
3293 }
db_get_boolean(const char * zName,int dflt)3294 int db_get_boolean(const char *zName, int dflt){
3295 char *zVal = db_get(zName, dflt ? "on" : "off");
3296 if( is_truth(zVal) ){
3297 dflt = 1;
3298 }else if( is_false(zVal) ){
3299 dflt = 0;
3300 }
3301 fossil_free(zVal);
3302 return dflt;
3303 }
db_get_versioned_boolean(const char * zName,int dflt)3304 int db_get_versioned_boolean(const char *zName, int dflt){
3305 char *zVal = db_get_versioned(zName, 0);
3306 if( zVal==0 ) return dflt;
3307 if( is_truth(zVal) ) return 1;
3308 if( is_false(zVal) ) return 0;
3309 return dflt;
3310 }
db_lget(const char * zName,const char * zDefault)3311 char *db_lget(const char *zName, const char *zDefault){
3312 return db_text(zDefault,
3313 "SELECT value FROM vvar WHERE name=%Q", zName);
3314 }
db_lset(const char * zName,const char * zValue)3315 void db_lset(const char *zName, const char *zValue){
3316 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
3317 }
db_lget_int(const char * zName,int dflt)3318 int db_lget_int(const char *zName, int dflt){
3319 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
3320 }
db_lset_int(const char * zName,int value)3321 void db_lset_int(const char *zName, int value){
3322 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
3323 }
3324
3325 /* Va-args versions of db_get(), db_set(), and db_unset()
3326 **
3327 ** codecheck1.c verifies that the format string for db_set_mprintf()
3328 ** and db_unset_mprintf() begins with an ASCII character prefix. We
3329 ** don't want that format string to begin with %s or %d as that might
3330 ** allow an injection attack to set or overwrite arbitrary settings.
3331 */
db_get_mprintf(const char * zDefault,const char * zFormat,...)3332 char *db_get_mprintf(const char *zDefault, const char *zFormat, ...){
3333 va_list ap;
3334 char *zName;
3335 char *zResult;
3336 va_start(ap, zFormat);
3337 zName = vmprintf(zFormat, ap);
3338 va_end(ap);
3339 zResult = db_get(zName, zDefault);
3340 fossil_free(zName);
3341 return zResult;
3342 }
db_set_mprintf(const char * zNew,int iGlobal,const char * zFormat,...)3343 void db_set_mprintf(const char *zNew, int iGlobal, const char *zFormat, ...){
3344 va_list ap;
3345 char *zName;
3346 va_start(ap, zFormat);
3347 zName = vmprintf(zFormat, ap);
3348 va_end(ap);
3349 db_set(zName/*works-like:"x"*/, zNew, iGlobal);
3350 fossil_free(zName);
3351 }
db_unset_mprintf(int iGlobal,const char * zFormat,...)3352 void db_unset_mprintf(int iGlobal, const char *zFormat, ...){
3353 va_list ap;
3354 char *zName;
3355 va_start(ap, zFormat);
3356 zName = vmprintf(zFormat, ap);
3357 va_end(ap);
3358 db_unset(zName/*works-like:"x"*/, iGlobal);
3359 fossil_free(zName);
3360 }
3361
3362
3363
3364 #if INTERFACE
3365 /* Manifest generation flags */
3366 #define MFESTFLG_RAW 0x01
3367 #define MFESTFLG_UUID 0x02
3368 #define MFESTFLG_TAGS 0x04
3369 #endif /* INTERFACE */
3370
3371 /*
3372 ** Get the manifest setting. For backwards compatibility first check if the
3373 ** value is a boolean. If it's not a boolean, treat each character as a flag
3374 ** to enable a manifest type. This system puts certain boundary conditions on
3375 ** which letters can be used to represent flags (any permutation of flags must
3376 ** not be able to fully form one of the boolean values).
3377 */
db_get_manifest_setting(void)3378 int db_get_manifest_setting(void){
3379 int flg;
3380 char *zVal = db_get("manifest", 0);
3381 if( zVal==0 || is_false(zVal) ){
3382 return 0;
3383 }else if( is_truth(zVal) ){
3384 return MFESTFLG_RAW|MFESTFLG_UUID;
3385 }
3386 flg = 0;
3387 while( *zVal ){
3388 switch( *zVal ){
3389 case 'r': flg |= MFESTFLG_RAW; break;
3390 case 'u': flg |= MFESTFLG_UUID; break;
3391 case 't': flg |= MFESTFLG_TAGS; break;
3392 }
3393 zVal++;
3394 }
3395 return flg;
3396 }
3397
3398
3399 /*
3400 ** Record the name of a local repository in the global_config() database.
3401 ** The repository filename %s is recorded as an entry with a "name" field
3402 ** of the following form:
3403 **
3404 ** repo:%s
3405 **
3406 ** The value field is set to 1.
3407 **
3408 ** If running from a local checkout, also record the root of the checkout
3409 ** as follows:
3410 **
3411 ** ckout:%s
3412 **
3413 ** Where %s is the checkout root. The value is the repository file.
3414 */
db_record_repository_filename(const char * zName)3415 void db_record_repository_filename(const char *zName){
3416 char *zRepoSetting;
3417 char *zCkoutSetting;
3418 Blob full;
3419 if( zName==0 ){
3420 if( !g.localOpen ) return;
3421 zName = db_repository_filename();
3422 }
3423 file_canonical_name(zName, &full, 0);
3424 (void)filename_collation(); /* Initialize before connection swap */
3425 db_swap_connections();
3426 zRepoSetting = mprintf("repo:%q", blob_str(&full));
3427
3428 db_unprotect(PROTECT_CONFIG);
3429 db_multi_exec(
3430 "DELETE FROM global_config WHERE name %s = %Q;",
3431 filename_collation(), zRepoSetting
3432 );
3433 db_multi_exec(
3434 "INSERT OR IGNORE INTO global_config(name,value)"
3435 "VALUES(%Q,1);",
3436 zRepoSetting
3437 );
3438 db_protect_pop();
3439 fossil_free(zRepoSetting);
3440 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
3441 Blob localRoot;
3442 file_canonical_name(g.zLocalRoot, &localRoot, 1);
3443 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
3444 db_unprotect(PROTECT_CONFIG);
3445 db_multi_exec(
3446 "DELETE FROM global_config WHERE name %s = %Q;",
3447 filename_collation(), zCkoutSetting
3448 );
3449 db_multi_exec(
3450 "REPLACE INTO global_config(name, value)"
3451 "VALUES(%Q,%Q);",
3452 zCkoutSetting, blob_str(&full)
3453 );
3454 db_swap_connections();
3455 db_optional_sql("repository",
3456 "DELETE FROM config WHERE name %s = %Q;",
3457 filename_collation(), zCkoutSetting
3458 );
3459 db_optional_sql("repository",
3460 "REPLACE INTO config(name,value,mtime)"
3461 "VALUES(%Q,1,now());",
3462 zCkoutSetting
3463 );
3464 db_protect_pop();
3465 fossil_free(zCkoutSetting);
3466 blob_reset(&localRoot);
3467 }else{
3468 db_swap_connections();
3469 }
3470 blob_reset(&full);
3471 }
3472
3473 /*
3474 ** COMMAND: open
3475 **
3476 ** Usage: %fossil open REPOSITORY ?VERSION? ?OPTIONS?
3477 **
3478 ** Open a new connection to the repository name REPOSITORY. A checkout
3479 ** for the repository is created with its root at the current working
3480 ** directory, or in DIR if the "--workdir DIR" is used. If VERSION is
3481 ** specified then that version is checked out. Otherwise the most recent
3482 ** check-in on the main branch (usually "trunk") is used.
3483 **
3484 ** REPOSITORY can be the filename for a repository that already exists on the
3485 ** local machine or it can be a URI for a remote repository. If REPOSITORY
3486 ** is a URI in one of the formats recognized by the [[clone]] command, then
3487 ** remote repo is first cloned, then the clone is opened. The clone will be
3488 ** stored in the current directory, or in DIR if the "--repodir DIR" option
3489 ** is used. The name of the clone will be taken from the last term of the URI.
3490 ** For "http:" and "https:" URIs, you can append an extra term to the end of
3491 ** the URI to get any repository name you like. For example:
3492 **
3493 ** fossil open https://fossil-scm.org/home/new-name
3494 **
3495 ** The base URI for cloning is "https://fossil-scm.org/home". The extra
3496 ** "new-name" term means that the cloned repository will be called
3497 ** "new-name.fossil".
3498 **
3499 ** Options:
3500 ** --empty Initialize checkout as being empty, but still connected
3501 ** with the local repository. If you commit this checkout,
3502 ** it will become a new "initial" commit in the repository.
3503 ** -f|--force Continue with the open even if the working directory is
3504 ** not empty.
3505 ** --force-missing Force opening a repository with missing content
3506 ** --keep Only modify the manifest and manifest.uuid files
3507 ** --nested Allow opening a repository inside an opened checkout
3508 ** --nosync Do not auto-sync the repository prior to opening
3509 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3510 ** the clone in DIR rather than in "."
3511 ** --setmtime Set timestamps of all files to match their SCM-side
3512 ** times (the timestamp of the last checkin which modified
3513 ** them).
3514 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3515 ** directory is created if it does not exist.
3516 **
3517 ** See also: [[close]], [[clone]]
3518 */
cmd_open(void)3519 void cmd_open(void){
3520 int emptyFlag;
3521 int keepFlag;
3522 int forceMissingFlag;
3523 int allowNested;
3524 int setmtimeFlag; /* --setmtime. Set mtimes on files */
3525 int bForce = 0; /* --force. Open even if non-empty dir */
3526 static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
3527 const char *zWorkDir; /* --workdir value */
3528 const char *zRepo = 0; /* Name of the repository file */
3529 const char *zRepoDir = 0; /* --repodir value */
3530 char *zPwd; /* Initial working directory */
3531 int isUri = 0; /* True if REPOSITORY is a URI */
3532 int nLocal; /* Number of preexisting files in cwd */
3533 int bNosync = 0; /* --nosync. Omit auto-sync */
3534
3535 url_proxy_options();
3536 emptyFlag = find_option("empty",0,0)!=0;
3537 keepFlag = find_option("keep",0,0)!=0;
3538 forceMissingFlag = find_option("force-missing",0,0)!=0;
3539 allowNested = find_option("nested",0,0)!=0;
3540 setmtimeFlag = find_option("setmtime",0,0)!=0;
3541 zWorkDir = find_option("workdir",0,1);
3542 zRepoDir = find_option("repodir",0,1);
3543 bForce = find_option("force","f",0)!=0;
3544 bNosync = find_option("nosync",0,0)!=0;
3545 zPwd = file_getcwd(0,0);
3546
3547
3548 /* We should be done with options.. */
3549 verify_all_options();
3550
3551 if( g.argc!=3 && g.argc!=4 ){
3552 usage("REPOSITORY-FILENAME ?VERSION?");
3553 }
3554 zRepo = g.argv[2];
3555 if( sqlite3_strglob("http://*", zRepo)==0
3556 || sqlite3_strglob("https://*", zRepo)==0
3557 || sqlite3_strglob("ssh:*", zRepo)==0
3558 || sqlite3_strglob("file:*", zRepo)==0
3559 ){
3560 isUri = 1;
3561 }
3562
3563 /* If --workdir is specified, change to the requested working directory */
3564 if( zWorkDir ){
3565 if( !isUri ){
3566 zRepo = file_canonical_name_dup(zRepo);
3567 }
3568 if( zRepoDir ){
3569 zRepoDir = file_canonical_name_dup(zRepoDir);
3570 }
3571 if( file_isdir(zWorkDir, ExtFILE)!=1 ){
3572 file_mkfolder(zWorkDir, ExtFILE, 0, 0);
3573 if( file_mkdir(zWorkDir, ExtFILE, 0) ){
3574 fossil_fatal("cannot create directory %s", zWorkDir);
3575 }
3576 }
3577 if( file_chdir(zWorkDir, 0) ){
3578 fossil_fatal("unable to make %s the working directory", zWorkDir);
3579 }
3580 }
3581 if( keepFlag==0
3582 && bForce==0
3583 && (nLocal = file_directory_size(".", 0, 1))>0
3584 && (nLocal>1 || isUri || !file_in_cwd(zRepo))
3585 ){
3586 fossil_fatal("directory %s is not empty\n"
3587 "use the -f or --force option to override", file_getcwd(0,0));
3588 }
3589
3590 if( db_open_local_v2(0, allowNested) ){
3591 fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
3592 }
3593
3594 /* If REPOSITORY looks like a URI, then try to clone it first */
3595 if( isUri ){
3596 char *zNewBase; /* Base name of the cloned repository file */
3597 const char *zUri; /* URI to clone */
3598 int rc; /* Result code from fossil_system() */
3599 Blob cmd; /* Clone command to be run */
3600 char *zCmd; /* String version of the clone command */
3601
3602 zUri = zRepo;
3603 zNewBase = url_to_repo_basename(zUri);
3604 if( zNewBase==0 ){
3605 fossil_fatal("unable to deduce a repository name from the url \"%s\"",
3606 zUri);
3607 }
3608 if( zRepoDir==0 ) zRepoDir = zPwd;
3609 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3610 fossil_free(zNewBase);
3611 blob_init(&cmd, 0, 0);
3612 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
3613 blob_append(&cmd, " clone", -1);
3614 blob_append_escaped_arg(&cmd, zUri, 1);
3615 blob_append_escaped_arg(&cmd, zRepo, 1);
3616 zCmd = blob_str(&cmd);
3617 fossil_print("%s\n", zCmd);
3618 if( zWorkDir ) file_chdir(zPwd, 0);
3619 rc = fossil_system(zCmd);
3620 if( rc ){
3621 fossil_fatal("clone of %s failed", zUri);
3622 }
3623 blob_reset(&cmd);
3624 if( zWorkDir ) file_chdir(zWorkDir, 0);
3625 }else if( zRepoDir ){
3626 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3627 "argument is a URI that begins with http:, https:, ssh:, "
3628 "or file:");
3629 }
3630
3631 db_open_repository(zRepo);
3632
3633 /* Figure out which revision to open. */
3634 if( !emptyFlag ){
3635 if( g.argc==4 ){
3636 g.zOpenRevision = g.argv[3];
3637 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
3638 g.zOpenRevision = db_get("main-branch", 0);
3639 }
3640 if( !bNosync
3641 && autosync_loop(SYNC_PULL, db_get_int("autosync-tries", 1), 1)
3642 && !bForce
3643 ){
3644 fossil_fatal("unable to auto-sync the repository");
3645 }
3646 }
3647
3648
3649 #if defined(_WIN32) || defined(__CYGWIN__)
3650 # define LOCALDB_NAME "./_FOSSIL_"
3651 #else
3652 # define LOCALDB_NAME "./.fslckout"
3653 #endif
3654 db_init_database(LOCALDB_NAME, zLocalSchema, zLocalSchemaVmerge,
3655 #ifdef FOSSIL_LOCAL_WAL
3656 "COMMIT; PRAGMA journal_mode=WAL; BEGIN;",
3657 #endif
3658 (char*)0);
3659 db_delete_on_failure(LOCALDB_NAME);
3660 db_open_local(0);
3661 db_lset("repository", zRepo);
3662 db_record_repository_filename(zRepo);
3663 db_set_checkout(0);
3664 azNewArgv[0] = g.argv[0];
3665 g.argv = azNewArgv;
3666 if( !emptyFlag ){
3667 g.argc = 3;
3668 if( g.zOpenRevision ){
3669 azNewArgv[g.argc-1] = g.zOpenRevision;
3670 }else{
3671 azNewArgv[g.argc-1] = "--latest";
3672 }
3673 if( keepFlag ){
3674 azNewArgv[g.argc++] = "--keep";
3675 }
3676 if( forceMissingFlag ){
3677 azNewArgv[g.argc++] = "--force-missing";
3678 }
3679 checkout_cmd();
3680 }
3681 if( setmtimeFlag ){
3682 int const vid = db_lget_int("checkout", 0);
3683 if(vid!=0){
3684 vfile_check_signature(vid, CKSIG_SETMTIME);
3685 }
3686 }
3687 g.argc = 2;
3688 info_cmd();
3689 }
3690
3691 /*
3692 ** Print the current value of a setting identified by the pSetting
3693 ** pointer.
3694 */
print_setting(const Setting * pSetting)3695 void print_setting(const Setting *pSetting){
3696 Stmt q;
3697 if( g.repositoryOpen ){
3698 db_prepare(&q,
3699 "SELECT '(local)', value FROM config WHERE name=%Q"
3700 " UNION ALL "
3701 "SELECT '(global)', value FROM global_config WHERE name=%Q",
3702 pSetting->name, pSetting->name
3703 );
3704 }else{
3705 db_prepare(&q,
3706 "SELECT '(global)', value FROM global_config WHERE name=%Q",
3707 pSetting->name
3708 );
3709 }
3710 if( db_step(&q)==SQLITE_ROW ){
3711 fossil_print("%-20s %-8s %s\n", pSetting->name, db_column_text(&q, 0),
3712 db_column_text(&q, 1));
3713 }else{
3714 fossil_print("%-20s\n", pSetting->name);
3715 }
3716 if( pSetting->versionable && g.localOpen ){
3717 /* Check to see if this is overridden by a versionable settings file */
3718 Blob versionedPathname;
3719 blob_zero(&versionedPathname);
3720 blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
3721 g.zLocalRoot, pSetting->name);
3722 if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
3723 fossil_print(" (overridden by contents of file .fossil-settings/%s)\n",
3724 pSetting->name);
3725 }
3726 }
3727 db_finalize(&q);
3728 }
3729
3730 #if INTERFACE
3731 /*
3732 ** Define all settings, which can be controlled via the set/unset
3733 ** command.
3734 **
3735 ** var is the name of the internal configuration name for db_(un)set.
3736 ** If var is 0, the settings name is used.
3737 **
3738 ** width is the length for the edit field on the behavior page, 0 is
3739 ** used for on/off checkboxes. A negative value indicates that that
3740 ** page should not render this setting. Such values may be rendered
3741 ** separately/manually on another page, e.g., /setup_access, and are
3742 ** exposed via the CLI settings command.
3743 **
3744 ** The behaviour page doesn't use a special layout. It lists all
3745 ** set-commands and displays the 'set'-help as info.
3746 */
3747 struct Setting {
3748 const char *name; /* Name of the setting */
3749 const char *var; /* Internal variable name used by db_set() */
3750 int width; /* Width of display. 0 for boolean values and
3751 ** negative for values which should not appear
3752 ** on the /setup_settings page. */
3753 char versionable; /* Is this setting versionable? */
3754 char forceTextArea; /* Force using a text area for display? */
3755 char sensitive; /* True if this a security-sensitive setting */
3756 const char *def; /* Default value */
3757 };
3758 #endif /* INTERFACE */
3759
3760 /*
3761 ** SETTING: access-log boolean default=off
3762 **
3763 ** When the access-log setting is enabled, all login attempts (successful
3764 ** and unsuccessful) on the web interface are recorded in the "access" table
3765 ** of the repository.
3766 */
3767 /*
3768 ** SETTING: admin-log boolean default=off
3769 **
3770 ** When the admin-log setting is enabled, configuration changes are recorded
3771 ** in the "admin_log" table of the repository.
3772 */
3773 /*
3774 ** SETTING: allow-symlinks boolean default=off sensitive
3775 **
3776 ** When allow-symlinks is OFF, Fossil does not see symbolic links
3777 ** (a.k.a "symlinks") on disk as a separate class of object. Instead Fossil
3778 ** sees the object that the symlink points to. Fossil will only manage files
3779 ** and directories, not symlinks. When a symlink is added to a repository,
3780 ** the object that the symlink points to is added, not the symlink itself.
3781 **
3782 ** When allow-symlinks is ON, Fossil sees symlinks on disk as a separate
3783 ** object class that is distinct from files and directories. When a symlink
3784 ** is added to a repository, Fossil stores the target filename. In other
3785 ** words, Fossil stores the symlink itself, not the object that the symlink
3786 ** points to.
3787 **
3788 ** Symlinks are not cross-platform. They are not available on all
3789 ** operating systems and file systems. Hence the allow-symlinks setting is
3790 ** OFF by default, for portability.
3791 */
3792 /*
3793 ** SETTING: auto-captcha boolean default=on variable=autocaptcha
3794 ** If enabled, the /login page provides a button that will automatically
3795 ** fill in the captcha password. This makes things easier for human users,
3796 ** at the expense of also making logins easier for malicious robots.
3797 */
3798 /*
3799 ** SETTING: auto-hyperlink boolean default=on
3800 ** Use javascript to enable hyperlinks on web pages
3801 ** for all users (regardless of the "h" privilege) if the
3802 ** User-Agent string in the HTTP header look like it came
3803 ** from real person, not a spider or bot.
3804 */
3805 /*
3806 ** SETTING: auto-shun boolean default=on
3807 ** If enabled, automatically pull the shunning list
3808 ** from a server to which the client autosyncs.
3809 */
3810 /*
3811 ** SETTING: autosync width=16 default=on
3812 ** This setting can take either a boolean value or "pullonly"
3813 ** If enabled, automatically pull prior to commit
3814 ** or update and automatically push after commit or
3815 ** tag or branch creation. If the value is "pullonly"
3816 ** then only pull operations occur automatically.
3817 */
3818 /*
3819 ** SETTING: autosync-tries width=16 default=1
3820 ** If autosync is enabled setting this to a value greater
3821 ** than zero will cause autosync to try no more than this
3822 ** number of attempts if there is a sync failure.
3823 */
3824 /*
3825 ** SETTING: backoffice-nodelay boolean default=off
3826 ** If backoffice-nodelay is true, then the backoffice processing
3827 ** will never invoke sleep(). If it has nothing useful to do,
3828 ** it simply exits.
3829 */
3830 /*
3831 ** SETTING: backoffice-disable boolean default=off
3832 ** If backoffice-disable is true, then the automatic backoffice
3833 ** processing is disabled. Automatic backoffice processing is the
3834 ** backoffice work that normally runs after each web page is
3835 ** rendered. Backoffice processing that is triggered by the
3836 ** "fossil backoffice" command is unaffected by this setting.
3837 **
3838 ** Backoffice processing does things such as delivering
3839 ** email notifications. So if this setting is true, and if
3840 ** there is no cron job periodically running "fossil backoffice",
3841 ** email notifications and other work normally done by the
3842 ** backoffice will not occur.
3843 */
3844 /*
3845 ** SETTING: backoffice-logfile width=40 sensitive
3846 ** If backoffice-logfile is not an empty string and is a valid
3847 ** filename, then a one-line message is appended to that file
3848 ** every time the backoffice runs. This can be used for debugging,
3849 ** to ensure that backoffice is running appropriately.
3850 */
3851 /*
3852 ** SETTING: binary-glob width=40 versionable block-text
3853 ** The VALUE of this setting is a comma or newline-separated list of
3854 ** GLOB patterns that should be treated as binary files
3855 ** for committing and merging purposes. Example: *.jpg
3856 */
3857 #if defined(_WIN32)||defined(__CYGWIN__)||defined(__DARWIN__)
3858 /*
3859 ** SETTING: case-sensitive boolean default=off
3860 ** If TRUE, the files whose names differ only in case
3861 ** are considered distinct. If FALSE files whose names
3862 ** differ only in case are the same file. Defaults to
3863 ** TRUE for unix and FALSE for Cygwin, Mac and Windows.
3864 */
3865 #endif
3866 #if !(defined(_WIN32)||defined(__CYGWIN__)||defined(__DARWIN__))
3867 /*
3868 ** SETTING: case-sensitive boolean default=on
3869 ** If TRUE, the files whose names differ only in case
3870 ** are considered distinct. If FALSE files whose names
3871 ** differ only in case are the same file. Defaults to
3872 ** TRUE for unix and FALSE for Cygwin, Mac and Windows.
3873 */
3874 #endif
3875 /*
3876 ** SETTING: clean-glob width=40 versionable block-text
3877 ** The VALUE of this setting is a comma or newline-separated list of GLOB
3878 ** patterns specifying files that the "clean" command will
3879 ** delete without prompting or allowing undo.
3880 ** Example: *.a,*.lib,*.o
3881 */
3882 /*
3883 ** SETTING: clearsign boolean default=off
3884 ** When enabled, fossil will attempt to sign all commits
3885 ** with gpg. When disabled, commits will be unsigned.
3886 */
3887 /*
3888 ** SETTING: comment-format width=16 default=1
3889 ** Set the default options for printing timeline comments to the console.
3890 **
3891 ** The global --comfmtflags command-line option (or alias --comment-format)
3892 ** overrides this setting.
3893 **
3894 ** Possible values are:
3895 ** 1 Activate the legacy comment printing format (default).
3896 **
3897 ** Or a bitwise combination of the following flags:
3898 ** 0 Activate the newer (non-legacy) comment printing format.
3899 ** 2 Trim leading and trailing CR and LF characters.
3900 ** 4 Trim leading and trailing white space characters.
3901 ** 8 Attempt to break lines on word boundaries.
3902 ** 16 Break lines before the original comment embedded in other text.
3903 **
3904 ** Note: To preserve line breaks, activate the newer (non-legacy) comment
3905 ** printing format (i.e. set to "0", or a combination not including "1").
3906 **
3907 ** Note: The options for timeline comments displayed on the web UI can be
3908 ** configured through the /setup_timeline web page.
3909 */
3910 /*
3911 ** SETTING: crlf-glob width=40 versionable block-text
3912 ** The value is a comma or newline-separated list of GLOB patterns for
3913 ** text files in which it is ok to have CR, CR+LF or mixed
3914 ** line endings. Set to "*" to disable CR+LF checking.
3915 ** The crnl-glob setting is a compatibility alias.
3916 */
3917 /*
3918 ** SETTING: crnl-glob width=40 versionable block-text
3919 ** This is an alias for the crlf-glob setting.
3920 */
3921 /*
3922 ** SETTING: default-perms width=16 default=u sensitive
3923 ** Permissions given automatically to new users. For more
3924 ** information on permissions see the Users page in Server
3925 ** Administration of the HTTP UI.
3926 */
3927 /*
3928 ** SETTING: diff-binary boolean default=on
3929 ** If enabled, permit files that may be binary
3930 ** or that match the "binary-glob" setting to be used with
3931 ** external diff programs. If disabled, skip these files.
3932 */
3933 /*
3934 ** SETTING: diff-command width=40 sensitive
3935 ** The value is an external command to run when performing a diff.
3936 ** If undefined, the internal text diff will be used.
3937 */
3938 /*
3939 ** SETTING: dont-push boolean default=off
3940 ** If enabled, prevent this repository from pushing from client to
3941 ** server. This can be used as an extra precaution to prevent
3942 ** accidental pushes to a public server from a private clone.
3943 */
3944 /*
3945 ** SETTING: dotfiles boolean versionable default=off
3946 ** If enabled, include --dotfiles option for all compatible commands.
3947 */
3948 /*
3949 ** SETTING: editor width=32 sensitive
3950 ** The value is an external command that will launch the
3951 ** text editor command used for check-in comments.
3952 */
3953 /*
3954 ** SETTING: empty-dirs width=40 versionable block-text
3955 ** The value is a comma or newline-separated list of pathnames. On
3956 ** update and checkout commands, if no file or directory
3957 ** exists with that name, an empty directory will be
3958 ** created.
3959 */
3960 /*
3961 ** SETTING: encoding-glob width=40 versionable block-text
3962 ** The value is a comma or newline-separated list of GLOB
3963 ** patterns specifying files that the "commit" command will
3964 ** ignore when issuing warnings about text files that may
3965 ** use another encoding than ASCII or UTF-8. Set to "*"
3966 ** to disable encoding checking.
3967 */
3968 #if defined(FOSSIL_ENABLE_EXEC_REL_PATHS)
3969 /*
3970 ** SETTING: exec-rel-paths boolean default=on
3971 ** When executing certain external commands (e.g. diff and
3972 ** gdiff), use relative paths.
3973 */
3974 #endif
3975 #if !defined(FOSSIL_ENABLE_EXEC_REL_PATHS)
3976 /*
3977 ** SETTING: exec-rel-paths boolean default=off
3978 ** When executing certain external commands (e.g. diff and
3979 ** gdiff), use relative paths.
3980 */
3981 #endif
3982
3983 /*
3984 ** SETTING: fileedit-glob width=40 block-text
3985 ** A comma- or newline-separated list of globs of filenames
3986 ** which are allowed to be edited using the /fileedit page.
3987 ** An empty list prohibits editing via that page. Note that
3988 ** it cannot edit binary files, so the list should not
3989 ** contain any globs for, e.g., images or PDFs.
3990 */
3991 /*
3992 ** SETTING: gdiff-command width=40 default=gdiff sensitive
3993 ** The value is an external command to run when performing a graphical
3994 ** diff. If undefined, text diff will be used.
3995 */
3996 /*
3997 ** SETTING: gmerge-command width=40 sensitive
3998 ** The value is a graphical merge conflict resolver command operating
3999 ** on four files. Examples:
4000 **
4001 ** kdiff3 "%baseline" "%original" "%merge" -o "%output"
4002 ** xxdiff "%original" "%baseline" "%merge" -M "%output"
4003 ** meld "%baseline" "%original" "%merge" --output "%output"
4004 */
4005 /*
4006 ** SETTING: hash-digits width=5 default=10
4007 ** The number of hexadecimal digits of the SHA3 hash to display.
4008 */
4009 /*
4010 ** SETTING: http-port width=16 default=8080
4011 ** The default TCP/IP port number to use by the "server"
4012 ** and "ui" commands.
4013 */
4014 /*
4015 ** SETTING: https-login boolean default=off
4016 ** If true, then the Fossil web server will redirect unencrypted
4017 ** login screen requests to HTTPS.
4018 */
4019 /*
4020 ** SETTING: ignore-glob width=40 versionable block-text
4021 ** The value is a comma or newline-separated list of GLOB
4022 ** patterns specifying files that the "add", "addremove",
4023 ** "clean", and "extras" commands will ignore.
4024 **
4025 ** Example: *.log customCode.c notes.txt
4026 */
4027 /*
4028 ** SETTING: keep-glob width=40 versionable block-text
4029 ** The value is a comma or newline-separated list of GLOB
4030 ** patterns specifying files that the "clean" command will keep.
4031 */
4032 /*
4033 ** SETTING: localauth boolean default=off
4034 ** If enabled, require that HTTP connections from the loopback
4035 ** address (127.0.0.1) be authenticated by password. If false,
4036 ** some HTTP requests might be granted full "Setup" user
4037 ** privileges without having to present login credentials.
4038 ** This mechanism allows the "fossil ui" command to provide
4039 ** full access to the repository without requiring the user to
4040 ** log in first.
4041 **
4042 ** In order for full "Setup" privilege to be granted without a
4043 ** login, the following conditions must be met:
4044 **
4045 ** (1) This setting ("localauth") must be off
4046 ** (2) The HTTP request arrive over the loopback TCP/IP
4047 ** address (127.0.01) or else via SSH.
4048 ** (3) The request must be HTTP, not HTTPS. (This
4049 ** restriction is designed to help prevent accidentally
4050 ** providing "Setup" privileges to requests arriving
4051 ** over a reverse proxy.)
4052 ** (4) The command that launched the fossil server must be
4053 ** one of the following:
4054 ** (a) "fossil ui"
4055 ** (b) "fossil server" with the --localauth option
4056 ** (c) "fossil http" with the --localauth option
4057 ** (d) CGI with the "localauth" setting in the cgi script.
4058 **
4059 ** For maximum security, set "localauth" to 1. However, because
4060 ** of the other restrictions (2) through (4), it should be safe
4061 ** to leave "localauth" set to 0 in most installations, and
4062 ** especially on cloned repositories on workstations. Leaving
4063 ** "localauth" at 0 makes the "fossil ui" command more convenient
4064 ** to use.
4065 */
4066 /*
4067 ** SETTING: lock-timeout width=25 default=60
4068 ** This is the number of seconds that a check-in lock will be held on
4069 ** the server before the lock expires. The default is a 60-second delay.
4070 ** Set this value to zero to disable the check-in lock mechanism.
4071 **
4072 ** This value should be set on the server to which users auto-sync
4073 ** their work. This setting has no effect on client repositories. The
4074 ** check-in lock mechanism is only effective if all users are auto-syncing
4075 ** to the same server.
4076 **
4077 ** Check-in locks are an advisory mechanism designed to help prevent
4078 ** accidental forks due to a check-in race in installations where many
4079 ** users are committing to the same branch and auto-sync is enabled.
4080 ** As forks are harmless, there is no danger in disabling this mechanism.
4081 ** However, keeping check-in locks turned on can help prevent unnecessary
4082 ** confusion.
4083 */
4084 /*
4085 ** SETTING: main-branch width=40 default=trunk
4086 ** The value is the primary branch for the project.
4087 */
4088 /*
4089 ** SETTING: manifest width=5 versionable
4090 ** If enabled, automatically create files "manifest" and "manifest.uuid"
4091 ** in every checkout.
4092 **
4093 ** Optionally use combinations of characters 'r' for "manifest",
4094 ** 'u' for "manifest.uuid" and 't' for "manifest.tags". The SQLite
4095 ** and Fossil repositories both require manifests.
4096 */
4097 /*
4098 ** SETTING: max-loadavg width=25 default=0.0
4099 ** Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
4100 ** are disallowed if the system load average goes above this
4101 ** value. "0.0" means no limit. This only works on unix.
4102 ** Only local settings of this value make a difference since
4103 ** when running as a web-server, Fossil does not open the
4104 ** global configuration database.
4105 */
4106 /*
4107 ** SETTING: max-upload width=25 default=250000
4108 ** A limit on the size of uplink HTTP requests.
4109 */
4110 /*
4111 ** SETTING: mimetypes width=40 versionable block-text
4112 ** A list of file extension-to-mimetype mappings, one per line. e.g.
4113 ** "foo application/x-foo". File extensions are compared
4114 ** case-insensitively in the order listed in this setting. A leading
4115 ** '.' on file extensions is permitted but not required.
4116 */
4117 /*
4118 ** SETTING: mtime-changes boolean default=on
4119 ** Use file modification times (mtimes) to detect when
4120 ** files have been modified. If disabled, all managed files
4121 ** are hashed to detect changes, which can be slow for large
4122 ** projects.
4123 */
4124 /*
4125 ** SETTING: mv-rm-files boolean default=off
4126 ** If enabled, the "mv" and "rename" commands will also move
4127 ** the associated files within the checkout -AND- the "rm"
4128 ** and "delete" commands will also remove the associated
4129 ** files from within the checkout.
4130 */
4131 /*
4132 ** SETTING: pgp-command width=40 sensitive
4133 ** Command used to clear-sign manifests at check-in.
4134 ** Default value is "gpg --clearsign -o"
4135 */
4136 /*
4137 ** SETTING: forbid-delta-manifests boolean default=off
4138 ** If enabled on a client, new delta manifests are prohibited on
4139 ** commits. If enabled on a server, whenever a client attempts
4140 ** to obtain a check-in lock during auto-sync, the server will
4141 ** send the "pragma avoid-delta-manifests" statement in its reply,
4142 ** which will cause the client to avoid generating a delta
4143 ** manifest.
4144 */
4145 /*
4146 ** SETTING: proxy width=32 default=off
4147 ** URL of the HTTP proxy. If undefined or "off" then
4148 ** the "http_proxy" environment variable is consulted.
4149 ** If the http_proxy environment variable is undefined
4150 ** then a direct HTTP connection is used.
4151 */
4152 /*
4153 ** SETTING: redirect-to-https default=0 width=-1
4154 ** Specifies whether or not to redirect http:// requests to
4155 ** https:// URIs. A value of 0 (the default) means not to
4156 ** redirect, 1 means to redirect only the /login page, and 2
4157 ** means to always redirect.
4158 */
4159 /*
4160 ** SETTING: relative-paths boolean default=on
4161 ** When showing changes and extras, report paths relative
4162 ** to the current working directory.
4163 */
4164 /*
4165 ** SETTING: repo-cksum boolean default=on
4166 ** Compute checksums over all files in each checkout as a double-check
4167 ** of correctness. Disable this on large repositories for a performance
4168 ** improvement.
4169 */
4170 /*
4171 ** SETTING: repolist-skin width=2 default=0
4172 ** If non-zero then use this repository as the skin for a repository list
4173 ** such as created by the one of:
4174 **
4175 ** 1) fossil server DIRECTORY --repolist
4176 ** 2) fossil ui DIRECTORY --repolist
4177 ** 3) fossil http DIRECTORY --repolist
4178 ** 4) (The "repolist" option in a CGI script)
4179 ** 5) fossil all ui
4180 ** 6) fossil all server
4181 **
4182 ** All repositories are searched (in lexicographical order) and the first
4183 ** repository with a non-zero "repolist-skin" value is used as the skin
4184 ** for the repository list page. If none of the repositories on the list
4185 ** have a non-zero "repolist-skin" setting then the repository list is
4186 ** displayed using unadorned HTML ("skinless").
4187 **
4188 ** If repolist-skin has a value of 2, then the repository is omitted from
4189 ** the list in use cases 1 through 4, but not for 5 and 6.
4190 */
4191 /*
4192 ** SETTING: self-register boolean default=off sensitive
4193 ** Allow users to register themselves through the HTTP UI.
4194 ** This is useful if you want to see other names than
4195 ** "Anonymous" in e.g. ticketing system. On the other hand
4196 ** users can not be deleted.
4197 */
4198 /*
4199 ** SETTING: ssh-command width=40 sensitive
4200 ** The command used to talk to a remote machine with the "ssh://" protocol.
4201 */
4202 /*
4203 ** SETTING: ssl-ca-location width=40 sensitive
4204 ** The full pathname to a file containing PEM encoded
4205 ** CA root certificates, or a directory of certificates
4206 ** with filenames formed from the certificate hashes as
4207 ** required by OpenSSL.
4208 **
4209 ** If set, this will override the OS default list of
4210 ** OpenSSL CAs. If unset, the default list will be used.
4211 ** Some platforms may add additional certificates.
4212 ** Checking your platform behaviour is required if the
4213 ** exact contents of the CA root is critical for your
4214 ** application.
4215 */
4216 /*
4217 ** SETTING: ssl-identity width=40 sensitive
4218 ** The full pathname to a file containing a certificate
4219 ** and private key in PEM format. Create by concatenating
4220 ** the certificate and private key files.
4221 **
4222 ** This identity will be presented to SSL servers to
4223 ** authenticate this client, in addition to the normal
4224 ** password authentication.
4225 */
4226 #ifdef FOSSIL_ENABLE_TCL
4227 /*
4228 ** SETTING: tcl boolean default=off sensitive
4229 ** If enabled Tcl integration commands will be added to the TH1
4230 ** interpreter, allowing arbitrary Tcl expressions and
4231 ** scripts to be evaluated from TH1. Additionally, the Tcl
4232 ** interpreter will be able to evaluate arbitrary TH1
4233 ** expressions and scripts.
4234 */
4235 /*
4236 ** SETTING: tcl-setup width=40 block-text sensitive
4237 ** This is the setup script to be evaluated after creating
4238 ** and initializing the Tcl interpreter. By default, this
4239 ** is empty and no extra setup is performed.
4240 */
4241 #endif /* FOSSIL_ENABLE_TCL */
4242 /*
4243 ** SETTING: tclsh width=80 default=tclsh sensitive
4244 ** Name of the external TCL interpreter used for such things
4245 ** as running the GUI diff viewer launched by the --tk option
4246 ** of the various "diff" commands.
4247 */
4248 #ifdef FOSSIL_ENABLE_TH1_DOCS
4249 /*
4250 ** SETTING: th1-docs boolean default=off sensitive
4251 ** If enabled, this allows embedded documentation files to contain
4252 ** arbitrary TH1 scripts that are evaluated on the server. If native
4253 ** Tcl integration is also enabled, this setting has the
4254 ** potential to allow anybody with check-in privileges to
4255 ** do almost anything that the associated operating system
4256 ** user account could do. Extreme caution should be used
4257 ** when enabling this setting.
4258 */
4259 #endif
4260 #ifdef FOSSIL_ENABLE_TH1_HOOKS
4261 /*
4262 ** SETTING: th1-hooks boolean default=off
4263 ** If enabled, special TH1 commands will be called before and
4264 ** after any Fossil command or web page.
4265 */
4266 #endif
4267 /*
4268 ** SETTING: th1-setup width=40 block-text
4269 ** This is the setup script to be evaluated after creating
4270 ** and initializing the TH1 interpreter. By default, this
4271 ** is empty and no extra setup is performed.
4272 */
4273 /*
4274 ** SETTING: th1-uri-regexp width=40 block-text
4275 ** Specify which URI's are allowed in HTTP requests from
4276 ** TH1 scripts. If empty, no HTTP requests are allowed
4277 ** whatsoever.
4278 */
4279 /*
4280 ** SETTING: default-csp width=40 block-text
4281 **
4282 ** The text of the Content Security Policy that is included
4283 ** in the Content-Security-Policy: header field of the HTTP
4284 ** reply and in the default HTML <head> section that is added when the
4285 ** skin header does not specify a <head> section. The text "$nonce"
4286 ** is replaced by the random nonce that is created for each web page.
4287 **
4288 ** If this setting is an empty string or is omitted, then
4289 ** the following default Content Security Policy is used:
4290 **
4291 ** default-src 'self' data:;
4292 ** script-src 'self' 'nonce-$nonce';
4293 ** style-src 'self' 'unsafe-inline';
4294 ** img-src * data:;
4295 **
4296 ** The default CSP is recommended. The main reason to change
4297 ** this setting would be to add CDNs from which it is safe to
4298 ** load additional content.
4299 */
4300 /*
4301 ** SETTING: uv-sync boolean default=off
4302 ** If true, automatically send unversioned files as part
4303 ** of a "fossil clone" or "fossil sync" command. The
4304 ** default is false, in which case the -u option is
4305 ** needed to clone or sync unversioned files.
4306 */
4307 /*
4308 ** SETTING: web-browser width=30 sensitive
4309 ** A shell command used to launch your preferred
4310 ** web browser when given a URL as an argument.
4311 ** Defaults to "start" on windows, "open" on Mac,
4312 ** and "firefox" on Unix.
4313 */
4314
4315 /*
4316 ** Look up a control setting by its name. Return a pointer to the Setting
4317 ** object, or NULL if there is no such setting.
4318 **
4319 ** If allowPrefix is true, then the Setting returned is the first one for
4320 ** which zName is a prefix of the Setting name.
4321 */
db_find_setting(const char * zName,int allowPrefix)4322 Setting *db_find_setting(const char *zName, int allowPrefix){
4323 int lwr, mid, upr, c;
4324 int n = (int)strlen(zName) + !allowPrefix;
4325 int nSetting;
4326 const Setting *aSetting = setting_info(&nSetting);
4327 lwr = 0;
4328 upr = nSetting - 1;
4329 while( upr>=lwr ){
4330 mid = (upr+lwr)/2;
4331 c = fossil_strncmp(zName, aSetting[mid].name, n);
4332 if( c<0 ){
4333 upr = mid - 1;
4334 }else if( c>0 ){
4335 lwr = mid + 1;
4336 }else{
4337 if( allowPrefix ){
4338 while( mid>lwr && fossil_strncmp(zName, aSetting[mid-1].name, n)==0 ){
4339 mid--;
4340 }
4341 }
4342 return (Setting*)&aSetting[mid];
4343 }
4344 }
4345 return 0;
4346 }
4347
4348 /*
4349 ** COMMAND: settings
4350 ** COMMAND: unset*
4351 **
4352 ** Usage: %fossil settings ?SETTING? ?VALUE? ?OPTIONS?
4353 ** or: %fossil unset SETTING ?OPTIONS?
4354 **
4355 ** The "settings" command with no arguments lists all settings and their
4356 ** values. With just a SETTING name it shows the current value of that setting.
4357 ** With a VALUE argument it changes the property for the current repository.
4358 **
4359 ** Settings marked as versionable are overridden by the contents of the
4360 ** file named .fossil-settings/PROPERTY in the check-out root, if that
4361 ** file exists.
4362 **
4363 ** The "unset" command clears a setting.
4364 **
4365 ** Settings can have both a "local" repository-only value and "global" value
4366 ** that applies to all repositories. The local values are stored in the
4367 ** "config" table of the repository and the global values are stored in the
4368 ** configuration database. If both a local and a global value exists for a
4369 ** setting, the local value takes precedence. This command normally operates
4370 ** on the local settings. Use the --global option to change global settings.
4371 **
4372 ** Options:
4373 ** --global set or unset the given property globally instead of
4374 ** setting or unsetting it for the open repository only.
4375 **
4376 ** --exact only consider exact name matches.
4377 **
4378 ** See also: [[configuration]]
4379 */
setting_cmd(void)4380 void setting_cmd(void){
4381 int i;
4382 int globalFlag = find_option("global","g",0)!=0;
4383 int exactFlag = find_option("exact",0,0)!=0;
4384 int unsetFlag = g.argv[1][0]=='u';
4385 int nSetting;
4386 const Setting *aSetting = setting_info(&nSetting);
4387 find_repository_option();
4388 verify_all_options();
4389 db_open_config(1, 0);
4390 if( !globalFlag ){
4391 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0);
4392 }
4393 if( !g.repositoryOpen ){
4394 globalFlag = 1;
4395 }
4396 if( unsetFlag && g.argc!=3 ){
4397 usage("PROPERTY ?-global?");
4398 }
4399
4400 if( g.argc==2 ){
4401 for(i=0; i<nSetting; i++){
4402 print_setting(&aSetting[i]);
4403 }
4404 }else if( g.argc==3 || g.argc==4 ){
4405 const char *zName = g.argv[2];
4406 int n = (int)strlen(zName);
4407 const Setting *pSetting = db_find_setting(zName, !exactFlag);
4408 if( pSetting==0 ){
4409 fossil_fatal("no such setting: %s", zName);
4410 }
4411 if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
4412 fossil_fatal("cannot set 'manifest' globally");
4413 }
4414 if( unsetFlag || g.argc==4 ){
4415 int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
4416 if( n!=strlen(pSetting[0].name) && pSetting[1].name &&
4417 fossil_strncmp(pSetting[1].name, zName, n)==0 ){
4418 Blob x;
4419 int i;
4420 blob_init(&x,0,0);
4421 for(i=0; pSetting[i].name; i++){
4422 if( fossil_strncmp(pSetting[i].name,zName,n)!=0 ) break;
4423 blob_appendf(&x, " %s", pSetting[i].name);
4424 }
4425 fossil_fatal("ambiguous setting \"%s\" - might be:%s",
4426 zName, blob_str(&x));
4427 }
4428 if( globalFlag && isManifest ){
4429 fossil_fatal("cannot set 'manifest' globally");
4430 }
4431 if( unsetFlag ){
4432 db_unset(pSetting->name/*works-like:"x"*/, globalFlag);
4433 }else{
4434 db_protect_only(PROTECT_NONE);
4435 db_set(pSetting->name/*works-like:"x"*/, g.argv[3], globalFlag);
4436 db_protect_pop();
4437 }
4438 if( isManifest && g.localOpen ){
4439 manifest_to_disk(db_lget_int("checkout", 0));
4440 }
4441 }else{
4442 while( pSetting->name ){
4443 if( exactFlag ){
4444 if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
4445 }else{
4446 if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
4447 }
4448 print_setting(pSetting);
4449 pSetting++;
4450 }
4451 }
4452 }else{
4453 usage("?PROPERTY? ?VALUE? ?-global?");
4454 }
4455 }
4456
4457 /*
4458 ** The input in a timespan measured in days. Return a string which
4459 ** describes that timespan in units of seconds, minutes, hours, days,
4460 ** or years, depending on its duration.
4461 */
db_timespan_name(double rSpan)4462 char *db_timespan_name(double rSpan){
4463 if( rSpan<0 ) rSpan = -rSpan;
4464 rSpan *= 24.0*3600.0; /* Convert units to seconds */
4465 if( rSpan<120.0 ){
4466 return sqlite3_mprintf("%.1f seconds", rSpan);
4467 }
4468 rSpan /= 60.0; /* Convert units to minutes */
4469 if( rSpan<90.0 ){
4470 return sqlite3_mprintf("%.1f minutes", rSpan);
4471 }
4472 rSpan /= 60.0; /* Convert units to hours */
4473 if( rSpan<=48.0 ){
4474 return sqlite3_mprintf("%.1f hours", rSpan);
4475 }
4476 rSpan /= 24.0; /* Convert units to days */
4477 if( rSpan<=365.0 ){
4478 return sqlite3_mprintf("%.1f days", rSpan);
4479 }
4480 rSpan /= 356.24; /* Convert units to years */
4481 return sqlite3_mprintf("%.1f years", rSpan);
4482 }
4483
4484 /*
4485 ** COMMAND: test-timespan
4486 **
4487 ** Usage: %fossil test-timespan TIMESTAMP
4488 **
4489 ** Print the approximate span of time from now to TIMESTAMP.
4490 */
test_timespan_cmd(void)4491 void test_timespan_cmd(void){
4492 double rDiff;
4493 if( g.argc!=3 ) usage("TIMESTAMP");
4494 sqlite3_open(":memory:", &g.db);
4495 rDiff = db_double(0.0, "SELECT julianday('now') - julianday(%Q)", g.argv[2]);
4496 fossil_print("Time differences: %s\n", db_timespan_name(rDiff));
4497 sqlite3_close(g.db);
4498 g.db = 0;
4499 g.repositoryOpen = 0;
4500 g.localOpen = 0;
4501 }
4502
4503 /*
4504 ** COMMAND: test-without-rowid
4505 **
4506 ** Usage: %fossil test-without-rowid FILENAME...
4507 **
4508 ** Change the Fossil repository FILENAME to make use of the WITHOUT ROWID
4509 ** optimization. FILENAME can also be the configuration database file
4510 ** (~/.fossil or ~/.config/fossil.db) or a local .fslckout or _FOSSIL_ file.
4511 **
4512 ** The purpose of this command is for testing the WITHOUT ROWID capabilities
4513 ** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil.
4514 **
4515 ** Options:
4516 ** --dryrun | -n No changes. Just print what would happen.
4517 */
test_without_rowid(void)4518 void test_without_rowid(void){
4519 int i, j;
4520 Stmt q;
4521 Blob allSql;
4522 int dryRun = find_option("dry-run", "n", 0)!=0;
4523 for(i=2; i<g.argc; i++){
4524 db_open_or_attach(g.argv[i], "main");
4525 blob_init(&allSql, "BEGIN;\n", -1);
4526 db_prepare(&q,
4527 "SELECT name, sql FROM main.sqlite_schema "
4528 " WHERE type='table' AND sql NOT LIKE '%%WITHOUT ROWID%%'"
4529 " AND name IN ('global_config','shun','concealed','config',"
4530 " 'plink','tagxref','backlink','vcache');"
4531 );
4532 while( db_step(&q)==SQLITE_ROW ){
4533 const char *zTName = db_column_text(&q, 0);
4534 const char *zOrigSql = db_column_text(&q, 1);
4535 Blob newSql;
4536 blob_init(&newSql, 0, 0);
4537 for(j=0; zOrigSql[j]; j++){
4538 if( fossil_strnicmp(zOrigSql+j,"unique",6)==0 ){
4539 blob_append(&newSql, zOrigSql, j);
4540 blob_append(&newSql, "PRIMARY KEY", -1);
4541 zOrigSql += j+6;
4542 j = -1;
4543 }
4544 }
4545 blob_append(&newSql, zOrigSql, -1);
4546 blob_append_sql(&allSql,
4547 "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
4548 "%s WITHOUT ROWID;\n"
4549 "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
4550 "DROP TABLE \"x_%w\";\n",
4551 zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
4552 );
4553 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n",
4554 zTName, g.argv[i]);
4555 blob_reset(&newSql);
4556 }
4557 blob_append_sql(&allSql, "COMMIT;\n");
4558 db_finalize(&q);
4559 if( dryRun ){
4560 fossil_print("SQL that would have been evaluated:\n");
4561 fossil_print("%.78c\n", '-');
4562 fossil_print("%s", blob_sql_text(&allSql));
4563 }else{
4564 db_multi_exec("%s", blob_sql_text(&allSql));
4565 }
4566 blob_reset(&allSql);
4567 db_close(1);
4568 }
4569 }
4570
4571 /*
4572 ** Make sure the adminlog table exists. Create it if it does not
4573 */
create_admin_log_table(void)4574 void create_admin_log_table(void){
4575 static int once = 0;
4576 if( once ) return;
4577 once = 1;
4578 db_multi_exec(
4579 "CREATE TABLE IF NOT EXISTS repository.admin_log(\n"
4580 " id INTEGER PRIMARY KEY,\n"
4581 " time INTEGER, -- Seconds since 1970\n"
4582 " page TEXT, -- path of page\n"
4583 " who TEXT, -- User who made the change\n"
4584 " what TEXT -- What changed\n"
4585 ")"
4586 );
4587 }
4588
4589 /*
4590 ** Write a message into the admin_event table, if admin logging is
4591 ** enabled via the admin-log configuration option.
4592 */
admin_log(const char * zFormat,...)4593 void admin_log(const char *zFormat, ...){
4594 Blob what = empty_blob;
4595 va_list ap;
4596 if( !db_get_boolean("admin-log", 0) ){
4597 /* Potential leak here (on %z params) but
4598 the alternative is to let blob_vappendf()
4599 do it below. */
4600 return;
4601 }
4602 create_admin_log_table();
4603 va_start(ap,zFormat);
4604 blob_vappendf( &what, zFormat, ap );
4605 va_end(ap);
4606 db_multi_exec("INSERT INTO admin_log(time,page,who,what)"
4607 " VALUES(now(), %Q, %Q, %B)",
4608 g.zPath, g.zLogin, &what);
4609 blob_reset(&what);
4610 }
4611
4612 /*
4613 ** COMMAND: test-database-names
4614 **
4615 ** Print the names of the various database files:
4616 ** (1) The main repository database
4617 ** (2) The local checkout database
4618 ** (3) The global configuration database
4619 */
test_database_name_cmd(void)4620 void test_database_name_cmd(void){
4621 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
4622 fossil_print("Repository database: %s\n", g.zRepositoryName);
4623 fossil_print("Local database: %s\n", g.zLocalDbName);
4624 fossil_print("Config database: %s\n", g.zConfigDbName);
4625 }
4626
4627 /*
4628 ** Compute a "fingerprint" on the repository. A fingerprint is used
4629 ** to verify that that the repository has not been replaced by a clone
4630 ** of the same repository. More precisely, a fingerprint are used to
4631 ** verify that the mapping between SHA3 hashes and RID values is unchanged.
4632 **
4633 ** The checkout database ("localdb") stores RID values. When associating
4634 ** a checkout database against a repository database, it is useful to verify
4635 ** the fingerprint so that we know tha the RID values in the checkout
4636 ** database still correspond to the correct entries in the BLOB table of
4637 ** the repository.
4638 **
4639 ** The fingerprint is based on the RCVFROM table. When constructing a
4640 ** new fingerprint, use the most recent RCVFROM entry. (Set rcvid==0 to
4641 ** accomplish this.) When verifying an old fingerprint, use the same
4642 ** RCVFROM entry that generated the fingerprint in the first place.
4643 **
4644 ** The fingerprint consists of the rcvid, a "/", and the MD5 checksum of
4645 ** the remaining fields of the RCVFROM table entry. MD5 is used for this
4646 ** because it is 4x faster than SHA3 and 5x faster than SHA1, and there
4647 ** are no security concerns - this is just a checksum, not a security
4648 ** token.
4649 */
db_fingerprint(int rcvid,int iVersion)4650 char *db_fingerprint(int rcvid, int iVersion){
4651 char *z = 0;
4652 Blob sql = BLOB_INITIALIZER;
4653 Stmt q;
4654 if( iVersion==0 ){
4655 /* The original fingerprint algorithm used "quote(mtime)". But this
4656 ** could give slightly different answers depending on how the floating-
4657 ** point hardware is configured. For example, it gave different
4658 ** answers on native Linux versus running under valgrind. */
4659 blob_append_sql(&sql,
4660 "SELECT rcvid, quote(uid), quote(mtime), quote(nonce), quote(ipaddr)"
4661 " FROM rcvfrom"
4662 );
4663 }else{
4664 /* These days, we use "datetime(mtime)" for more consistent answers */
4665 blob_append_sql(&sql,
4666 "SELECT rcvid, quote(uid), datetime(mtime), quote(nonce), quote(ipaddr)"
4667 " FROM rcvfrom"
4668 );
4669 }
4670 if( rcvid<=0 ){
4671 blob_append_sql(&sql, " ORDER BY rcvid DESC LIMIT 1");
4672 }else{
4673 blob_append_sql(&sql, " WHERE rcvid=%d", rcvid);
4674 }
4675 db_prepare_blob(&q, &sql);
4676 blob_reset(&sql);
4677 if( db_step(&q)==SQLITE_ROW ){
4678 int i;
4679 md5sum_init();
4680 for(i=1; i<=4; i++){
4681 md5sum_step_text(db_column_text(&q,i),-1);
4682 }
4683 z = mprintf("%d/%s",db_column_int(&q,0),md5sum_finish(0));
4684 }
4685 db_finalize(&q);
4686 return z;
4687 }
4688
4689 /*
4690 ** COMMAND: test-fingerprint
4691 **
4692 ** Usage: %fossil test-fingerprint ?RCVID?
4693 **
4694 ** Display the repository fingerprint using the supplied RCVID or
4695 ** using the latest RCVID if not is given on the command line.
4696 ** Show both the legacy and the newer version of the fingerprint,
4697 ** and the currently stored fingerprint if there is one.
4698 */
test_fingerprint(void)4699 void test_fingerprint(void){
4700 int rcvid = 0;
4701 db_find_and_open_repository(OPEN_ANY_SCHEMA,0);
4702 if( g.argc==3 ){
4703 rcvid = atoi(g.argv[2]);
4704 }else if( g.argc!=2 ){
4705 fossil_fatal("wrong number of arguments");
4706 }
4707 fossil_print("legacy: %z\n", db_fingerprint(rcvid, 0));
4708 fossil_print("version-1: %z\n", db_fingerprint(rcvid, 1));
4709 if( g.localOpen ){
4710 fossil_print("localdb: %z\n", db_lget("fingerprint","(none)"));
4711 fossil_print("db_fingerprint_ok(): %d\n", db_fingerprint_ok());
4712 }
4713 fossil_print("Fossil version: %s - %.10s %.19s\n",
4714 RELEASE_VERSION, MANIFEST_DATE, MANIFEST_UUID);
4715 }
4716
4717 /*
4718 ** Set the value of the "checkout" entry in the VVAR table.
4719 **
4720 ** Also set "fingerprint" and "checkout-hash".
4721 */
db_set_checkout(int rid)4722 void db_set_checkout(int rid){
4723 char *z;
4724 db_lset_int("checkout", rid);
4725 if (rid != 0) {
4726 z = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid);
4727 db_lset("checkout-hash", z);
4728 fossil_free(z);
4729 z = db_fingerprint(0, 1);
4730 db_lset("fingerprint", z);
4731 fossil_free(z);
4732 }
4733 }
4734
4735 /*
4736 ** Verify that the fingerprint recorded in the "fingerprint" entry
4737 ** of the VVAR table matches the fingerprint on the currently
4738 ** connected repository. Return true if the fingerprint is ok, and
4739 ** return false if the fingerprint does not match.
4740 */
db_fingerprint_ok(void)4741 int db_fingerprint_ok(void){
4742 char *zCkout; /* The fingerprint recorded in the checkout database */
4743 char *zRepo; /* The fingerprint of the repository */
4744 int rc; /* Result */
4745
4746 if( !db_lget_int("checkout", 0) ){
4747 /* We have an empty checkout, fingerprint is still NULL. */
4748 return 2;
4749 }
4750 zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
4751 if( zCkout==0 ){
4752 /* This is an older checkout that does not record a fingerprint.
4753 ** We have to assume everything is ok */
4754 return 2;
4755 }
4756 zRepo = db_fingerprint(atoi(zCkout), 1);
4757 rc = fossil_strcmp(zCkout,zRepo)==0;
4758 fossil_free(zRepo);
4759 /* If the initial test fails, try again using the older fingerprint
4760 ** algorithm */
4761 if( !rc ){
4762 zRepo = db_fingerprint(atoi(zCkout), 0);
4763 rc = fossil_strcmp(zCkout,zRepo)==0;
4764 fossil_free(zRepo);
4765 }
4766 fossil_free(zCkout);
4767 return rc;
4768 }
4769