/*
** 2016-05-05
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file implements a utility function (and a utility program) that
** makes a copy of an SQLite database while simultaneously zeroing out all
** deleted content.
**
** Normally (when PRAGMA secure_delete=OFF, which is the default) when SQLite
** deletes content, it does not overwrite the deleted content but rather marks
** the region of the file that held that content as being reusable.  This can
** cause deleted content to recoverable from the database file.  This stale
** content is removed by the VACUUM command, but VACUUM can be expensive for
** large databases.  When in PRAGMA secure_delete=ON mode, the deleted content
** is zeroed, but secure_delete=ON has overhead as well.
**
** This utility attempts to make a copy of a complete SQLite database where
** all of the deleted content is zeroed out in the copy, and it attempts to
** do so while being faster than running VACUUM.
**
** Usage:
**
**   int sqlite3_scrub_backup(
**       const char *zSourceFile,   // Source database filename
**       const char *zDestFile,     // Destination database filename
**       char **pzErrMsg            // Write error message here
**   );
**
** Simply call the API above specifying the filename of the source database
** and the name of the backup copy.  The source database must already exist
** and can be in active use. (A read lock is held during the backup.)  The
** destination file should not previously exist.  If the pzErrMsg parameter
** is non-NULL and if an error occurs, then an error message might be written
** into memory obtained from sqlite3_malloc() and *pzErrMsg made to point to
** that error message.  But if the error is an OOM, the error might not be
** reported.  The routine always returns non-zero if there is an error.
**
** If compiled with -DSCRUB_STANDALONE then a main() procedure is added and
** this file becomes a standalone program that can be run as follows:
**
**      ./sqlite3scrub SOURCE DEST
*/
#include "sqlite3.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

typedef struct ScrubState ScrubState;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;


/* State information for a scrub-and-backup operation */
struct ScrubState {
  const char *zSrcFile;    /* Name of the source file */
  const char *zDestFile;   /* Name of the destination file */
  int rcErr;               /* Error code */
  char *zErr;              /* Error message text */
  sqlite3 *dbSrc;          /* Source database connection */
  sqlite3_file *pSrc;      /* Source file handle */
  sqlite3 *dbDest;         /* Destination database connection */
  sqlite3_file *pDest;     /* Destination file handle */
  u32 szPage;              /* Page size */
  u32 szUsable;            /* Usable bytes on each page */
  u32 nPage;               /* Number of pages */
  u32 iLastPage;           /* Page number of last page written so far*/
  u8 *page1;               /* Content of page 1 */
};

/* Store an error message */
static void scrubBackupErr(ScrubState *p, const char *zFormat, ...){
  va_list ap;
  sqlite3_free(p->zErr);
  va_start(ap, zFormat);
  p->zErr = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  if( p->rcErr==0 ) p->rcErr = SQLITE_ERROR;
}

/* Allocate memory to hold a single page of content */
static u8 *scrubBackupAllocPage(ScrubState *p){
  u8 *pPage;
  if( p->rcErr ) return 0;
  pPage = sqlite3_malloc( p->szPage );
  if( pPage==0 ) p->rcErr = SQLITE_NOMEM;
  return pPage;
}

/* Read a page from the source database into memory.  Use the memory
** provided by pBuf if not NULL or allocate a new page if pBuf==NULL.
*/
static u8 *scrubBackupRead(ScrubState *p, int pgno, u8 *pBuf){
  int rc;
  sqlite3_int64 iOff;
  u8 *pOut = pBuf;
  if( p->rcErr ) return 0;
  if( pOut==0 ){
    pOut = scrubBackupAllocPage(p);
    if( pOut==0 ) return 0;
  }
  iOff = (pgno-1)*(sqlite3_int64)p->szPage;
  rc = p->pSrc->pMethods->xRead(p->pSrc, pOut, p->szPage, iOff);
  if( rc!=SQLITE_OK ){
    if( pBuf==0 ) sqlite3_free(pOut);
    pOut = 0;
    scrubBackupErr(p, "read failed for page %d", pgno);
    p->rcErr = SQLITE_IOERR;
  }
  return pOut;  
}

/* Write a page to the destination database */
static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
  int rc;
  sqlite3_int64 iOff;
  if( p->rcErr ) return;
  iOff = (pgno-1)*(sqlite3_int64)p->szPage;
  rc = p->pDest->pMethods->xWrite(p->pDest, pData, p->szPage, iOff);
  if( rc!=SQLITE_OK ){
    scrubBackupErr(p, "write failed for page %d", pgno);
    p->rcErr = SQLITE_IOERR;
  }
  if( pgno>p->iLastPage ) p->iLastPage = pgno;
}

/* Prepare a statement against the "db" database. */
static sqlite3_stmt *scrubBackupPrepare(
  ScrubState *p,      /* Backup context */
  sqlite3 *db,        /* Database to prepare against */
  const char *zSql    /* SQL statement */
){
  sqlite3_stmt *pStmt;
  if( p->rcErr ) return 0;
  p->rcErr = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( p->rcErr ){
    scrubBackupErr(p, "SQL error \"%s\" on \"%s\"",
                   sqlite3_errmsg(db), zSql);
    sqlite3_finalize(pStmt);
    return 0;
  }
  return pStmt;
}


/* Open the source database file */
static void scrubBackupOpenSrc(ScrubState *p){
  sqlite3_stmt *pStmt;
  int rc;
  /* Open the source database file */
  p->rcErr = sqlite3_open_v2(p->zSrcFile, &p->dbSrc,
                 SQLITE_OPEN_READWRITE |
                 SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0);
  if( p->rcErr ){
    scrubBackupErr(p, "cannot open source database: %s",
                      sqlite3_errmsg(p->dbSrc));
    return;
  }
  p->rcErr = sqlite3_exec(p->dbSrc, "SELECT 1 FROM sqlite_master; BEGIN;",
                          0, 0, 0);
  if( p->rcErr ){
    scrubBackupErr(p,
       "cannot start a read transaction on the source database: %s",
       sqlite3_errmsg(p->dbSrc));
    return;
  }
  rc = sqlite3_wal_checkpoint_v2(p->dbSrc, "main", SQLITE_CHECKPOINT_FULL,
                                 0, 0);
  if( rc ){
    scrubBackupErr(p, "cannot checkpoint the source database");
    return;
  }
  pStmt = scrubBackupPrepare(p, p->dbSrc, "PRAGMA page_size");
  if( pStmt==0 ) return;
  rc = sqlite3_step(pStmt);
  if( rc==SQLITE_ROW ){
    p->szPage = sqlite3_column_int(pStmt, 0);
  }else{
    scrubBackupErr(p, "unable to determine the page size");
  }
  sqlite3_finalize(pStmt);
  if( p->rcErr ) return;
  pStmt = scrubBackupPrepare(p, p->dbSrc, "PRAGMA page_count");
  if( pStmt==0 ) return;
  rc = sqlite3_step(pStmt);
  if( rc==SQLITE_ROW ){
    p->nPage = sqlite3_column_int(pStmt, 0);
  }else{
    scrubBackupErr(p, "unable to determine the size of the source database");
  }
  sqlite3_finalize(pStmt);
  sqlite3_file_control(p->dbSrc, "main", SQLITE_FCNTL_FILE_POINTER, &p->pSrc);
  if( p->pSrc==0 || p->pSrc->pMethods==0 ){
    scrubBackupErr(p, "cannot get the source file handle");
    p->rcErr = SQLITE_ERROR;
  }
}

/* Create and open the destination file */
static void scrubBackupOpenDest(ScrubState *p){
  sqlite3_stmt *pStmt;
  int rc;
  char *zSql;
  if( p->rcErr ) return;
  p->rcErr = sqlite3_open_v2(p->zDestFile, &p->dbDest,
                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
                 SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0);
  if( p->rcErr ){
    scrubBackupErr(p, "cannot open destination database: %s",
                      sqlite3_errmsg(p->dbDest));
    return;
  }
  zSql = sqlite3_mprintf("PRAGMA page_size(%u);", p->szPage);
  if( zSql==0 ){
    p->rcErr = SQLITE_NOMEM;
    return;
  }
  p->rcErr = sqlite3_exec(p->dbDest, zSql, 0, 0, 0);
  sqlite3_free(zSql);
  if( p->rcErr ){
    scrubBackupErr(p,
       "cannot set the page size on the destination database: %s",
       sqlite3_errmsg(p->dbDest));
    return;
  }
  sqlite3_exec(p->dbDest, "PRAGMA journal_mode=OFF;", 0, 0, 0);
  p->rcErr = sqlite3_exec(p->dbDest, "BEGIN EXCLUSIVE;", 0, 0, 0);
  if( p->rcErr ){
    scrubBackupErr(p,
       "cannot start a write transaction on the destination database: %s",
       sqlite3_errmsg(p->dbDest));
    return;
  }
  pStmt = scrubBackupPrepare(p, p->dbDest, "PRAGMA page_count;");
  if( pStmt==0 ) return;
  rc = sqlite3_step(pStmt);
  if( rc!=SQLITE_ROW ){
    scrubBackupErr(p, "cannot measure the size of the destination");
  }else if( sqlite3_column_int(pStmt, 0)>1 ){
    scrubBackupErr(p, "destination database is not empty - holds %d pages",
                   sqlite3_column_int(pStmt, 0));
  }
  sqlite3_finalize(pStmt);
  sqlite3_file_control(p->dbDest, "main", SQLITE_FCNTL_FILE_POINTER, &p->pDest);
  if( p->pDest==0 || p->pDest->pMethods==0 ){
    scrubBackupErr(p, "cannot get the destination file handle");
    p->rcErr = SQLITE_ERROR;
  }
}

/* Read a 32-bit big-endian integer */
static u32 scrubBackupInt32(const u8 *a){
  u32 v = a[3];
  v += ((u32)a[2])<<8;
  v += ((u32)a[1])<<16;
  v += ((u32)a[0])<<24;
  return v;
}

/* Read a 16-bit big-endian integer */
static u32 scrubBackupInt16(const u8 *a){
  return (a[0]<<8) + a[1];
}

/*
** Read a varint.  Put the value in *pVal and return the number of bytes.
*/
static int scrubBackupVarint(const u8 *z, sqlite3_int64 *pVal){
  sqlite3_int64 v = 0;
  int i;
  for(i=0; i<8; i++){
    v = (v<<7) + (z[i]&0x7f);
    if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
  }
  v = (v<<8) + (z[i]&0xff);
  *pVal = v;
  return 9;
}

/*
** Return the number of bytes in a varint.
*/
static int scrubBackupVarintSize(const u8 *z){
  int i;
  for(i=0; i<8; i++){
    if( (z[i]&0x80)==0 ){ return i+1; }
  }
  return 9;
}

/*
** Copy the freelist trunk page given, and all its descendents,
** zeroing out as much as possible in the process.
*/
static void scrubBackupFreelist(ScrubState *p, int pgno, u32 nFree){
  u8 *a, *aBuf;
  u32 n, mx;

  if( p->rcErr ) return;
  aBuf = scrubBackupAllocPage(p);
  if( aBuf==0 ) return;
 
  while( pgno && nFree){
    a = scrubBackupRead(p, pgno, aBuf);
    if( a==0 ) break;
    n = scrubBackupInt32(&a[4]);
    mx = p->szUsable/4 - 2;
    if( n<mx ){
      memset(&a[n*4+8], 0, 4*(mx-n));
    }
    scrubBackupWrite(p, pgno, a);
    pgno = scrubBackupInt32(a);
#if 0
    /* There is really no point in copying the freelist leaf pages.
    ** Simply leave them uninitialized in the destination database.  The
    ** OS filesystem should zero those pages for us automatically.
    */
    for(i=0; i<n && nFree; i++){
      u32 iLeaf = scrubBackupInt32(&a[i*4+8]);
      if( aZero==0 ){
        aZero = scrubBackupAllocPage(p);
        if( aZero==0 ){ pgno = 0; break; }
        memset(aZero, 0, p->szPage);
      }
      scrubBackupWrite(p, iLeaf, aZero);
      nFree--;
    }
#endif
  }
  sqlite3_free(aBuf);
}

/*
** Copy an overflow chain from source to destination.  Zero out any
** unused tail at the end of the overflow chain.
*/
static void scrubBackupOverflow(ScrubState *p, int pgno, u32 nByte){
  u8 *a, *aBuf;

  aBuf = scrubBackupAllocPage(p);
  if( aBuf==0 ) return;
  while( nByte>0 && pgno!=0 ){
    a = scrubBackupRead(p, pgno, aBuf);
    if( a==0 ) break;
    if( nByte >= (p->szUsable)-4 ){
      nByte -= (p->szUsable) - 4;
    }else{
      u32 x = (p->szUsable - 4) - nByte;
      u32 i = p->szUsable - x;
      memset(&a[i], 0, x);
      nByte = 0;
    }
    scrubBackupWrite(p, pgno, a);
    pgno = scrubBackupInt32(a);
  }
  sqlite3_free(aBuf);      
}
   

/*
** Copy B-Tree page pgno, and all of its children, from source to destination.
** Zero out deleted content during the copy.
*/
static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){
  u8 *a;
  u32 i, n, pc;
  u32 nCell;
  u32 nPrefix;
  u32 szHdr;
  u32 iChild;
  u8 *aTop;
  u8 *aCell;
  u32 x, y;
  int ln = 0;

  
  if( p->rcErr ) return;
  if( iDepth>50 ){
    scrubBackupErr(p, "corrupt: b-tree too deep at page %d", pgno);
    return;
  }
  if( pgno==1 ){
    a = p->page1;
  }else{
    a = scrubBackupRead(p, pgno, 0);
    if( a==0 ) return;
  }
  nPrefix = pgno==1 ? 100 : 0;
  aTop = &a[nPrefix];
  szHdr = 8 + 4*(aTop[0]==0x02 || aTop[0]==0x05);
  aCell = aTop + szHdr;
  nCell = scrubBackupInt16(&aTop[3]);

  /* Zero out the gap between the cell index and the start of the
  ** cell content area */
  x = scrubBackupInt16(&aTop[5]);  /* First byte of cell content area */
  if( x>p->szUsable ){ ln=__LINE__; goto btree_corrupt; }
  y = szHdr + nPrefix + nCell*2;
  if( y>x ){ ln=__LINE__; goto btree_corrupt; }
  if( y<x ) memset(a+y, 0, x-y);  /* Zero the gap */

  /* Zero out all the free blocks */  
  pc = scrubBackupInt16(&aTop[1]);
  if( pc>0 && pc<x ){ ln=__LINE__; goto btree_corrupt; }
  while( pc ){
    if( pc>(p->szUsable)-4 ){ ln=__LINE__; goto btree_corrupt; }
    n = scrubBackupInt16(&a[pc+2]);
    if( pc+n>(p->szUsable) ){ ln=__LINE__; goto btree_corrupt; }
    if( n>4 ) memset(&a[pc+4], 0, n-4);
    x = scrubBackupInt16(&a[pc]);
    if( x<pc+4 && x>0 ){ ln=__LINE__; goto btree_corrupt; }
    pc = x;
  }

  /* Write this one page */
  scrubBackupWrite(p, pgno, a);

  /* Walk the tree and process child pages */
  for(i=0; i<nCell; i++){
    u32 X, M, K, nLocal;
    sqlite3_int64 P;
    pc = scrubBackupInt16(&aCell[i*2]);
    if( pc <= szHdr ){ ln=__LINE__; goto btree_corrupt; }
    if( pc > p->szUsable-3 ){ ln=__LINE__; goto btree_corrupt; }
    if( aTop[0]==0x05 || aTop[0]==0x02 ){
      if( pc+4 > p->szUsable ){ ln=__LINE__; goto btree_corrupt; }
      iChild = scrubBackupInt32(&a[pc]);
      pc += 4;
      scrubBackupBtree(p, iChild, iDepth+1);
      if( aTop[0]==0x05 ) continue;
    }
    pc += scrubBackupVarint(&a[pc], &P);
    if( pc >= p->szUsable ){ ln=__LINE__; goto btree_corrupt; }
    if( aTop[0]==0x0d ){
      X = p->szUsable - 35;
    }else{
      X = ((p->szUsable - 12)*64/255) - 23;
    }
    if( P<=X ){
      /* All content is local.  No overflow */
      continue;
    }
    M = ((p->szUsable - 12)*32/255)-23;
    K = M + ((P-M)%(p->szUsable-4));
    if( aTop[0]==0x0d ){
      pc += scrubBackupVarintSize(&a[pc]);
      if( pc > (p->szUsable-4) ){ ln=__LINE__; goto btree_corrupt; }
    }
    nLocal = K<=X ? K : M;
    if( pc+nLocal > p->szUsable-4 ){ ln=__LINE__; goto btree_corrupt; }
    iChild = scrubBackupInt32(&a[pc+nLocal]);
    scrubBackupOverflow(p, iChild, P-nLocal);
  }

  /* Walk the right-most tree */
  if( aTop[0]==0x05 || aTop[0]==0x02 ){
    iChild = scrubBackupInt32(&aTop[8]);
    scrubBackupBtree(p, iChild, iDepth+1);
  }

  /* All done */
  if( pgno>1 ) sqlite3_free(a);
  return;

btree_corrupt:
  scrubBackupErr(p, "corruption on page %d of source database (errid=%d)",
                 pgno, ln);
  if( pgno>1 ) sqlite3_free(a);  
}

/*
** Copy all ptrmap pages from source to destination.
** This routine is only called if the source database is in autovacuum
** or incremental vacuum mode.
*/
static void scrubBackupPtrmap(ScrubState *p){
  u32 pgno = 2;
  u32 J = p->szUsable/5;
  u32 iLock = (1073742335/p->szPage)+1;
  u8 *a, *pBuf;
  if( p->rcErr ) return;
  pBuf = scrubBackupAllocPage(p);
  if( pBuf==0 ) return;
  while( pgno<=p->nPage ){
    a = scrubBackupRead(p, pgno, pBuf);
    if( a==0 ) break;
    scrubBackupWrite(p, pgno, a);
    pgno += J+1;
    if( pgno==iLock ) pgno++;
  }
  sqlite3_free(pBuf);
}

int sqlite3_scrub_backup(
  const char *zSrcFile,    /* Source file */
  const char *zDestFile,   /* Destination file */
  char **pzErr             /* Write error here if non-NULL */
){
  ScrubState s;
  u32 n, i;
  sqlite3_stmt *pStmt;

  memset(&s, 0, sizeof(s));
  s.zSrcFile = zSrcFile;
  s.zDestFile = zDestFile;

  /* Open both source and destination databases */
  scrubBackupOpenSrc(&s);
  scrubBackupOpenDest(&s);

  /* Read in page 1 */
  s.page1 = scrubBackupRead(&s, 1, 0);
  if( s.page1==0 ) goto scrub_abort;
  s.szUsable = s.szPage - s.page1[20];

  /* Copy the freelist */    
  n = scrubBackupInt32(&s.page1[36]);
  i = scrubBackupInt32(&s.page1[32]);
  if( n ) scrubBackupFreelist(&s, i, n);

  /* Copy ptrmap pages */
  n = scrubBackupInt32(&s.page1[52]);
  if( n ) scrubBackupPtrmap(&s);

  /* Copy all of the btrees */
  scrubBackupBtree(&s, 1, 0);
  pStmt = scrubBackupPrepare(&s, s.dbSrc,
       "SELECT rootpage FROM sqlite_master WHERE coalesce(rootpage,0)>0");
  if( pStmt==0 ) goto scrub_abort;
  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    i = (u32)sqlite3_column_int(pStmt, 0);
    scrubBackupBtree(&s, i, 0);
  }
  sqlite3_finalize(pStmt);

  /* If the last page of the input db file is a free-list leaf, then the
  ** backup file on disk is still smaller than the size indicated within 
  ** the database header. In this case, write a page of zeroes to the 
  ** last page of the backup database so that SQLite does not mistakenly
  ** think the db is corrupt.  */
  if( s.iLastPage<s.nPage ){
    u8 *aZero = scrubBackupAllocPage(&s);
    if( aZero ){
      memset(aZero, 0, s.szPage);
      scrubBackupWrite(&s, s.nPage, aZero);
      sqlite3_free(aZero);
    }
  }

scrub_abort:    
  /* Close the destination database without closing the transaction. If we
  ** commit, page zero will be overwritten. */
  sqlite3_close(s.dbDest);

  /* But do close out the read-transaction on the source database */
  sqlite3_exec(s.dbSrc, "COMMIT;", 0, 0, 0);
  sqlite3_close(s.dbSrc);
  sqlite3_free(s.page1);
  if( pzErr ){
    *pzErr = s.zErr;
  }else{
    sqlite3_free(s.zErr);
  }
  return s.rcErr;
}   

#ifdef SCRUB_STANDALONE
/* Error and warning log */
static void errorLogCallback(void *pNotUsed, int iErr, const char *zMsg){
  const char *zType;
  switch( iErr&0xff ){
    case SQLITE_WARNING: zType = "WARNING";  break;
    case SQLITE_NOTICE:  zType = "NOTICE";   break;
    default:             zType = "ERROR";    break;
  }
  fprintf(stderr, "%s: %s\n", zType, zMsg);
}

/* The main() routine when this utility is run as a stand-alone program */
int main(int argc, char **argv){
  char *zErr = 0;
  int rc;
  if( argc!=3 ){
    fprintf(stderr,"Usage: %s SOURCE DESTINATION\n", argv[0]);
    exit(1);
  }
  sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, 0);
  rc = sqlite3_scrub_backup(argv[1], argv[2], &zErr);
  if( rc==SQLITE_NOMEM ){
    fprintf(stderr, "%s: out of memory\n", argv[0]);
    exit(1);
  }
  if( zErr ){
    fprintf(stderr, "%s: %s\n", argv[0], zErr);
    sqlite3_free(zErr);
    exit(1);
  }
  return 0;
}
#endif
