1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8 /*
9 ** 2001 September 15
10 **
11 ** The author disclaims copyright to this source code. In place of
12 ** a legal notice, here is a blessing:
13 **
14 ** May you do good and not evil.
15 ** May you find forgiveness for yourself and forgive others.
16 ** May you share freely, never taking more than you give.
17 **
18 *************************************************************************
19 ** This file contains code to implement the "sqlite" command line
20 ** utility for accessing SQLite databases.
21 **
22 ** $Id: shell.c,v 1.93 2004/03/17 23:42:13 drh Exp $
23 */
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include "sqlite.h"
28 #include "sqlite-misc.h" /* SUNW addition */
29 #include <ctype.h>
30
31 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
32 # include <signal.h>
33 # include <pwd.h>
34 # include <unistd.h>
35 # include <sys/types.h>
36 #endif
37
38 #ifdef __MACOS__
39 # include <console.h>
40 # include <signal.h>
41 # include <unistd.h>
42 # include <extras.h>
43 # include <Files.h>
44 # include <Folders.h>
45 #endif
46
47 #if defined(HAVE_READLINE) && HAVE_READLINE==1
48 # include <readline/readline.h>
49 # include <readline/history.h>
50 #else
51 # define readline(p) local_getline(p,stdin)
52 # define add_history(X)
53 # define read_history(X)
54 # define write_history(X)
55 # define stifle_history(X)
56 #endif
57
58 /* Make sure isatty() has a prototype.
59 */
60 extern int isatty();
61
62 /*
63 ** The following is the open SQLite database. We make a pointer
64 ** to this database a static variable so that it can be accessed
65 ** by the SIGINT handler to interrupt database processing.
66 */
67 static sqlite *db = 0;
68
69 /*
70 ** True if an interrupt (Control-C) has been received.
71 */
72 static int seenInterrupt = 0;
73
74 /*
75 ** This is the name of our program. It is set in main(), used
76 ** in a number of other places, mostly for error messages.
77 */
78 static char *Argv0;
79
80 /*
81 ** Prompt strings. Initialized in main. Settable with
82 ** .prompt main continue
83 */
84 static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
85 static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
86
87
88 /*
89 ** Determines if a string is a number of not.
90 */
91 extern int sqliteIsNumber(const char*);
92
93 /*
94 ** This routine reads a line of text from standard input, stores
95 ** the text in memory obtained from malloc() and returns a pointer
96 ** to the text. NULL is returned at end of file, or if malloc()
97 ** fails.
98 **
99 ** The interface is like "readline" but no command-line editing
100 ** is done.
101 */
local_getline(char * zPrompt,FILE * in)102 static char *local_getline(char *zPrompt, FILE *in){
103 char *zLine;
104 int nLine;
105 int n;
106 int eol;
107
108 if( zPrompt && *zPrompt ){
109 printf("%s",zPrompt);
110 fflush(stdout);
111 }
112 nLine = 100;
113 zLine = malloc( nLine );
114 if( zLine==0 ) return 0;
115 n = 0;
116 eol = 0;
117 while( !eol ){
118 if( n+100>nLine ){
119 nLine = nLine*2 + 100;
120 zLine = realloc(zLine, nLine);
121 if( zLine==0 ) return 0;
122 }
123 if( fgets(&zLine[n], nLine - n, in)==0 ){
124 if( n==0 ){
125 free(zLine);
126 return 0;
127 }
128 zLine[n] = 0;
129 eol = 1;
130 break;
131 }
132 while( zLine[n] ){ n++; }
133 if( n>0 && zLine[n-1]=='\n' ){
134 n--;
135 zLine[n] = 0;
136 eol = 1;
137 }
138 }
139 zLine = realloc( zLine, n+1 );
140 return zLine;
141 }
142
143 /*
144 ** Retrieve a single line of input text. "isatty" is true if text
145 ** is coming from a terminal. In that case, we issue a prompt and
146 ** attempt to use "readline" for command-line editing. If "isatty"
147 ** is false, use "local_getline" instead of "readline" and issue no prompt.
148 **
149 ** zPrior is a string of prior text retrieved. If not the empty
150 ** string, then issue a continuation prompt.
151 */
one_input_line(const char * zPrior,FILE * in)152 static char *one_input_line(const char *zPrior, FILE *in){
153 char *zPrompt;
154 char *zResult;
155 if( in!=0 ){
156 return local_getline(0, in);
157 }
158 if( zPrior && zPrior[0] ){
159 zPrompt = continuePrompt;
160 }else{
161 zPrompt = mainPrompt;
162 }
163 zResult = readline(zPrompt);
164 if( zResult ) add_history(zResult);
165 return zResult;
166 }
167
168 struct previous_mode_data {
169 int valid; /* Is there legit data in here? */
170 int mode;
171 int showHeader;
172 int colWidth[100];
173 };
174 /*
175 ** An pointer to an instance of this structure is passed from
176 ** the main program to the callback. This is used to communicate
177 ** state and mode information.
178 */
179 struct callback_data {
180 sqlite *db; /* The database */
181 int echoOn; /* True to echo input commands */
182 int cnt; /* Number of records displayed so far */
183 FILE *out; /* Write results here */
184 int mode; /* An output mode setting */
185 int showHeader; /* True to show column names in List or Column mode */
186 char *zDestTable; /* Name of destination table when MODE_Insert */
187 char separator[20]; /* Separator character for MODE_List */
188 int colWidth[100]; /* Requested width of each column when in column mode*/
189 int actualWidth[100]; /* Actual width of each column */
190 char nullvalue[20]; /* The text to print when a NULL comes back from
191 ** the database */
192 struct previous_mode_data explainPrev;
193 /* Holds the mode information just before
194 ** .explain ON */
195 char outfile[FILENAME_MAX]; /* Filename for *out */
196 const char *zDbFilename; /* name of the database file */
197 char *zKey; /* Encryption key */
198 };
199
200 /*
201 ** These are the allowed modes.
202 */
203 #define MODE_Line 0 /* One column per line. Blank line between records */
204 #define MODE_Column 1 /* One record per line in neat columns */
205 #define MODE_List 2 /* One record per line with a separator */
206 #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
207 #define MODE_Html 4 /* Generate an XHTML table */
208 #define MODE_Insert 5 /* Generate SQL "insert" statements */
209 #define MODE_NUM_OF 6 /* The number of modes (not a mode itself) */
210
211 char *modeDescr[MODE_NUM_OF] = {
212 "line",
213 "column",
214 "list",
215 "semi",
216 "html",
217 "insert"
218 };
219
220 /*
221 ** Number of elements in an array
222 */
223 #define ArraySize(X) (sizeof(X)/sizeof(X[0]))
224
225 /*
226 ** Output the given string as a quoted string using SQL quoting conventions.
227 */
output_quoted_string(FILE * out,const char * z)228 static void output_quoted_string(FILE *out, const char *z){
229 int i;
230 int nSingle = 0;
231 for(i=0; z[i]; i++){
232 if( z[i]=='\'' ) nSingle++;
233 }
234 if( nSingle==0 ){
235 fprintf(out,"'%s'",z);
236 }else{
237 fprintf(out,"'");
238 while( *z ){
239 for(i=0; z[i] && z[i]!='\''; i++){}
240 if( i==0 ){
241 fprintf(out,"''");
242 z++;
243 }else if( z[i]=='\'' ){
244 fprintf(out,"%.*s''",i,z);
245 z += i+1;
246 }else{
247 fprintf(out,"%s",z);
248 break;
249 }
250 }
251 fprintf(out,"'");
252 }
253 }
254
255 /*
256 ** Output the given string with characters that are special to
257 ** HTML escaped.
258 */
output_html_string(FILE * out,const char * z)259 static void output_html_string(FILE *out, const char *z){
260 int i;
261 while( *z ){
262 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
263 if( i>0 ){
264 fprintf(out,"%.*s",i,z);
265 }
266 if( z[i]=='<' ){
267 fprintf(out,"<");
268 }else if( z[i]=='&' ){
269 fprintf(out,"&");
270 }else{
271 break;
272 }
273 z += i + 1;
274 }
275 }
276
277 /*
278 ** This routine runs when the user presses Ctrl-C
279 */
interrupt_handler(int NotUsed)280 static void interrupt_handler(int NotUsed){
281 seenInterrupt = 1;
282 if( db ) sqlite_interrupt(db);
283 }
284
285 /*
286 ** This is the callback routine that the SQLite library
287 ** invokes for each row of a query result.
288 */
callback(void * pArg,int nArg,char ** azArg,char ** azCol)289 static int callback(void *pArg, int nArg, char **azArg, char **azCol){
290 int i;
291 struct callback_data *p = (struct callback_data*)pArg;
292 switch( p->mode ){
293 case MODE_Line: {
294 int w = 5;
295 if( azArg==0 ) break;
296 for(i=0; i<nArg; i++){
297 int len = strlen(azCol[i]);
298 if( len>w ) w = len;
299 }
300 if( p->cnt++>0 ) fprintf(p->out,"\n");
301 for(i=0; i<nArg; i++){
302 fprintf(p->out,"%*s = %s\n", w, azCol[i],
303 azArg[i] ? azArg[i] : p->nullvalue);
304 }
305 break;
306 }
307 case MODE_Column: {
308 if( p->cnt++==0 ){
309 for(i=0; i<nArg; i++){
310 int w, n;
311 if( i<ArraySize(p->colWidth) ){
312 w = p->colWidth[i];
313 }else{
314 w = 0;
315 }
316 if( w<=0 ){
317 w = strlen(azCol[i] ? azCol[i] : "");
318 if( w<10 ) w = 10;
319 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
320 if( w<n ) w = n;
321 }
322 if( i<ArraySize(p->actualWidth) ){
323 p->actualWidth[i] = w;
324 }
325 if( p->showHeader ){
326 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
327 }
328 }
329 if( p->showHeader ){
330 for(i=0; i<nArg; i++){
331 int w;
332 if( i<ArraySize(p->actualWidth) ){
333 w = p->actualWidth[i];
334 }else{
335 w = 10;
336 }
337 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
338 "----------------------------------------------------------",
339 i==nArg-1 ? "\n": " ");
340 }
341 }
342 }
343 if( azArg==0 ) break;
344 for(i=0; i<nArg; i++){
345 int w;
346 if( i<ArraySize(p->actualWidth) ){
347 w = p->actualWidth[i];
348 }else{
349 w = 10;
350 }
351 fprintf(p->out,"%-*.*s%s",w,w,
352 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
353 }
354 break;
355 }
356 case MODE_Semi:
357 case MODE_List: {
358 if( p->cnt++==0 && p->showHeader ){
359 for(i=0; i<nArg; i++){
360 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
361 }
362 }
363 if( azArg==0 ) break;
364 for(i=0; i<nArg; i++){
365 char *z = azArg[i];
366 if( z==0 ) z = p->nullvalue;
367 fprintf(p->out, "%s", z);
368 if( i<nArg-1 ){
369 fprintf(p->out, "%s", p->separator);
370 }else if( p->mode==MODE_Semi ){
371 fprintf(p->out, ";\n");
372 }else{
373 fprintf(p->out, "\n");
374 }
375 }
376 break;
377 }
378 case MODE_Html: {
379 if( p->cnt++==0 && p->showHeader ){
380 fprintf(p->out,"<TR>");
381 for(i=0; i<nArg; i++){
382 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
383 }
384 fprintf(p->out,"</TR>\n");
385 }
386 if( azArg==0 ) break;
387 fprintf(p->out,"<TR>");
388 for(i=0; i<nArg; i++){
389 fprintf(p->out,"<TD>");
390 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
391 fprintf(p->out,"</TD>\n");
392 }
393 fprintf(p->out,"</TR>\n");
394 break;
395 }
396 case MODE_Insert: {
397 if( azArg==0 ) break;
398 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
399 for(i=0; i<nArg; i++){
400 char *zSep = i>0 ? ",": "";
401 if( azArg[i]==0 ){
402 fprintf(p->out,"%sNULL",zSep);
403 }else if( sqliteIsNumber(azArg[i]) ){
404 fprintf(p->out,"%s%s",zSep, azArg[i]);
405 }else{
406 if( zSep[0] ) fprintf(p->out,"%s",zSep);
407 output_quoted_string(p->out, azArg[i]);
408 }
409 }
410 fprintf(p->out,");\n");
411 break;
412 }
413 }
414 return 0;
415 }
416
417 /*
418 ** Set the destination table field of the callback_data structure to
419 ** the name of the table given. Escape any quote characters in the
420 ** table name.
421 */
set_table_name(struct callback_data * p,const char * zName)422 static void set_table_name(struct callback_data *p, const char *zName){
423 int i, n;
424 int needQuote;
425 char *z;
426
427 if( p->zDestTable ){
428 free(p->zDestTable);
429 p->zDestTable = 0;
430 }
431 if( zName==0 ) return;
432 needQuote = !isalpha(*zName) && *zName!='_';
433 for(i=n=0; zName[i]; i++, n++){
434 if( !isalnum(zName[i]) && zName[i]!='_' ){
435 needQuote = 1;
436 if( zName[i]=='\'' ) n++;
437 }
438 }
439 if( needQuote ) n += 2;
440 z = p->zDestTable = malloc( n+1 );
441 if( z==0 ){
442 fprintf(stderr,"Out of memory!\n");
443 exit(1);
444 }
445 n = 0;
446 if( needQuote ) z[n++] = '\'';
447 for(i=0; zName[i]; i++){
448 z[n++] = zName[i];
449 if( zName[i]=='\'' ) z[n++] = '\'';
450 }
451 if( needQuote ) z[n++] = '\'';
452 z[n] = 0;
453 }
454
455 /*
456 ** This is a different callback routine used for dumping the database.
457 ** Each row received by this callback consists of a table name,
458 ** the table type ("index" or "table") and SQL to create the table.
459 ** This routine should print text sufficient to recreate the table.
460 */
dump_callback(void * pArg,int nArg,char ** azArg,char ** azCol)461 static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
462 struct callback_data *p = (struct callback_data *)pArg;
463 if( nArg!=3 ) return 1;
464 fprintf(p->out, "%s;\n", azArg[2]);
465 if( strcmp(azArg[1],"table")==0 ){
466 struct callback_data d2;
467 d2 = *p;
468 d2.mode = MODE_Insert;
469 d2.zDestTable = 0;
470 set_table_name(&d2, azArg[0]);
471 sqlite_exec_printf(p->db,
472 "SELECT * FROM '%q'",
473 callback, &d2, 0, azArg[0]
474 );
475 set_table_name(&d2, 0);
476 }
477 return 0;
478 }
479
480 /*
481 ** Text of a help message
482 */
483 static char zHelp[] =
484 ".databases List names and files of attached databases\n"
485 ".dump ?TABLE? ... Dump the database in a text format\n"
486 ".echo ON|OFF Turn command echo on or off\n"
487 ".exit Exit this program\n"
488 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
489 ".header(s) ON|OFF Turn display of headers on or off\n"
490 ".help Show this message\n"
491 ".indices TABLE Show names of all indices on TABLE\n"
492 ".mode MODE Set mode to one of \"line(s)\", \"column(s)\", \n"
493 " \"insert\", \"list\", or \"html\"\n"
494 ".mode insert TABLE Generate SQL insert statements for TABLE\n"
495 ".nullvalue STRING Print STRING instead of nothing for NULL data\n"
496 ".output FILENAME Send output to FILENAME\n"
497 ".output stdout Send output to the screen\n"
498 ".prompt MAIN CONTINUE Replace the standard prompts\n"
499 ".quit Exit this program\n"
500 ".read FILENAME Execute SQL in FILENAME\n"
501 #ifdef SQLITE_HAS_CODEC
502 ".rekey OLD NEW NEW Change the encryption key\n"
503 #endif
504 ".schema ?TABLE? Show the CREATE statements\n"
505 ".separator STRING Change separator string for \"list\" mode\n"
506 ".show Show the current values for various settings\n"
507 ".tables ?PATTERN? List names of tables matching a pattern\n"
508 ".timeout MS Try opening locked tables for MS milliseconds\n"
509 ".width NUM NUM ... Set column widths for \"column\" mode\n"
510 ;
511
512 /* Forward reference */
513 static void process_input(struct callback_data *p, FILE *in);
514
515 /*
516 ** Make sure the database is open. If it is not, then open it. If
517 ** the database fails to open, print an error message and exit.
518 */
open_db(struct callback_data * p)519 static void open_db(struct callback_data *p){
520 if( p->db==0 ){
521 char *zErrMsg = 0;
522 #ifdef SQLITE_HAS_CODEC
523 int n = p->zKey ? strlen(p->zKey) : 0;
524 db = p->db = sqlite_open_encrypted(p->zDbFilename, p->zKey, n, 0, &zErrMsg);
525 #else
526 db = p->db = sqlite_open(p->zDbFilename, 0, &zErrMsg);
527 #endif
528 if( p->db==0 ){
529 if( zErrMsg ){
530 fprintf(stderr,"Unable to open database \"%s\": %s\n",
531 p->zDbFilename, zErrMsg);
532 }else{
533 fprintf(stderr,"Unable to open database %s\n", p->zDbFilename);
534 }
535 exit(1);
536 }
537 }
538 }
539
540 /*
541 ** If an input line begins with "." then invoke this routine to
542 ** process that line.
543 **
544 ** Return 1 to exit and 0 to continue.
545 */
do_meta_command(char * zLine,struct callback_data * p)546 static int do_meta_command(char *zLine, struct callback_data *p){
547 int i = 1;
548 int nArg = 0;
549 int n, c;
550 int rc = 0;
551 char *azArg[50];
552
553 /* Parse the input line into tokens.
554 */
555 while( zLine[i] && nArg<ArraySize(azArg) ){
556 while( isspace(zLine[i]) ){ i++; }
557 if( zLine[i]==0 ) break;
558 if( zLine[i]=='\'' || zLine[i]=='"' ){
559 int delim = zLine[i++];
560 azArg[nArg++] = &zLine[i];
561 while( zLine[i] && zLine[i]!=delim ){ i++; }
562 if( zLine[i]==delim ){
563 zLine[i++] = 0;
564 }
565 }else{
566 azArg[nArg++] = &zLine[i];
567 while( zLine[i] && !isspace(zLine[i]) ){ i++; }
568 if( zLine[i] ) zLine[i++] = 0;
569 }
570 }
571
572 /* Process the input line.
573 */
574 if( nArg==0 ) return rc;
575 n = strlen(azArg[0]);
576 c = azArg[0][0];
577 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
578 struct callback_data data;
579 char *zErrMsg = 0;
580 open_db(p);
581 memcpy(&data, p, sizeof(data));
582 data.showHeader = 1;
583 data.mode = MODE_Column;
584 data.colWidth[0] = 3;
585 data.colWidth[1] = 15;
586 data.colWidth[2] = 58;
587 sqlite_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
588 if( zErrMsg ){
589 fprintf(stderr,"Error: %s\n", zErrMsg);
590 sqlite_freemem(zErrMsg);
591 }
592 }else
593
594 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
595 char *zErrMsg = 0;
596 open_db(p);
597 fprintf(p->out, "BEGIN TRANSACTION;\n");
598 if( nArg==1 ){
599 sqlite_exec(p->db,
600 "SELECT name, type, sql FROM sqlite_master "
601 "WHERE type!='meta' AND sql NOT NULL "
602 "ORDER BY substr(type,2,1), name",
603 dump_callback, p, &zErrMsg
604 );
605 }else{
606 int i;
607 for(i=1; i<nArg && zErrMsg==0; i++){
608 sqlite_exec_printf(p->db,
609 "SELECT name, type, sql FROM sqlite_master "
610 "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
611 "ORDER BY substr(type,2,1), name",
612 dump_callback, p, &zErrMsg, azArg[i]
613 );
614 }
615 }
616 if( zErrMsg ){
617 fprintf(stderr,"Error: %s\n", zErrMsg);
618 sqlite_freemem(zErrMsg);
619 }else{
620 fprintf(p->out, "COMMIT;\n");
621 }
622 }else
623
624 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
625 int j;
626 char *z = azArg[1];
627 int val = atoi(azArg[1]);
628 for(j=0; z[j]; j++){
629 if( isupper(z[j]) ) z[j] = tolower(z[j]);
630 }
631 if( strcmp(z,"on")==0 ){
632 val = 1;
633 }else if( strcmp(z,"yes")==0 ){
634 val = 1;
635 }
636 p->echoOn = val;
637 }else
638
639 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
640 rc = 1;
641 }else
642
643 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
644 int j;
645 char *z = nArg>=2 ? azArg[1] : "1";
646 int val = atoi(z);
647 for(j=0; z[j]; j++){
648 if( isupper(z[j]) ) z[j] = tolower(z[j]);
649 }
650 if( strcmp(z,"on")==0 ){
651 val = 1;
652 }else if( strcmp(z,"yes")==0 ){
653 val = 1;
654 }
655 if(val == 1) {
656 if(!p->explainPrev.valid) {
657 p->explainPrev.valid = 1;
658 p->explainPrev.mode = p->mode;
659 p->explainPrev.showHeader = p->showHeader;
660 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
661 }
662 /* We could put this code under the !p->explainValid
663 ** condition so that it does not execute if we are already in
664 ** explain mode. However, always executing it allows us an easy
665 ** was to reset to explain mode in case the user previously
666 ** did an .explain followed by a .width, .mode or .header
667 ** command.
668 */
669 p->mode = MODE_Column;
670 p->showHeader = 1;
671 memset(p->colWidth,0,ArraySize(p->colWidth));
672 p->colWidth[0] = 4;
673 p->colWidth[1] = 12;
674 p->colWidth[2] = 10;
675 p->colWidth[3] = 10;
676 p->colWidth[4] = 35;
677 }else if (p->explainPrev.valid) {
678 p->explainPrev.valid = 0;
679 p->mode = p->explainPrev.mode;
680 p->showHeader = p->explainPrev.showHeader;
681 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
682 }
683 }else
684
685 if( c=='h' && (strncmp(azArg[0], "header", n)==0
686 ||
687 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
688 int j;
689 char *z = azArg[1];
690 int val = atoi(azArg[1]);
691 for(j=0; z[j]; j++){
692 if( isupper(z[j]) ) z[j] = tolower(z[j]);
693 }
694 if( strcmp(z,"on")==0 ){
695 val = 1;
696 }else if( strcmp(z,"yes")==0 ){
697 val = 1;
698 }
699 p->showHeader = val;
700 }else
701
702 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
703 fprintf(stderr,zHelp);
704 }else
705
706 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
707 struct callback_data data;
708 char *zErrMsg = 0;
709 open_db(p);
710 memcpy(&data, p, sizeof(data));
711 data.showHeader = 0;
712 data.mode = MODE_List;
713 sqlite_exec_printf(p->db,
714 "SELECT name FROM sqlite_master "
715 "WHERE type='index' AND tbl_name LIKE '%q' "
716 "UNION ALL "
717 "SELECT name FROM sqlite_temp_master "
718 "WHERE type='index' AND tbl_name LIKE '%q' "
719 "ORDER BY 1",
720 callback, &data, &zErrMsg, azArg[1], azArg[1]
721 );
722 if( zErrMsg ){
723 fprintf(stderr,"Error: %s\n", zErrMsg);
724 sqlite_freemem(zErrMsg);
725 }
726 }else
727
728 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
729 int n2 = strlen(azArg[1]);
730 if( strncmp(azArg[1],"line",n2)==0
731 ||
732 strncmp(azArg[1],"lines",n2)==0 ){
733 p->mode = MODE_Line;
734 }else if( strncmp(azArg[1],"column",n2)==0
735 ||
736 strncmp(azArg[1],"columns",n2)==0 ){
737 p->mode = MODE_Column;
738 }else if( strncmp(azArg[1],"list",n2)==0 ){
739 p->mode = MODE_List;
740 }else if( strncmp(azArg[1],"html",n2)==0 ){
741 p->mode = MODE_Html;
742 }else if( strncmp(azArg[1],"insert",n2)==0 ){
743 p->mode = MODE_Insert;
744 if( nArg>=3 ){
745 set_table_name(p, azArg[2]);
746 }else{
747 set_table_name(p, "table");
748 }
749 }else {
750 fprintf(stderr,"mode should be on of: column html insert line list\n");
751 }
752 }else
753
754 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
755 sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
756 }else
757
758 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
759 if( p->out!=stdout ){
760 fclose(p->out);
761 }
762 if( strcmp(azArg[1],"stdout")==0 ){
763 p->out = stdout;
764 strcpy(p->outfile,"stdout");
765 }else{
766 p->out = fopen(azArg[1], "wb");
767 if( p->out==0 ){
768 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
769 p->out = stdout;
770 } else {
771 strcpy(p->outfile,azArg[1]);
772 }
773 }
774 }else
775
776 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
777 if( nArg >= 2) {
778 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
779 }
780 if( nArg >= 3) {
781 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
782 }
783 }else
784
785 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
786 rc = 1;
787 }else
788
789 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
790 FILE *alt = fopen(azArg[1], "rb");
791 if( alt==0 ){
792 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
793 }else{
794 process_input(p, alt);
795 fclose(alt);
796 }
797 }else
798
799 #ifdef SQLITE_HAS_CODEC
800 if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){
801 char *zOld = p->zKey;
802 if( zOld==0 ) zOld = "";
803 if( strcmp(azArg[1],zOld) ){
804 fprintf(stderr,"old key is incorrect\n");
805 }else if( strcmp(azArg[2], azArg[3]) ){
806 fprintf(stderr,"2nd copy of new key does not match the 1st\n");
807 }else{
808 sqlite_freemem(p->zKey);
809 p->zKey = sqlite_mprintf("%s", azArg[2]);
810 sqlite_rekey(p->db, p->zKey, strlen(p->zKey));
811 }
812 }else
813 #endif
814
815 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
816 struct callback_data data;
817 char *zErrMsg = 0;
818 open_db(p);
819 memcpy(&data, p, sizeof(data));
820 data.showHeader = 0;
821 data.mode = MODE_Semi;
822 if( nArg>1 ){
823 extern int sqliteStrICmp(const char*,const char*);
824 if( sqliteStrICmp(azArg[1],"sqlite_master")==0 ){
825 char *new_argv[2], *new_colv[2];
826 new_argv[0] = "CREATE TABLE sqlite_master (\n"
827 " type text,\n"
828 " name text,\n"
829 " tbl_name text,\n"
830 " rootpage integer,\n"
831 " sql text\n"
832 ")";
833 new_argv[1] = 0;
834 new_colv[0] = "sql";
835 new_colv[1] = 0;
836 callback(&data, 1, new_argv, new_colv);
837 }else if( sqliteStrICmp(azArg[1],"sqlite_temp_master")==0 ){
838 char *new_argv[2], *new_colv[2];
839 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
840 " type text,\n"
841 " name text,\n"
842 " tbl_name text,\n"
843 " rootpage integer,\n"
844 " sql text\n"
845 ")";
846 new_argv[1] = 0;
847 new_colv[0] = "sql";
848 new_colv[1] = 0;
849 callback(&data, 1, new_argv, new_colv);
850 }else{
851 sqlite_exec_printf(p->db,
852 "SELECT sql FROM "
853 " (SELECT * FROM sqlite_master UNION ALL"
854 " SELECT * FROM sqlite_temp_master) "
855 "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
856 "ORDER BY substr(type,2,1), name",
857 callback, &data, &zErrMsg, azArg[1]);
858 }
859 }else{
860 sqlite_exec(p->db,
861 "SELECT sql FROM "
862 " (SELECT * FROM sqlite_master UNION ALL"
863 " SELECT * FROM sqlite_temp_master) "
864 "WHERE type!='meta' AND sql NOTNULL "
865 "ORDER BY substr(type,2,1), name",
866 callback, &data, &zErrMsg
867 );
868 }
869 if( zErrMsg ){
870 fprintf(stderr,"Error: %s\n", zErrMsg);
871 sqlite_freemem(zErrMsg);
872 }
873 }else
874
875 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
876 sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
877 }else
878
879 if( c=='s' && strncmp(azArg[0], "show", n)==0){
880 int i;
881 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
882 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
883 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
884 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
885 fprintf(p->out,"%9.9s: %s\n","nullvalue", p->nullvalue);
886 fprintf(p->out,"%9.9s: %s\n","output",
887 strlen(p->outfile) ? p->outfile : "stdout");
888 fprintf(p->out,"%9.9s: %s\n","separator", p->separator);
889 fprintf(p->out,"%9.9s: ","width");
890 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
891 fprintf(p->out,"%d ",p->colWidth[i]);
892 }
893 fprintf(p->out,"\n\n");
894 }else
895
896 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
897 char **azResult;
898 int nRow, rc;
899 char *zErrMsg;
900 open_db(p);
901 if( nArg==1 ){
902 rc = sqlite_get_table(p->db,
903 "SELECT name FROM sqlite_master "
904 "WHERE type IN ('table','view') "
905 "UNION ALL "
906 "SELECT name FROM sqlite_temp_master "
907 "WHERE type IN ('table','view') "
908 "ORDER BY 1",
909 &azResult, &nRow, 0, &zErrMsg
910 );
911 }else{
912 rc = sqlite_get_table_printf(p->db,
913 "SELECT name FROM sqlite_master "
914 "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
915 "UNION ALL "
916 "SELECT name FROM sqlite_temp_master "
917 "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
918 "ORDER BY 1",
919 &azResult, &nRow, 0, &zErrMsg, azArg[1], azArg[1]
920 );
921 }
922 if( zErrMsg ){
923 fprintf(stderr,"Error: %s\n", zErrMsg);
924 sqlite_freemem(zErrMsg);
925 }
926 if( rc==SQLITE_OK ){
927 int len, maxlen = 0;
928 int i, j;
929 int nPrintCol, nPrintRow;
930 for(i=1; i<=nRow; i++){
931 if( azResult[i]==0 ) continue;
932 len = strlen(azResult[i]);
933 if( len>maxlen ) maxlen = len;
934 }
935 nPrintCol = 80/(maxlen+2);
936 if( nPrintCol<1 ) nPrintCol = 1;
937 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
938 for(i=0; i<nPrintRow; i++){
939 for(j=i+1; j<=nRow; j+=nPrintRow){
940 char *zSp = j<=nPrintRow ? "" : " ";
941 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
942 }
943 printf("\n");
944 }
945 }
946 sqlite_free_table(azResult);
947 }else
948
949 if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
950 open_db(p);
951 sqlite_busy_timeout(p->db, atoi(azArg[1]));
952 }else
953
954 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
955 int j;
956 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
957 p->colWidth[j-1] = atoi(azArg[j]);
958 }
959 }else
960
961 {
962 fprintf(stderr, "unknown command or invalid arguments: "
963 " \"%s\". Enter \".help\" for help\n", azArg[0]);
964 }
965
966 return rc;
967 }
968
969 /*
970 ** Return TRUE if the last non-whitespace character in z[] is a semicolon.
971 ** z[] is N characters long.
972 */
_ends_with_semicolon(const char * z,int N)973 static int _ends_with_semicolon(const char *z, int N){
974 while( N>0 && isspace(z[N-1]) ){ N--; }
975 return N>0 && z[N-1]==';';
976 }
977
978 /*
979 ** Test to see if a line consists entirely of whitespace.
980 */
_all_whitespace(const char * z)981 static int _all_whitespace(const char *z){
982 for(; *z; z++){
983 if( isspace(*z) ) continue;
984 if( *z=='/' && z[1]=='*' ){
985 z += 2;
986 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
987 if( *z==0 ) return 0;
988 z++;
989 continue;
990 }
991 if( *z=='-' && z[1]=='-' ){
992 z += 2;
993 while( *z && *z!='\n' ){ z++; }
994 if( *z==0 ) return 1;
995 continue;
996 }
997 return 0;
998 }
999 return 1;
1000 }
1001
1002 /*
1003 ** Return TRUE if the line typed in is an SQL command terminator other
1004 ** than a semi-colon. The SQL Server style "go" command is understood
1005 ** as is the Oracle "/".
1006 */
_is_command_terminator(const char * zLine)1007 static int _is_command_terminator(const char *zLine){
1008 extern int sqliteStrNICmp(const char*,const char*,int);
1009 while( isspace(*zLine) ){ zLine++; };
1010 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
1011 if( sqliteStrNICmp(zLine,"go",2)==0 && _all_whitespace(&zLine[2]) ){
1012 return 1; /* SQL Server */
1013 }
1014 return 0;
1015 }
1016
1017 /*
1018 ** Read input from *in and process it. If *in==0 then input
1019 ** is interactive - the user is typing it it. Otherwise, input
1020 ** is coming from a file or device. A prompt is issued and history
1021 ** is saved only if input is interactive. An interrupt signal will
1022 ** cause this routine to exit immediately, unless input is interactive.
1023 */
process_input(struct callback_data * p,FILE * in)1024 static void process_input(struct callback_data *p, FILE *in){
1025 char *zLine;
1026 char *zSql = 0;
1027 int nSql = 0;
1028 char *zErrMsg;
1029 int rc;
1030 while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
1031 if( seenInterrupt ){
1032 if( in!=0 ) break;
1033 seenInterrupt = 0;
1034 }
1035 if( p->echoOn ) printf("%s\n", zLine);
1036 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
1037 if( zLine && zLine[0]=='.' && nSql==0 ){
1038 int rc = do_meta_command(zLine, p);
1039 free(zLine);
1040 if( rc ) break;
1041 continue;
1042 }
1043 if( _is_command_terminator(zLine) ){
1044 strcpy(zLine,";");
1045 }
1046 if( zSql==0 ){
1047 int i;
1048 for(i=0; zLine[i] && isspace(zLine[i]); i++){}
1049 if( zLine[i]!=0 ){
1050 nSql = strlen(zLine);
1051 zSql = malloc( nSql+1 );
1052 strcpy(zSql, zLine);
1053 }
1054 }else{
1055 int len = strlen(zLine);
1056 zSql = realloc( zSql, nSql + len + 2 );
1057 if( zSql==0 ){
1058 fprintf(stderr,"%s: out of memory!\n", Argv0);
1059 exit(1);
1060 }
1061 strcpy(&zSql[nSql++], "\n");
1062 strcpy(&zSql[nSql], zLine);
1063 nSql += len;
1064 }
1065 free(zLine);
1066 if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite_complete(zSql) ){
1067 p->cnt = 0;
1068 open_db(p);
1069 rc = sqlite_exec(p->db, zSql, callback, p, &zErrMsg);
1070 if( rc || zErrMsg ){
1071 if( in!=0 && !p->echoOn ) printf("%s\n",zSql);
1072 if( zErrMsg!=0 ){
1073 printf("SQL error: %s\n", zErrMsg);
1074 sqlite_freemem(zErrMsg);
1075 zErrMsg = 0;
1076 }else{
1077 printf("SQL error: %s\n", sqlite_error_string(rc));
1078 }
1079 }
1080 free(zSql);
1081 zSql = 0;
1082 nSql = 0;
1083 }
1084 }
1085 if( zSql ){
1086 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
1087 free(zSql);
1088 }
1089 }
1090
1091 /*
1092 ** Return a pathname which is the user's home directory. A
1093 ** 0 return indicates an error of some kind. Space to hold the
1094 ** resulting string is obtained from malloc(). The calling
1095 ** function should free the result.
1096 */
find_home_dir(void)1097 static char *find_home_dir(void){
1098 char *home_dir = NULL;
1099
1100 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
1101 struct passwd *pwent;
1102 uid_t uid = getuid();
1103 if( (pwent=getpwuid(uid)) != NULL) {
1104 home_dir = pwent->pw_dir;
1105 }
1106 #endif
1107
1108 #ifdef __MACOS__
1109 char home_path[_MAX_PATH+1];
1110 home_dir = getcwd(home_path, _MAX_PATH);
1111 #endif
1112
1113 if (!home_dir) {
1114 home_dir = getenv("HOME");
1115 if (!home_dir) {
1116 home_dir = getenv("HOMEPATH"); /* Windows? */
1117 }
1118 }
1119
1120 #if defined(_WIN32) || defined(WIN32)
1121 if (!home_dir) {
1122 home_dir = "c:";
1123 }
1124 #endif
1125
1126 if( home_dir ){
1127 char *z = malloc( strlen(home_dir)+1 );
1128 if( z ) strcpy(z, home_dir);
1129 home_dir = z;
1130 }
1131
1132 return home_dir;
1133 }
1134
1135 /*
1136 ** Read input from the file given by sqliterc_override. Or if that
1137 ** parameter is NULL, take input from ~/.sqliterc
1138 */
process_sqliterc(struct callback_data * p,const char * sqliterc_override)1139 static void process_sqliterc(
1140 struct callback_data *p, /* Configuration data */
1141 const char *sqliterc_override /* Name of config file. NULL to use default */
1142 ){
1143 char *home_dir = NULL;
1144 const char *sqliterc = sqliterc_override;
1145 char *zBuf;
1146 FILE *in = NULL;
1147
1148 if (sqliterc == NULL) {
1149 home_dir = find_home_dir();
1150 if( home_dir==0 ){
1151 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1152 return;
1153 }
1154 zBuf = malloc(strlen(home_dir) + 15);
1155 if( zBuf==0 ){
1156 fprintf(stderr,"%s: out of memory!\n", Argv0);
1157 exit(1);
1158 }
1159 sprintf(zBuf,"%s/.sqliterc",home_dir);
1160 free(home_dir);
1161 sqliterc = (const char*)zBuf;
1162 }
1163 in = fopen(sqliterc,"rb");
1164 if( in ){
1165 if( isatty(fileno(stdout)) ){
1166 printf("Loading resources from %s\n",sqliterc);
1167 }
1168 process_input(p,in);
1169 fclose(in);
1170 }
1171 return;
1172 }
1173
1174 /*
1175 ** Show available command line options
1176 */
1177 static const char zOptions[] =
1178 " -init filename read/process named file\n"
1179 " -echo print commands before execution\n"
1180 " -[no]header turn headers on or off\n"
1181 " -column set output mode to 'column'\n"
1182 " -html set output mode to HTML\n"
1183 #ifdef SQLITE_HAS_CODEC
1184 " -key KEY encryption key\n"
1185 #endif
1186 " -line set output mode to 'line'\n"
1187 " -list set output mode to 'list'\n"
1188 " -separator 'x' set output field separator (|)\n"
1189 " -nullvalue 'text' set text string for NULL values\n"
1190 " -version show SQLite version\n"
1191 " -help show this text, also show dot-commands\n"
1192 ;
usage(int showDetail)1193 static void usage(int showDetail){
1194 fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
1195 if( showDetail ){
1196 fprintf(stderr, "Options are:\n%s", zOptions);
1197 }else{
1198 fprintf(stderr, "Use the -help option for additional information\n");
1199 }
1200 exit(1);
1201 }
1202
1203 /*
1204 ** Initialize the state information in data
1205 */
main_init(struct callback_data * data)1206 void main_init(struct callback_data *data) {
1207 memset(data, 0, sizeof(*data));
1208 data->mode = MODE_List;
1209 strcpy(data->separator,"|");
1210 data->showHeader = 0;
1211 strcpy(mainPrompt,"sqlite> ");
1212 strcpy(continuePrompt," ...> ");
1213 }
1214
main(int argc,char ** argv)1215 int main(int argc, char **argv){
1216 char *zErrMsg = 0;
1217 struct callback_data data;
1218 const char *zInitFile = 0;
1219 char *zFirstCmd = 0;
1220 int i;
1221 extern int sqliteOsFileExists(const char*);
1222
1223 sqlite_temp_directory = "/etc/svc/volatile"; /* SUNW addition */
1224
1225 #ifdef __MACOS__
1226 argc = ccommand(&argv);
1227 #endif
1228
1229 Argv0 = argv[0];
1230 main_init(&data);
1231
1232 /* Make sure we have a valid signal handler early, before anything
1233 ** else is done.
1234 */
1235 #ifdef SIGINT
1236 signal(SIGINT, interrupt_handler);
1237 #endif
1238
1239 /* Do an initial pass through the command-line argument to locate
1240 ** the name of the database file, the name of the initialization file,
1241 ** and the first command to execute.
1242 */
1243 for(i=1; i<argc-1; i++){
1244 if( argv[i][0]!='-' ) break;
1245 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1246 i++;
1247 }else if( strcmp(argv[i],"-init")==0 ){
1248 i++;
1249 zInitFile = argv[i];
1250 }else if( strcmp(argv[i],"-key")==0 ){
1251 i++;
1252 data.zKey = sqlite_mprintf("%s",argv[i]);
1253 }
1254 }
1255 if( i<argc ){
1256 data.zDbFilename = argv[i++];
1257 }else{
1258 data.zDbFilename = ":memory:";
1259 }
1260 if( i<argc ){
1261 zFirstCmd = argv[i++];
1262 }
1263 data.out = stdout;
1264
1265 /* Go ahead and open the database file if it already exists. If the
1266 ** file does not exist, delay opening it. This prevents empty database
1267 ** files from being created if a user mistypes the database name argument
1268 ** to the sqlite command-line tool.
1269 */
1270 if( sqliteOsFileExists(data.zDbFilename) ){
1271 open_db(&data);
1272 }
1273
1274 /* Process the initialization file if there is one. If no -init option
1275 ** is given on the command line, look for a file named ~/.sqliterc and
1276 ** try to process it.
1277 */
1278 process_sqliterc(&data,zInitFile);
1279
1280 /* Make a second pass through the command-line argument and set
1281 ** options. This second pass is delayed until after the initialization
1282 ** file is processed so that the command-line arguments will override
1283 ** settings in the initialization file.
1284 */
1285 for(i=1; i<argc && argv[i][0]=='-'; i++){
1286 char *z = argv[i];
1287 if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
1288 i++;
1289 }else if( strcmp(z,"-html")==0 ){
1290 data.mode = MODE_Html;
1291 }else if( strcmp(z,"-list")==0 ){
1292 data.mode = MODE_List;
1293 }else if( strcmp(z,"-line")==0 ){
1294 data.mode = MODE_Line;
1295 }else if( strcmp(z,"-column")==0 ){
1296 data.mode = MODE_Column;
1297 }else if( strcmp(z,"-separator")==0 ){
1298 i++;
1299 sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
1300 }else if( strcmp(z,"-nullvalue")==0 ){
1301 i++;
1302 sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
1303 }else if( strcmp(z,"-header")==0 ){
1304 data.showHeader = 1;
1305 }else if( strcmp(z,"-noheader")==0 ){
1306 data.showHeader = 0;
1307 }else if( strcmp(z,"-echo")==0 ){
1308 data.echoOn = 1;
1309 }else if( strcmp(z,"-version")==0 ){
1310 printf("%s\n", sqlite_version);
1311 return 1;
1312 }else if( strcmp(z,"-help")==0 ){
1313 usage(1);
1314 }else{
1315 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
1316 fprintf(stderr,"Use -help for a list of options.\n");
1317 return 1;
1318 }
1319 }
1320
1321 if( zFirstCmd ){
1322 /* Run just the command that follows the database name
1323 */
1324 if( zFirstCmd[0]=='.' ){
1325 do_meta_command(zFirstCmd, &data);
1326 exit(0);
1327 }else{
1328 int rc;
1329 open_db(&data);
1330 rc = sqlite_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
1331 if( rc!=0 && zErrMsg!=0 ){
1332 fprintf(stderr,"SQL error: %s\n", zErrMsg);
1333 exit(1);
1334 }
1335 }
1336 }else{
1337 /* Run commands received from standard input
1338 */
1339 if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
1340 char *zHome;
1341 char *zHistory = 0;
1342 printf(
1343 "SQLite version %s\n"
1344 "Enter \".help\" for instructions\n",
1345 sqlite_version
1346 );
1347 zHome = find_home_dir();
1348 if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
1349 sprintf(zHistory,"%s/.sqlite_history", zHome);
1350 }
1351 if( zHistory ) read_history(zHistory);
1352 process_input(&data, 0);
1353 if( zHistory ){
1354 stifle_history(100);
1355 write_history(zHistory);
1356 }
1357 }else{
1358 process_input(&data, stdin);
1359 }
1360 }
1361 set_table_name(&data, 0);
1362 if( db ) sqlite_close(db);
1363 return 0;
1364 }
1365