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