xref: /titanic_52/usr/src/cmd/sqlite/shell.c (revision b6c3f7863936abeae522e48a13887dddeb691a45)
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 */
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 */
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 */
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 */
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,"&lt;");
268     }else if( z[i]=='&' ){
269       fprintf(out,"&amp;");
270     }else{
271       break;
272     }
273     z += i + 1;
274   }
275 }
276 
277 /*
278 ** This routine runs when the user presses Ctrl-C
279 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 ;
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 */
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 
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