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,"<"); 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 */ 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