Index: ext/misc/fileio.c ================================================================== --- ext/misc/fileio.c +++ ext/misc/fileio.c @@ -356,31 +356,41 @@ } } } /* -** SQL function: filetype(MODE) +** SQL function: lsmode(MODE) ** -** Based on the integer mode, return one of "file", "directory", or "symlink". +** Given a numberic st_mode from stat(), convert it into a human-readable +** text string in the style of "ls -l". */ -static void fileTypeFunc( +static void lsModeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - const char *zMode; + int i; int iMode = sqlite3_value_int(argv[0]); + char z[16]; if( S_ISLNK(iMode) ){ - zMode = "symlink"; + z[0] = 'l'; }else if( S_ISREG(iMode) ){ - zMode = "file"; + z[0] = '-'; }else if( S_ISDIR(iMode) ){ - zMode = "directory"; + z[0] = 'd'; }else{ - zMode = "unknown"; + z[0] = '?'; + } + for(i=0; i<3; i++){ + int m = (iMode >> ((2-i)*3)); + char *a = &z[1 + i*3]; + a[0] = (m & 0x4) ? 'r' : '-'; + a[1] = (m & 0x2) ? 'w' : '-'; + a[2] = (m & 0x1) ? 'x' : '-'; } - sqlite3_result_text(context, zMode, -1, SQLITE_STATIC); + z[10] = '\0'; + sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -791,13 +801,13 @@ if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0, writefileFunc, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "fileType", 1, SQLITE_UTF8, 0, - fileTypeFunc, 0, 0); + rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0, + lsModeFunc, 0, 0); } if( rc==SQLITE_OK ){ rc = fsdirRegister(db); } return rc; } Index: src/shell.c.in ================================================================== --- src/shell.c.in +++ src/shell.c.in @@ -4854,45 +4854,18 @@ } } *pzWhere = zWhere; } -/* -** Argument zMode must point to a buffer at least 11 bytes in size. This -** function populates this buffer with the string interpretation of -** the unix file mode passed as the second argument (e.g. "drwxr-xr-x"). -*/ -static void shellModeToString(char *zMode, int mode){ - int i; - - /* Magic numbers copied from [man 2 stat] */ - if( mode & 0040000 ){ - zMode[0] = 'd'; - }else if( (mode & 0120000)==0120000 ){ - zMode[0] = 'l'; - }else{ - zMode[0] = '-'; - } - - for(i=0; i<3; i++){ - int m = (mode >> ((2-i)*3)); - char *a = &zMode[1 + i*3]; - a[0] = (m & 0x4) ? 'r' : '-'; - a[1] = (m & 0x2) ? 'w' : '-'; - a[2] = (m & 0x1) ? 'x' : '-'; - } - zMode[10] = '\0'; -} - /* ** Implementation of .ar "lisT" command. */ static int arListCommand(ArCommand *pAr){ const char *zSql = "SELECT %s FROM %s WHERE %s"; const char *azCols[] = { "name", - "mode, sz, datetime(mtime, 'unixepoch'), name" + "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" }; char *zWhere = 0; sqlite3_stmt *pSql = 0; int rc; @@ -4905,14 +4878,12 @@ if( pAr->bDryRun ){ utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql)); }else{ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( pAr->bVerbose ){ - char zMode[11]; - shellModeToString(zMode, sqlite3_column_int(pSql, 0)); - - utf8_printf(pAr->p->out, "%s % 10d %s %s\n", zMode, + utf8_printf(pAr->p->out, "%s % 10d %s %s\n", + sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1), sqlite3_column_text(pSql, 2), sqlite3_column_text(pSql, 3) ); }else{ @@ -5003,11 +4974,16 @@ int rc; if( pAr->bDryRun ){ utf8_printf(pAr->p->out, "%s\n", zSql); rc = SQLITE_OK; }else{ - rc = sqlite3_exec(pAr->db, zSql, 0, 0, 0); + char *zErr = 0; + rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); + if( zErr ){ + utf8_printf(stdout, "ERROR: %s\n", zErr); + sqlite3_free(zErr); + } } return rc; } @@ -5039,17 +5015,17 @@ "REPLACE INTO sqlar(name,mode,mtime,sz,data)\n" " SELECT\n" " %s,\n" " mode,\n" " mtime,\n" - " CASE filetype(mode)\n" - " WHEN 'file' THEN length(data)\n" - " WHEN 'directory' THEN 0\n" + " CASE substr(lsmode(mode),1,1)\n" + " WHEN '-' THEN length(data)\n" + " WHEN 'd' THEN 0\n" " ELSE -1 END,\n" - " CASE WHEN filetype(mode)<>'directory' THEN data ELSE NULL END\n" + " CASE WHEN lsmode(mode) LIKE 'd%%' THEN NULL else data END\n" " FROM fsdir(%Q,%Q)\n" - " WHERE filetype(mode)<>'unknown'"; + " WHERE lsmode(mode) NOT LIKE '?%%';"; int i; /* For iterating through azFile[] */ int rc; /* Return code */ rc = arExecSql(pAr, "SAVEPOINT ar;"); if( rc!=SQLITE_OK ) return rc;