Hex Artifact Content
Not logged in

Artifact 2bf3326797b20e398b2b8ad406182498ff9955f4:

File src/vfile.c part of check-in [6eca3132fe] - Fix an off-by-one error that can cause a segfault during sync. by drh on 2007-08-09 11:55:52.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 37 20 44 2e 20 52 69 63 68  (c) 2007 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 50 72 6f 63 65 64 75 72 65  .**.** Procedure
0370: 73 20 66 6f 72 20 6d 61 6e 61 67 69 6e 67 20 74  s for managing t
0380: 68 65 20 56 46 49 4c 45 20 74 61 62 6c 65 2e 0a  he VFILE table..
0390: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 63 6f 6e  */.#include "con
03a0: 66 69 67 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  fig.h".#include 
03b0: 22 76 66 69 6c 65 2e 68 22 0a 23 69 6e 63 6c 75  "vfile.h".#inclu
03c0: 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69  de <assert.h>.#i
03d0: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 79 70 65  nclude <sys/type
03e0: 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 64  s.h>.#include <d
03f0: 69 72 65 6e 74 2e 68 3e 0a 0a 2f 2a 0a 2a 2a 20  irent.h>../*.** 
0400: 47 69 76 65 6e 20 61 20 55 55 49 44 2c 20 72 65  Given a UUID, re
0410: 74 75 72 6e 20 74 68 65 20 63 6f 72 72 65 73 70  turn the corresp
0420: 6f 6e 64 69 6e 67 20 72 65 63 6f 72 64 20 49 44  onding record ID
0430: 2e 20 20 49 66 20 74 68 65 20 55 55 49 44 0a 2a  .  If the UUID.*
0440: 2a 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  * does not exist
0450: 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e  , then return 0.
0460: 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 74 68 69 73 20  .**.** For this 
0470: 72 6f 75 74 69 6e 65 2c 20 74 68 65 20 55 55 49  routine, the UUI
0480: 44 20 6d 75 73 74 20 62 65 20 65 78 61 63 74 2e  D must be exact.
0490: 20 20 46 6f 72 20 61 20 6d 61 74 63 68 20 61 67    For a match ag
04a0: 61 69 6e 73 74 0a 2a 2a 20 75 73 65 72 20 69 6e  ainst.** user in
04b0: 70 75 74 20 77 69 74 68 20 6d 69 78 65 64 20 63  put with mixed c
04c0: 61 73 65 2c 20 75 73 65 20 72 65 73 6f 6c 76 65  ase, use resolve
04d0: 5f 75 75 69 64 28 29 2e 0a 2a 2a 0a 2a 2a 20 49  _uuid()..**.** I
04e0: 66 20 74 68 65 20 55 55 49 44 20 69 73 20 6e 6f  f the UUID is no
04f0: 74 20 66 6f 75 6e 64 20 61 6e 64 20 70 68 61 6e  t found and phan
0500: 74 6f 6d 69 7a 65 20 69 73 20 31 2c 20 74 68 65  tomize is 1, the
0510: 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 0a 2a 2a  n attempt to .**
0520: 20 63 72 65 61 74 65 20 61 20 70 68 61 6e 74 6f   create a phanto
0530: 6d 20 72 65 63 6f 72 64 2e 0a 2a 2f 0a 69 6e 74  m record..*/.int
0540: 20 75 75 69 64 5f 74 6f 5f 72 69 64 28 63 6f 6e   uuid_to_rid(con
0550: 73 74 20 63 68 61 72 20 2a 7a 55 75 69 64 2c 20  st char *zUuid, 
0560: 69 6e 74 20 70 68 61 6e 74 6f 6d 69 7a 65 29 7b  int phantomize){
0570: 0a 20 20 69 6e 74 20 72 69 64 2c 20 73 7a 3b 0a  .  int rid, sz;.
0580: 20 20 63 68 61 72 20 7a 5b 55 55 49 44 5f 53 49    char z[UUID_SI
0590: 5a 45 2b 31 5d 3b 0a 20 20 0a 20 20 73 7a 20 3d  ZE+1];.  .  sz =
05a0: 20 73 74 72 6c 65 6e 28 7a 55 75 69 64 29 3b 0a   strlen(zUuid);.
05b0: 20 20 69 66 28 20 73 7a 21 3d 55 55 49 44 5f 53    if( sz!=UUID_S
05c0: 49 5a 45 20 7c 7c 20 21 76 61 6c 69 64 61 74 65  IZE || !validate
05d0: 31 36 28 7a 55 75 69 64 2c 20 73 7a 29 20 29 7b  16(zUuid, sz) ){
05e0: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
05f0: 20 7d 0a 20 20 73 74 72 63 70 79 28 7a 2c 20 7a   }.  strcpy(z, z
0600: 55 75 69 64 29 3b 0a 20 20 63 61 6e 6f 6e 69 63  Uuid);.  canonic
0610: 61 6c 31 36 28 7a 2c 20 73 7a 29 3b 0a 20 20 72  al16(z, sz);.  r
0620: 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20 22  id = db_int(0, "
0630: 53 45 4c 45 43 54 20 72 69 64 20 46 52 4f 4d 20  SELECT rid FROM 
0640: 62 6c 6f 62 20 57 48 45 52 45 20 75 75 69 64 3d  blob WHERE uuid=
0650: 25 51 22 2c 20 7a 29 3b 0a 20 20 69 66 28 20 72  %Q", z);.  if( r
0660: 69 64 3d 3d 30 20 26 26 20 70 68 61 6e 74 6f 6d  id==0 && phantom
0670: 69 7a 65 20 29 7b 0a 20 20 20 20 72 69 64 20 3d  ize ){.    rid =
0680: 20 63 6f 6e 74 65 6e 74 5f 70 75 74 28 30 2c 20   content_put(0, 
0690: 7a 55 75 69 64 29 3b 0a 20 20 7d 0a 20 20 72 65  zUuid);.  }.  re
06a0: 74 75 72 6e 20 72 69 64 3b 0a 7d 0a 0a 2f 2a 0a  turn rid;.}../*.
06b0: 2a 2a 20 42 75 69 6c 64 20 61 20 63 61 74 61 6c  ** Build a catal
06c0: 6f 67 20 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20  og of all files 
06d0: 69 6e 20 61 20 62 61 73 65 6c 69 6e 65 2e 0a 2a  in a baseline..*
06e0: 2a 20 57 65 20 73 63 61 6e 20 74 68 65 20 62 61  * We scan the ba
06f0: 73 65 6c 69 6e 65 20 66 69 6c 65 20 66 6f 72 20  seline file for 
0700: 6c 69 6e 65 73 20 6f 66 20 74 68 65 20 66 6f 72  lines of the for
0710: 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 46 20 4e  m:.**.**     F N
0720: 41 4d 45 20 55 55 49 44 0a 2a 2a 0a 2a 2a 20 45  AME UUID.**.** E
0730: 61 63 68 20 73 75 63 68 20 6c 69 6e 65 20 6d 61  ach such line ma
0740: 6b 65 73 20 61 6e 20 65 6e 74 72 79 20 69 6e 20  kes an entry in 
0750: 74 68 65 20 56 46 49 4c 45 20 74 61 62 6c 65 2e  the VFILE table.
0760: 0a 2a 2f 0a 76 6f 69 64 20 76 66 69 6c 65 5f 62  .*/.void vfile_b
0770: 75 69 6c 64 28 69 6e 74 20 76 69 64 2c 20 42 6c  uild(int vid, Bl
0780: 6f 62 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 69  ob *p){.  int ri
0790: 64 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  d;.  char *zName
07a0: 2c 20 2a 7a 55 75 69 64 3b 0a 20 20 53 74 6d 74  , *zUuid;.  Stmt
07b0: 20 69 6e 73 3b 0a 20 20 42 6c 6f 62 20 6c 69 6e   ins;.  Blob lin
07c0: 65 2c 20 74 6f 6b 65 6e 2c 20 6e 61 6d 65 2c 20  e, token, name, 
07d0: 75 75 69 64 3b 0a 20 20 69 6e 74 20 73 65 65 6e  uuid;.  int seen
07e0: 48 65 61 64 65 72 20 3d 20 30 3b 0a 20 20 64 62  Header = 0;.  db
07f0: 5f 62 65 67 69 6e 5f 74 72 61 6e 73 61 63 74 69  _begin_transacti
0800: 6f 6e 28 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69  on();.  db_multi
0810: 5f 65 78 65 63 28 22 44 45 4c 45 54 45 20 46 52  _exec("DELETE FR
0820: 4f 4d 20 76 66 69 6c 65 20 57 48 45 52 45 20 76  OM vfile WHERE v
0830: 69 64 3d 25 64 22 2c 20 76 69 64 29 3b 0a 20 20  id=%d", vid);.  
0840: 64 62 5f 70 72 65 70 61 72 65 28 26 69 6e 73 2c  db_prepare(&ins,
0850: 0a 20 20 20 20 22 49 4e 53 45 52 54 20 49 4e 54  .    "INSERT INT
0860: 4f 20 76 66 69 6c 65 28 76 69 64 2c 72 69 64 2c  O vfile(vid,rid,
0870: 6d 72 69 64 2c 70 61 74 68 6e 61 6d 65 29 20 22  mrid,pathname) "
0880: 0a 20 20 20 20 22 20 56 41 4c 55 45 53 28 3a 76  .    " VALUES(:v
0890: 69 64 2c 3a 69 64 2c 3a 69 64 2c 3a 6e 61 6d 65  id,:id,:id,:name
08a0: 29 22 29 3b 0a 20 20 64 62 5f 62 69 6e 64 5f 69  )");.  db_bind_i
08b0: 6e 74 28 26 69 6e 73 2c 20 22 3a 76 69 64 22 2c  nt(&ins, ":vid",
08c0: 20 76 69 64 29 3b 0a 20 20 77 68 69 6c 65 28 20   vid);.  while( 
08d0: 62 6c 6f 62 5f 6c 69 6e 65 28 70 2c 20 26 6c 69  blob_line(p, &li
08e0: 6e 65 29 20 29 7b 0a 20 20 20 20 63 68 61 72 20  ne) ){.    char 
08f0: 2a 7a 20 3d 20 62 6c 6f 62 5f 62 75 66 66 65 72  *z = blob_buffer
0900: 28 26 6c 69 6e 65 29 3b 0a 20 20 20 20 69 66 28  (&line);.    if(
0910: 20 7a 5b 30 5d 3d 3d 27 2d 27 20 29 7b 0a 20 20   z[0]=='-' ){.  
0920: 20 20 20 20 69 66 28 20 73 65 65 6e 48 65 61 64      if( seenHead
0930: 65 72 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  er ) break;.    
0940: 20 20 77 68 69 6c 65 28 20 62 6c 6f 62 5f 6c 69    while( blob_li
0950: 6e 65 28 70 2c 20 26 6c 69 6e 65 29 3e 31 20 29  ne(p, &line)>1 )
0960: 7b 7d 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f  {}.      if( blo
0970: 62 5f 6c 69 6e 65 28 70 2c 20 26 6c 69 6e 65 29  b_line(p, &line)
0980: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==0 ) break;.   
0990: 20 7d 0a 20 20 20 20 73 65 65 6e 48 65 61 64 65   }.    seenHeade
09a0: 72 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 7a  r = 1;.    if( z
09b0: 5b 30 5d 21 3d 27 46 27 20 7c 7c 20 7a 5b 31 5d  [0]!='F' || z[1]
09c0: 21 3d 27 20 27 20 29 20 63 6f 6e 74 69 6e 75 65  !=' ' ) continue
09d0: 3b 0a 20 20 20 20 62 6c 6f 62 5f 74 6f 6b 65 6e  ;.    blob_token
09e0: 28 26 6c 69 6e 65 2c 20 26 74 6f 6b 65 6e 29 3b  (&line, &token);
09f0: 20 20 2f 2a 20 53 6b 69 70 20 74 68 65 20 22 46    /* Skip the "F
0a00: 22 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 20 20 69  " token */.    i
0a10: 66 28 20 62 6c 6f 62 5f 74 6f 6b 65 6e 28 26 6c  f( blob_token(&l
0a20: 69 6e 65 2c 20 26 6e 61 6d 65 29 3d 3d 30 20 29  ine, &name)==0 )
0a30: 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66 28 20   break;.    if( 
0a40: 62 6c 6f 62 5f 74 6f 6b 65 6e 28 26 6c 69 6e 65  blob_token(&line
0a50: 2c 20 26 75 75 69 64 29 3d 3d 30 20 29 20 62 72  , &uuid)==0 ) br
0a60: 65 61 6b 3b 0a 20 20 20 20 7a 4e 61 6d 65 20 3d  eak;.    zName =
0a70: 20 62 6c 6f 62 5f 73 74 72 28 26 6e 61 6d 65 29   blob_str(&name)
0a80: 3b 0a 20 20 20 20 64 65 66 6f 73 73 69 6c 69 7a  ;.    defossiliz
0a90: 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 7a 55  e(zName);.    zU
0aa0: 75 69 64 20 3d 20 62 6c 6f 62 5f 73 74 72 28 26  uid = blob_str(&
0ab0: 75 75 69 64 29 3b 0a 20 20 20 20 72 69 64 20 3d  uuid);.    rid =
0ac0: 20 75 75 69 64 5f 74 6f 5f 72 69 64 28 7a 55 75   uuid_to_rid(zUu
0ad0: 69 64 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20  id, 0);.    if( 
0ae0: 72 69 64 3e 30 20 26 26 20 66 69 6c 65 5f 69 73  rid>0 && file_is
0af0: 5f 73 69 6d 70 6c 65 5f 70 61 74 68 6e 61 6d 65  _simple_pathname
0b00: 28 7a 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20 20  (zName) ){.     
0b10: 20 64 62 5f 62 69 6e 64 5f 69 6e 74 28 26 69 6e   db_bind_int(&in
0b20: 73 2c 20 22 3a 69 64 22 2c 20 72 69 64 29 3b 0a  s, ":id", rid);.
0b30: 20 20 20 20 20 20 64 62 5f 62 69 6e 64 5f 74 65        db_bind_te
0b40: 78 74 28 26 69 6e 73 2c 20 22 3a 6e 61 6d 65 22  xt(&ins, ":name"
0b50: 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20  , zName);.      
0b60: 64 62 5f 73 74 65 70 28 26 69 6e 73 29 3b 0a 20  db_step(&ins);. 
0b70: 20 20 20 20 20 64 62 5f 72 65 73 65 74 28 26 69       db_reset(&i
0b80: 6e 73 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62  ns);.    }.    b
0b90: 6c 6f 62 5f 72 65 73 65 74 28 26 6e 61 6d 65 29  lob_reset(&name)
0ba0: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74  ;.    blob_reset
0bb0: 28 26 75 75 69 64 29 3b 0a 20 20 7d 0a 20 20 64  (&uuid);.  }.  d
0bc0: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 69 6e 73 29  b_finalize(&ins)
0bd0: 3b 0a 20 20 64 62 5f 65 6e 64 5f 74 72 61 6e 73  ;.  db_end_trans
0be0: 61 63 74 69 6f 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a  action(0);.}../*
0bf0: 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65 20 66 69  .** Check the fi
0c00: 6c 65 20 73 69 67 6e 61 74 75 72 65 20 6f 66 20  le signature of 
0c10: 74 68 65 20 64 69 73 6b 20 69 6d 61 67 65 20 66  the disk image f
0c20: 6f 72 20 65 76 65 72 79 20 56 46 49 4c 45 20 6f  or every VFILE o
0c30: 66 20 76 69 64 2e 0a 2a 2a 0a 2a 2a 20 53 65 74  f vid..**.** Set
0c40: 20 74 68 65 20 56 46 49 4c 45 2e 43 48 4e 47 45   the VFILE.CHNGE
0c50: 44 20 66 69 65 6c 64 20 6f 6e 20 65 76 65 72 79  D field on every
0c60: 20 66 69 6c 65 20 74 68 61 74 20 68 61 73 20 63   file that has c
0c70: 68 61 6e 67 65 64 2e 20 20 41 6c 73 6f 20 0a 2a  hanged.  Also .*
0c80: 2a 20 73 65 74 20 56 46 49 4c 45 2e 43 48 4e 47  * set VFILE.CHNG
0c90: 45 44 20 6f 6e 20 65 76 65 72 79 20 66 6f 6c 64  ED on every fold
0ca0: 65 72 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  er that contains
0cb0: 20 61 20 66 69 6c 65 20 6f 72 20 66 6f 6c 64 65   a file or folde
0cc0: 72 20 0a 2a 2a 20 74 68 61 74 20 68 61 73 20 63  r .** that has c
0cd0: 68 61 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66  hanged..**.** If
0ce0: 20 56 46 49 4c 45 2e 44 45 4c 45 54 45 44 20 69   VFILE.DELETED i
0cf0: 73 20 6e 75 6c 6c 20 6f 72 20 69 66 20 56 46 49  s null or if VFI
0d00: 4c 45 2e 52 49 44 20 69 73 20 7a 65 72 6f 2c 20  LE.RID is zero, 
0d10: 74 68 65 6e 20 77 65 20 63 61 6e 20 61 73 73 75  then we can assu
0d20: 6d 65 0a 2a 2a 20 74 68 65 20 66 69 6c 65 20 68  me.** the file h
0d30: 61 73 20 63 68 61 6e 67 65 64 20 77 69 74 68 6f  as changed witho
0d40: 75 74 20 68 61 76 69 6e 67 20 74 68 65 20 63 68  ut having the ch
0d50: 65 63 6b 20 74 68 65 20 6f 6e 2d 64 69 73 6b 20  eck the on-disk 
0d60: 69 6d 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 76  image..*/.void v
0d70: 66 69 6c 65 5f 63 68 65 63 6b 5f 73 69 67 6e 61  file_check_signa
0d80: 74 75 72 65 28 69 6e 74 20 76 69 64 29 7b 0a 20  ture(int vid){. 
0d90: 20 53 74 6d 74 20 71 3b 0a 20 20 42 6c 6f 62 20   Stmt q;.  Blob 
0da0: 66 69 6c 65 43 6b 73 75 6d 2c 20 6f 72 69 67 43  fileCksum, origC
0db0: 6b 73 75 6d 3b 0a 0a 20 20 64 62 5f 62 65 67 69  ksum;..  db_begi
0dc0: 6e 5f 74 72 61 6e 73 61 63 74 69 6f 6e 28 29 3b  n_transaction();
0dd0: 0a 20 20 64 62 5f 70 72 65 70 61 72 65 28 26 71  .  db_prepare(&q
0de0: 2c 20 22 53 45 4c 45 43 54 20 69 64 2c 20 25 51  , "SELECT id, %Q
0df0: 20 7c 7c 20 70 61 74 68 6e 61 6d 65 2c 22 0a 20   || pathname,". 
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e10: 22 20 20 20 20 20 20 20 76 66 69 6c 65 2e 6d 72  "       vfile.mr
0e20: 69 64 2c 20 64 65 6c 65 74 65 64 2c 20 63 68 6e  id, deleted, chn
0e30: 67 65 64 2c 20 75 75 69 64 22 0a 20 20 20 20 20  ged, uuid".     
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 22 20 20 46              "  F
0e50: 52 4f 4d 20 76 66 69 6c 65 20 4c 45 46 54 20 4a  ROM vfile LEFT J
0e60: 4f 49 4e 20 62 6c 6f 62 20 4f 4e 20 76 66 69 6c  OIN blob ON vfil
0e70: 65 2e 6d 72 69 64 3d 62 6c 6f 62 2e 72 69 64 22  e.mrid=blob.rid"
0e80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0e90: 20 20 22 20 57 48 45 52 45 20 76 69 64 3d 25 64    " WHERE vid=%d
0ea0: 20 22 2c 20 67 2e 7a 4c 6f 63 61 6c 52 6f 6f 74   ", g.zLocalRoot
0eb0: 2c 20 76 69 64 29 3b 0a 20 20 77 68 69 6c 65 28  , vid);.  while(
0ec0: 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51   db_step(&q)==SQ
0ed0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
0ee0: 69 6e 74 20 69 64 2c 20 72 69 64 2c 20 69 73 44  int id, rid, isD
0ef0: 65 6c 65 74 65 64 3b 0a 20 20 20 20 63 6f 6e 73  eleted;.    cons
0f00: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20  t char *zName;. 
0f10: 20 20 20 69 6e 74 20 63 68 6e 67 65 64 20 3d 20     int chnged = 
0f20: 30 3b 0a 20 20 20 20 69 6e 74 20 6f 6c 64 43 68  0;.    int oldCh
0f30: 6e 67 65 64 3b 0a 0a 20 20 20 20 69 64 20 3d 20  nged;..    id = 
0f40: 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71  db_column_int(&q
0f50: 2c 20 30 29 3b 0a 20 20 20 20 7a 4e 61 6d 65 20  , 0);.    zName 
0f60: 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74  = db_column_text
0f70: 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 72 69 64  (&q, 1);.    rid
0f80: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74   = db_column_int
0f90: 28 26 71 2c 20 32 29 3b 0a 20 20 20 20 69 73 44  (&q, 2);.    isD
0fa0: 65 6c 65 74 65 64 20 3d 20 64 62 5f 63 6f 6c 75  eleted = db_colu
0fb0: 6d 6e 5f 69 6e 74 28 26 71 2c 20 33 29 3b 0a 20  mn_int(&q, 3);. 
0fc0: 20 20 20 6f 6c 64 43 68 6e 67 65 64 20 3d 20 64     oldChnged = d
0fd0: 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c  b_column_int(&q,
0fe0: 20 34 29 3b 0a 20 20 20 20 69 66 28 20 6f 6c 64   4);.    if( old
0ff0: 43 68 6e 67 65 64 3e 3d 32 20 29 7b 0a 20 20 20  Chnged>=2 ){.   
1000: 20 20 20 63 68 6e 67 65 64 20 3d 20 6f 6c 64 43     chnged = oldC
1010: 68 6e 67 65 64 3b 0a 20 20 20 20 7d 65 6c 73 65  hnged;.    }else
1020: 20 69 66 28 20 69 73 44 65 6c 65 74 65 64 20 7c   if( isDeleted |
1030: 7c 20 72 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20  | rid==0 ){.    
1040: 20 20 63 68 6e 67 65 64 20 3d 20 31 3b 0a 20 20    chnged = 1;.  
1050: 20 20 7d 0a 20 20 20 20 69 66 28 20 63 68 6e 67    }.    if( chng
1060: 65 64 21 3d 31 20 29 7b 0a 20 20 20 20 20 20 64  ed!=1 ){.      d
1070: 62 5f 65 70 68 65 6d 65 72 61 6c 5f 62 6c 6f 62  b_ephemeral_blob
1080: 28 26 71 2c 20 35 2c 20 26 6f 72 69 67 43 6b 73  (&q, 5, &origCks
1090: 75 6d 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73  um);.      if( s
10a0: 68 61 31 73 75 6d 5f 66 69 6c 65 28 7a 4e 61 6d  ha1sum_file(zNam
10b0: 65 2c 20 26 66 69 6c 65 43 6b 73 75 6d 29 20 29  e, &fileCksum) )
10c0: 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 7a  {.        blob_z
10d0: 65 72 6f 28 26 66 69 6c 65 43 6b 73 75 6d 29 3b  ero(&fileCksum);
10e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
10f0: 66 28 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28  f( blob_compare(
1100: 26 66 69 6c 65 43 6b 73 75 6d 2c 20 26 6f 72 69  &fileCksum, &ori
1110: 67 43 6b 73 75 6d 29 20 29 7b 0a 20 20 20 20 20  gCksum) ){.     
1120: 20 20 20 63 68 6e 67 65 64 20 3d 20 31 3b 0a 20     chnged = 1;. 
1130: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 6c 6f       }.      blo
1140: 62 5f 72 65 73 65 74 28 26 6f 72 69 67 43 6b 73  b_reset(&origCks
1150: 75 6d 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f  um);.      blob_
1160: 72 65 73 65 74 28 26 66 69 6c 65 43 6b 73 75 6d  reset(&fileCksum
1170: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
1180: 20 63 68 6e 67 65 64 21 3d 6f 6c 64 43 68 6e 67   chnged!=oldChng
1190: 65 64 20 29 7b 0a 20 20 20 20 20 20 64 62 5f 6d  ed ){.      db_m
11a0: 75 6c 74 69 5f 65 78 65 63 28 22 55 50 44 41 54  ulti_exec("UPDAT
11b0: 45 20 76 66 69 6c 65 20 53 45 54 20 63 68 6e 67  E vfile SET chng
11c0: 65 64 3d 25 64 20 57 48 45 52 45 20 69 64 3d 25  ed=%d WHERE id=%
11d0: 64 22 2c 20 63 68 6e 67 65 64 2c 20 69 64 29 3b  d", chnged, id);
11e0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 64 62 5f  .    }.  }.  db_
11f0: 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20  finalize(&q);.  
1200: 64 62 5f 65 6e 64 5f 74 72 61 6e 73 61 63 74 69  db_end_transacti
1210: 6f 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  on(0);.}../*.** 
1220: 57 72 69 74 65 20 61 6c 6c 20 66 69 6c 65 73 20  Write all files 
1230: 66 72 6f 6d 20 76 69 64 20 74 6f 20 74 68 65 20  from vid to the 
1240: 64 69 73 6b 2e 20 20 4f 72 20 69 66 20 76 69 64  disk.  Or if vid
1250: 3d 3d 30 20 61 6e 64 20 69 64 21 3d 30 0a 2a 2a  ==0 and id!=0.**
1260: 20 77 72 69 74 65 20 6a 75 73 74 20 74 68 65 20   write just the 
1270: 73 70 65 63 69 66 69 63 20 66 69 6c 65 20 77 68  specific file wh
1280: 65 72 65 20 56 46 49 4c 45 2e 49 44 3d 69 64 2e  ere VFILE.ID=id.
1290: 0a 2a 2f 0a 76 6f 69 64 20 76 66 69 6c 65 5f 74  .*/.void vfile_t
12a0: 6f 5f 64 69 73 6b 28 69 6e 74 20 76 69 64 2c 20  o_disk(int vid, 
12b0: 69 6e 74 20 69 64 2c 20 69 6e 74 20 76 65 72 62  int id, int verb
12c0: 6f 73 65 29 7b 0a 20 20 53 74 6d 74 20 71 3b 0a  ose){.  Stmt q;.
12d0: 20 20 42 6c 6f 62 20 63 6f 6e 74 65 6e 74 3b 0a    Blob content;.
12e0: 20 20 69 6e 74 20 6e 52 65 70 6f 73 20 3d 20 73    int nRepos = s
12f0: 74 72 6c 65 6e 28 67 2e 7a 4c 6f 63 61 6c 52 6f  trlen(g.zLocalRo
1300: 6f 74 29 3b 0a 0a 20 20 69 66 28 20 76 69 64 3e  ot);..  if( vid>
1310: 30 20 26 26 20 69 64 3d 3d 30 20 29 7b 0a 20 20  0 && id==0 ){.  
1320: 20 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c    db_prepare(&q,
1330: 20 22 53 45 4c 45 43 54 20 69 64 2c 20 25 51 20   "SELECT id, %Q 
1340: 7c 7c 20 70 61 74 68 6e 61 6d 65 2c 20 6d 72 69  || pathname, mri
1350: 64 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  d".             
1360: 20 20 20 20 20 20 22 20 20 46 52 4f 4d 20 76 66        "  FROM vf
1370: 69 6c 65 22 0a 20 20 20 20 20 20 20 20 20 20 20  ile".           
1380: 20 20 20 20 20 20 20 20 22 20 57 48 45 52 45 20          " WHERE 
1390: 76 69 64 3d 25 64 20 41 4e 44 20 6d 72 69 64 3e  vid=%d AND mrid>
13a0: 30 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  0",.            
13b0: 20 20 20 20 20 20 20 67 2e 7a 4c 6f 63 61 6c 52         g.zLocalR
13c0: 6f 6f 74 2c 20 76 69 64 29 3b 0a 20 20 7d 65 6c  oot, vid);.  }el
13d0: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
13e0: 76 69 64 3d 3d 30 20 26 26 20 69 64 3e 30 20 29  vid==0 && id>0 )
13f0: 3b 0a 20 20 20 20 64 62 5f 70 72 65 70 61 72 65  ;.    db_prepare
1400: 28 26 71 2c 20 22 53 45 4c 45 43 54 20 69 64 2c  (&q, "SELECT id,
1410: 20 25 51 20 7c 7c 20 70 61 74 68 6e 61 6d 65 2c   %Q || pathname,
1420: 20 6d 72 69 64 22 0a 20 20 20 20 20 20 20 20 20   mrid".         
1430: 20 20 20 20 20 20 20 20 20 20 22 20 20 46 52 4f            "  FRO
1440: 4d 20 76 66 69 6c 65 22 0a 20 20 20 20 20 20 20  M vfile".       
1450: 20 20 20 20 20 20 20 20 20 20 20 20 22 20 57 48              " WH
1460: 45 52 45 20 69 64 3d 25 64 20 41 4e 44 20 6d 72  ERE id=%d AND mr
1470: 69 64 3e 30 22 2c 0a 20 20 20 20 20 20 20 20 20  id>0",.         
1480: 20 20 20 20 20 20 20 20 20 20 67 2e 7a 4c 6f 63            g.zLoc
1490: 61 6c 52 6f 6f 74 2c 20 69 64 29 3b 0a 20 20 7d  alRoot, id);.  }
14a0: 0a 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74 65  .  while( db_ste
14b0: 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f  p(&q)==SQLITE_RO
14c0: 57 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 64 2c  W ){.    int id,
14d0: 20 72 69 64 3b 0a 20 20 20 20 63 6f 6e 73 74 20   rid;.    const 
14e0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 0a 20 20  char *zName;..  
14f0: 20 20 69 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e    id = db_column
1500: 5f 69 6e 74 28 26 71 2c 20 30 29 3b 0a 20 20 20  _int(&q, 0);.   
1510: 20 7a 4e 61 6d 65 20 3d 20 64 62 5f 63 6f 6c 75   zName = db_colu
1520: 6d 6e 5f 74 65 78 74 28 26 71 2c 20 31 29 3b 0a  mn_text(&q, 1);.
1530: 20 20 20 20 72 69 64 20 3d 20 64 62 5f 63 6f 6c      rid = db_col
1540: 75 6d 6e 5f 69 6e 74 28 26 71 2c 20 32 29 3b 0a  umn_int(&q, 2);.
1550: 20 20 20 20 63 6f 6e 74 65 6e 74 5f 67 65 74 28      content_get(
1560: 72 69 64 2c 20 26 63 6f 6e 74 65 6e 74 29 3b 0a  rid, &content);.
1570: 20 20 20 20 69 66 28 20 76 65 72 62 6f 73 65 20      if( verbose 
1580: 29 20 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c  ) printf("%s\n",
1590: 20 26 7a 4e 61 6d 65 5b 6e 52 65 70 6f 73 5d 29   &zName[nRepos])
15a0: 3b 0a 20 20 20 20 62 6c 6f 62 5f 77 72 69 74 65  ;.    blob_write
15b0: 5f 74 6f 5f 66 69 6c 65 28 26 63 6f 6e 74 65 6e  _to_file(&conten
15c0: 74 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20  t, zName);.  }. 
15d0: 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29   db_finalize(&q)
15e0: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65  ;.}.../*.** Dele
15f0: 74 65 20 66 72 6f 6d 20 74 68 65 20 64 69 73 6b  te from the disk
1600: 20 65 76 65 72 79 20 66 69 6c 65 20 69 6e 20 56   every file in V
1610: 46 49 4c 45 20 76 69 64 2e 0a 2a 2f 0a 76 6f 69  FILE vid..*/.voi
1620: 64 20 76 66 69 6c 65 5f 75 6e 6c 69 6e 6b 28 69  d vfile_unlink(i
1630: 6e 74 20 76 69 64 29 7b 0a 20 20 53 74 6d 74 20  nt vid){.  Stmt 
1640: 71 3b 0a 20 20 64 62 5f 70 72 65 70 61 72 65 28  q;.  db_prepare(
1650: 26 71 2c 20 22 53 45 4c 45 43 54 20 25 51 20 7c  &q, "SELECT %Q |
1660: 7c 20 70 61 74 68 6e 61 6d 65 20 46 52 4f 4d 20  | pathname FROM 
1670: 76 66 69 6c 65 22 0a 20 20 20 20 20 20 20 20 20  vfile".         
1680: 20 20 20 20 20 20 20 20 22 20 57 48 45 52 45 20          " WHERE 
1690: 76 69 64 3d 25 64 20 41 4e 44 20 6d 72 69 64 3e  vid=%d AND mrid>
16a0: 30 22 2c 20 67 2e 7a 4c 6f 63 61 6c 52 6f 6f 74  0", g.zLocalRoot
16b0: 2c 20 76 69 64 29 3b 0a 20 20 77 68 69 6c 65 28  , vid);.  while(
16c0: 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51   db_step(&q)==SQ
16d0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
16e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
16f0: 65 3b 0a 0a 20 20 20 20 7a 4e 61 6d 65 20 3d 20  e;..    zName = 
1700: 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 26  db_column_text(&
1710: 71 2c 20 30 29 3b 0a 20 20 20 20 75 6e 6c 69 6e  q, 0);.    unlin
1720: 6b 28 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20  k(zName);.  }.  
1730: 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b  db_finalize(&q);
1740: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 61 64 20 69  .}../*.** Load i
1750: 6e 74 6f 20 74 61 62 6c 65 20 53 46 49 4c 45 20  nto table SFILE 
1760: 74 68 65 20 6e 61 6d 65 20 6f 66 20 65 76 65 72  the name of ever
1770: 79 20 6f 72 64 69 6e 61 72 79 20 66 69 6c 65 20  y ordinary file 
1780: 69 6e 0a 2a 2a 20 74 68 65 20 64 69 72 65 63 74  in.** the direct
1790: 6f 72 79 20 70 50 61 74 68 2e 20 20 53 75 62 64  ory pPath.  Subd
17a0: 69 72 65 63 74 6f 72 69 65 73 20 61 72 65 20 73  irectories are s
17b0: 63 61 6e 6e 65 64 20 72 65 63 75 72 73 69 76 65  canned recursive
17c0: 6c 79 2e 0a 2a 2a 20 4f 6d 69 74 20 66 69 6c 65  ly..** Omit file
17d0: 73 20 6e 61 6d 65 64 20 69 6e 20 56 46 49 4c 45  s named in VFILE
17e0: 2e 76 69 64 0a 2a 2f 0a 76 6f 69 64 20 76 66 69  .vid.*/.void vfi
17f0: 6c 65 5f 73 63 61 6e 28 69 6e 74 20 76 69 64 2c  le_scan(int vid,
1800: 20 42 6c 6f 62 20 2a 70 50 61 74 68 29 7b 0a 20   Blob *pPath){. 
1810: 20 44 49 52 20 2a 64 3b 0a 20 20 69 6e 74 20 6f   DIR *d;.  int o
1820: 72 69 67 53 69 7a 65 3b 0a 20 20 63 6f 6e 73 74  rigSize;.  const
1830: 20 63 68 61 72 20 2a 7a 44 69 72 3b 0a 20 20 63   char *zDir;.  c
1840: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d  onst char *zForm
1850: 61 74 3b 0a 20 20 73 74 72 75 63 74 20 64 69 72  at;.  struct dir
1860: 65 6e 74 20 2a 70 45 6e 74 72 79 3b 0a 20 20 73  ent *pEntry;.  s
1870: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
1880: 20 2a 7a 53 71 6c 20 3d 20 22 53 45 4c 45 43 54   *zSql = "SELECT
1890: 20 31 20 46 52 4f 4d 20 76 66 69 6c 65 20 22 0a   1 FROM vfile ".
18a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18b0: 20 20 20 20 20 20 20 20 20 20 20 20 22 20 57 48              " WH
18c0: 45 52 45 20 70 61 74 68 6e 61 6d 65 3d 25 42 20  ERE pathname=%B 
18d0: 41 4e 44 20 4e 4f 54 20 64 65 6c 65 74 65 64 22  AND NOT deleted"
18e0: 3b 0a 0a 20 20 6f 72 69 67 53 69 7a 65 20 3d 20  ;..  origSize = 
18f0: 62 6c 6f 62 5f 73 69 7a 65 28 70 50 61 74 68 29  blob_size(pPath)
1900: 3b 0a 20 20 7a 44 69 72 20 3d 20 62 6c 6f 62 5f  ;.  zDir = blob_
1910: 73 74 72 28 70 50 61 74 68 29 3b 0a 20 20 69 66  str(pPath);.  if
1920: 28 20 7a 44 69 72 5b 30 5d 3d 3d 30 20 29 7b 0a  ( zDir[0]==0 ){.
1930: 20 20 20 20 20 7a 44 69 72 20 3d 20 22 2e 22 3b       zDir = ".";
1940: 0a 20 20 20 20 20 7a 46 6f 72 6d 61 74 20 3d 20  .     zFormat = 
1950: 22 25 73 22 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  "%s";.  }else{. 
1960: 20 20 20 20 7a 46 6f 72 6d 61 74 20 3d 20 22 2f      zFormat = "/
1970: 25 73 22 3b 0a 20 20 7d 0a 20 20 64 20 3d 20 6f  %s";.  }.  d = o
1980: 70 65 6e 64 69 72 28 7a 44 69 72 29 3b 0a 20 20  pendir(zDir);.  
1990: 69 66 28 20 64 20 29 7b 0a 20 20 20 20 77 68 69  if( d ){.    whi
19a0: 6c 65 28 20 28 70 45 6e 74 72 79 3d 72 65 61 64  le( (pEntry=read
19b0: 64 69 72 28 64 29 29 21 3d 30 20 29 7b 0a 20 20  dir(d))!=0 ){.  
19c0: 20 20 20 20 63 68 61 72 20 2a 7a 50 61 74 68 3b      char *zPath;
19d0: 0a 20 20 20 20 20 20 69 66 28 20 70 45 6e 74 72  .      if( pEntr
19e0: 79 2d 3e 64 5f 6e 61 6d 65 5b 30 5d 3d 3d 27 2e  y->d_name[0]=='.
19f0: 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  ' ) continue;.  
1a00: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
1a10: 28 70 50 61 74 68 2c 20 7a 46 6f 72 6d 61 74 2c  (pPath, zFormat,
1a20: 20 70 45 6e 74 72 79 2d 3e 64 5f 6e 61 6d 65 29   pEntry->d_name)
1a30: 3b 0a 20 20 20 20 20 20 7a 50 61 74 68 20 3d 20  ;.      zPath = 
1a40: 62 6c 6f 62 5f 73 74 72 28 70 50 61 74 68 29 3b  blob_str(pPath);
1a50: 0a 20 20 20 20 20 20 69 66 28 20 66 69 6c 65 5f  .      if( file_
1a60: 69 73 64 69 72 28 7a 50 61 74 68 29 3d 3d 31 20  isdir(zPath)==1 
1a70: 29 7b 0a 20 20 20 20 20 20 20 20 76 66 69 6c 65  ){.        vfile
1a80: 5f 73 63 61 6e 28 76 69 64 2c 20 70 50 61 74 68  _scan(vid, pPath
1a90: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  );.      }else i
1aa0: 66 28 20 66 69 6c 65 5f 69 73 66 69 6c 65 28 7a  f( file_isfile(z
1ab0: 50 61 74 68 29 20 26 26 20 21 64 62 5f 65 78 69  Path) && !db_exi
1ac0: 73 74 73 28 7a 53 71 6c 2c 70 50 61 74 68 29 20  sts(zSql,pPath) 
1ad0: 29 7b 0a 20 20 20 20 20 20 20 20 64 62 5f 6d 75  ){.        db_mu
1ae0: 6c 74 69 5f 65 78 65 63 28 22 49 4e 53 45 52 54  lti_exec("INSERT
1af0: 20 49 4e 54 4f 20 73 66 69 6c 65 20 56 41 4c 55   INTO sfile VALU
1b00: 45 53 28 25 42 29 22 2c 20 70 50 61 74 68 29 3b  ES(%B)", pPath);
1b10: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
1b20: 6c 6f 62 5f 72 65 73 69 7a 65 28 70 50 61 74 68  lob_resize(pPath
1b30: 2c 20 6f 72 69 67 53 69 7a 65 29 3b 0a 20 20 20  , origSize);.   
1b40: 20 7d 0a 20 20 7d 0a 20 20 63 6c 6f 73 65 64 69   }.  }.  closedi
1b50: 72 28 64 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  r(d);.}../*.** C
1b60: 6f 6d 70 75 74 65 20 61 6e 20 61 67 67 72 65 67  ompute an aggreg
1b70: 61 74 65 20 4d 44 35 20 63 68 65 63 6b 73 75 6d  ate MD5 checksum
1b80: 20 6f 76 65 72 20 74 68 65 20 64 69 73 6b 20 69   over the disk i
1b90: 6d 61 67 65 20 6f 66 20 65 76 65 72 79 0a 2a 2a  mage of every.**
1ba0: 20 66 69 6c 65 20 69 6e 20 76 69 64 2e 20 20 54   file in vid.  T
1bb0: 68 65 20 66 69 6c 65 20 6e 61 6d 65 73 20 61 72  he file names ar
1bc0: 65 20 70 61 72 74 20 6f 66 20 74 68 65 20 63 68  e part of the ch
1bd0: 65 63 6b 73 75 6d 2e 0a 2a 2a 0a 2a 2a 20 54 68  ecksum..**.** Th
1be0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 6f 70 65 72  is function oper
1bf0: 61 74 65 73 20 64 69 66 66 65 72 65 6e 74 6c 79  ates differently
1c00: 20 69 66 20 74 68 65 20 47 6c 6f 62 61 6c 2e 61   if the Global.a
1c10: 43 6f 6d 6d 69 74 46 69 6c 65 0a 2a 2a 20 76 61  CommitFile.** va
1c20: 72 69 61 62 6c 65 20 69 73 20 6e 6f 74 20 4e 55  riable is not NU
1c30: 4c 4c 2e 20 49 6e 20 74 68 61 74 20 63 61 73 65  LL. In that case
1c40: 2c 20 74 68 65 20 64 69 73 6b 20 69 6d 61 67 65  , the disk image
1c50: 20 69 73 20 75 73 65 64 20 66 6f 72 0a 2a 2a 20   is used for.** 
1c60: 65 61 63 68 20 66 69 6c 65 20 69 6e 20 61 43 6f  each file in aCo
1c70: 6d 6d 69 74 46 69 6c 65 5b 5d 20 61 6e 64 20 74  mmitFile[] and t
1c80: 68 65 20 72 65 70 6f 73 69 74 6f 72 79 20 69 6d  he repository im
1c90: 61 67 65 20 28 73 65 65 0a 2a 2a 20 76 66 69 6c  age (see.** vfil
1ca0: 65 5f 61 67 67 72 65 67 61 74 65 5f 63 68 65 63  e_aggregate_chec
1cb0: 6b 73 75 6d 5f 72 65 70 6f 73 69 74 6f 72 79 28  ksum_repository(
1cc0: 29 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 6c  ) is used for al
1cd0: 6c 20 6f 74 68 65 72 73 29 2e 0a 2a 2a 20 4e 65  l others)..** Ne
1ce0: 77 6c 79 20 61 64 64 65 64 20 66 69 6c 65 73 20  wly added files 
1cf0: 74 68 61 74 20 61 72 65 20 6e 6f 74 20 63 6f 6e  that are not con
1d00: 74 61 69 6e 65 64 20 69 6e 20 74 68 65 20 72 65  tained in the re
1d10: 70 6f 73 69 74 6f 72 79 20 61 72 65 0a 2a 2a 20  pository are.** 
1d20: 6f 6d 69 74 74 65 64 20 66 72 6f 6d 20 74 68 65  omitted from the
1d30: 20 63 68 65 63 6b 73 75 6d 20 69 66 20 74 68 65   checksum if the
1d40: 79 20 61 72 65 20 6e 6f 74 20 69 6e 20 47 6c 6f  y are not in Glo
1d50: 62 61 6c 2e 61 43 6f 6d 6d 69 74 46 69 6c 65 2e  bal.aCommitFile.
1d60: 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  .**.** Return th
1d70: 65 20 72 65 73 75 6c 74 69 6e 67 20 63 68 65 63  e resulting chec
1d80: 6b 73 75 6d 20 69 6e 20 62 6c 6f 62 20 70 4f 75  ksum in blob pOu
1d90: 74 2e 0a 2a 2f 0a 76 6f 69 64 20 76 66 69 6c 65  t..*/.void vfile
1da0: 5f 61 67 67 72 65 67 61 74 65 5f 63 68 65 63 6b  _aggregate_check
1db0: 73 75 6d 5f 64 69 73 6b 28 69 6e 74 20 76 69 64  sum_disk(int vid
1dc0: 2c 20 42 6c 6f 62 20 2a 70 4f 75 74 29 7b 0a 20  , Blob *pOut){. 
1dd0: 20 46 49 4c 45 20 2a 69 6e 3b 0a 20 20 53 74 6d   FILE *in;.  Stm
1de0: 74 20 71 3b 0a 20 20 63 68 61 72 20 7a 42 75 66  t q;.  char zBuf
1df0: 5b 34 30 39 36 5d 3b 0a 0a 20 20 64 62 5f 6d 75  [4096];..  db_mu
1e00: 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65  st_be_within_tre
1e10: 65 28 29 3b 0a 20 20 64 62 5f 70 72 65 70 61 72  e();.  db_prepar
1e20: 65 28 26 71 2c 20 0a 20 20 20 20 20 20 22 53 45  e(&q, .      "SE
1e30: 4c 45 43 54 20 25 51 20 7c 7c 20 70 61 74 68 6e  LECT %Q || pathn
1e40: 61 6d 65 2c 20 70 61 74 68 6e 61 6d 65 2c 20 66  ame, pathname, f
1e50: 69 6c 65 5f 69 73 5f 73 65 6c 65 63 74 65 64 28  ile_is_selected(
1e60: 69 64 29 2c 20 72 69 64 20 46 52 4f 4d 20 76 66  id), rid FROM vf
1e70: 69 6c 65 22 0a 20 20 20 20 20 20 22 20 57 48 45  ile".      " WHE
1e80: 52 45 20 4e 4f 54 20 64 65 6c 65 74 65 64 20 41  RE NOT deleted A
1e90: 4e 44 20 76 69 64 3d 25 64 22 0a 20 20 20 20 20  ND vid=%d".     
1ea0: 20 22 20 4f 52 44 45 52 20 42 59 20 70 61 74 68   " ORDER BY path
1eb0: 6e 61 6d 65 22 2c 0a 20 20 20 20 20 20 67 2e 7a  name",.      g.z
1ec0: 4c 6f 63 61 6c 52 6f 6f 74 2c 20 76 69 64 0a 20  LocalRoot, vid. 
1ed0: 20 29 3b 0a 20 20 6d 64 35 73 75 6d 5f 69 6e 69   );.  md5sum_ini
1ee0: 74 28 29 3b 0a 20 20 77 68 69 6c 65 28 20 64 62  t();.  while( db
1ef0: 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54  _step(&q)==SQLIT
1f00: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 63 6f 6e  E_ROW ){.    con
1f10: 73 74 20 63 68 61 72 20 2a 7a 46 75 6c 6c 70 61  st char *zFullpa
1f20: 74 68 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74  th = db_column_t
1f30: 65 78 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20  ext(&q, 0);.    
1f40: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
1f50: 65 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65  e = db_column_te
1f60: 78 74 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 69  xt(&q, 1);.    i
1f70: 6e 74 20 69 73 53 65 6c 65 63 74 65 64 20 3d 20  nt isSelected = 
1f80: 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71  db_column_int(&q
1f90: 2c 20 32 29 3b 0a 0a 20 20 20 20 69 66 28 20 69  , 2);..    if( i
1fa0: 73 53 65 6c 65 63 74 65 64 20 29 7b 0a 20 20 20  sSelected ){.   
1fb0: 20 20 20 6d 64 35 73 75 6d 5f 73 74 65 70 5f 74     md5sum_step_t
1fc0: 65 78 74 28 7a 4e 61 6d 65 2c 20 2d 31 29 3b 0a  ext(zName, -1);.
1fd0: 20 20 20 20 20 20 69 6e 20 3d 20 66 6f 70 65 6e        in = fopen
1fe0: 28 7a 46 75 6c 6c 70 61 74 68 2c 22 72 62 22 29  (zFullpath,"rb")
1ff0: 3b 0a 20 20 20 20 20 20 69 66 28 20 69 6e 3d 3d  ;.      if( in==
2000: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 64 35  0 ){.        md5
2010: 73 75 6d 5f 73 74 65 70 5f 74 65 78 74 28 22 20  sum_step_text(" 
2020: 30 5c 6e 22 2c 20 2d 31 29 3b 0a 20 20 20 20 20  0\n", -1);.     
2030: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
2040: 20 20 20 7d 0a 20 20 20 20 20 20 66 73 65 65 6b     }.      fseek
2050: 28 69 6e 2c 20 30 4c 2c 20 53 45 45 4b 5f 45 4e  (in, 0L, SEEK_EN
2060: 44 29 3b 0a 20 20 20 20 20 20 73 70 72 69 6e 74  D);.      sprint
2070: 66 28 7a 42 75 66 2c 20 22 20 25 6c 64 5c 6e 22  f(zBuf, " %ld\n"
2080: 2c 20 66 74 65 6c 6c 28 69 6e 29 29 3b 0a 20 20  , ftell(in));.  
2090: 20 20 20 20 66 73 65 65 6b 28 69 6e 2c 20 30 4c      fseek(in, 0L
20a0: 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 20 20 20  , SEEK_SET);.   
20b0: 20 20 20 6d 64 35 73 75 6d 5f 73 74 65 70 5f 74     md5sum_step_t
20c0: 65 78 74 28 7a 42 75 66 2c 20 2d 31 29 3b 0a 20  ext(zBuf, -1);. 
20d0: 20 20 20 20 20 66 6f 72 28 3b 3b 29 7b 0a 20 20       for(;;){.  
20e0: 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 20 20 20        int n;.   
20f0: 20 20 20 20 20 6e 20 3d 20 66 72 65 61 64 28 7a       n = fread(z
2100: 42 75 66 2c 20 31 2c 20 73 69 7a 65 6f 66 28 7a  Buf, 1, sizeof(z
2110: 42 75 66 29 2c 20 69 6e 29 3b 0a 20 20 20 20 20  Buf), in);.     
2120: 20 20 20 69 66 28 20 6e 3c 3d 30 20 29 20 62 72     if( n<=0 ) br
2130: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 6d 64 35  eak;.        md5
2140: 73 75 6d 5f 73 74 65 70 5f 74 65 78 74 28 7a 42  sum_step_text(zB
2150: 75 66 2c 20 6e 29 3b 0a 20 20 20 20 20 20 7d 0a  uf, n);.      }.
2160: 20 20 20 20 20 20 66 63 6c 6f 73 65 28 69 6e 29        fclose(in)
2170: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
2180: 20 20 20 69 6e 74 20 72 69 64 20 3d 20 64 62 5f     int rid = db_
2190: 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c 20 33  column_int(&q, 3
21a0: 29 3b 0a 20 20 20 20 20 20 63 68 61 72 20 7a 42  );.      char zB
21b0: 75 66 5b 31 30 30 5d 3b 0a 20 20 20 20 20 20 42  uf[100];.      B
21c0: 6c 6f 62 20 66 69 6c 65 3b 0a 0a 20 20 20 20 20  lob file;..     
21d0: 20 69 66 28 20 72 69 64 3e 30 20 29 7b 0a 20 20   if( rid>0 ){.  
21e0: 20 20 20 20 20 20 6d 64 35 73 75 6d 5f 73 74 65        md5sum_ste
21f0: 70 5f 74 65 78 74 28 7a 4e 61 6d 65 2c 20 2d 31  p_text(zName, -1
2200: 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  );.        blob_
2210: 7a 65 72 6f 28 26 66 69 6c 65 29 3b 0a 20 20 20  zero(&file);.   
2220: 20 20 20 20 20 63 6f 6e 74 65 6e 74 5f 67 65 74       content_get
2230: 28 72 69 64 2c 20 26 66 69 6c 65 29 3b 0a 20 20  (rid, &file);.  
2240: 20 20 20 20 20 20 73 70 72 69 6e 74 66 28 7a 42        sprintf(zB
2250: 75 66 2c 20 22 20 25 64 5c 6e 22 2c 20 62 6c 6f  uf, " %d\n", blo
2260: 62 5f 73 69 7a 65 28 26 66 69 6c 65 29 29 3b 0a  b_size(&file));.
2270: 20 20 20 20 20 20 20 20 6d 64 35 73 75 6d 5f 73          md5sum_s
2280: 74 65 70 5f 74 65 78 74 28 7a 42 75 66 2c 20 2d  tep_text(zBuf, -
2290: 31 29 3b 0a 20 20 20 20 20 20 20 20 6d 64 35 73  1);.        md5s
22a0: 75 6d 5f 73 74 65 70 5f 62 6c 6f 62 28 26 66 69  um_step_blob(&fi
22b0: 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f  le);.        blo
22c0: 62 5f 72 65 73 65 74 28 26 66 69 6c 65 29 3b 0a  b_reset(&file);.
22d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
22e0: 7d 0a 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28  }.  db_finalize(
22f0: 26 71 29 3b 0a 20 20 6d 64 35 73 75 6d 5f 66 69  &q);.  md5sum_fi
2300: 6e 69 73 68 28 70 4f 75 74 29 3b 0a 7d 0a 0a 2f  nish(pOut);.}../
2310: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 6e 20  *.** Compute an 
2320: 61 67 67 72 65 67 61 74 65 20 4d 44 35 20 63 68  aggregate MD5 ch
2330: 65 63 6b 73 75 6d 20 6f 76 65 72 20 74 68 65 20  ecksum over the 
2340: 72 65 70 6f 73 69 74 6f 72 79 20 69 6d 61 67 65  repository image
2350: 20 6f 66 20 65 76 65 72 79 0a 2a 2a 20 66 69 6c   of every.** fil
2360: 65 20 69 6e 20 76 69 64 2e 20 20 54 68 65 20 66  e in vid.  The f
2370: 69 6c 65 20 6e 61 6d 65 73 20 61 72 65 20 70 61  ile names are pa
2380: 72 74 20 6f 66 20 74 68 65 20 63 68 65 63 6b 73  rt of the checks
2390: 75 6d 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  um..**.** Return
23a0: 20 74 68 65 20 72 65 73 75 6c 74 69 6e 67 20 63   the resulting c
23b0: 68 65 63 6b 73 75 6d 20 69 6e 20 62 6c 6f 62 20  hecksum in blob 
23c0: 70 4f 75 74 2e 0a 2a 2f 0a 76 6f 69 64 20 76 66  pOut..*/.void vf
23d0: 69 6c 65 5f 61 67 67 72 65 67 61 74 65 5f 63 68  ile_aggregate_ch
23e0: 65 63 6b 73 75 6d 5f 72 65 70 6f 73 69 74 6f 72  ecksum_repositor
23f0: 79 28 69 6e 74 20 76 69 64 2c 20 42 6c 6f 62 20  y(int vid, Blob 
2400: 2a 70 4f 75 74 29 7b 0a 20 20 42 6c 6f 62 20 66  *pOut){.  Blob f
2410: 69 6c 65 3b 0a 20 20 53 74 6d 74 20 71 3b 0a 20  ile;.  Stmt q;. 
2420: 20 63 68 61 72 20 7a 42 75 66 5b 31 30 30 5d 3b   char zBuf[100];
2430: 0a 0a 20 20 64 62 5f 6d 75 73 74 5f 62 65 5f 77  ..  db_must_be_w
2440: 69 74 68 69 6e 5f 74 72 65 65 28 29 3b 0a 20 20  ithin_tree();.  
2450: 0a 20 20 64 62 5f 70 72 65 70 61 72 65 28 26 71  .  db_prepare(&q
2460: 2c 20 22 53 45 4c 45 43 54 20 70 61 74 68 6e 61  , "SELECT pathna
2470: 6d 65 2c 20 72 69 64 20 46 52 4f 4d 20 76 66 69  me, rid FROM vfi
2480: 6c 65 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  le".            
2490: 20 20 20 20 20 22 20 57 48 45 52 45 20 4e 4f 54       " WHERE NOT
24a0: 20 64 65 6c 65 74 65 64 20 41 4e 44 20 72 69 64   deleted AND rid
24b0: 3e 30 20 41 4e 44 20 76 69 64 3d 25 64 22 0a 20  >0 AND vid=%d". 
24c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24d0: 22 20 4f 52 44 45 52 20 42 59 20 70 61 74 68 6e  " ORDER BY pathn
24e0: 61 6d 65 22 2c 0a 20 20 20 20 20 20 20 20 20 20  ame",.          
24f0: 20 20 20 20 20 20 20 76 69 64 29 3b 0a 20 20 62         vid);.  b
2500: 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65 29 3b  lob_zero(&file);
2510: 0a 20 20 6d 64 35 73 75 6d 5f 69 6e 69 74 28 29  .  md5sum_init()
2520: 3b 0a 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74  ;.  while( db_st
2530: 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52  ep(&q)==SQLITE_R
2540: 4f 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  OW ){.    const 
2550: 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 64 62  char *zName = db
2560: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 26 71 2c  _column_text(&q,
2570: 20 30 29 3b 0a 20 20 20 20 69 6e 74 20 72 69 64   0);.    int rid
2580: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74   = db_column_int
2590: 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 6d 64 35  (&q, 1);.    md5
25a0: 73 75 6d 5f 73 74 65 70 5f 74 65 78 74 28 7a 4e  sum_step_text(zN
25b0: 61 6d 65 2c 20 2d 31 29 3b 0a 20 20 20 20 63 6f  ame, -1);.    co
25c0: 6e 74 65 6e 74 5f 67 65 74 28 72 69 64 2c 20 26  ntent_get(rid, &
25d0: 66 69 6c 65 29 3b 0a 20 20 20 20 73 70 72 69 6e  file);.    sprin
25e0: 74 66 28 7a 42 75 66 2c 20 22 20 25 64 5c 6e 22  tf(zBuf, " %d\n"
25f0: 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 26 66 69 6c  , blob_size(&fil
2600: 65 29 29 3b 0a 20 20 20 20 6d 64 35 73 75 6d 5f  e));.    md5sum_
2610: 73 74 65 70 5f 74 65 78 74 28 7a 42 75 66 2c 20  step_text(zBuf, 
2620: 2d 31 29 3b 0a 20 20 20 20 6d 64 35 73 75 6d 5f  -1);.    md5sum_
2630: 73 74 65 70 5f 62 6c 6f 62 28 26 66 69 6c 65 29  step_blob(&file)
2640: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74  ;.    blob_reset
2650: 28 26 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 64  (&file);.  }.  d
2660: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a  b_finalize(&q);.
2670: 20 20 6d 64 35 73 75 6d 5f 66 69 6e 69 73 68 28    md5sum_finish(
2680: 70 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  pOut);.}../*.** 
2690: 43 6f 6d 70 75 74 65 20 61 6e 20 61 67 67 72 65  Compute an aggre
26a0: 67 61 74 65 20 4d 44 35 20 63 68 65 63 6b 73 75  gate MD5 checksu
26b0: 6d 20 6f 76 65 72 20 74 68 65 20 72 65 70 6f 73  m over the repos
26c0: 69 74 6f 72 79 20 69 6d 61 67 65 20 6f 66 20 65  itory image of e
26d0: 76 65 72 79 0a 2a 2a 20 66 69 6c 65 20 69 6e 20  very.** file in 
26e0: 6d 61 6e 69 66 65 73 74 20 76 69 64 2e 20 20 54  manifest vid.  T
26f0: 68 65 20 66 69 6c 65 20 6e 61 6d 65 73 20 61 72  he file names ar
2700: 65 20 70 61 72 74 20 6f 66 20 74 68 65 20 63 68  e part of the ch
2710: 65 63 6b 73 75 6d 2e 0a 2a 2a 0a 2a 2a 20 52 65  ecksum..**.** Re
2720: 74 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74 69  turn the resulti
2730: 6e 67 20 63 68 65 63 6b 73 75 6d 20 69 6e 20 62  ng checksum in b
2740: 6c 6f 62 20 70 4f 75 74 2e 0a 2a 2f 0a 76 6f 69  lob pOut..*/.voi
2750: 64 20 76 66 69 6c 65 5f 61 67 67 72 65 67 61 74  d vfile_aggregat
2760: 65 5f 63 68 65 63 6b 73 75 6d 5f 6d 61 6e 69 66  e_checksum_manif
2770: 65 73 74 28 69 6e 74 20 76 69 64 2c 20 42 6c 6f  est(int vid, Blo
2780: 62 20 2a 70 4f 75 74 2c 20 42 6c 6f 62 20 2a 70  b *pOut, Blob *p
2790: 4d 61 6e 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69  ManOut){.  int i
27a0: 2c 20 66 69 64 3b 0a 20 20 42 6c 6f 62 20 66 69  , fid;.  Blob fi
27b0: 6c 65 2c 20 6d 66 69 6c 65 3b 0a 20 20 4d 61 6e  le, mfile;.  Man
27c0: 69 66 65 73 74 20 6d 3b 0a 20 20 63 68 61 72 20  ifest m;.  char 
27d0: 7a 42 75 66 5b 31 30 30 5d 3b 0a 0a 20 20 64 62  zBuf[100];..  db
27e0: 5f 6d 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f  _must_be_within_
27f0: 74 72 65 65 28 29 3b 0a 20 20 63 6f 6e 74 65 6e  tree();.  conten
2800: 74 5f 67 65 74 28 76 69 64 2c 20 26 6d 66 69 6c  t_get(vid, &mfil
2810: 65 29 3b 0a 20 20 69 66 28 20 6d 61 6e 69 66 65  e);.  if( manife
2820: 73 74 5f 70 61 72 73 65 28 26 6d 2c 20 26 6d 66  st_parse(&m, &mf
2830: 69 6c 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 62  ile)==0 ){.    b
2840: 6c 6f 62 5f 7a 65 72 6f 28 70 4f 75 74 29 3b 0a  lob_zero(pOut);.
2850: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
2860: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6d 2e 6e    for(i=0; i<m.n
2870: 46 69 6c 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  File; i++){.    
2880: 66 69 64 20 3d 20 75 75 69 64 5f 74 6f 5f 72 69  fid = uuid_to_ri
2890: 64 28 6d 2e 61 46 69 6c 65 5b 69 5d 2e 7a 55 75  d(m.aFile[i].zUu
28a0: 69 64 2c 20 30 29 3b 0a 20 20 20 20 6d 64 35 73  id, 0);.    md5s
28b0: 75 6d 5f 73 74 65 70 5f 74 65 78 74 28 6d 2e 61  um_step_text(m.a
28c0: 46 69 6c 65 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 2d  File[i].zName, -
28d0: 31 29 3b 0a 20 20 20 20 63 6f 6e 74 65 6e 74 5f  1);.    content_
28e0: 67 65 74 28 66 69 64 2c 20 26 66 69 6c 65 29 3b  get(fid, &file);
28f0: 0a 20 20 20 20 73 70 72 69 6e 74 66 28 7a 42 75  .    sprintf(zBu
2900: 66 2c 20 22 20 25 64 5c 6e 22 2c 20 62 6c 6f 62  f, " %d\n", blob
2910: 5f 73 69 7a 65 28 26 66 69 6c 65 29 29 3b 0a 20  _size(&file));. 
2920: 20 20 20 6d 64 35 73 75 6d 5f 73 74 65 70 5f 74     md5sum_step_t
2930: 65 78 74 28 7a 42 75 66 2c 20 2d 31 29 3b 0a 20  ext(zBuf, -1);. 
2940: 20 20 20 6d 64 35 73 75 6d 5f 73 74 65 70 5f 62     md5sum_step_b
2950: 6c 6f 62 28 26 66 69 6c 65 29 3b 0a 20 20 20 20  lob(&file);.    
2960: 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 69 6c 65  blob_reset(&file
2970: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 4d 61  );.  }.  if( pMa
2980: 6e 4f 75 74 20 29 7b 0a 20 20 20 20 62 6c 6f 62  nOut ){.    blob
2990: 5f 7a 65 72 6f 28 70 4d 61 6e 4f 75 74 29 3b 0a  _zero(pManOut);.
29a0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28      blob_append(
29b0: 70 4d 61 6e 4f 75 74 2c 20 6d 2e 7a 52 65 70 6f  pManOut, m.zRepo
29c0: 43 6b 73 75 6d 2c 20 2d 31 29 3b 0a 20 20 7d 0a  Cksum, -1);.  }.
29d0: 20 20 6d 61 6e 69 66 65 73 74 5f 63 6c 65 61 72    manifest_clear
29e0: 28 26 6d 29 3b 0a 20 20 6d 64 35 73 75 6d 5f 66  (&m);.  md5sum_f
29f0: 69 6e 69 73 68 28 70 4f 75 74 29 3b 0a 7d 0a 0a  inish(pOut);.}..
2a00: 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74  /*.** COMMAND: t
2a10: 65 73 74 2d 61 67 67 2d 63 6b 73 75 6d 0a 2a 2f  est-agg-cksum.*/
2a20: 0a 76 6f 69 64 20 74 65 73 74 5f 61 67 67 5f 63  .void test_agg_c
2a30: 6b 73 75 6d 5f 63 6d 64 28 76 6f 69 64 29 7b 0a  ksum_cmd(void){.
2a40: 20 20 69 6e 74 20 76 69 64 3b 0a 20 20 42 6c 6f    int vid;.  Blo
2a50: 62 20 68 61 73 68 2c 20 68 61 73 68 32 3b 0a 20  b hash, hash2;. 
2a60: 20 64 62 5f 6d 75 73 74 5f 62 65 5f 77 69 74 68   db_must_be_with
2a70: 69 6e 5f 74 72 65 65 28 29 3b 0a 20 20 76 69 64  in_tree();.  vid
2a80: 20 3d 20 64 62 5f 6c 67 65 74 5f 69 6e 74 28 22   = db_lget_int("
2a90: 63 68 65 63 6b 6f 75 74 22 2c 20 30 29 3b 0a 20  checkout", 0);. 
2aa0: 20 76 66 69 6c 65 5f 61 67 67 72 65 67 61 74 65   vfile_aggregate
2ab0: 5f 63 68 65 63 6b 73 75 6d 5f 64 69 73 6b 28 76  _checksum_disk(v
2ac0: 69 64 2c 20 26 68 61 73 68 29 3b 0a 20 20 70 72  id, &hash);.  pr
2ad0: 69 6e 74 66 28 22 64 69 73 6b 3a 20 20 20 20 20  intf("disk:     
2ae0: 25 73 5c 6e 22 2c 20 62 6c 6f 62 5f 73 74 72 28  %s\n", blob_str(
2af0: 26 68 61 73 68 29 29 3b 0a 20 20 62 6c 6f 62 5f  &hash));.  blob_
2b00: 72 65 73 65 74 28 26 68 61 73 68 29 3b 0a 20 20  reset(&hash);.  
2b10: 76 66 69 6c 65 5f 61 67 67 72 65 67 61 74 65 5f  vfile_aggregate_
2b20: 63 68 65 63 6b 73 75 6d 5f 72 65 70 6f 73 69 74  checksum_reposit
2b30: 6f 72 79 28 76 69 64 2c 20 26 68 61 73 68 29 3b  ory(vid, &hash);
2b40: 0a 20 20 70 72 69 6e 74 66 28 22 61 72 63 68 69  .  printf("archi
2b50: 76 65 3a 20 20 25 73 5c 6e 22 2c 20 62 6c 6f 62  ve:  %s\n", blob
2b60: 5f 73 74 72 28 26 68 61 73 68 29 29 3b 0a 20 20  _str(&hash));.  
2b70: 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73 68  blob_reset(&hash
2b80: 29 3b 0a 20 20 76 66 69 6c 65 5f 61 67 67 72 65  );.  vfile_aggre
2b90: 67 61 74 65 5f 63 68 65 63 6b 73 75 6d 5f 6d 61  gate_checksum_ma
2ba0: 6e 69 66 65 73 74 28 76 69 64 2c 20 26 68 61 73  nifest(vid, &has
2bb0: 68 2c 20 26 68 61 73 68 32 29 3b 0a 20 20 70 72  h, &hash2);.  pr
2bc0: 69 6e 74 66 28 22 6d 61 6e 69 66 65 73 74 3a 20  intf("manifest: 
2bd0: 25 73 5c 6e 22 2c 20 62 6c 6f 62 5f 73 74 72 28  %s\n", blob_str(
2be0: 26 68 61 73 68 29 29 3b 0a 20 20 70 72 69 6e 74  &hash));.  print
2bf0: 66 28 22 72 65 63 6f 72 64 65 64 3a 20 25 73 5c  f("recorded: %s\
2c00: 6e 22 2c 20 62 6c 6f 62 5f 73 74 72 28 26 68 61  n", blob_str(&ha
2c10: 73 68 32 29 29 3b 0a 7d 0a                       sh2));.}.