/ Hex Artifact Content
Login

Artifact 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb:


0000: 2f 2a 0a 2a 2a 20 32 30 31 36 2d 30 35 2d 30 35  /*.** 2016-05-05
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  file implements 
0190: 61 20 75 74 69 6c 69 74 79 20 66 75 6e 63 74 69  a utility functi
01a0: 6f 6e 20 28 61 6e 64 20 61 20 75 74 69 6c 69 74  on (and a utilit
01b0: 79 20 70 72 6f 67 72 61 6d 29 20 74 68 61 74 0a  y program) that.
01c0: 2a 2a 20 6d 61 6b 65 73 20 61 20 63 6f 70 79 20  ** makes a copy 
01d0: 6f 66 20 61 6e 20 53 51 4c 69 74 65 20 64 61 74  of an SQLite dat
01e0: 61 62 61 73 65 20 77 68 69 6c 65 20 73 69 6d 75  abase while simu
01f0: 6c 74 61 6e 65 6f 75 73 6c 79 20 7a 65 72 6f 69  ltaneously zeroi
0200: 6e 67 20 6f 75 74 20 61 6c 6c 0a 2a 2a 20 64 65  ng out all.** de
0210: 6c 65 74 65 64 20 63 6f 6e 74 65 6e 74 2e 0a 2a  leted content..*
0220: 2a 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c 79 20 28 77  *.** Normally (w
0230: 68 65 6e 20 50 52 41 47 4d 41 20 73 65 63 75 72  hen PRAGMA secur
0240: 65 5f 64 65 6c 65 74 65 3d 4f 46 46 2c 20 77 68  e_delete=OFF, wh
0250: 69 63 68 20 69 73 20 74 68 65 20 64 65 66 61 75  ich is the defau
0260: 6c 74 29 20 77 68 65 6e 20 53 51 4c 69 74 65 0a  lt) when SQLite.
0270: 2a 2a 20 64 65 6c 65 74 65 73 20 63 6f 6e 74 65  ** deletes conte
0280: 6e 74 2c 20 69 74 20 64 6f 65 73 20 6e 6f 74 20  nt, it does not 
0290: 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 64 65  overwrite the de
02a0: 6c 65 74 65 64 20 63 6f 6e 74 65 6e 74 20 62 75  leted content bu
02b0: 74 20 72 61 74 68 65 72 20 6d 61 72 6b 73 0a 2a  t rather marks.*
02c0: 2a 20 74 68 65 20 72 65 67 69 6f 6e 20 6f 66 20  * the region of 
02d0: 74 68 65 20 66 69 6c 65 20 74 68 61 74 20 68 65  the file that he
02e0: 6c 64 20 74 68 61 74 20 63 6f 6e 74 65 6e 74 20  ld that content 
02f0: 61 73 20 62 65 69 6e 67 20 72 65 75 73 61 62 6c  as being reusabl
0300: 65 2e 20 20 54 68 69 73 20 63 61 6e 0a 2a 2a 20  e.  This can.** 
0310: 63 61 75 73 65 20 64 65 6c 65 74 65 64 20 63 6f  cause deleted co
0320: 6e 74 65 6e 74 20 74 6f 20 72 65 63 6f 76 65 72  ntent to recover
0330: 61 62 6c 65 20 66 72 6f 6d 20 74 68 65 20 64 61  able from the da
0340: 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20 54 68  tabase file.  Th
0350: 69 73 20 73 74 61 6c 65 0a 2a 2a 20 63 6f 6e 74  is stale.** cont
0360: 65 6e 74 20 69 73 20 72 65 6d 6f 76 65 64 20 62  ent is removed b
0370: 79 20 74 68 65 20 56 41 43 55 55 4d 20 63 6f 6d  y the VACUUM com
0380: 6d 61 6e 64 2c 20 62 75 74 20 56 41 43 55 55 4d  mand, but VACUUM
0390: 20 63 61 6e 20 62 65 20 65 78 70 65 6e 73 69 76   can be expensiv
03a0: 65 20 66 6f 72 0a 2a 2a 20 6c 61 72 67 65 20 64  e for.** large d
03b0: 61 74 61 62 61 73 65 73 2e 20 20 57 68 65 6e 20  atabases.  When 
03c0: 69 6e 20 50 52 41 47 4d 41 20 73 65 63 75 72 65  in PRAGMA secure
03d0: 5f 64 65 6c 65 74 65 3d 4f 4e 20 6d 6f 64 65 2c  _delete=ON mode,
03e0: 20 74 68 65 20 64 65 6c 65 74 65 64 20 63 6f 6e   the deleted con
03f0: 74 65 6e 74 0a 2a 2a 20 69 73 20 7a 65 72 6f 65  tent.** is zeroe
0400: 64 2c 20 62 75 74 20 73 65 63 75 72 65 5f 64 65  d, but secure_de
0410: 6c 65 74 65 3d 4f 4e 20 68 61 73 20 6f 76 65 72  lete=ON has over
0420: 68 65 61 64 20 61 73 20 77 65 6c 6c 2e 0a 2a 2a  head as well..**
0430: 0a 2a 2a 20 54 68 69 73 20 75 74 69 6c 69 74 79  .** This utility
0440: 20 61 74 74 65 6d 70 74 73 20 74 6f 20 6d 61 6b   attempts to mak
0450: 65 20 61 20 63 6f 70 79 20 6f 66 20 61 20 63 6f  e a copy of a co
0460: 6d 70 6c 65 74 65 20 53 51 4c 69 74 65 20 64 61  mplete SQLite da
0470: 74 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20  tabase where.** 
0480: 61 6c 6c 20 6f 66 20 74 68 65 20 64 65 6c 65 74  all of the delet
0490: 65 64 20 63 6f 6e 74 65 6e 74 20 69 73 20 7a 65  ed content is ze
04a0: 72 6f 65 64 20 6f 75 74 20 69 6e 20 74 68 65 20  roed out in the 
04b0: 63 6f 70 79 2c 20 61 6e 64 20 69 74 20 61 74 74  copy, and it att
04c0: 65 6d 70 74 73 20 74 6f 0a 2a 2a 20 64 6f 20 73  empts to.** do s
04d0: 6f 20 77 68 69 6c 65 20 62 65 69 6e 67 20 66 61  o while being fa
04e0: 73 74 65 72 20 74 68 61 6e 20 72 75 6e 6e 69 6e  ster than runnin
04f0: 67 20 56 41 43 55 55 4d 2e 0a 2a 2a 0a 2a 2a 20  g VACUUM..**.** 
0500: 55 73 61 67 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 69  Usage:.**.**   i
0510: 6e 74 20 73 71 6c 69 74 65 33 5f 73 63 72 75 62  nt sqlite3_scrub
0520: 5f 62 61 63 6b 75 70 28 0a 2a 2a 20 20 20 20 20  _backup(.**     
0530: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
0540: 6f 75 72 63 65 46 69 6c 65 2c 20 20 20 2f 2f 20  ourceFile,   // 
0550: 53 6f 75 72 63 65 20 64 61 74 61 62 61 73 65 20  Source database 
0560: 66 69 6c 65 6e 61 6d 65 0a 2a 2a 20 20 20 20 20  filename.**     
0570: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
0580: 65 73 74 46 69 6c 65 2c 20 20 20 20 20 2f 2f 20  estFile,     // 
0590: 44 65 73 74 69 6e 61 74 69 6f 6e 20 64 61 74 61  Destination data
05a0: 62 61 73 65 20 66 69 6c 65 6e 61 6d 65 0a 2a 2a  base filename.**
05b0: 20 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70 7a         char **pz
05c0: 45 72 72 4d 73 67 20 20 20 20 20 20 20 20 20 20  ErrMsg          
05d0: 20 20 2f 2f 20 57 72 69 74 65 20 65 72 72 6f 72    // Write error
05e0: 20 6d 65 73 73 61 67 65 20 68 65 72 65 0a 2a 2a   message here.**
05f0: 20 20 20 29 3b 0a 2a 2a 0a 2a 2a 20 53 69 6d 70     );.**.** Simp
0600: 6c 79 20 63 61 6c 6c 20 74 68 65 20 41 50 49 20  ly call the API 
0610: 61 62 6f 76 65 20 73 70 65 63 69 66 79 69 6e 67  above specifying
0620: 20 74 68 65 20 66 69 6c 65 6e 61 6d 65 20 6f 66   the filename of
0630: 20 74 68 65 20 73 6f 75 72 63 65 20 64 61 74 61   the source data
0640: 62 61 73 65 0a 2a 2a 20 61 6e 64 20 74 68 65 20  base.** and the 
0650: 6e 61 6d 65 20 6f 66 20 74 68 65 20 62 61 63 6b  name of the back
0660: 75 70 20 63 6f 70 79 2e 20 20 54 68 65 20 73 6f  up copy.  The so
0670: 75 72 63 65 20 64 61 74 61 62 61 73 65 20 6d 75  urce database mu
0680: 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73 74  st already exist
0690: 0a 2a 2a 20 61 6e 64 20 63 61 6e 20 62 65 20 69  .** and can be i
06a0: 6e 20 61 63 74 69 76 65 20 75 73 65 2e 20 28 41  n active use. (A
06b0: 20 72 65 61 64 20 6c 6f 63 6b 20 69 73 20 68 65   read lock is he
06c0: 6c 64 20 64 75 72 69 6e 67 20 74 68 65 20 62 61  ld during the ba
06d0: 63 6b 75 70 2e 29 20 20 54 68 65 0a 2a 2a 20 64  ckup.)  The.** d
06e0: 65 73 74 69 6e 61 74 69 6f 6e 20 66 69 6c 65 20  estination file 
06f0: 73 68 6f 75 6c 64 20 6e 6f 74 20 70 72 65 76 69  should not previ
0700: 6f 75 73 6c 79 20 65 78 69 73 74 2e 20 20 49 66  ously exist.  If
0710: 20 74 68 65 20 70 7a 45 72 72 4d 73 67 20 70 61   the pzErrMsg pa
0720: 72 61 6d 65 74 65 72 0a 2a 2a 20 69 73 20 6e 6f  rameter.** is no
0730: 6e 2d 4e 55 4c 4c 20 61 6e 64 20 69 66 20 61 6e  n-NULL and if an
0740: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 74   error occurs, t
0750: 68 65 6e 20 61 6e 20 65 72 72 6f 72 20 6d 65 73  hen an error mes
0760: 73 61 67 65 20 6d 69 67 68 74 20 62 65 20 77 72  sage might be wr
0770: 69 74 74 65 6e 0a 2a 2a 20 69 6e 74 6f 20 6d 65  itten.** into me
0780: 6d 6f 72 79 20 6f 62 74 61 69 6e 65 64 20 66 72  mory obtained fr
0790: 6f 6d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  om sqlite3_mallo
07a0: 63 28 29 20 61 6e 64 20 2a 70 7a 45 72 72 4d 73  c() and *pzErrMs
07b0: 67 20 6d 61 64 65 20 74 6f 20 70 6f 69 6e 74 20  g made to point 
07c0: 74 6f 0a 2a 2a 20 74 68 61 74 20 65 72 72 6f 72  to.** that error
07d0: 20 6d 65 73 73 61 67 65 2e 20 20 42 75 74 20 69   message.  But i
07e0: 66 20 74 68 65 20 65 72 72 6f 72 20 69 73 20 61  f the error is a
07f0: 6e 20 4f 4f 4d 2c 20 74 68 65 20 65 72 72 6f 72  n OOM, the error
0800: 20 6d 69 67 68 74 20 6e 6f 74 20 62 65 0a 2a 2a   might not be.**
0810: 20 72 65 70 6f 72 74 65 64 2e 20 20 54 68 65 20   reported.  The 
0820: 72 6f 75 74 69 6e 65 20 61 6c 77 61 79 73 20 72  routine always r
0830: 65 74 75 72 6e 73 20 6e 6f 6e 2d 7a 65 72 6f 20  eturns non-zero 
0840: 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 65  if there is an e
0850: 72 72 6f 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 63  rror..**.** If c
0860: 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 2d 44 53  ompiled with -DS
0870: 43 52 55 42 5f 53 54 41 4e 44 41 4c 4f 4e 45 20  CRUB_STANDALONE 
0880: 74 68 65 6e 20 61 20 6d 61 69 6e 28 29 20 70 72  then a main() pr
0890: 6f 63 65 64 75 72 65 20 69 73 20 61 64 64 65 64  ocedure is added
08a0: 20 61 6e 64 0a 2a 2a 20 74 68 69 73 20 66 69 6c   and.** this fil
08b0: 65 20 62 65 63 6f 6d 65 73 20 61 20 73 74 61 6e  e becomes a stan
08c0: 64 61 6c 6f 6e 65 20 70 72 6f 67 72 61 6d 20 74  dalone program t
08d0: 68 61 74 20 63 61 6e 20 62 65 20 72 75 6e 20 61  hat can be run a
08e0: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
08f0: 20 20 20 20 20 20 2e 2f 73 71 6c 69 74 65 33 73        ./sqlite3s
0900: 63 72 75 62 20 53 4f 55 52 43 45 20 44 45 53 54  crub SOURCE DEST
0910: 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .*/.#include "sq
0920: 6c 69 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64  lite3.h".#includ
0930: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e  e <assert.h>.#in
0940: 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a  clude <stdio.h>.
0950: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0960: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0970: 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  darg.h>.#include
0980: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 0a 74 79 70   <string.h>..typ
0990: 65 64 65 66 20 73 74 72 75 63 74 20 53 63 72 75  edef struct Scru
09a0: 62 53 74 61 74 65 20 53 63 72 75 62 53 74 61 74  bState ScrubStat
09b0: 65 3b 0a 74 79 70 65 64 65 66 20 75 6e 73 69 67  e;.typedef unsig
09c0: 6e 65 64 20 63 68 61 72 20 75 38 3b 0a 74 79 70  ned char u8;.typ
09d0: 65 64 65 66 20 75 6e 73 69 67 6e 65 64 20 73 68  edef unsigned sh
09e0: 6f 72 74 20 75 31 36 3b 0a 74 79 70 65 64 65 66  ort u16;.typedef
09f0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 75 33   unsigned int u3
0a00: 32 3b 0a 0a 0a 2f 2a 20 53 74 61 74 65 20 69 6e  2;.../* State in
0a10: 66 6f 72 6d 61 74 69 6f 6e 20 66 6f 72 20 61 20  formation for a 
0a20: 73 63 72 75 62 2d 61 6e 64 2d 62 61 63 6b 75 70  scrub-and-backup
0a30: 20 6f 70 65 72 61 74 69 6f 6e 20 2a 2f 0a 73 74   operation */.st
0a40: 72 75 63 74 20 53 63 72 75 62 53 74 61 74 65 20  ruct ScrubState 
0a50: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  {.  const char *
0a60: 7a 53 72 63 46 69 6c 65 3b 20 20 20 20 2f 2a 20  zSrcFile;    /* 
0a70: 4e 61 6d 65 20 6f 66 20 74 68 65 20 73 6f 75 72  Name of the sour
0a80: 63 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e  ce file */.  con
0a90: 73 74 20 63 68 61 72 20 2a 7a 44 65 73 74 46 69  st char *zDestFi
0aa0: 6c 65 3b 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66  le;   /* Name of
0ab0: 20 74 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e   the destination
0ac0: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 72   file */.  int r
0ad0: 63 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20  cErr;           
0ae0: 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64      /* Error cod
0af0: 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 72  e */.  char *zEr
0b00: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
0b10: 2f 2a 20 45 72 72 6f 72 20 6d 65 73 73 61 67 65  /* Error message
0b20: 20 74 65 78 74 20 2a 2f 0a 20 20 73 71 6c 69 74   text */.  sqlit
0b30: 65 33 20 2a 64 62 53 72 63 3b 20 20 20 20 20 20  e3 *dbSrc;      
0b40: 20 20 20 20 2f 2a 20 53 6f 75 72 63 65 20 64 61      /* Source da
0b50: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
0b60: 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  n */.  sqlite3_f
0b70: 69 6c 65 20 2a 70 53 72 63 3b 20 20 20 20 20 20  ile *pSrc;      
0b80: 2f 2a 20 53 6f 75 72 63 65 20 66 69 6c 65 20 68  /* Source file h
0b90: 61 6e 64 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74  andle */.  sqlit
0ba0: 65 33 20 2a 64 62 44 65 73 74 3b 20 20 20 20 20  e3 *dbDest;     
0bb0: 20 20 20 20 2f 2a 20 44 65 73 74 69 6e 61 74 69      /* Destinati
0bc0: 6f 6e 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  on database conn
0bd0: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69  ection */.  sqli
0be0: 74 65 33 5f 66 69 6c 65 20 2a 70 44 65 73 74 3b  te3_file *pDest;
0bf0: 20 20 20 20 20 2f 2a 20 44 65 73 74 69 6e 61 74       /* Destinat
0c00: 69 6f 6e 20 66 69 6c 65 20 68 61 6e 64 6c 65 20  ion file handle 
0c10: 2a 2f 0a 20 20 75 33 32 20 73 7a 50 61 67 65 3b  */.  u32 szPage;
0c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c30: 20 50 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20   Page size */.  
0c40: 75 33 32 20 73 7a 55 73 61 62 6c 65 3b 20 20 20  u32 szUsable;   
0c50: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 61 62           /* Usab
0c60: 6c 65 20 62 79 74 65 73 20 6f 6e 20 65 61 63 68  le bytes on each
0c70: 20 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 6e   page */.  u32 n
0c80: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
0c90: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
0ca0: 20 70 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20   pages */.  u32 
0cb0: 69 4c 61 73 74 50 61 67 65 3b 20 20 20 20 20 20  iLastPage;      
0cc0: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
0cd0: 62 65 72 20 6f 66 20 6c 61 73 74 20 70 61 67 65  ber of last page
0ce0: 20 77 72 69 74 74 65 6e 20 73 6f 20 66 61 72 2a   written so far*
0cf0: 2f 0a 20 20 75 38 20 2a 70 61 67 65 31 3b 20 20  /.  u8 *page1;  
0d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0d10: 43 6f 6e 74 65 6e 74 20 6f 66 20 70 61 67 65 20  Content of page 
0d20: 31 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 53 74 6f 72  1 */.};../* Stor
0d30: 65 20 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 61  e an error messa
0d40: 67 65 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  ge */.static voi
0d50: 64 20 73 63 72 75 62 42 61 63 6b 75 70 45 72 72  d scrubBackupErr
0d60: 28 53 63 72 75 62 53 74 61 74 65 20 2a 70 2c 20  (ScrubState *p, 
0d70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72  const char *zFor
0d80: 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f  mat, ...){.  va_
0d90: 6c 69 73 74 20 61 70 3b 0a 20 20 73 71 6c 69 74  list ap;.  sqlit
0da0: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 45 72 72 29  e3_free(p->zErr)
0db0: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  ;.  va_start(ap,
0dc0: 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 70 2d 3e   zFormat);.  p->
0dd0: 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 76  zErr = sqlite3_v
0de0: 6d 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 2c  mprintf(zFormat,
0df0: 20 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61   ap);.  va_end(a
0e00: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 72 63 45  p);.  if( p->rcE
0e10: 72 72 3d 3d 30 20 29 20 70 2d 3e 72 63 45 72 72  rr==0 ) p->rcErr
0e20: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
0e30: 0a 7d 0a 0a 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  .}../* Allocate 
0e40: 6d 65 6d 6f 72 79 20 74 6f 20 68 6f 6c 64 20 61  memory to hold a
0e50: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 6f 66 20   single page of 
0e60: 63 6f 6e 74 65 6e 74 20 2a 2f 0a 73 74 61 74 69  content */.stati
0e70: 63 20 75 38 20 2a 73 63 72 75 62 42 61 63 6b 75  c u8 *scrubBacku
0e80: 70 41 6c 6c 6f 63 50 61 67 65 28 53 63 72 75 62  pAllocPage(Scrub
0e90: 53 74 61 74 65 20 2a 70 29 7b 0a 20 20 75 38 20  State *p){.  u8 
0ea0: 2a 70 50 61 67 65 3b 0a 20 20 69 66 28 20 70 2d  *pPage;.  if( p-
0eb0: 3e 72 63 45 72 72 20 29 20 72 65 74 75 72 6e 20  >rcErr ) return 
0ec0: 30 3b 0a 20 20 70 50 61 67 65 20 3d 20 73 71 6c  0;.  pPage = sql
0ed0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 70 2d 3e  ite3_malloc( p->
0ee0: 73 7a 50 61 67 65 20 29 3b 0a 20 20 69 66 28 20  szPage );.  if( 
0ef0: 70 50 61 67 65 3d 3d 30 20 29 20 70 2d 3e 72 63  pPage==0 ) p->rc
0f00: 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d  Err = SQLITE_NOM
0f10: 45 4d 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 61  EM;.  return pPa
0f20: 67 65 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20 61  ge;.}../* Read a
0f30: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 73   page from the s
0f40: 6f 75 72 63 65 20 64 61 74 61 62 61 73 65 20 69  ource database i
0f50: 6e 74 6f 20 6d 65 6d 6f 72 79 2e 20 20 55 73 65  nto memory.  Use
0f60: 20 74 68 65 20 6d 65 6d 6f 72 79 0a 2a 2a 20 70   the memory.** p
0f70: 72 6f 76 69 64 65 64 20 62 79 20 70 42 75 66 20  rovided by pBuf 
0f80: 69 66 20 6e 6f 74 20 4e 55 4c 4c 20 6f 72 20 61  if not NULL or a
0f90: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
0fa0: 67 65 20 69 66 20 70 42 75 66 3d 3d 4e 55 4c 4c  ge if pBuf==NULL
0fb0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 38 20 2a  ..*/.static u8 *
0fc0: 73 63 72 75 62 42 61 63 6b 75 70 52 65 61 64 28  scrubBackupRead(
0fd0: 53 63 72 75 62 53 74 61 74 65 20 2a 70 2c 20 69  ScrubState *p, i
0fe0: 6e 74 20 70 67 6e 6f 2c 20 75 38 20 2a 70 42 75  nt pgno, u8 *pBu
0ff0: 66 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  f){.  int rc;.  
1000: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f  sqlite3_int64 iO
1010: 66 66 3b 0a 20 20 75 38 20 2a 70 4f 75 74 20 3d  ff;.  u8 *pOut =
1020: 20 70 42 75 66 3b 0a 20 20 69 66 28 20 70 2d 3e   pBuf;.  if( p->
1030: 72 63 45 72 72 20 29 20 72 65 74 75 72 6e 20 30  rcErr ) return 0
1040: 3b 0a 20 20 69 66 28 20 70 4f 75 74 3d 3d 30 20  ;.  if( pOut==0 
1050: 29 7b 0a 20 20 20 20 70 4f 75 74 20 3d 20 73 63  ){.    pOut = sc
1060: 72 75 62 42 61 63 6b 75 70 41 6c 6c 6f 63 50 61  rubBackupAllocPa
1070: 67 65 28 70 29 3b 0a 20 20 20 20 69 66 28 20 70  ge(p);.    if( p
1080: 4f 75 74 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  Out==0 ) return 
1090: 30 3b 0a 20 20 7d 0a 20 20 69 4f 66 66 20 3d 20  0;.  }.  iOff = 
10a0: 28 70 67 6e 6f 2d 31 29 2a 28 73 71 6c 69 74 65  (pgno-1)*(sqlite
10b0: 33 5f 69 6e 74 36 34 29 70 2d 3e 73 7a 50 61 67  3_int64)p->szPag
10c0: 65 3b 0a 20 20 72 63 20 3d 20 70 2d 3e 70 53 72  e;.  rc = p->pSr
10d0: 63 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 52 65  c->pMethods->xRe
10e0: 61 64 28 70 2d 3e 70 53 72 63 2c 20 70 4f 75 74  ad(p->pSrc, pOut
10f0: 2c 20 70 2d 3e 73 7a 50 61 67 65 2c 20 69 4f 66  , p->szPage, iOf
1100: 66 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  f);.  if( rc!=SQ
1110: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
1120: 66 28 20 70 42 75 66 3d 3d 30 20 29 20 73 71 6c  f( pBuf==0 ) sql
1130: 69 74 65 33 5f 66 72 65 65 28 70 4f 75 74 29 3b  ite3_free(pOut);
1140: 0a 20 20 20 20 70 4f 75 74 20 3d 20 30 3b 0a 20  .    pOut = 0;. 
1150: 20 20 20 73 63 72 75 62 42 61 63 6b 75 70 45 72     scrubBackupEr
1160: 72 28 70 2c 20 22 72 65 61 64 20 66 61 69 6c 65  r(p, "read faile
1170: 64 20 66 6f 72 20 70 61 67 65 20 25 64 22 2c 20  d for page %d", 
1180: 70 67 6e 6f 29 3b 0a 20 20 20 20 70 2d 3e 72 63  pgno);.    p->rc
1190: 45 72 72 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45  Err = SQLITE_IOE
11a0: 52 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  RR;.  }.  return
11b0: 20 70 4f 75 74 3b 20 20 0a 7d 0a 0a 2f 2a 20 57   pOut;  .}../* W
11c0: 72 69 74 65 20 61 20 70 61 67 65 20 74 6f 20 74  rite a page to t
11d0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 64  he destination d
11e0: 61 74 61 62 61 73 65 20 2a 2f 0a 73 74 61 74 69  atabase */.stati
11f0: 63 20 76 6f 69 64 20 73 63 72 75 62 42 61 63 6b  c void scrubBack
1200: 75 70 57 72 69 74 65 28 53 63 72 75 62 53 74 61  upWrite(ScrubSta
1210: 74 65 20 2a 70 2c 20 69 6e 74 20 70 67 6e 6f 2c  te *p, int pgno,
1220: 20 63 6f 6e 73 74 20 75 38 20 2a 70 44 61 74 61   const u8 *pData
1230: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73  ){.  int rc;.  s
1240: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
1250: 66 3b 0a 20 20 69 66 28 20 70 2d 3e 72 63 45 72  f;.  if( p->rcEr
1260: 72 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 4f  r ) return;.  iO
1270: 66 66 20 3d 20 28 70 67 6e 6f 2d 31 29 2a 28 73  ff = (pgno-1)*(s
1280: 71 6c 69 74 65 33 5f 69 6e 74 36 34 29 70 2d 3e  qlite3_int64)p->
1290: 73 7a 50 61 67 65 3b 0a 20 20 72 63 20 3d 20 70  szPage;.  rc = p
12a0: 2d 3e 70 44 65 73 74 2d 3e 70 4d 65 74 68 6f 64  ->pDest->pMethod
12b0: 73 2d 3e 78 57 72 69 74 65 28 70 2d 3e 70 44 65  s->xWrite(p->pDe
12c0: 73 74 2c 20 70 44 61 74 61 2c 20 70 2d 3e 73 7a  st, pData, p->sz
12d0: 50 61 67 65 2c 20 69 4f 66 66 29 3b 0a 20 20 69  Page, iOff);.  i
12e0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
12f0: 20 29 7b 0a 20 20 20 20 73 63 72 75 62 42 61 63   ){.    scrubBac
1300: 6b 75 70 45 72 72 28 70 2c 20 22 77 72 69 74 65  kupErr(p, "write
1310: 20 66 61 69 6c 65 64 20 66 6f 72 20 70 61 67 65   failed for page
1320: 20 25 64 22 2c 20 70 67 6e 6f 29 3b 0a 20 20 20   %d", pgno);.   
1330: 20 70 2d 3e 72 63 45 72 72 20 3d 20 53 51 4c 49   p->rcErr = SQLI
1340: 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 20 20  TE_IOERR;.  }.  
1350: 69 66 28 20 70 67 6e 6f 3e 70 2d 3e 69 4c 61 73  if( pgno>p->iLas
1360: 74 50 61 67 65 20 29 20 70 2d 3e 69 4c 61 73 74  tPage ) p->iLast
1370: 50 61 67 65 20 3d 20 70 67 6e 6f 3b 0a 7d 0a 0a  Page = pgno;.}..
1380: 2f 2a 20 50 72 65 70 61 72 65 20 61 20 73 74 61  /* Prepare a sta
1390: 74 65 6d 65 6e 74 20 61 67 61 69 6e 73 74 20 74  tement against t
13a0: 68 65 20 22 64 62 22 20 64 61 74 61 62 61 73 65  he "db" database
13b0: 2e 20 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69  . */.static sqli
13c0: 74 65 33 5f 73 74 6d 74 20 2a 73 63 72 75 62 42  te3_stmt *scrubB
13d0: 61 63 6b 75 70 50 72 65 70 61 72 65 28 0a 20 20  ackupPrepare(.  
13e0: 53 63 72 75 62 53 74 61 74 65 20 2a 70 2c 20 20  ScrubState *p,  
13f0: 20 20 20 20 2f 2a 20 42 61 63 6b 75 70 20 63 6f      /* Backup co
1400: 6e 74 65 78 74 20 2a 2f 0a 20 20 73 71 6c 69 74  ntext */.  sqlit
1410: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 2f  e3 *db,        /
1420: 2a 20 44 61 74 61 62 61 73 65 20 74 6f 20 70 72  * Database to pr
1430: 65 70 61 72 65 20 61 67 61 69 6e 73 74 20 2a 2f  epare against */
1440: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1450: 53 71 6c 20 20 20 20 2f 2a 20 53 51 4c 20 73 74  Sql    /* SQL st
1460: 61 74 65 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20  atement */.){.  
1470: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
1480: 74 6d 74 3b 0a 20 20 69 66 28 20 70 2d 3e 72 63  tmt;.  if( p->rc
1490: 45 72 72 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  Err ) return 0;.
14a0: 20 20 70 2d 3e 72 63 45 72 72 20 3d 20 73 71 6c    p->rcErr = sql
14b0: 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28  ite3_prepare_v2(
14c0: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
14d0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69 66 28 20  Stmt, 0);.  if( 
14e0: 70 2d 3e 72 63 45 72 72 20 29 7b 0a 20 20 20 20  p->rcErr ){.    
14f0: 73 63 72 75 62 42 61 63 6b 75 70 45 72 72 28 70  scrubBackupErr(p
1500: 2c 20 22 53 51 4c 20 65 72 72 6f 72 20 5c 22 25  , "SQL error \"%
1510: 73 5c 22 20 6f 6e 20 5c 22 25 73 5c 22 22 2c 0a  s\" on \"%s\"",.
1520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1530: 20 20 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73     sqlite3_errms
1540: 67 28 64 62 29 2c 20 7a 53 71 6c 29 3b 0a 20 20  g(db), zSql);.  
1550: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
1560: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 72  ze(pStmt);.    r
1570: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 72  eturn 0;.  }.  r
1580: 65 74 75 72 6e 20 70 53 74 6d 74 3b 0a 7d 0a 0a  eturn pStmt;.}..
1590: 0a 2f 2a 20 4f 70 65 6e 20 74 68 65 20 73 6f 75  ./* Open the sou
15a0: 72 63 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  rce database fil
15b0: 65 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  e */.static void
15c0: 20 73 63 72 75 62 42 61 63 6b 75 70 4f 70 65 6e   scrubBackupOpen
15d0: 53 72 63 28 53 63 72 75 62 53 74 61 74 65 20 2a  Src(ScrubState *
15e0: 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  p){.  sqlite3_st
15f0: 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 69 6e 74  mt *pStmt;.  int
1600: 20 72 63 3b 0a 20 20 2f 2a 20 4f 70 65 6e 20 74   rc;.  /* Open t
1610: 68 65 20 73 6f 75 72 63 65 20 64 61 74 61 62 61  he source databa
1620: 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 70 2d 3e  se file */.  p->
1630: 72 63 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f  rcErr = sqlite3_
1640: 6f 70 65 6e 5f 76 32 28 70 2d 3e 7a 53 72 63 46  open_v2(p->zSrcF
1650: 69 6c 65 2c 20 26 70 2d 3e 64 62 53 72 63 2c 0a  ile, &p->dbSrc,.
1660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1670: 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41   SQLITE_OPEN_REA
1680: 44 57 52 49 54 45 20 7c 0a 20 20 20 20 20 20 20  DWRITE |.       
1690: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
16a0: 5f 4f 50 45 4e 5f 55 52 49 20 7c 20 53 51 4c 49  _OPEN_URI | SQLI
16b0: 54 45 5f 4f 50 45 4e 5f 50 52 49 56 41 54 45 43  TE_OPEN_PRIVATEC
16c0: 41 43 48 45 2c 20 30 29 3b 0a 20 20 69 66 28 20  ACHE, 0);.  if( 
16d0: 70 2d 3e 72 63 45 72 72 20 29 7b 0a 20 20 20 20  p->rcErr ){.    
16e0: 73 63 72 75 62 42 61 63 6b 75 70 45 72 72 28 70  scrubBackupErr(p
16f0: 2c 20 22 63 61 6e 6e 6f 74 20 6f 70 65 6e 20 73  , "cannot open s
1700: 6f 75 72 63 65 20 64 61 74 61 62 61 73 65 3a 20  ource database: 
1710: 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  %s",.           
1720: 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
1730: 65 33 5f 65 72 72 6d 73 67 28 70 2d 3e 64 62 53  e3_errmsg(p->dbS
1740: 72 63 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  rc));.    return
1750: 3b 0a 20 20 7d 0a 20 20 70 2d 3e 72 63 45 72 72  ;.  }.  p->rcErr
1760: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
1770: 70 2d 3e 64 62 53 72 63 2c 20 22 53 45 4c 45 43  p->dbSrc, "SELEC
1780: 54 20 31 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  T 1 FROM sqlite_
1790: 6d 61 73 74 65 72 3b 20 42 45 47 49 4e 3b 22 2c  master; BEGIN;",
17a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
17b0: 20 20 20 20 20 20 20 20 20 20 20 30 2c 20 30 2c             0, 0,
17c0: 20 30 29 3b 0a 20 20 69 66 28 20 70 2d 3e 72 63   0);.  if( p->rc
17d0: 45 72 72 20 29 7b 0a 20 20 20 20 73 63 72 75 62  Err ){.    scrub
17e0: 42 61 63 6b 75 70 45 72 72 28 70 2c 0a 20 20 20  BackupErr(p,.   
17f0: 20 20 20 20 22 63 61 6e 6e 6f 74 20 73 74 61 72      "cannot star
1800: 74 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  t a read transac
1810: 74 69 6f 6e 20 6f 6e 20 74 68 65 20 73 6f 75 72  tion on the sour
1820: 63 65 20 64 61 74 61 62 61 73 65 3a 20 25 73 22  ce database: %s"
1830: 2c 0a 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  ,.       sqlite3
1840: 5f 65 72 72 6d 73 67 28 70 2d 3e 64 62 53 72 63  _errmsg(p->dbSrc
1850: 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a  ));.    return;.
1860: 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74    }.  rc = sqlit
1870: 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e  e3_wal_checkpoin
1880: 74 5f 76 32 28 70 2d 3e 64 62 53 72 63 2c 20 22  t_v2(p->dbSrc, "
1890: 6d 61 69 6e 22 2c 20 53 51 4c 49 54 45 5f 43 48  main", SQLITE_CH
18a0: 45 43 4b 50 4f 49 4e 54 5f 46 55 4c 4c 2c 0a 20  ECKPOINT_FULL,. 
18b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18d0: 30 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63 20  0, 0);.  if( rc 
18e0: 29 7b 0a 20 20 20 20 73 63 72 75 62 42 61 63 6b  ){.    scrubBack
18f0: 75 70 45 72 72 28 70 2c 20 22 63 61 6e 6e 6f 74  upErr(p, "cannot
1900: 20 63 68 65 63 6b 70 6f 69 6e 74 20 74 68 65 20   checkpoint the 
1910: 73 6f 75 72 63 65 20 64 61 74 61 62 61 73 65 22  source database"
1920: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20  );.    return;. 
1930: 20 7d 0a 20 20 70 53 74 6d 74 20 3d 20 73 63 72   }.  pStmt = scr
1940: 75 62 42 61 63 6b 75 70 50 72 65 70 61 72 65 28  ubBackupPrepare(
1950: 70 2c 20 70 2d 3e 64 62 53 72 63 2c 20 22 50 52  p, p->dbSrc, "PR
1960: 41 47 4d 41 20 70 61 67 65 5f 73 69 7a 65 22 29  AGMA page_size")
1970: 3b 0a 20 20 69 66 28 20 70 53 74 6d 74 3d 3d 30  ;.  if( pStmt==0
1980: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 72 63 20   ) return;.  rc 
1990: 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  = sqlite3_step(p
19a0: 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 3d  Stmt);.  if( rc=
19b0: 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20  =SQLITE_ROW ){. 
19c0: 20 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 73     p->szPage = s
19d0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
19e0: 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 7d  t(pStmt, 0);.  }
19f0: 65 6c 73 65 7b 0a 20 20 20 20 73 63 72 75 62 42  else{.    scrubB
1a00: 61 63 6b 75 70 45 72 72 28 70 2c 20 22 75 6e 61  ackupErr(p, "una
1a10: 62 6c 65 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ble to determine
1a20: 20 74 68 65 20 70 61 67 65 20 73 69 7a 65 22 29   the page size")
1a30: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
1a40: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
1a50: 0a 20 20 69 66 28 20 70 2d 3e 72 63 45 72 72 20  .  if( p->rcErr 
1a60: 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 53 74 6d  ) return;.  pStm
1a70: 74 20 3d 20 73 63 72 75 62 42 61 63 6b 75 70 50  t = scrubBackupP
1a80: 72 65 70 61 72 65 28 70 2c 20 70 2d 3e 64 62 53  repare(p, p->dbS
1a90: 72 63 2c 20 22 50 52 41 47 4d 41 20 70 61 67 65  rc, "PRAGMA page
1aa0: 5f 63 6f 75 6e 74 22 29 3b 0a 20 20 69 66 28 20  _count");.  if( 
1ab0: 70 53 74 6d 74 3d 3d 30 20 29 20 72 65 74 75 72  pStmt==0 ) retur
1ac0: 6e 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  n;.  rc = sqlite
1ad0: 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b 0a 20  3_step(pStmt);. 
1ae0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1af0: 52 4f 57 20 29 7b 0a 20 20 20 20 70 2d 3e 6e 50  ROW ){.    p->nP
1b00: 61 67 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  age = sqlite3_co
1b10: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20  lumn_int(pStmt, 
1b20: 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  0);.  }else{.   
1b30: 20 73 63 72 75 62 42 61 63 6b 75 70 45 72 72 28   scrubBackupErr(
1b40: 70 2c 20 22 75 6e 61 62 6c 65 20 74 6f 20 64 65  p, "unable to de
1b50: 74 65 72 6d 69 6e 65 20 74 68 65 20 73 69 7a 65  termine the size
1b60: 20 6f 66 20 74 68 65 20 73 6f 75 72 63 65 20 64   of the source d
1b70: 61 74 61 62 61 73 65 22 29 3b 0a 20 20 7d 0a 20  atabase");.  }. 
1b80: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
1b90: 65 28 70 53 74 6d 74 29 3b 0a 20 20 73 71 6c 69  e(pStmt);.  sqli
1ba0: 74 65 33 5f 66 69 6c 65 5f 63 6f 6e 74 72 6f 6c  te3_file_control
1bb0: 28 70 2d 3e 64 62 53 72 63 2c 20 22 6d 61 69 6e  (p->dbSrc, "main
1bc0: 22 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f  ", SQLITE_FCNTL_
1bd0: 46 49 4c 45 5f 50 4f 49 4e 54 45 52 2c 20 26 70  FILE_POINTER, &p
1be0: 2d 3e 70 53 72 63 29 3b 0a 20 20 69 66 28 20 70  ->pSrc);.  if( p
1bf0: 2d 3e 70 53 72 63 3d 3d 30 20 7c 7c 20 70 2d 3e  ->pSrc==0 || p->
1c00: 70 53 72 63 2d 3e 70 4d 65 74 68 6f 64 73 3d 3d  pSrc->pMethods==
1c10: 30 20 29 7b 0a 20 20 20 20 73 63 72 75 62 42 61  0 ){.    scrubBa
1c20: 63 6b 75 70 45 72 72 28 70 2c 20 22 63 61 6e 6e  ckupErr(p, "cann
1c30: 6f 74 20 67 65 74 20 74 68 65 20 73 6f 75 72 63  ot get the sourc
1c40: 65 20 66 69 6c 65 20 68 61 6e 64 6c 65 22 29 3b  e file handle");
1c50: 0a 20 20 20 20 70 2d 3e 72 63 45 72 72 20 3d 20  .    p->rcErr = 
1c60: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
1c70: 7d 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65 20 61  }.}../* Create a
1c80: 6e 64 20 6f 70 65 6e 20 74 68 65 20 64 65 73 74  nd open the dest
1c90: 69 6e 61 74 69 6f 6e 20 66 69 6c 65 20 2a 2f 0a  ination file */.
1ca0: 73 74 61 74 69 63 20 76 6f 69 64 20 73 63 72 75  static void scru
1cb0: 62 42 61 63 6b 75 70 4f 70 65 6e 44 65 73 74 28  bBackupOpenDest(
1cc0: 53 63 72 75 62 53 74 61 74 65 20 2a 70 29 7b 0a  ScrubState *p){.
1cd0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
1ce0: 70 53 74 6d 74 3b 0a 20 20 69 6e 74 20 72 63 3b  pStmt;.  int rc;
1cf0: 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20  .  char *zSql;. 
1d00: 20 69 66 28 20 70 2d 3e 72 63 45 72 72 20 29 20   if( p->rcErr ) 
1d10: 72 65 74 75 72 6e 3b 0a 20 20 70 2d 3e 72 63 45  return;.  p->rcE
1d20: 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6f 70 65  rr = sqlite3_ope
1d30: 6e 5f 76 32 28 70 2d 3e 7a 44 65 73 74 46 69 6c  n_v2(p->zDestFil
1d40: 65 2c 20 26 70 2d 3e 64 62 44 65 73 74 2c 0a 20  e, &p->dbDest,. 
1d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d60: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44  SQLITE_OPEN_READ
1d70: 57 52 49 54 45 20 7c 20 53 51 4c 49 54 45 5f 4f  WRITE | SQLITE_O
1d80: 50 45 4e 5f 43 52 45 41 54 45 20 7c 0a 20 20 20  PEN_CREATE |.   
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
1da0: 4c 49 54 45 5f 4f 50 45 4e 5f 55 52 49 20 7c 20  LITE_OPEN_URI | 
1db0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 50 52 49 56  SQLITE_OPEN_PRIV
1dc0: 41 54 45 43 41 43 48 45 2c 20 30 29 3b 0a 20 20  ATECACHE, 0);.  
1dd0: 69 66 28 20 70 2d 3e 72 63 45 72 72 20 29 7b 0a  if( p->rcErr ){.
1de0: 20 20 20 20 73 63 72 75 62 42 61 63 6b 75 70 45      scrubBackupE
1df0: 72 72 28 70 2c 20 22 63 61 6e 6e 6f 74 20 6f 70  rr(p, "cannot op
1e00: 65 6e 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 64  en destination d
1e10: 61 74 61 62 61 73 65 3a 20 25 73 22 2c 0a 20 20  atabase: %s",.  
1e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e30: 20 20 20 20 73 71 6c 69 74 65 33 5f 65 72 72 6d      sqlite3_errm
1e40: 73 67 28 70 2d 3e 64 62 44 65 73 74 29 29 3b 0a  sg(p->dbDest));.
1e50: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
1e60: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
1e70: 5f 6d 70 72 69 6e 74 66 28 22 50 52 41 47 4d 41  _mprintf("PRAGMA
1e80: 20 70 61 67 65 5f 73 69 7a 65 28 25 75 29 3b 22   page_size(%u);"
1e90: 2c 20 70 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20  , p->szPage);.  
1ea0: 69 66 28 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20  if( zSql==0 ){. 
1eb0: 20 20 20 70 2d 3e 72 63 45 72 72 20 3d 20 53 51     p->rcErr = SQ
1ec0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
1ed0: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 70 2d  return;.  }.  p-
1ee0: 3e 72 63 45 72 72 20 3d 20 73 71 6c 69 74 65 33  >rcErr = sqlite3
1ef0: 5f 65 78 65 63 28 70 2d 3e 64 62 44 65 73 74 2c  _exec(p->dbDest,
1f00: 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b   zSql, 0, 0, 0);
1f10: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
1f20: 7a 53 71 6c 29 3b 0a 20 20 69 66 28 20 70 2d 3e  zSql);.  if( p->
1f30: 72 63 45 72 72 20 29 7b 0a 20 20 20 20 73 63 72  rcErr ){.    scr
1f40: 75 62 42 61 63 6b 75 70 45 72 72 28 70 2c 0a 20  ubBackupErr(p,. 
1f50: 20 20 20 20 20 20 22 63 61 6e 6e 6f 74 20 73 65        "cannot se
1f60: 74 20 74 68 65 20 70 61 67 65 20 73 69 7a 65 20  t the page size 
1f70: 6f 6e 20 74 68 65 20 64 65 73 74 69 6e 61 74 69  on the destinati
1f80: 6f 6e 20 64 61 74 61 62 61 73 65 3a 20 25 73 22  on database: %s"
1f90: 2c 0a 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  ,.       sqlite3
1fa0: 5f 65 72 72 6d 73 67 28 70 2d 3e 64 62 44 65 73  _errmsg(p->dbDes
1fb0: 74 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b  t));.    return;
1fc0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 65  .  }.  sqlite3_e
1fd0: 78 65 63 28 70 2d 3e 64 62 44 65 73 74 2c 20 22  xec(p->dbDest, "
1fe0: 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d  PRAGMA journal_m
1ff0: 6f 64 65 3d 4f 46 46 3b 22 2c 20 30 2c 20 30 2c  ode=OFF;", 0, 0,
2000: 20 30 29 3b 0a 20 20 70 2d 3e 72 63 45 72 72 20   0);.  p->rcErr 
2010: 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  = sqlite3_exec(p
2020: 2d 3e 64 62 44 65 73 74 2c 20 22 42 45 47 49 4e  ->dbDest, "BEGIN
2030: 20 45 58 43 4c 55 53 49 56 45 3b 22 2c 20 30 2c   EXCLUSIVE;", 0,
2040: 20 30 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 2d   0, 0);.  if( p-
2050: 3e 72 63 45 72 72 20 29 7b 0a 20 20 20 20 73 63  >rcErr ){.    sc
2060: 72 75 62 42 61 63 6b 75 70 45 72 72 28 70 2c 0a  rubBackupErr(p,.
2070: 20 20 20 20 20 20 20 22 63 61 6e 6e 6f 74 20 73         "cannot s
2080: 74 61 72 74 20 61 20 77 72 69 74 65 20 74 72 61  tart a write tra
2090: 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20  nsaction on the 
20a0: 64 65 73 74 69 6e 61 74 69 6f 6e 20 64 61 74 61  destination data
20b0: 62 61 73 65 3a 20 25 73 22 2c 0a 20 20 20 20 20  base: %s",.     
20c0: 20 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67    sqlite3_errmsg
20d0: 28 70 2d 3e 64 62 44 65 73 74 29 29 3b 0a 20 20  (p->dbDest));.  
20e0: 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20    return;.  }.  
20f0: 70 53 74 6d 74 20 3d 20 73 63 72 75 62 42 61 63  pStmt = scrubBac
2100: 6b 75 70 50 72 65 70 61 72 65 28 70 2c 20 70 2d  kupPrepare(p, p-
2110: 3e 64 62 44 65 73 74 2c 20 22 50 52 41 47 4d 41  >dbDest, "PRAGMA
2120: 20 70 61 67 65 5f 63 6f 75 6e 74 3b 22 29 3b 0a   page_count;");.
2130: 20 20 69 66 28 20 70 53 74 6d 74 3d 3d 30 20 29    if( pStmt==0 )
2140: 20 72 65 74 75 72 6e 3b 0a 20 20 72 63 20 3d 20   return;.  rc = 
2150: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74  sqlite3_step(pSt
2160: 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  mt);.  if( rc!=S
2170: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
2180: 20 73 63 72 75 62 42 61 63 6b 75 70 45 72 72 28   scrubBackupErr(
2190: 70 2c 20 22 63 61 6e 6e 6f 74 20 6d 65 61 73 75  p, "cannot measu
21a0: 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74  re the size of t
21b0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 22 29  he destination")
21c0: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 73 71  ;.  }else if( sq
21d0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
21e0: 28 70 53 74 6d 74 2c 20 30 29 3e 31 20 29 7b 0a  (pStmt, 0)>1 ){.
21f0: 20 20 20 20 73 63 72 75 62 42 61 63 6b 75 70 45      scrubBackupE
2200: 72 72 28 70 2c 20 22 64 65 73 74 69 6e 61 74 69  rr(p, "destinati
2210: 6f 6e 20 64 61 74 61 62 61 73 65 20 69 73 20 6e  on database is n
2220: 6f 74 20 65 6d 70 74 79 20 2d 20 68 6f 6c 64 73  ot empty - holds
2230: 20 25 64 20 70 61 67 65 73 22 2c 0a 20 20 20 20   %d pages",.    
2240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
2250: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
2260: 74 28 70 53 74 6d 74 2c 20 30 29 29 3b 0a 20 20  t(pStmt, 0));.  
2270: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  }.  sqlite3_fina
2280: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 73  lize(pStmt);.  s
2290: 71 6c 69 74 65 33 5f 66 69 6c 65 5f 63 6f 6e 74  qlite3_file_cont
22a0: 72 6f 6c 28 70 2d 3e 64 62 44 65 73 74 2c 20 22  rol(p->dbDest, "
22b0: 6d 61 69 6e 22 2c 20 53 51 4c 49 54 45 5f 46 43  main", SQLITE_FC
22c0: 4e 54 4c 5f 46 49 4c 45 5f 50 4f 49 4e 54 45 52  NTL_FILE_POINTER
22d0: 2c 20 26 70 2d 3e 70 44 65 73 74 29 3b 0a 20 20  , &p->pDest);.  
22e0: 69 66 28 20 70 2d 3e 70 44 65 73 74 3d 3d 30 20  if( p->pDest==0 
22f0: 7c 7c 20 70 2d 3e 70 44 65 73 74 2d 3e 70 4d 65  || p->pDest->pMe
2300: 74 68 6f 64 73 3d 3d 30 20 29 7b 0a 20 20 20 20  thods==0 ){.    
2310: 73 63 72 75 62 42 61 63 6b 75 70 45 72 72 28 70  scrubBackupErr(p
2320: 2c 20 22 63 61 6e 6e 6f 74 20 67 65 74 20 74 68  , "cannot get th
2330: 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 66 69  e destination fi
2340: 6c 65 20 68 61 6e 64 6c 65 22 29 3b 0a 20 20 20  le handle");.   
2350: 20 70 2d 3e 72 63 45 72 72 20 3d 20 53 51 4c 49   p->rcErr = SQLI
2360: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 7d 0a  TE_ERROR;.  }.}.
2370: 0a 2f 2a 20 52 65 61 64 20 61 20 33 32 2d 62 69  ./* Read a 32-bi
2380: 74 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74  t big-endian int
2390: 65 67 65 72 20 2a 2f 0a 73 74 61 74 69 63 20 75  eger */.static u
23a0: 33 32 20 73 63 72 75 62 42 61 63 6b 75 70 49 6e  32 scrubBackupIn
23b0: 74 33 32 28 63 6f 6e 73 74 20 75 38 20 2a 61 29  t32(const u8 *a)
23c0: 7b 0a 20 20 75 33 32 20 76 20 3d 20 61 5b 33 5d  {.  u32 v = a[3]
23d0: 3b 0a 20 20 76 20 2b 3d 20 28 28 75 33 32 29 61  ;.  v += ((u32)a
23e0: 5b 32 5d 29 3c 3c 38 3b 0a 20 20 76 20 2b 3d 20  [2])<<8;.  v += 
23f0: 28 28 75 33 32 29 61 5b 31 5d 29 3c 3c 31 36 3b  ((u32)a[1])<<16;
2400: 0a 20 20 76 20 2b 3d 20 28 28 75 33 32 29 61 5b  .  v += ((u32)a[
2410: 30 5d 29 3c 3c 32 34 3b 0a 20 20 72 65 74 75 72  0])<<24;.  retur
2420: 6e 20 76 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20  n v;.}../* Read 
2430: 61 20 31 36 2d 62 69 74 20 62 69 67 2d 65 6e 64  a 16-bit big-end
2440: 69 61 6e 20 69 6e 74 65 67 65 72 20 2a 2f 0a 73  ian integer */.s
2450: 74 61 74 69 63 20 75 33 32 20 73 63 72 75 62 42  tatic u32 scrubB
2460: 61 63 6b 75 70 49 6e 74 31 36 28 63 6f 6e 73 74  ackupInt16(const
2470: 20 75 38 20 2a 61 29 7b 0a 20 20 72 65 74 75 72   u8 *a){.  retur
2480: 6e 20 28 61 5b 30 5d 3c 3c 38 29 20 2b 20 61 5b  n (a[0]<<8) + a[
2490: 31 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  1];.}../*.** Rea
24a0: 64 20 61 20 76 61 72 69 6e 74 2e 20 20 50 75 74  d a varint.  Put
24b0: 20 74 68 65 20 76 61 6c 75 65 20 69 6e 20 2a 70   the value in *p
24c0: 56 61 6c 20 61 6e 64 20 72 65 74 75 72 6e 20 74  Val and return t
24d0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
24e0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
24f0: 74 20 73 63 72 75 62 42 61 63 6b 75 70 56 61 72  t scrubBackupVar
2500: 69 6e 74 28 63 6f 6e 73 74 20 75 38 20 2a 7a 2c  int(const u8 *z,
2510: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a   sqlite3_int64 *
2520: 70 56 61 6c 29 7b 0a 20 20 73 71 6c 69 74 65 33  pVal){.  sqlite3
2530: 5f 69 6e 74 36 34 20 76 20 3d 20 30 3b 0a 20 20  _int64 v = 0;.  
2540: 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30  int i;.  for(i=0
2550: 3b 20 69 3c 38 3b 20 69 2b 2b 29 7b 0a 20 20 20  ; i<8; i++){.   
2560: 20 76 20 3d 20 28 76 3c 3c 37 29 20 2b 20 28 7a   v = (v<<7) + (z
2570: 5b 69 5d 26 30 78 37 66 29 3b 0a 20 20 20 20 69  [i]&0x7f);.    i
2580: 66 28 20 28 7a 5b 69 5d 26 30 78 38 30 29 3d 3d  f( (z[i]&0x80)==
2590: 30 20 29 7b 20 2a 70 56 61 6c 20 3d 20 76 3b 20  0 ){ *pVal = v; 
25a0: 72 65 74 75 72 6e 20 69 2b 31 3b 20 7d 0a 20 20  return i+1; }.  
25b0: 7d 0a 20 20 76 20 3d 20 28 76 3c 3c 38 29 20 2b  }.  v = (v<<8) +
25c0: 20 28 7a 5b 69 5d 26 30 78 66 66 29 3b 0a 20 20   (z[i]&0xff);.  
25d0: 2a 70 56 61 6c 20 3d 20 76 3b 0a 20 20 72 65 74  *pVal = v;.  ret
25e0: 75 72 6e 20 39 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 9;.}../*.** 
25f0: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
2600: 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 61 20  r of bytes in a 
2610: 76 61 72 69 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  varint..*/.stati
2620: 63 20 69 6e 74 20 73 63 72 75 62 42 61 63 6b 75  c int scrubBacku
2630: 70 56 61 72 69 6e 74 53 69 7a 65 28 63 6f 6e 73  pVarintSize(cons
2640: 74 20 75 38 20 2a 7a 29 7b 0a 20 20 69 6e 74 20  t u8 *z){.  int 
2650: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
2660: 38 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  8; i++){.    if(
2670: 20 28 7a 5b 69 5d 26 30 78 38 30 29 3d 3d 30 20   (z[i]&0x80)==0 
2680: 29 7b 20 72 65 74 75 72 6e 20 69 2b 31 3b 20 7d  ){ return i+1; }
2690: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 39 3b  .  }.  return 9;
26a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 74  .}../*.** Copy t
26b0: 68 65 20 66 72 65 65 6c 69 73 74 20 74 72 75 6e  he freelist trun
26c0: 6b 20 70 61 67 65 20 67 69 76 65 6e 2c 20 61 6e  k page given, an
26d0: 64 20 61 6c 6c 20 69 74 73 20 64 65 73 63 65 6e  d all its descen
26e0: 64 65 6e 74 73 2c 0a 2a 2a 20 7a 65 72 6f 69 6e  dents,.** zeroin
26f0: 67 20 6f 75 74 20 61 73 20 6d 75 63 68 20 61 73  g out as much as
2700: 20 70 6f 73 73 69 62 6c 65 20 69 6e 20 74 68 65   possible in the
2710: 20 70 72 6f 63 65 73 73 2e 0a 2a 2f 0a 73 74 61   process..*/.sta
2720: 74 69 63 20 76 6f 69 64 20 73 63 72 75 62 42 61  tic void scrubBa
2730: 63 6b 75 70 46 72 65 65 6c 69 73 74 28 53 63 72  ckupFreelist(Scr
2740: 75 62 53 74 61 74 65 20 2a 70 2c 20 69 6e 74 20  ubState *p, int 
2750: 70 67 6e 6f 2c 20 75 33 32 20 6e 46 72 65 65 29  pgno, u32 nFree)
2760: 7b 0a 20 20 75 38 20 2a 61 2c 20 2a 61 42 75 66  {.  u8 *a, *aBuf
2770: 3b 0a 20 20 75 33 32 20 6e 2c 20 6d 78 3b 0a 0a  ;.  u32 n, mx;..
2780: 20 20 69 66 28 20 70 2d 3e 72 63 45 72 72 20 29    if( p->rcErr )
2790: 20 72 65 74 75 72 6e 3b 0a 20 20 61 42 75 66 20   return;.  aBuf 
27a0: 3d 20 73 63 72 75 62 42 61 63 6b 75 70 41 6c 6c  = scrubBackupAll
27b0: 6f 63 50 61 67 65 28 70 29 3b 0a 20 20 69 66 28  ocPage(p);.  if(
27c0: 20 61 42 75 66 3d 3d 30 20 29 20 72 65 74 75 72   aBuf==0 ) retur
27d0: 6e 3b 0a 20 0a 20 20 77 68 69 6c 65 28 20 70 67  n;. .  while( pg
27e0: 6e 6f 20 26 26 20 6e 46 72 65 65 29 7b 0a 20 20  no && nFree){.  
27f0: 20 20 61 20 3d 20 73 63 72 75 62 42 61 63 6b 75    a = scrubBacku
2800: 70 52 65 61 64 28 70 2c 20 70 67 6e 6f 2c 20 61  pRead(p, pgno, a
2810: 42 75 66 29 3b 0a 20 20 20 20 69 66 28 20 61 3d  Buf);.    if( a=
2820: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =0 ) break;.    
2830: 6e 20 3d 20 73 63 72 75 62 42 61 63 6b 75 70 49  n = scrubBackupI
2840: 6e 74 33 32 28 26 61 5b 34 5d 29 3b 0a 20 20 20  nt32(&a[4]);.   
2850: 20 6d 78 20 3d 20 70 2d 3e 73 7a 55 73 61 62 6c   mx = p->szUsabl
2860: 65 2f 34 20 2d 20 32 3b 0a 20 20 20 20 69 66 28  e/4 - 2;.    if(
2870: 20 6e 3c 6d 78 20 29 7b 0a 20 20 20 20 20 20 6d   n<mx ){.      m
2880: 65 6d 73 65 74 28 26 61 5b 6e 2a 34 2b 38 5d 2c  emset(&a[n*4+8],
2890: 20 30 2c 20 34 2a 28 6d 78 2d 6e 29 29 3b 0a 20   0, 4*(mx-n));. 
28a0: 20 20 20 7d 0a 20 20 20 20 73 63 72 75 62 42 61     }.    scrubBa
28b0: 63 6b 75 70 57 72 69 74 65 28 70 2c 20 70 67 6e  ckupWrite(p, pgn
28c0: 6f 2c 20 61 29 3b 0a 20 20 20 20 70 67 6e 6f 20  o, a);.    pgno 
28d0: 3d 20 73 63 72 75 62 42 61 63 6b 75 70 49 6e 74  = scrubBackupInt
28e0: 33 32 28 61 29 3b 0a 23 69 66 20 30 0a 20 20 20  32(a);.#if 0.   
28f0: 20 2f 2a 20 54 68 65 72 65 20 69 73 20 72 65 61   /* There is rea
2900: 6c 6c 79 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20  lly no point in 
2910: 63 6f 70 79 69 6e 67 20 74 68 65 20 66 72 65 65  copying the free
2920: 6c 69 73 74 20 6c 65 61 66 20 70 61 67 65 73 2e  list leaf pages.
2930: 0a 20 20 20 20 2a 2a 20 53 69 6d 70 6c 79 20 6c  .    ** Simply l
2940: 65 61 76 65 20 74 68 65 6d 20 75 6e 69 6e 69 74  eave them uninit
2950: 69 61 6c 69 7a 65 64 20 69 6e 20 74 68 65 20 64  ialized in the d
2960: 65 73 74 69 6e 61 74 69 6f 6e 20 64 61 74 61 62  estination datab
2970: 61 73 65 2e 20 20 54 68 65 0a 20 20 20 20 2a 2a  ase.  The.    **
2980: 20 4f 53 20 66 69 6c 65 73 79 73 74 65 6d 20 73   OS filesystem s
2990: 68 6f 75 6c 64 20 7a 65 72 6f 20 74 68 6f 73 65  hould zero those
29a0: 20 70 61 67 65 73 20 66 6f 72 20 75 73 20 61 75   pages for us au
29b0: 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 20 20 20  tomatically..   
29c0: 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   */.    for(i=0;
29d0: 20 69 3c 6e 20 26 26 20 6e 46 72 65 65 3b 20 69   i<n && nFree; i
29e0: 2b 2b 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69  ++){.      u32 i
29f0: 4c 65 61 66 20 3d 20 73 63 72 75 62 42 61 63 6b  Leaf = scrubBack
2a00: 75 70 49 6e 74 33 32 28 26 61 5b 69 2a 34 2b 38  upInt32(&a[i*4+8
2a10: 5d 29 3b 0a 20 20 20 20 20 20 69 66 28 20 61 5a  ]);.      if( aZ
2a20: 65 72 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ero==0 ){.      
2a30: 20 20 61 5a 65 72 6f 20 3d 20 73 63 72 75 62 42    aZero = scrubB
2a40: 61 63 6b 75 70 41 6c 6c 6f 63 50 61 67 65 28 70  ackupAllocPage(p
2a50: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61  );.        if( a
2a60: 5a 65 72 6f 3d 3d 30 20 29 7b 20 70 67 6e 6f 20  Zero==0 ){ pgno 
2a70: 3d 20 30 3b 20 62 72 65 61 6b 3b 20 7d 0a 20 20  = 0; break; }.  
2a80: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61 5a 65        memset(aZe
2a90: 72 6f 2c 20 30 2c 20 70 2d 3e 73 7a 50 61 67 65  ro, 0, p->szPage
2aa0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
2ab0: 20 73 63 72 75 62 42 61 63 6b 75 70 57 72 69 74   scrubBackupWrit
2ac0: 65 28 70 2c 20 69 4c 65 61 66 2c 20 61 5a 65 72  e(p, iLeaf, aZer
2ad0: 6f 29 3b 0a 20 20 20 20 20 20 6e 46 72 65 65 2d  o);.      nFree-
2ae0: 2d 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a  -;.    }.#endif.
2af0: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72    }.  sqlite3_fr
2b00: 65 65 28 61 42 75 66 29 3b 0a 7d 0a 0a 2f 2a 0a  ee(aBuf);.}../*.
2b10: 2a 2a 20 43 6f 70 79 20 61 6e 20 6f 76 65 72 66  ** Copy an overf
2b20: 6c 6f 77 20 63 68 61 69 6e 20 66 72 6f 6d 20 73  low chain from s
2b30: 6f 75 72 63 65 20 74 6f 20 64 65 73 74 69 6e 61  ource to destina
2b40: 74 69 6f 6e 2e 20 20 5a 65 72 6f 20 6f 75 74 20  tion.  Zero out 
2b50: 61 6e 79 0a 2a 2a 20 75 6e 75 73 65 64 20 74 61  any.** unused ta
2b60: 69 6c 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  il at the end of
2b70: 20 74 68 65 20 6f 76 65 72 66 6c 6f 77 20 63 68   the overflow ch
2b80: 61 69 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ain..*/.static v
2b90: 6f 69 64 20 73 63 72 75 62 42 61 63 6b 75 70 4f  oid scrubBackupO
2ba0: 76 65 72 66 6c 6f 77 28 53 63 72 75 62 53 74 61  verflow(ScrubSta
2bb0: 74 65 20 2a 70 2c 20 69 6e 74 20 70 67 6e 6f 2c  te *p, int pgno,
2bc0: 20 75 33 32 20 6e 42 79 74 65 29 7b 0a 20 20 75   u32 nByte){.  u
2bd0: 38 20 2a 61 2c 20 2a 61 42 75 66 3b 0a 0a 20 20  8 *a, *aBuf;..  
2be0: 61 42 75 66 20 3d 20 73 63 72 75 62 42 61 63 6b  aBuf = scrubBack
2bf0: 75 70 41 6c 6c 6f 63 50 61 67 65 28 70 29 3b 0a  upAllocPage(p);.
2c00: 20 20 69 66 28 20 61 42 75 66 3d 3d 30 20 29 20    if( aBuf==0 ) 
2c10: 72 65 74 75 72 6e 3b 0a 20 20 77 68 69 6c 65 28  return;.  while(
2c20: 20 6e 42 79 74 65 3e 30 20 26 26 20 70 67 6e 6f   nByte>0 && pgno
2c30: 21 3d 30 20 29 7b 0a 20 20 20 20 61 20 3d 20 73  !=0 ){.    a = s
2c40: 63 72 75 62 42 61 63 6b 75 70 52 65 61 64 28 70  crubBackupRead(p
2c50: 2c 20 70 67 6e 6f 2c 20 61 42 75 66 29 3b 0a 20  , pgno, aBuf);. 
2c60: 20 20 20 69 66 28 20 61 3d 3d 30 20 29 20 62 72     if( a==0 ) br
2c70: 65 61 6b 3b 0a 20 20 20 20 69 66 28 20 6e 42 79  eak;.    if( nBy
2c80: 74 65 20 3e 3d 20 28 70 2d 3e 73 7a 55 73 61 62  te >= (p->szUsab
2c90: 6c 65 29 2d 34 20 29 7b 0a 20 20 20 20 20 20 6e  le)-4 ){.      n
2ca0: 42 79 74 65 20 2d 3d 20 28 70 2d 3e 73 7a 55 73  Byte -= (p->szUs
2cb0: 61 62 6c 65 29 20 2d 20 34 3b 0a 20 20 20 20 7d  able) - 4;.    }
2cc0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 75 33 32 20  else{.      u32 
2cd0: 78 20 3d 20 28 70 2d 3e 73 7a 55 73 61 62 6c 65  x = (p->szUsable
2ce0: 20 2d 20 34 29 20 2d 20 6e 42 79 74 65 3b 0a 20   - 4) - nByte;. 
2cf0: 20 20 20 20 20 75 33 32 20 69 20 3d 20 70 2d 3e       u32 i = p->
2d00: 73 7a 55 73 61 62 6c 65 20 2d 20 78 3b 0a 20 20  szUsable - x;.  
2d10: 20 20 20 20 6d 65 6d 73 65 74 28 26 61 5b 69 5d      memset(&a[i]
2d20: 2c 20 30 2c 20 78 29 3b 0a 20 20 20 20 20 20 6e  , 0, x);.      n
2d30: 42 79 74 65 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Byte = 0;.    }.
2d40: 20 20 20 20 73 63 72 75 62 42 61 63 6b 75 70 57      scrubBackupW
2d50: 72 69 74 65 28 70 2c 20 70 67 6e 6f 2c 20 61 29  rite(p, pgno, a)
2d60: 3b 0a 20 20 20 20 70 67 6e 6f 20 3d 20 73 63 72  ;.    pgno = scr
2d70: 75 62 42 61 63 6b 75 70 49 6e 74 33 32 28 61 29  ubBackupInt32(a)
2d80: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
2d90: 66 72 65 65 28 61 42 75 66 29 3b 20 20 20 20 20  free(aBuf);     
2da0: 20 0a 7d 0a 20 20 20 0a 0a 2f 2a 0a 2a 2a 20 43   .}.   ../*.** C
2db0: 6f 70 79 20 42 2d 54 72 65 65 20 70 61 67 65 20  opy B-Tree page 
2dc0: 70 67 6e 6f 2c 20 61 6e 64 20 61 6c 6c 20 6f 66  pgno, and all of
2dd0: 20 69 74 73 20 63 68 69 6c 64 72 65 6e 2c 20 66   its children, f
2de0: 72 6f 6d 20 73 6f 75 72 63 65 20 74 6f 20 64 65  rom source to de
2df0: 73 74 69 6e 61 74 69 6f 6e 2e 0a 2a 2a 20 5a 65  stination..** Ze
2e00: 72 6f 20 6f 75 74 20 64 65 6c 65 74 65 64 20 63  ro out deleted c
2e10: 6f 6e 74 65 6e 74 20 64 75 72 69 6e 67 20 74 68  ontent during th
2e20: 65 20 63 6f 70 79 2e 0a 2a 2f 0a 73 74 61 74 69  e copy..*/.stati
2e30: 63 20 76 6f 69 64 20 73 63 72 75 62 42 61 63 6b  c void scrubBack
2e40: 75 70 42 74 72 65 65 28 53 63 72 75 62 53 74 61  upBtree(ScrubSta
2e50: 74 65 20 2a 70 2c 20 69 6e 74 20 70 67 6e 6f 2c  te *p, int pgno,
2e60: 20 69 6e 74 20 69 44 65 70 74 68 29 7b 0a 20 20   int iDepth){.  
2e70: 75 38 20 2a 61 3b 0a 20 20 75 33 32 20 69 2c 20  u8 *a;.  u32 i, 
2e80: 6e 2c 20 70 63 3b 0a 20 20 75 33 32 20 6e 43 65  n, pc;.  u32 nCe
2e90: 6c 6c 3b 0a 20 20 75 33 32 20 6e 50 72 65 66 69  ll;.  u32 nPrefi
2ea0: 78 3b 0a 20 20 75 33 32 20 73 7a 48 64 72 3b 0a  x;.  u32 szHdr;.
2eb0: 20 20 75 33 32 20 69 43 68 69 6c 64 3b 0a 20 20    u32 iChild;.  
2ec0: 75 38 20 2a 61 54 6f 70 3b 0a 20 20 75 38 20 2a  u8 *aTop;.  u8 *
2ed0: 61 43 65 6c 6c 3b 0a 20 20 75 33 32 20 78 2c 20  aCell;.  u32 x, 
2ee0: 79 3b 0a 20 20 69 6e 74 20 6c 6e 20 3d 20 30 3b  y;.  int ln = 0;
2ef0: 0a 0a 20 20 0a 20 20 69 66 28 20 70 2d 3e 72 63  ..  .  if( p->rc
2f00: 45 72 72 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  Err ) return;.  
2f10: 69 66 28 20 69 44 65 70 74 68 3e 35 30 20 29 7b  if( iDepth>50 ){
2f20: 0a 20 20 20 20 73 63 72 75 62 42 61 63 6b 75 70  .    scrubBackup
2f30: 45 72 72 28 70 2c 20 22 63 6f 72 72 75 70 74 3a  Err(p, "corrupt:
2f40: 20 62 2d 74 72 65 65 20 74 6f 6f 20 64 65 65 70   b-tree too deep
2f50: 20 61 74 20 70 61 67 65 20 25 64 22 2c 20 70 67   at page %d", pg
2f60: 6e 6f 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b  no);.    return;
2f70: 0a 20 20 7d 0a 20 20 69 66 28 20 70 67 6e 6f 3d  .  }.  if( pgno=
2f80: 3d 31 20 29 7b 0a 20 20 20 20 61 20 3d 20 70 2d  =1 ){.    a = p-
2f90: 3e 70 61 67 65 31 3b 0a 20 20 7d 65 6c 73 65 7b  >page1;.  }else{
2fa0: 0a 20 20 20 20 61 20 3d 20 73 63 72 75 62 42 61  .    a = scrubBa
2fb0: 63 6b 75 70 52 65 61 64 28 70 2c 20 70 67 6e 6f  ckupRead(p, pgno
2fc0: 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 61 3d  , 0);.    if( a=
2fd0: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 7d  =0 ) return;.  }
2fe0: 0a 20 20 6e 50 72 65 66 69 78 20 3d 20 70 67 6e  .  nPrefix = pgn
2ff0: 6f 3d 3d 31 20 3f 20 31 30 30 20 3a 20 30 3b 0a  o==1 ? 100 : 0;.
3000: 20 20 61 54 6f 70 20 3d 20 26 61 5b 6e 50 72 65    aTop = &a[nPre
3010: 66 69 78 5d 3b 0a 20 20 73 7a 48 64 72 20 3d 20  fix];.  szHdr = 
3020: 38 20 2b 20 34 2a 28 61 54 6f 70 5b 30 5d 3d 3d  8 + 4*(aTop[0]==
3030: 30 78 30 32 20 7c 7c 20 61 54 6f 70 5b 30 5d 3d  0x02 || aTop[0]=
3040: 3d 30 78 30 35 29 3b 0a 20 20 61 43 65 6c 6c 20  =0x05);.  aCell 
3050: 3d 20 61 54 6f 70 20 2b 20 73 7a 48 64 72 3b 0a  = aTop + szHdr;.
3060: 20 20 6e 43 65 6c 6c 20 3d 20 73 63 72 75 62 42    nCell = scrubB
3070: 61 63 6b 75 70 49 6e 74 31 36 28 26 61 54 6f 70  ackupInt16(&aTop
3080: 5b 33 5d 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f  [3]);..  /* Zero
3090: 20 6f 75 74 20 74 68 65 20 67 61 70 20 62 65 74   out the gap bet
30a0: 77 65 65 6e 20 74 68 65 20 63 65 6c 6c 20 69 6e  ween the cell in
30b0: 64 65 78 20 61 6e 64 20 74 68 65 20 73 74 61 72  dex and the star
30c0: 74 20 6f 66 20 74 68 65 0a 20 20 2a 2a 20 63 65  t of the.  ** ce
30d0: 6c 6c 20 63 6f 6e 74 65 6e 74 20 61 72 65 61 20  ll content area 
30e0: 2a 2f 0a 20 20 78 20 3d 20 73 63 72 75 62 42 61  */.  x = scrubBa
30f0: 63 6b 75 70 49 6e 74 31 36 28 26 61 54 6f 70 5b  ckupInt16(&aTop[
3100: 35 5d 29 3b 20 20 2f 2a 20 46 69 72 73 74 20 62  5]);  /* First b
3110: 79 74 65 20 6f 66 20 63 65 6c 6c 20 63 6f 6e 74  yte of cell cont
3120: 65 6e 74 20 61 72 65 61 20 2a 2f 0a 20 20 69 66  ent area */.  if
3130: 28 20 78 3e 70 2d 3e 73 7a 55 73 61 62 6c 65 20  ( x>p->szUsable 
3140: 29 7b 20 6c 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b 20  ){ ln=__LINE__; 
3150: 67 6f 74 6f 20 62 74 72 65 65 5f 63 6f 72 72 75  goto btree_corru
3160: 70 74 3b 20 7d 0a 20 20 79 20 3d 20 73 7a 48 64  pt; }.  y = szHd
3170: 72 20 2b 20 6e 50 72 65 66 69 78 20 2b 20 6e 43  r + nPrefix + nC
3180: 65 6c 6c 2a 32 3b 0a 20 20 69 66 28 20 79 3e 78  ell*2;.  if( y>x
3190: 20 29 7b 20 6c 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b   ){ ln=__LINE__;
31a0: 20 67 6f 74 6f 20 62 74 72 65 65 5f 63 6f 72 72   goto btree_corr
31b0: 75 70 74 3b 20 7d 0a 20 20 69 66 28 20 79 3c 78  upt; }.  if( y<x
31c0: 20 29 20 6d 65 6d 73 65 74 28 61 2b 79 2c 20 30   ) memset(a+y, 0
31d0: 2c 20 78 2d 79 29 3b 20 20 2f 2a 20 5a 65 72 6f  , x-y);  /* Zero
31e0: 20 74 68 65 20 67 61 70 20 2a 2f 0a 0a 20 20 2f   the gap */..  /
31f0: 2a 20 5a 65 72 6f 20 6f 75 74 20 61 6c 6c 20 74  * Zero out all t
3200: 68 65 20 66 72 65 65 20 62 6c 6f 63 6b 73 20 2a  he free blocks *
3210: 2f 20 20 0a 20 20 70 63 20 3d 20 73 63 72 75 62  /  .  pc = scrub
3220: 42 61 63 6b 75 70 49 6e 74 31 36 28 26 61 54 6f  BackupInt16(&aTo
3230: 70 5b 31 5d 29 3b 0a 20 20 69 66 28 20 70 63 3e  p[1]);.  if( pc>
3240: 30 20 26 26 20 70 63 3c 78 20 29 7b 20 6c 6e 3d  0 && pc<x ){ ln=
3250: 5f 5f 4c 49 4e 45 5f 5f 3b 20 67 6f 74 6f 20 62  __LINE__; goto b
3260: 74 72 65 65 5f 63 6f 72 72 75 70 74 3b 20 7d 0a  tree_corrupt; }.
3270: 20 20 77 68 69 6c 65 28 20 70 63 20 29 7b 0a 20    while( pc ){. 
3280: 20 20 20 69 66 28 20 70 63 3e 28 70 2d 3e 73 7a     if( pc>(p->sz
3290: 55 73 61 62 6c 65 29 2d 34 20 29 7b 20 6c 6e 3d  Usable)-4 ){ ln=
32a0: 5f 5f 4c 49 4e 45 5f 5f 3b 20 67 6f 74 6f 20 62  __LINE__; goto b
32b0: 74 72 65 65 5f 63 6f 72 72 75 70 74 3b 20 7d 0a  tree_corrupt; }.
32c0: 20 20 20 20 6e 20 3d 20 73 63 72 75 62 42 61 63      n = scrubBac
32d0: 6b 75 70 49 6e 74 31 36 28 26 61 5b 70 63 2b 32  kupInt16(&a[pc+2
32e0: 5d 29 3b 0a 20 20 20 20 69 66 28 20 70 63 2b 6e  ]);.    if( pc+n
32f0: 3e 28 70 2d 3e 73 7a 55 73 61 62 6c 65 29 20 29  >(p->szUsable) )
3300: 7b 20 6c 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b 20 67  { ln=__LINE__; g
3310: 6f 74 6f 20 62 74 72 65 65 5f 63 6f 72 72 75 70  oto btree_corrup
3320: 74 3b 20 7d 0a 20 20 20 20 69 66 28 20 6e 3e 34  t; }.    if( n>4
3330: 20 29 20 6d 65 6d 73 65 74 28 26 61 5b 70 63 2b   ) memset(&a[pc+
3340: 34 5d 2c 20 30 2c 20 6e 2d 34 29 3b 0a 20 20 20  4], 0, n-4);.   
3350: 20 78 20 3d 20 73 63 72 75 62 42 61 63 6b 75 70   x = scrubBackup
3360: 49 6e 74 31 36 28 26 61 5b 70 63 5d 29 3b 0a 20  Int16(&a[pc]);. 
3370: 20 20 20 69 66 28 20 78 3c 70 63 2b 34 20 26 26     if( x<pc+4 &&
3380: 20 78 3e 30 20 29 7b 20 6c 6e 3d 5f 5f 4c 49 4e   x>0 ){ ln=__LIN
3390: 45 5f 5f 3b 20 67 6f 74 6f 20 62 74 72 65 65 5f  E__; goto btree_
33a0: 63 6f 72 72 75 70 74 3b 20 7d 0a 20 20 20 20 70  corrupt; }.    p
33b0: 63 20 3d 20 78 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  c = x;.  }..  /*
33c0: 20 57 72 69 74 65 20 74 68 69 73 20 6f 6e 65 20   Write this one 
33d0: 70 61 67 65 20 2a 2f 0a 20 20 73 63 72 75 62 42  page */.  scrubB
33e0: 61 63 6b 75 70 57 72 69 74 65 28 70 2c 20 70 67  ackupWrite(p, pg
33f0: 6e 6f 2c 20 61 29 3b 0a 0a 20 20 2f 2a 20 57 61  no, a);..  /* Wa
3400: 6c 6b 20 74 68 65 20 74 72 65 65 20 61 6e 64 20  lk the tree and 
3410: 70 72 6f 63 65 73 73 20 63 68 69 6c 64 20 70 61  process child pa
3420: 67 65 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  ges */.  for(i=0
3430: 3b 20 69 3c 6e 43 65 6c 6c 3b 20 69 2b 2b 29 7b  ; i<nCell; i++){
3440: 0a 20 20 20 20 75 33 32 20 58 2c 20 4d 2c 20 4b  .    u32 X, M, K
3450: 2c 20 6e 4c 6f 63 61 6c 3b 0a 20 20 20 20 73 71  , nLocal;.    sq
3460: 6c 69 74 65 33 5f 69 6e 74 36 34 20 50 3b 0a 20  lite3_int64 P;. 
3470: 20 20 20 70 63 20 3d 20 73 63 72 75 62 42 61 63     pc = scrubBac
3480: 6b 75 70 49 6e 74 31 36 28 26 61 43 65 6c 6c 5b  kupInt16(&aCell[
3490: 69 2a 32 5d 29 3b 0a 20 20 20 20 69 66 28 20 70  i*2]);.    if( p
34a0: 63 20 3c 3d 20 73 7a 48 64 72 20 29 7b 20 6c 6e  c <= szHdr ){ ln
34b0: 3d 5f 5f 4c 49 4e 45 5f 5f 3b 20 67 6f 74 6f 20  =__LINE__; goto 
34c0: 62 74 72 65 65 5f 63 6f 72 72 75 70 74 3b 20 7d  btree_corrupt; }
34d0: 0a 20 20 20 20 69 66 28 20 70 63 20 3e 20 70 2d  .    if( pc > p-
34e0: 3e 73 7a 55 73 61 62 6c 65 2d 33 20 29 7b 20 6c  >szUsable-3 ){ l
34f0: 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b 20 67 6f 74 6f  n=__LINE__; goto
3500: 20 62 74 72 65 65 5f 63 6f 72 72 75 70 74 3b 20   btree_corrupt; 
3510: 7d 0a 20 20 20 20 69 66 28 20 61 54 6f 70 5b 30  }.    if( aTop[0
3520: 5d 3d 3d 30 78 30 35 20 7c 7c 20 61 54 6f 70 5b  ]==0x05 || aTop[
3530: 30 5d 3d 3d 30 78 30 32 20 29 7b 0a 20 20 20 20  0]==0x02 ){.    
3540: 20 20 69 66 28 20 70 63 2b 34 20 3e 20 70 2d 3e    if( pc+4 > p->
3550: 73 7a 55 73 61 62 6c 65 20 29 7b 20 6c 6e 3d 5f  szUsable ){ ln=_
3560: 5f 4c 49 4e 45 5f 5f 3b 20 67 6f 74 6f 20 62 74  _LINE__; goto bt
3570: 72 65 65 5f 63 6f 72 72 75 70 74 3b 20 7d 0a 20  ree_corrupt; }. 
3580: 20 20 20 20 20 69 43 68 69 6c 64 20 3d 20 73 63       iChild = sc
3590: 72 75 62 42 61 63 6b 75 70 49 6e 74 33 32 28 26  rubBackupInt32(&
35a0: 61 5b 70 63 5d 29 3b 0a 20 20 20 20 20 20 70 63  a[pc]);.      pc
35b0: 20 2b 3d 20 34 3b 0a 20 20 20 20 20 20 73 63 72   += 4;.      scr
35c0: 75 62 42 61 63 6b 75 70 42 74 72 65 65 28 70 2c  ubBackupBtree(p,
35d0: 20 69 43 68 69 6c 64 2c 20 69 44 65 70 74 68 2b   iChild, iDepth+
35e0: 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20 61 54  1);.      if( aT
35f0: 6f 70 5b 30 5d 3d 3d 30 78 30 35 20 29 20 63 6f  op[0]==0x05 ) co
3600: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20  ntinue;.    }.  
3610: 20 20 70 63 20 2b 3d 20 73 63 72 75 62 42 61 63    pc += scrubBac
3620: 6b 75 70 56 61 72 69 6e 74 28 26 61 5b 70 63 5d  kupVarint(&a[pc]
3630: 2c 20 26 50 29 3b 0a 20 20 20 20 69 66 28 20 70  , &P);.    if( p
3640: 63 20 3e 3d 20 70 2d 3e 73 7a 55 73 61 62 6c 65  c >= p->szUsable
3650: 20 29 7b 20 6c 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b   ){ ln=__LINE__;
3660: 20 67 6f 74 6f 20 62 74 72 65 65 5f 63 6f 72 72   goto btree_corr
3670: 75 70 74 3b 20 7d 0a 20 20 20 20 69 66 28 20 61  upt; }.    if( a
3680: 54 6f 70 5b 30 5d 3d 3d 30 78 30 64 20 29 7b 0a  Top[0]==0x0d ){.
3690: 20 20 20 20 20 20 58 20 3d 20 70 2d 3e 73 7a 55        X = p->szU
36a0: 73 61 62 6c 65 20 2d 20 33 35 3b 0a 20 20 20 20  sable - 35;.    
36b0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 58 20 3d  }else{.      X =
36c0: 20 28 28 70 2d 3e 73 7a 55 73 61 62 6c 65 20 2d   ((p->szUsable -
36d0: 20 31 32 29 2a 36 34 2f 32 35 35 29 20 2d 20 32   12)*64/255) - 2
36e0: 33 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  3;.    }.    if(
36f0: 20 50 3c 3d 58 20 29 7b 0a 20 20 20 20 20 20 2f   P<=X ){.      /
3700: 2a 20 41 6c 6c 20 63 6f 6e 74 65 6e 74 20 69 73  * All content is
3710: 20 6c 6f 63 61 6c 2e 20 20 4e 6f 20 6f 76 65 72   local.  No over
3720: 66 6c 6f 77 20 2a 2f 0a 20 20 20 20 20 20 63 6f  flow */.      co
3730: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20  ntinue;.    }.  
3740: 20 20 4d 20 3d 20 28 28 70 2d 3e 73 7a 55 73 61    M = ((p->szUsa
3750: 62 6c 65 20 2d 20 31 32 29 2a 33 32 2f 32 35 35  ble - 12)*32/255
3760: 29 2d 32 33 3b 0a 20 20 20 20 4b 20 3d 20 4d 20  )-23;.    K = M 
3770: 2b 20 28 28 50 2d 4d 29 25 28 70 2d 3e 73 7a 55  + ((P-M)%(p->szU
3780: 73 61 62 6c 65 2d 34 29 29 3b 0a 20 20 20 20 69  sable-4));.    i
3790: 66 28 20 61 54 6f 70 5b 30 5d 3d 3d 30 78 30 64  f( aTop[0]==0x0d
37a0: 20 29 7b 0a 20 20 20 20 20 20 70 63 20 2b 3d 20   ){.      pc += 
37b0: 73 63 72 75 62 42 61 63 6b 75 70 56 61 72 69 6e  scrubBackupVarin
37c0: 74 53 69 7a 65 28 26 61 5b 70 63 5d 29 3b 0a 20  tSize(&a[pc]);. 
37d0: 20 20 20 20 20 69 66 28 20 70 63 20 3e 20 28 70       if( pc > (p
37e0: 2d 3e 73 7a 55 73 61 62 6c 65 2d 34 29 20 29 7b  ->szUsable-4) ){
37f0: 20 6c 6e 3d 5f 5f 4c 49 4e 45 5f 5f 3b 20 67 6f   ln=__LINE__; go
3800: 74 6f 20 62 74 72 65 65 5f 63 6f 72 72 75 70 74  to btree_corrupt
3810: 3b 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 6e 4c  ; }.    }.    nL
3820: 6f 63 61 6c 20 3d 20 4b 3c 3d 58 20 3f 20 4b 20  ocal = K<=X ? K 
3830: 3a 20 4d 3b 0a 20 20 20 20 69 66 28 20 70 63 2b  : M;.    if( pc+
3840: 6e 4c 6f 63 61 6c 20 3e 20 70 2d 3e 73 7a 55 73  nLocal > p->szUs
3850: 61 62 6c 65 2d 34 20 29 7b 20 6c 6e 3d 5f 5f 4c  able-4 ){ ln=__L
3860: 49 4e 45 5f 5f 3b 20 67 6f 74 6f 20 62 74 72 65  INE__; goto btre
3870: 65 5f 63 6f 72 72 75 70 74 3b 20 7d 0a 20 20 20  e_corrupt; }.   
3880: 20 69 43 68 69 6c 64 20 3d 20 73 63 72 75 62 42   iChild = scrubB
3890: 61 63 6b 75 70 49 6e 74 33 32 28 26 61 5b 70 63  ackupInt32(&a[pc
38a0: 2b 6e 4c 6f 63 61 6c 5d 29 3b 0a 20 20 20 20 73  +nLocal]);.    s
38b0: 63 72 75 62 42 61 63 6b 75 70 4f 76 65 72 66 6c  crubBackupOverfl
38c0: 6f 77 28 70 2c 20 69 43 68 69 6c 64 2c 20 50 2d  ow(p, iChild, P-
38d0: 6e 4c 6f 63 61 6c 29 3b 0a 20 20 7d 0a 0a 20 20  nLocal);.  }..  
38e0: 2f 2a 20 57 61 6c 6b 20 74 68 65 20 72 69 67 68  /* Walk the righ
38f0: 74 2d 6d 6f 73 74 20 74 72 65 65 20 2a 2f 0a 20  t-most tree */. 
3900: 20 69 66 28 20 61 54 6f 70 5b 30 5d 3d 3d 30 78   if( aTop[0]==0x
3910: 30 35 20 7c 7c 20 61 54 6f 70 5b 30 5d 3d 3d 30  05 || aTop[0]==0
3920: 78 30 32 20 29 7b 0a 20 20 20 20 69 43 68 69 6c  x02 ){.    iChil
3930: 64 20 3d 20 73 63 72 75 62 42 61 63 6b 75 70 49  d = scrubBackupI
3940: 6e 74 33 32 28 26 61 54 6f 70 5b 38 5d 29 3b 0a  nt32(&aTop[8]);.
3950: 20 20 20 20 73 63 72 75 62 42 61 63 6b 75 70 42      scrubBackupB
3960: 74 72 65 65 28 70 2c 20 69 43 68 69 6c 64 2c 20  tree(p, iChild, 
3970: 69 44 65 70 74 68 2b 31 29 3b 0a 20 20 7d 0a 0a  iDepth+1);.  }..
3980: 20 20 2f 2a 20 41 6c 6c 20 64 6f 6e 65 20 2a 2f    /* All done */
3990: 0a 20 20 69 66 28 20 70 67 6e 6f 3e 31 20 29 20  .  if( pgno>1 ) 
39a0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 29 3b  sqlite3_free(a);
39b0: 0a 20 20 72 65 74 75 72 6e 3b 0a 0a 62 74 72 65  .  return;..btre
39c0: 65 5f 63 6f 72 72 75 70 74 3a 0a 20 20 73 63 72  e_corrupt:.  scr
39d0: 75 62 42 61 63 6b 75 70 45 72 72 28 70 2c 20 22  ubBackupErr(p, "
39e0: 63 6f 72 72 75 70 74 69 6f 6e 20 6f 6e 20 70 61  corruption on pa
39f0: 67 65 20 25 64 20 6f 66 20 73 6f 75 72 63 65 20  ge %d of source 
3a00: 64 61 74 61 62 61 73 65 20 28 65 72 72 69 64 3d  database (errid=
3a10: 25 64 29 22 2c 0a 20 20 20 20 20 20 20 20 20 20  %d)",.          
3a20: 20 20 20 20 20 20 20 70 67 6e 6f 2c 20 6c 6e 29         pgno, ln)
3a30: 3b 0a 20 20 69 66 28 20 70 67 6e 6f 3e 31 20 29  ;.  if( pgno>1 )
3a40: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 29   sqlite3_free(a)
3a50: 3b 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70  ;  .}../*.** Cop
3a60: 79 20 61 6c 6c 20 70 74 72 6d 61 70 20 70 61 67  y all ptrmap pag
3a70: 65 73 20 66 72 6f 6d 20 73 6f 75 72 63 65 20 74  es from source t
3a80: 6f 20 64 65 73 74 69 6e 61 74 69 6f 6e 2e 0a 2a  o destination..*
3a90: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69  * This routine i
3aa0: 73 20 6f 6e 6c 79 20 63 61 6c 6c 65 64 20 69 66  s only called if
3ab0: 20 74 68 65 20 73 6f 75 72 63 65 20 64 61 74 61   the source data
3ac0: 62 61 73 65 20 69 73 20 69 6e 20 61 75 74 6f 76  base is in autov
3ad0: 61 63 75 75 6d 0a 2a 2a 20 6f 72 20 69 6e 63 72  acuum.** or incr
3ae0: 65 6d 65 6e 74 61 6c 20 76 61 63 75 75 6d 20 6d  emental vacuum m
3af0: 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ode..*/.static v
3b00: 6f 69 64 20 73 63 72 75 62 42 61 63 6b 75 70 50  oid scrubBackupP
3b10: 74 72 6d 61 70 28 53 63 72 75 62 53 74 61 74 65  trmap(ScrubState
3b20: 20 2a 70 29 7b 0a 20 20 75 33 32 20 70 67 6e 6f   *p){.  u32 pgno
3b30: 20 3d 20 32 3b 0a 20 20 75 33 32 20 4a 20 3d 20   = 2;.  u32 J = 
3b40: 70 2d 3e 73 7a 55 73 61 62 6c 65 2f 35 3b 0a 20  p->szUsable/5;. 
3b50: 20 75 33 32 20 69 4c 6f 63 6b 20 3d 20 28 31 30   u32 iLock = (10
3b60: 37 33 37 34 32 33 33 35 2f 70 2d 3e 73 7a 50 61  73742335/p->szPa
3b70: 67 65 29 2b 31 3b 0a 20 20 75 38 20 2a 61 2c 20  ge)+1;.  u8 *a, 
3b80: 2a 70 42 75 66 3b 0a 20 20 69 66 28 20 70 2d 3e  *pBuf;.  if( p->
3b90: 72 63 45 72 72 20 29 20 72 65 74 75 72 6e 3b 0a  rcErr ) return;.
3ba0: 20 20 70 42 75 66 20 3d 20 73 63 72 75 62 42 61    pBuf = scrubBa
3bb0: 63 6b 75 70 41 6c 6c 6f 63 50 61 67 65 28 70 29  ckupAllocPage(p)
3bc0: 3b 0a 20 20 69 66 28 20 70 42 75 66 3d 3d 30 20  ;.  if( pBuf==0 
3bd0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 77 68 69 6c  ) return;.  whil
3be0: 65 28 20 70 67 6e 6f 3c 3d 70 2d 3e 6e 50 61 67  e( pgno<=p->nPag
3bf0: 65 20 29 7b 0a 20 20 20 20 61 20 3d 20 73 63 72  e ){.    a = scr
3c00: 75 62 42 61 63 6b 75 70 52 65 61 64 28 70 2c 20  ubBackupRead(p, 
3c10: 70 67 6e 6f 2c 20 70 42 75 66 29 3b 0a 20 20 20  pgno, pBuf);.   
3c20: 20 69 66 28 20 61 3d 3d 30 20 29 20 62 72 65 61   if( a==0 ) brea
3c30: 6b 3b 0a 20 20 20 20 73 63 72 75 62 42 61 63 6b  k;.    scrubBack
3c40: 75 70 57 72 69 74 65 28 70 2c 20 70 67 6e 6f 2c  upWrite(p, pgno,
3c50: 20 61 29 3b 0a 20 20 20 20 70 67 6e 6f 20 2b 3d   a);.    pgno +=
3c60: 20 4a 2b 31 3b 0a 20 20 20 20 69 66 28 20 70 67   J+1;.    if( pg
3c70: 6e 6f 3d 3d 69 4c 6f 63 6b 20 29 20 70 67 6e 6f  no==iLock ) pgno
3c80: 2b 2b 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  ++;.  }.  sqlite
3c90: 33 5f 66 72 65 65 28 70 42 75 66 29 3b 0a 7d 0a  3_free(pBuf);.}.
3ca0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 73 63 72  .int sqlite3_scr
3cb0: 75 62 5f 62 61 63 6b 75 70 28 0a 20 20 63 6f 6e  ub_backup(.  con
3cc0: 73 74 20 63 68 61 72 20 2a 7a 53 72 63 46 69 6c  st char *zSrcFil
3cd0: 65 2c 20 20 20 20 2f 2a 20 53 6f 75 72 63 65 20  e,    /* Source 
3ce0: 66 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  file */.  const 
3cf0: 63 68 61 72 20 2a 7a 44 65 73 74 46 69 6c 65 2c  char *zDestFile,
3d00: 20 20 20 2f 2a 20 44 65 73 74 69 6e 61 74 69 6f     /* Destinatio
3d10: 6e 20 66 69 6c 65 20 2a 2f 0a 20 20 63 68 61 72  n file */.  char
3d20: 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20   **pzErr        
3d30: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 65 72       /* Write er
3d40: 72 6f 72 20 68 65 72 65 20 69 66 20 6e 6f 6e 2d  ror here if non-
3d50: 4e 55 4c 4c 20 2a 2f 0a 29 7b 0a 20 20 53 63 72  NULL */.){.  Scr
3d60: 75 62 53 74 61 74 65 20 73 3b 0a 20 20 75 33 32  ubState s;.  u32
3d70: 20 6e 2c 20 69 3b 0a 20 20 73 71 6c 69 74 65 33   n, i;.  sqlite3
3d80: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 0a 20  _stmt *pStmt;.. 
3d90: 20 6d 65 6d 73 65 74 28 26 73 2c 20 30 2c 20 73   memset(&s, 0, s
3da0: 69 7a 65 6f 66 28 73 29 29 3b 0a 20 20 73 2e 7a  izeof(s));.  s.z
3db0: 53 72 63 46 69 6c 65 20 3d 20 7a 53 72 63 46 69  SrcFile = zSrcFi
3dc0: 6c 65 3b 0a 20 20 73 2e 7a 44 65 73 74 46 69 6c  le;.  s.zDestFil
3dd0: 65 20 3d 20 7a 44 65 73 74 46 69 6c 65 3b 0a 0a  e = zDestFile;..
3de0: 20 20 2f 2a 20 4f 70 65 6e 20 62 6f 74 68 20 73    /* Open both s
3df0: 6f 75 72 63 65 20 61 6e 64 20 64 65 73 74 69 6e  ource and destin
3e00: 61 74 69 6f 6e 20 64 61 74 61 62 61 73 65 73 20  ation databases 
3e10: 2a 2f 0a 20 20 73 63 72 75 62 42 61 63 6b 75 70  */.  scrubBackup
3e20: 4f 70 65 6e 53 72 63 28 26 73 29 3b 0a 20 20 73  OpenSrc(&s);.  s
3e30: 63 72 75 62 42 61 63 6b 75 70 4f 70 65 6e 44 65  crubBackupOpenDe
3e40: 73 74 28 26 73 29 3b 0a 0a 20 20 2f 2a 20 52 65  st(&s);..  /* Re
3e50: 61 64 20 69 6e 20 70 61 67 65 20 31 20 2a 2f 0a  ad in page 1 */.
3e60: 20 20 73 2e 70 61 67 65 31 20 3d 20 73 63 72 75    s.page1 = scru
3e70: 62 42 61 63 6b 75 70 52 65 61 64 28 26 73 2c 20  bBackupRead(&s, 
3e80: 31 2c 20 30 29 3b 0a 20 20 69 66 28 20 73 2e 70  1, 0);.  if( s.p
3e90: 61 67 65 31 3d 3d 30 20 29 20 67 6f 74 6f 20 73  age1==0 ) goto s
3ea0: 63 72 75 62 5f 61 62 6f 72 74 3b 0a 20 20 73 2e  crub_abort;.  s.
3eb0: 73 7a 55 73 61 62 6c 65 20 3d 20 73 2e 73 7a 50  szUsable = s.szP
3ec0: 61 67 65 20 2d 20 73 2e 70 61 67 65 31 5b 32 30  age - s.page1[20
3ed0: 5d 3b 0a 0a 20 20 2f 2a 20 43 6f 70 79 20 74 68  ];..  /* Copy th
3ee0: 65 20 66 72 65 65 6c 69 73 74 20 2a 2f 20 20 20  e freelist */   
3ef0: 20 0a 20 20 6e 20 3d 20 73 63 72 75 62 42 61 63   .  n = scrubBac
3f00: 6b 75 70 49 6e 74 33 32 28 26 73 2e 70 61 67 65  kupInt32(&s.page
3f10: 31 5b 33 36 5d 29 3b 0a 20 20 69 20 3d 20 73 63  1[36]);.  i = sc
3f20: 72 75 62 42 61 63 6b 75 70 49 6e 74 33 32 28 26  rubBackupInt32(&
3f30: 73 2e 70 61 67 65 31 5b 33 32 5d 29 3b 0a 20 20  s.page1[32]);.  
3f40: 69 66 28 20 6e 20 29 20 73 63 72 75 62 42 61 63  if( n ) scrubBac
3f50: 6b 75 70 46 72 65 65 6c 69 73 74 28 26 73 2c 20  kupFreelist(&s, 
3f60: 69 2c 20 6e 29 3b 0a 0a 20 20 2f 2a 20 43 6f 70  i, n);..  /* Cop
3f70: 79 20 70 74 72 6d 61 70 20 70 61 67 65 73 20 2a  y ptrmap pages *
3f80: 2f 0a 20 20 6e 20 3d 20 73 63 72 75 62 42 61 63  /.  n = scrubBac
3f90: 6b 75 70 49 6e 74 33 32 28 26 73 2e 70 61 67 65  kupInt32(&s.page
3fa0: 31 5b 35 32 5d 29 3b 0a 20 20 69 66 28 20 6e 20  1[52]);.  if( n 
3fb0: 29 20 73 63 72 75 62 42 61 63 6b 75 70 50 74 72  ) scrubBackupPtr
3fc0: 6d 61 70 28 26 73 29 3b 0a 0a 20 20 2f 2a 20 43  map(&s);..  /* C
3fd0: 6f 70 79 20 61 6c 6c 20 6f 66 20 74 68 65 20 62  opy all of the b
3fe0: 74 72 65 65 73 20 2a 2f 0a 20 20 73 63 72 75 62  trees */.  scrub
3ff0: 42 61 63 6b 75 70 42 74 72 65 65 28 26 73 2c 20  BackupBtree(&s, 
4000: 31 2c 20 30 29 3b 0a 20 20 70 53 74 6d 74 20 3d  1, 0);.  pStmt =
4010: 20 73 63 72 75 62 42 61 63 6b 75 70 50 72 65 70   scrubBackupPrep
4020: 61 72 65 28 26 73 2c 20 73 2e 64 62 53 72 63 2c  are(&s, s.dbSrc,
4030: 0a 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20  .       "SELECT 
4040: 72 6f 6f 74 70 61 67 65 20 46 52 4f 4d 20 73 71  rootpage FROM sq
4050: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
4060: 45 20 63 6f 61 6c 65 73 63 65 28 72 6f 6f 74 70  E coalesce(rootp
4070: 61 67 65 2c 30 29 3e 30 22 29 3b 0a 20 20 69 66  age,0)>0");.  if
4080: 28 20 70 53 74 6d 74 3d 3d 30 20 29 20 67 6f 74  ( pStmt==0 ) got
4090: 6f 20 73 63 72 75 62 5f 61 62 6f 72 74 3b 0a 20  o scrub_abort;. 
40a0: 20 77 68 69 6c 65 28 20 73 71 6c 69 74 65 33 5f   while( sqlite3_
40b0: 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c  step(pStmt)==SQL
40c0: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 69  ITE_ROW ){.    i
40d0: 20 3d 20 28 75 33 32 29 73 71 6c 69 74 65 33 5f   = (u32)sqlite3_
40e0: 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74  column_int(pStmt
40f0: 2c 20 30 29 3b 0a 20 20 20 20 73 63 72 75 62 42  , 0);.    scrubB
4100: 61 63 6b 75 70 42 74 72 65 65 28 26 73 2c 20 69  ackupBtree(&s, i
4110: 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  , 0);.  }.  sqli
4120: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
4130: 6d 74 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  mt);..  /* If th
4140: 65 20 6c 61 73 74 20 70 61 67 65 20 6f 66 20 74  e last page of t
4150: 68 65 20 69 6e 70 75 74 20 64 62 20 66 69 6c 65  he input db file
4160: 20 69 73 20 61 20 66 72 65 65 2d 6c 69 73 74 20   is a free-list 
4170: 6c 65 61 66 2c 20 74 68 65 6e 20 74 68 65 0a 20  leaf, then the. 
4180: 20 2a 2a 20 62 61 63 6b 75 70 20 66 69 6c 65 20   ** backup file 
4190: 6f 6e 20 64 69 73 6b 20 69 73 20 73 74 69 6c 6c  on disk is still
41a0: 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 74 68   smaller than th
41b0: 65 20 73 69 7a 65 20 69 6e 64 69 63 61 74 65 64  e size indicated
41c0: 20 77 69 74 68 69 6e 20 0a 20 20 2a 2a 20 74 68   within .  ** th
41d0: 65 20 64 61 74 61 62 61 73 65 20 68 65 61 64 65  e database heade
41e0: 72 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c  r. In this case,
41f0: 20 77 72 69 74 65 20 61 20 70 61 67 65 20 6f 66   write a page of
4200: 20 7a 65 72 6f 65 73 20 74 6f 20 74 68 65 20 0a   zeroes to the .
4210: 20 20 2a 2a 20 6c 61 73 74 20 70 61 67 65 20 6f    ** last page o
4220: 66 20 74 68 65 20 62 61 63 6b 75 70 20 64 61 74  f the backup dat
4230: 61 62 61 73 65 20 73 6f 20 74 68 61 74 20 53 51  abase so that SQ
4240: 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74 20 6d 69  Lite does not mi
4250: 73 74 61 6b 65 6e 6c 79 0a 20 20 2a 2a 20 74 68  stakenly.  ** th
4260: 69 6e 6b 20 74 68 65 20 64 62 20 69 73 20 63 6f  ink the db is co
4270: 72 72 75 70 74 2e 20 20 2a 2f 0a 20 20 69 66 28  rrupt.  */.  if(
4280: 20 73 2e 69 4c 61 73 74 50 61 67 65 3c 73 2e 6e   s.iLastPage<s.n
4290: 50 61 67 65 20 29 7b 0a 20 20 20 20 75 38 20 2a  Page ){.    u8 *
42a0: 61 5a 65 72 6f 20 3d 20 73 63 72 75 62 42 61 63  aZero = scrubBac
42b0: 6b 75 70 41 6c 6c 6f 63 50 61 67 65 28 26 73 29  kupAllocPage(&s)
42c0: 3b 0a 20 20 20 20 69 66 28 20 61 5a 65 72 6f 20  ;.    if( aZero 
42d0: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  ){.      memset(
42e0: 61 5a 65 72 6f 2c 20 30 2c 20 73 2e 73 7a 50 61  aZero, 0, s.szPa
42f0: 67 65 29 3b 0a 20 20 20 20 20 20 73 63 72 75 62  ge);.      scrub
4300: 42 61 63 6b 75 70 57 72 69 74 65 28 26 73 2c 20  BackupWrite(&s, 
4310: 73 2e 6e 50 61 67 65 2c 20 61 5a 65 72 6f 29 3b  s.nPage, aZero);
4320: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
4330: 72 65 65 28 61 5a 65 72 6f 29 3b 0a 20 20 20 20  ree(aZero);.    
4340: 7d 0a 20 20 7d 0a 0a 73 63 72 75 62 5f 61 62 6f  }.  }..scrub_abo
4350: 72 74 3a 20 20 20 20 0a 20 20 2f 2a 20 43 6c 6f  rt:    .  /* Clo
4360: 73 65 20 74 68 65 20 64 65 73 74 69 6e 61 74 69  se the destinati
4370: 6f 6e 20 64 61 74 61 62 61 73 65 20 77 69 74 68  on database with
4380: 6f 75 74 20 63 6c 6f 73 69 6e 67 20 74 68 65 20  out closing the 
4390: 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20  transaction. If 
43a0: 77 65 0a 20 20 2a 2a 20 63 6f 6d 6d 69 74 2c 20  we.  ** commit, 
43b0: 70 61 67 65 20 7a 65 72 6f 20 77 69 6c 6c 20 62  page zero will b
43c0: 65 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 20 2a  e overwritten. *
43d0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f 73  /.  sqlite3_clos
43e0: 65 28 73 2e 64 62 44 65 73 74 29 3b 0a 0a 20 20  e(s.dbDest);..  
43f0: 2f 2a 20 42 75 74 20 64 6f 20 63 6c 6f 73 65 20  /* But do close 
4400: 6f 75 74 20 74 68 65 20 72 65 61 64 2d 74 72 61  out the read-tra
4410: 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20  nsaction on the 
4420: 73 6f 75 72 63 65 20 64 61 74 61 62 61 73 65 20  source database 
4430: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 65  */.  sqlite3_exe
4440: 63 28 73 2e 64 62 53 72 63 2c 20 22 43 4f 4d 4d  c(s.dbSrc, "COMM
4450: 49 54 3b 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  IT;", 0, 0, 0);.
4460: 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f 73 65 28    sqlite3_close(
4470: 73 2e 64 62 53 72 63 29 3b 0a 20 20 73 71 6c 69  s.dbSrc);.  sqli
4480: 74 65 33 5f 66 72 65 65 28 73 2e 70 61 67 65 31  te3_free(s.page1
4490: 29 3b 0a 20 20 69 66 28 20 70 7a 45 72 72 20 29  );.  if( pzErr )
44a0: 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73  {.    *pzErr = s
44b0: 2e 7a 45 72 72 3b 0a 20 20 7d 65 6c 73 65 7b 0a  .zErr;.  }else{.
44c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
44d0: 28 73 2e 7a 45 72 72 29 3b 0a 20 20 7d 0a 20 20  (s.zErr);.  }.  
44e0: 72 65 74 75 72 6e 20 73 2e 72 63 45 72 72 3b 0a  return s.rcErr;.
44f0: 7d 20 20 20 0a 0a 23 69 66 64 65 66 20 53 43 52  }   ..#ifdef SCR
4500: 55 42 5f 53 54 41 4e 44 41 4c 4f 4e 45 0a 2f 2a  UB_STANDALONE./*
4510: 20 45 72 72 6f 72 20 61 6e 64 20 77 61 72 6e 69   Error and warni
4520: 6e 67 20 6c 6f 67 20 2a 2f 0a 73 74 61 74 69 63  ng log */.static
4530: 20 76 6f 69 64 20 65 72 72 6f 72 4c 6f 67 43 61   void errorLogCa
4540: 6c 6c 62 61 63 6b 28 76 6f 69 64 20 2a 70 4e 6f  llback(void *pNo
4550: 74 55 73 65 64 2c 20 69 6e 74 20 69 45 72 72 2c  tUsed, int iErr,
4560: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d 73   const char *zMs
4570: 67 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  g){.  const char
4580: 20 2a 7a 54 79 70 65 3b 0a 20 20 73 77 69 74 63   *zType;.  switc
4590: 68 28 20 69 45 72 72 26 30 78 66 66 20 29 7b 0a  h( iErr&0xff ){.
45a0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
45b0: 57 41 52 4e 49 4e 47 3a 20 7a 54 79 70 65 20 3d  WARNING: zType =
45c0: 20 22 57 41 52 4e 49 4e 47 22 3b 20 20 62 72 65   "WARNING";  bre
45d0: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c  ak;.    case SQL
45e0: 49 54 45 5f 4e 4f 54 49 43 45 3a 20 20 7a 54 79  ITE_NOTICE:  zTy
45f0: 70 65 20 3d 20 22 4e 4f 54 49 43 45 22 3b 20 20  pe = "NOTICE";  
4600: 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65 66 61   break;.    defa
4610: 75 6c 74 3a 20 20 20 20 20 20 20 20 20 20 20 20  ult:            
4620: 20 7a 54 79 70 65 20 3d 20 22 45 52 52 4f 52 22   zType = "ERROR"
4630: 3b 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  ;    break;.  }.
4640: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
4650: 2c 20 22 25 73 3a 20 25 73 5c 6e 22 2c 20 7a 54  , "%s: %s\n", zT
4660: 79 70 65 2c 20 7a 4d 73 67 29 3b 0a 7d 0a 0a 2f  ype, zMsg);.}../
4670: 2a 20 54 68 65 20 6d 61 69 6e 28 29 20 72 6f 75  * The main() rou
4680: 74 69 6e 65 20 77 68 65 6e 20 74 68 69 73 20 75  tine when this u
4690: 74 69 6c 69 74 79 20 69 73 20 72 75 6e 20 61 73  tility is run as
46a0: 20 61 20 73 74 61 6e 64 2d 61 6c 6f 6e 65 20 70   a stand-alone p
46b0: 72 6f 67 72 61 6d 20 2a 2f 0a 69 6e 74 20 6d 61  rogram */.int ma
46c0: 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61  in(int argc, cha
46d0: 72 20 2a 2a 61 72 67 76 29 7b 0a 20 20 63 68 61  r **argv){.  cha
46e0: 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a 20 20 69  r *zErr = 0;.  i
46f0: 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 61 72 67  nt rc;.  if( arg
4700: 63 21 3d 33 20 29 7b 0a 20 20 20 20 66 70 72 69  c!=3 ){.    fpri
4710: 6e 74 66 28 73 74 64 65 72 72 2c 22 55 73 61 67  ntf(stderr,"Usag
4720: 65 3a 20 25 73 20 53 4f 55 52 43 45 20 44 45 53  e: %s SOURCE DES
4730: 54 49 4e 41 54 49 4f 4e 5c 6e 22 2c 20 61 72 67  TINATION\n", arg
4740: 76 5b 30 5d 29 3b 0a 20 20 20 20 65 78 69 74 28  v[0]);.    exit(
4750: 31 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  1);.  }.  sqlite
4760: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
4770: 43 4f 4e 46 49 47 5f 4c 4f 47 2c 20 65 72 72 6f  CONFIG_LOG, erro
4780: 72 4c 6f 67 43 61 6c 6c 62 61 63 6b 2c 20 30 29  rLogCallback, 0)
4790: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
47a0: 5f 73 63 72 75 62 5f 62 61 63 6b 75 70 28 61 72  _scrub_backup(ar
47b0: 67 76 5b 31 5d 2c 20 61 72 67 76 5b 32 5d 2c 20  gv[1], argv[2], 
47c0: 26 7a 45 72 72 29 3b 0a 20 20 69 66 28 20 72 63  &zErr);.  if( rc
47d0: 3d 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29  ==SQLITE_NOMEM )
47e0: 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 73 74  {.    fprintf(st
47f0: 64 65 72 72 2c 20 22 25 73 3a 20 6f 75 74 20 6f  derr, "%s: out o
4800: 66 20 6d 65 6d 6f 72 79 5c 6e 22 2c 20 61 72 67  f memory\n", arg
4810: 76 5b 30 5d 29 3b 0a 20 20 20 20 65 78 69 74 28  v[0]);.    exit(
4820: 31 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 7a 45  1);.  }.  if( zE
4830: 72 72 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74  rr ){.    fprint
4840: 66 28 73 74 64 65 72 72 2c 20 22 25 73 3a 20 25  f(stderr, "%s: %
4850: 73 5c 6e 22 2c 20 61 72 67 76 5b 30 5d 2c 20 7a  s\n", argv[0], z
4860: 45 72 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  Err);.    sqlite
4870: 33 5f 66 72 65 65 28 7a 45 72 72 29 3b 0a 20 20  3_free(zErr);.  
4880: 20 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20    exit(1);.  }. 
4890: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e   return 0;.}.#en
48a0: 64 69 66 0a                                      dif.