Fossil SCM

fossil-scm / src / sqlcmd.c
Blame History Raw 487 lines
1
/*
2
** Copyright (c) 2010 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
** [email protected]
14
** http://www.hwaci.com/drh/
15
**
16
*******************************************************************************
17
**
18
** This module contains the code that initializes the "sqlite3" command-line
19
** shell against the repository database. The command-line shell itself
20
** is a copy of the "shell.c" code from SQLite. This file contains logic
21
** to initialize the code in shell.c.
22
*/
23
#include "config.h"
24
#include "sqlcmd.h"
25
#include <stdlib.h> /* atexit() */
26
#include <zlib.h>
27
#ifndef _WIN32
28
# include "linenoise.h"
29
#endif
30
31
/*
32
** True if the "fossil sql" command has the --test flag. False otherwise.
33
*/
34
static int local_bSqlCmdTest = 0;
35
36
/*
37
** Implementation of the "content(X)" SQL function. Return the complete
38
** content of artifact identified by X as a blob.
39
*/
40
static void sqlcmd_content(
41
sqlite3_context *context,
42
int argc,
43
sqlite3_value **argv
44
){
45
int rid;
46
Blob cx;
47
const char *zName;
48
assert( argc==1 );
49
zName = (const char*)sqlite3_value_text(argv[0]);
50
if( zName==0 ) return;
51
g.db = sqlite3_context_db_handle(context);
52
g.repositoryOpen = 1;
53
rid = name_to_rid(zName);
54
if( rid==0 ) return;
55
if( content_get(rid, &cx) ){
56
sqlite3_result_blob(context, blob_buffer(&cx), blob_size(&cx),
57
SQLITE_TRANSIENT);
58
blob_reset(&cx);
59
}
60
}
61
62
/*
63
** Implementation of the "compress(X)" SQL function. The input X is
64
** compressed using zLib and the output is returned.
65
*/
66
static void sqlcmd_compress(
67
sqlite3_context *context,
68
int argc,
69
sqlite3_value **argv
70
){
71
const unsigned char *pIn;
72
unsigned char *pOut;
73
unsigned int nIn;
74
unsigned long int nOut;
75
int rc;
76
77
pIn = sqlite3_value_blob(argv[0]);
78
nIn = sqlite3_value_bytes(argv[0]);
79
nOut = 13 + nIn + (nIn+999)/1000;
80
pOut = sqlite3_malloc( nOut+4 );
81
pOut[0] = nIn>>24 & 0xff;
82
pOut[1] = nIn>>16 & 0xff;
83
pOut[2] = nIn>>8 & 0xff;
84
pOut[3] = nIn & 0xff;
85
rc = compress(&pOut[4], &nOut, pIn, nIn);
86
if( rc==Z_OK ){
87
sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free);
88
}else if( rc==Z_MEM_ERROR ){
89
sqlite3_free(pOut);
90
sqlite3_result_error_nomem(context);
91
}else{
92
sqlite3_free(pOut);
93
sqlite3_result_error(context, "input cannot be zlib compressed", -1);
94
}
95
}
96
97
/*
98
** Implementation of the "decompress(X)" SQL function. The argument X
99
** is a blob which was obtained from compress(Y). The output will be
100
** the value Y.
101
*/
102
static void sqlcmd_decompress(
103
sqlite3_context *context,
104
int argc,
105
sqlite3_value **argv
106
){
107
const unsigned char *pIn;
108
unsigned char *pOut;
109
unsigned int nIn;
110
unsigned long int nOut;
111
int rc;
112
113
pIn = sqlite3_value_blob(argv[0]);
114
if( pIn==0 ) return;
115
nIn = sqlite3_value_bytes(argv[0]);
116
if( nIn<4 ) return;
117
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
118
pOut = sqlite3_malloc( nOut+1 );
119
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
120
if( rc==Z_OK ){
121
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
122
}else if( rc==Z_MEM_ERROR ){
123
sqlite3_free(pOut);
124
sqlite3_result_error_nomem(context);
125
}else{
126
sqlite3_free(pOut);
127
sqlite3_result_error(context, "input is not zlib compressed", -1);
128
}
129
}
130
131
/*
132
** Implementation of the "gather_artifact_stats(X)" SQL function.
133
** That function merely calls the gather_artifact_stats() function
134
** in stat.c to populate the ARTSTAT temporary table.
135
*/
136
static void sqlcmd_gather_artifact_stats(
137
sqlite3_context *context,
138
int argc,
139
sqlite3_value **argv
140
){
141
gather_artifact_stats(1);
142
}
143
144
/*
145
** Add the content(), compress(), decompress(), and
146
** gather_artifact_stats() SQL functions to database connection db.
147
**
148
** Also add whatis().
149
*/
150
int add_content_sql_commands(sqlite3 *db){
151
sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0,
152
sqlcmd_content, 0, 0);
153
sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
154
sqlcmd_compress, 0, 0);
155
sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0,
156
sqlcmd_decompress, 0, 0);
157
sqlite3_create_function(db, "gather_artifact_stats", 0, SQLITE_UTF8, 0,
158
sqlcmd_gather_artifact_stats, 0, 0);
159
sqlite3_create_function(db, "whatis", 1, SQLITE_UTF8|SQLITE_RESULT_SUBTYPE, 0,
160
whatis_sql_function, 0, 0);
161
return SQLITE_OK;
162
}
163
164
/*
165
** Undocumented test SQL functions:
166
**
167
** db_protect(X)
168
** db_protect_pop(X)
169
**
170
** These invoke the corresponding C routines.
171
**
172
** WARNING:
173
** Do not instantiate these functions for any Fossil webpage or command
174
** method other than the "fossil sql" command. If an attacker gains access
175
** to these functions, he will be able to disable other defense mechanisms.
176
**
177
** This routines are for interactive testing only. They are experimental
178
** and undocumented (apart from this comments) and might go away or change
179
** in future releases.
180
**
181
** 2020-11-29: These functions are now only available if the "fossil sql"
182
** command is started with the --test option.
183
*/
184
static void sqlcmd_db_protect(
185
sqlite3_context *context,
186
int argc,
187
sqlite3_value **argv
188
){
189
unsigned mask = 0;
190
const char *z = (const char*)sqlite3_value_text(argv[0]);
191
if( z!=0 && local_bSqlCmdTest ){
192
if( sqlite3_stricmp(z,"user")==0 ) mask |= PROTECT_USER;
193
if( sqlite3_stricmp(z,"config")==0 ) mask |= PROTECT_CONFIG;
194
if( sqlite3_stricmp(z,"sensitive")==0 ) mask |= PROTECT_SENSITIVE;
195
if( sqlite3_stricmp(z,"readonly")==0 ) mask |= PROTECT_READONLY;
196
if( sqlite3_stricmp(z,"all")==0 ) mask |= PROTECT_ALL;
197
db_protect(mask);
198
}
199
}
200
static void sqlcmd_db_protect_pop(
201
sqlite3_context *context,
202
int argc,
203
sqlite3_value **argv
204
){
205
if( !local_bSqlCmdTest ) db_protect_pop();
206
}
207
208
/*
209
** This is the "automatic extension" initializer that runs right after
210
** the connection to the repository database is opened. Set up the
211
** database connection to be more useful to the human operator.
212
*/
213
static int sqlcmd_autoinit(
214
sqlite3 *db,
215
const char **pzErrMsg,
216
const void *notUsed
217
){
218
int mTrace = SQLITE_TRACE_CLOSE;
219
add_content_sql_commands(db);
220
db_add_aux_functions(db);
221
re_add_sql_func(db);
222
search_sql_setup(db);
223
foci_register(db);
224
deltafunc_init(db);
225
helptext_vtab_register(db);
226
builtin_vtab_register(db);
227
g.repositoryOpen = 1;
228
g.db = db;
229
sqlite3_busy_timeout(db, 10000);
230
if( g.zRepositoryName ){
231
sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository");
232
db_maybe_set_encryption_key(db, g.zRepositoryName);
233
}
234
if( g.zLocalDbName ){
235
char *zSql = sqlite3_mprintf("ATTACH %Q AS 'localdb' KEY ''",
236
g.zLocalDbName);
237
sqlite3_exec(db, zSql, 0, 0, 0);
238
sqlite3_free(zSql);
239
}
240
if( g.zConfigDbName ){
241
char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''",
242
g.zConfigDbName);
243
sqlite3_exec(db, zSql, 0, 0, 0);
244
sqlite3_free(zSql);
245
}
246
(void)timeline_query_for_tty(); /* Registers wiki_to_text() as side-effect */
247
/* Arrange to trace close operations so that static prepared statements
248
** will get cleaned up when the shell closes the database connection */
249
if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE;
250
sqlite3_trace_v2(db, mTrace, db_sql_trace, 0);
251
if( g.zRepositoryName ){
252
db_protect_only(PROTECT_NONE);
253
sqlite3_set_authorizer(db, db_top_authorizer, db);
254
if( local_bSqlCmdTest ){
255
sqlite3_create_function(db, "db_protect", 1, SQLITE_UTF8, 0,
256
sqlcmd_db_protect, 0, 0);
257
sqlite3_create_function(db, "db_protect_pop", 0, SQLITE_UTF8, 0,
258
sqlcmd_db_protect_pop, 0, 0);
259
sqlite3_create_function(db, "shared_secret", 2, SQLITE_UTF8, 0,
260
sha1_shared_secret_sql_function, 0, 0);
261
}
262
}
263
return SQLITE_OK;
264
}
265
266
/*
267
** atexit() handler that cleans up global state modified by this module.
268
*/
269
static void sqlcmd_atexit(void) {
270
g.zConfigDbName = 0; /* prevent panic */
271
}
272
273
/*
274
** This routine is called by the sqlite3 command-line shell to
275
** to load the name the Fossil repository database.
276
*/
277
void sqlcmd_get_dbname(const char **pzRepoName){
278
*pzRepoName = g.zRepositoryName;
279
}
280
281
/*
282
** This routine is called by the sqlite3 command-line shell to do
283
** extra initialization prior to starting up the shell.
284
*/
285
void sqlcmd_init_proc(void){
286
sqlite3_initialize();
287
sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit);
288
}
289
290
#if USE_SEE
291
/*
292
** This routine is called by the patched sqlite3 command-line shell in order
293
** to load the encryption key for the open Fossil database. The memory that
294
** is pointed to by the value placed in pzKey must be obtained from malloc.
295
*/
296
void fossil_key(const char **pzKey, int *pnKey){
297
char *zSavedKey = db_get_saved_encryption_key();
298
char *zKey;
299
size_t savedKeySize = db_get_saved_encryption_key_size();
300
301
if( !db_is_valid_saved_encryption_key(zSavedKey, savedKeySize) ) return;
302
zKey = (char*)malloc( savedKeySize );
303
if( zKey ){
304
memcpy(zKey, zSavedKey, savedKeySize);
305
*pzKey = zKey;
306
if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
307
*pnKey = (int)strlen(zKey);
308
}else{
309
*pnKey = -1;
310
}
311
}else{
312
fossil_fatal("failed to allocate %u bytes for key", savedKeySize);
313
}
314
}
315
#endif
316
317
/*
318
** This routine closes the Fossil databases and/or invalidates the global
319
** state variables that keep track of them.
320
*/
321
static void fossil_close(int bDb, int noRepository){
322
if( bDb ) db_close(1);
323
if( noRepository ) g.zRepositoryName = 0;
324
g.db = 0;
325
g.repositoryOpen = 0;
326
g.localOpen = 0;
327
}
328
329
/*
330
** This routine overrides some of the prompt generation behavior in the
331
** SQLite shell. Always return a static string. For invalid inputs,
332
** return a zero-length string. Valid inputs:
333
**
334
** 1 Default main prompt.
335
** 2 Default continuation prompt.
336
** 3 Environment variable to override main prompt ("FOSSIL_PS1")
337
** 4 Environment variable to override continuatio ("FOSSIL_PS2")
338
** 'A' The name of the application. (Nominally "Fossil")
339
** 'V' Version number including patch. (ex: "2.29.1")
340
** 'v' Version number without patch. (ex: "2.29")
341
*/
342
const char *sqlcmd_ps_appdef(int c){
343
switch( c ){
344
/* Default prompt strings */
345
case 1: return "/e[1;34m/A-/v /e[1;/x33/:36/;m/f/e[0m-> ";
346
case 2: return "/B/e[1;/x33/:36/;m/C/e[0m-> ";
347
348
/* Names of environment variables to override cases 1 and 2 */
349
case 3: return "FOSSIL_PS1";
350
case 4: return "FOSSIL_PS2";
351
352
/* Application name */
353
case 'A': return "Fossil";
354
355
/* Version numbers */
356
case 'V': return RELEASE_VERSION;
357
case 'v': {
358
const char *zFull = RELEASE_VERSION;
359
const char *zD1, *zD2;
360
size_t i;
361
static char zRelease[32];
362
zD2 = strrchr(zFull,'.');
363
zD1 = strchr(zFull,'.');
364
if( zD2==0 || zD2==zD1 ){
365
return zFull;
366
}
367
i = zD2 - zFull;
368
if( i>sizeof(zRelease)-1 ) return zFull;
369
memcpy(zRelease, zFull, i);
370
zRelease[i] = 0;
371
return zRelease;
372
}
373
}
374
return "";
375
}
376
377
/*
378
** COMMAND: sql
379
** COMMAND: sqlite3*
380
**
381
** Usage: %fossil sql ?OPTIONS?
382
**
383
** Run the sqlite3 command-line shell on the Fossil repository
384
** identified by the -R option, or on the current repository.
385
** See https://www.sqlite.org/cli.html for additional information about
386
** the sqlite3 command-line shell.
387
**
388
** WARNING: Careless use of this command can corrupt a Fossil repository
389
** in ways that are unrecoverable. Be sure you know what you are doing before
390
** running any SQL commands that modify the repository database. Use the
391
** --readonly option to prevent accidental damage to the repository.
392
**
393
** Options:
394
** --no-repository Skip opening the repository database
395
** --readonly Open the repository read-only. No changes
396
** are allowed. This is a recommended safety
397
** precaution to prevent repository damage.
398
** -R REPOSITORY Use REPOSITORY as the repository database
399
** --test Enable some testing and analysis features
400
** that are normally disabled.
401
**
402
** All of the standard sqlite3 command-line shell options should also
403
** work.
404
**
405
** The following SQL extensions are provided with this Fossil-enhanced
406
** version of the sqlite3 command-line shell:
407
**
408
** builtin A virtual table that contains one row for
409
** each datafile that is built into the Fossil
410
** binary.
411
**
412
** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID)
413
** found in check-in X (another BLOB.RID value).
414
**
415
** compress(X) Compress text X with the same algorithm used
416
** to compress artifacts in the BLOB table.
417
**
418
** content(X) Return the content of artifact X. X can be an
419
** artifact hash or hash prefix or a tag. Artifacts
420
** are stored compressed and deltaed. This function
421
** does all necessary decompression and undeltaing.
422
**
423
** decompress(X) Decompress text X. Undoes the work of
424
** compress(X).
425
**
426
** delta_apply(X,D) Apply delta D to source blob X and return
427
** the result.
428
**
429
** delta_create(X,Y) Create and return a delta that will convert
430
** X into Y.
431
**
432
** delta_output_size(D) Return the number of bytes of output to expect
433
** when applying delta D
434
**
435
** delta_parse(D) A table-valued function that deconstructs
436
** delta D and returns rows for each element of
437
** that delta.
438
**
439
** files_of_checkin(X) A table-valued function that returns info on
440
** all files contained in check-in X. Example:
441
**
442
** SELECT * FROM files_of_checkin('trunk');
443
**
444
** helptext A virtual table with one row for each command,
445
** webpage, and setting together with the built-in
446
** help text.
447
**
448
** now() Return the number of seconds since 1970.
449
**
450
** obscure(T) Obfuscate the text password T so that its
451
** original value is not readily visible. Fossil
452
** uses this same algorithm when storing passwords
453
** of remote URLs.
454
**
455
** regexp The REGEXP operator works, unlike in
456
** standard SQLite.
457
**
458
** symbolic_name_to_rid(X) Return the BLOB.RID corresponding to symbolic
459
** name X.
460
*/
461
void cmd_sqlite3(void){
462
int noRepository;
463
char *zConfigDb;
464
extern int sqlite3_shell(int, char**);
465
#ifdef FOSSIL_ENABLE_TH1_HOOKS
466
g.fNoThHook = 1;
467
#endif
468
noRepository = find_option("no-repository", 0, 0)!=0;
469
local_bSqlCmdTest = find_option("test",0,0)!=0;
470
if( !noRepository ){
471
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
472
}
473
db_open_config(1,0);
474
zConfigDb = fossil_strdup(g.zConfigDbName);
475
fossil_close(1, noRepository);
476
sqlite3_shutdown();
477
#if !defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE)
478
linenoiseSetMultiLine(1);
479
#endif
480
atexit(sqlcmd_atexit);
481
g.zConfigDbName = zConfigDb;
482
g.argv[1] = "--noinit";
483
sqlite3_shell(g.argc, g.argv);
484
sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
485
fossil_close(0, noRepository);
486
}
487

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button