/ Check-in [b64681a6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improve the shell tool ".ar --list --verbose" command.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sqlar-shell-support
Files: files | file ages | folders
SHA3-256: b64681a644c419bb98d00980a6cb56ef5a0aff5ef5321955631f0b4c88aac283
User & Date: dan 2017-12-27 21:13:21
Context
2017-12-29
20:19
Update ext/misc/zipfile.c to support creating and adding entries to existing zip archives. check-in: 2dec2dec user: dan tags: sqlar-shell-support
2017-12-27
21:13
Improve the shell tool ".ar --list --verbose" command. check-in: b64681a6 user: dan tags: sqlar-shell-support
18:54
Have the shell tool ".ar --list" and ".ar --extract" commands support zip files. Currently the "-zip" switch is required. check-in: a532a0f6 user: dan tags: sqlar-shell-support
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/zipfile.c.

    46     46     "f HIDDEN   /* Name of zip file */"                              \
    47     47   ");"
    48     48   
    49     49   #define ZIPFILE_F_COLUMN_IDX 6    /* Index of column "f" in the above */
    50     50   
    51     51   #define ZIPFILE_BUFFER_SIZE (64*1024)
    52     52   
           53  +
           54  +#define ZIPFILE_EXTRA_TIMESTAMP 0x5455
           55  +
    53     56   /*
    54     57   ** Set the error message contained in context ctx to the results of
    55     58   ** vprintf(zFmt, ...).
    56     59   */
    57     60   static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
    58     61     char *zMsg = 0;
    59     62     va_list ap;
................................................................................
   337    340           pCsr->cds.zFile = sqlite3_mprintf("%.*s", (int)pCsr->cds.nFile, aRead);
   338    341           pCsr->iNextOff += szFix;
   339    342           pCsr->iNextOff += pCsr->cds.nFile;
   340    343           pCsr->iNextOff += pCsr->cds.nExtra;
   341    344           pCsr->iNextOff += pCsr->cds.nComment;
   342    345         }
   343    346   
   344         -      /* Scan the "extra" fields */
          347  +      /* Scan the cds.nExtra bytes of "extra" fields for any that can
          348  +      ** be interpreted. The general format of an extra field is:
          349  +      **
          350  +      **   Header ID    2 bytes
          351  +      **   Data Size    2 bytes
          352  +      **   Data         N bytes
          353  +      **
          354  +      */
   345    355         if( rc==SQLITE_OK ){
   346    356           u8 *p = &aRead[pCsr->cds.nFile];
   347    357           u8 *pEnd = &p[pCsr->cds.nExtra];
   348    358   
   349    359           while( p<pEnd ){
   350    360             u16 id = zipfileRead16(p);
   351    361             u16 nByte = zipfileRead16(p);
   352    362   
   353    363             switch( id ){
   354         -            case 0x5455: {        /* Extended timestamp */
          364  +            case ZIPFILE_EXTRA_TIMESTAMP: {
   355    365                 u8 b = p[0];
   356    366                 if( b & 0x01 ){     /* 0x01 -> modtime is present */
   357    367                   pCsr->mTime = zipfileGetU32(&p[1]);
   358    368                   pCsr->flags |= ZIPFILE_MTIME_VALID;
   359    369                 }
   360    370                 break;
   361    371               }
   362         -
   363         -            case 0x7875:          /* Info-ZIP Unix (new) */
   364         -              break;
   365    372             }
   366    373   
   367    374             p += nByte;
   368    375           }
   369    376         }
   370    377       }
   371    378     }

Changes to src/shell.c.in.

  4572   4572           }
  4573   4573           zSep = " OR ";
  4574   4574         }
  4575   4575       }
  4576   4576     }
  4577   4577     *pzWhere = zWhere;
  4578   4578   }
         4579  +
         4580  +/*
         4581  +** Argument zMode must point to a buffer at least 11 bytes in size. This
         4582  +** function populates this buffer with the string interpretation of
         4583  +** the unix file mode passed as the second argument (e.g. "drwxr-xr-x").
         4584  +*/
         4585  +static void shellModeToString(char *zMode, int mode){
         4586  +  int i;
         4587  +
         4588  +  /* Magic numbers copied from [man 2 stat] */
         4589  +  if( mode & 0040000 ){
         4590  +    zMode[0] = 'd';
         4591  +  }else if( (mode & 0120000)==0120000 ){
         4592  +    zMode[0] = 'l';
         4593  +  }else{
         4594  +    zMode[0] = '-';
         4595  +  }
         4596  +
         4597  +  for(i=0; i<3; i++){
         4598  +    int m = (mode >> ((2-i)*3));
         4599  +    char *a = &zMode[1 + i*3];
         4600  +    a[0] = (m & 0x4) ? 'r' : '-';
         4601  +    a[1] = (m & 0x2) ? 'w' : '-';
         4602  +    a[2] = (m & 0x1) ? 'x' : '-';
         4603  +  }
         4604  +  zMode[10] = '\0';
         4605  +}
  4579   4606   
  4580   4607   /*
  4581   4608   ** Implementation of .ar "lisT" command. 
  4582   4609   */
  4583   4610   static int arListCommand(ShellState *p, sqlite3 *db, ArCommand *pAr){
  4584         -  const char *zSql = "SELECT name FROM %s WHERE %s"; 
         4611  +  const char *zSql = "SELECT %s FROM %s WHERE %s"; 
  4585   4612     const char *zTbl = (pAr->bZip ? "zipfile(?)" : "sqlar");
         4613  +  const char *azCols[] = {
         4614  +    "name",
         4615  +    "mode, sz, datetime(mtime, 'unixepoch'), name"
         4616  +  };
  4586   4617   
  4587   4618     char *zWhere = 0;
  4588   4619     sqlite3_stmt *pSql = 0;
  4589   4620     int rc;
  4590   4621   
  4591   4622     rc = arCheckEntries(db, pAr);
  4592   4623     arWhereClause(&rc, pAr, &zWhere);
  4593   4624   
  4594         -  shellPreparePrintf(db, &rc, &pSql, zSql, zTbl, zWhere);
         4625  +  shellPreparePrintf(db, &rc, &pSql, zSql, azCols[pAr->bVerbose], zTbl, zWhere);
  4595   4626     if( rc==SQLITE_OK && pAr->bZip ){
  4596   4627       sqlite3_bind_text(pSql, 1, pAr->zFile, -1, SQLITE_TRANSIENT);
  4597   4628     }
  4598   4629     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
  4599         -    raw_printf(p->out, "%s\n", sqlite3_column_text(pSql, 0));
         4630  +    if( pAr->bVerbose ){
         4631  +      char zMode[11];
         4632  +      shellModeToString(zMode, sqlite3_column_int(pSql, 0));
         4633  +
         4634  +      raw_printf(p->out, "%s % 10d  %s  %s\n", zMode,
         4635  +          sqlite3_column_int(pSql, 1), 
         4636  +          sqlite3_column_text(pSql, 2),
         4637  +          sqlite3_column_text(pSql, 3)
         4638  +      );
         4639  +    }else{
         4640  +      raw_printf(p->out, "%s\n", sqlite3_column_text(pSql, 0));
         4641  +    }
  4600   4642     }
  4601   4643   
  4602   4644     shellFinalize(&rc, pSql);
  4603   4645     return rc;
  4604   4646   }
  4605   4647   
  4606   4648