Hex Artifact Content
Not logged in

Artifact 78443669a55da452f994f35937cb0ae094ea0655:

File src/xfer.c part of check-in [73bddaebb9] - The delta compress on xfer is working better now, but still needs work. by drh on 2007-08-09 17:42:59.

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 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65 20 74   contains code t
0380: 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74 68 65 20  o implement the 
0390: 66 69 6c 65 20 74 72 61 6e 73 66 65 72 20 70 72  file transfer pr
03a0: 6f 74 6f 63 6f 6c 2e 0a 2a 2f 0a 23 69 6e 63 6c  otocol..*/.#incl
03b0: 75 64 65 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23  ude "config.h".#
03c0: 69 6e 63 6c 75 64 65 20 22 78 66 65 72 2e 68 22  include "xfer.h"
03d0: 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 6c  ../*.** Try to l
03e0: 6f 63 61 74 65 20 61 20 72 65 63 6f 72 64 20 74  ocate a record t
03f0: 68 61 74 20 69 73 20 73 69 6d 69 6c 61 72 20 74  hat is similar t
0400: 6f 20 72 69 64 20 61 6e 64 20 69 73 20 61 20 6c  o rid and is a l
0410: 69 6b 65 6c 79 0a 2a 2a 20 63 61 6e 64 69 64 61  ikely.** candida
0420: 74 65 20 66 6f 72 20 64 65 6c 74 61 20 61 67 61  te for delta aga
0430: 69 6e 73 74 20 72 69 64 2e 20 20 54 68 65 20 73  inst rid.  The s
0440: 69 6d 69 6c 61 72 20 72 65 63 6f 72 64 20 6d 75  imilar record mu
0450: 73 74 20 62 65 0a 2a 2a 20 72 65 66 65 72 65 6e  st be.** referen
0460: 63 65 64 20 69 6e 20 74 68 65 20 6f 6e 72 65 6d  ced in the onrem
0470: 6f 74 65 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a  ote table..**.**
0480: 20 52 65 74 75 72 6e 20 74 68 65 20 69 6e 74 65   Return the inte
0490: 67 65 72 20 72 65 63 6f 72 64 20 49 44 20 6f 66  ger record ID of
04a0: 20 74 68 65 20 73 69 6d 69 6c 61 72 20 72 65 63   the similar rec
04b0: 6f 72 64 2e 20 20 4f 72 20 72 65 74 75 72 6e 0a  ord.  Or return.
04c0: 2a 2a 20 30 20 69 66 20 6e 6f 6e 65 20 69 73 20  ** 0 if none is 
04d0: 66 6f 75 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  found..*/.static
04e0: 20 69 6e 74 20 73 69 6d 69 6c 61 72 5f 72 65 63   int similar_rec
04f0: 6f 72 64 28 69 6e 74 20 72 69 64 2c 20 69 6e 74  ord(int rid, int
0500: 20 74 72 61 63 65 46 6c 61 67 29 7b 0a 20 20 69   traceFlag){.  i
0510: 6e 74 20 69 6e 43 6e 74 2c 20 6f 75 74 43 6e 74  nt inCnt, outCnt
0520: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 53 74 6d  ;.  int i;.  Stm
0530: 74 20 71 3b 0a 20 20 69 6e 74 20 71 75 65 75 65  t q;.  int queue
0540: 5b 31 30 30 5d 3b 0a 20 20 73 74 61 74 69 63 20  [100];.  static 
0550: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a 51 75  const char *azQu
0560: 65 72 79 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20  ery[] = {.      
0570: 2f 2a 20 53 63 61 6e 20 74 68 65 20 64 65 6c 74  /* Scan the delt
0580: 61 20 74 61 62 6c 65 20 66 69 72 73 74 20 2a 2f  a table first */
0590: 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 73  .      "SELECT s
05a0: 72 63 69 64 2c 20 45 58 49 53 54 53 28 53 45 4c  rcid, EXISTS(SEL
05b0: 45 43 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65 6d  ECT 1 FROM onrem
05c0: 6f 74 65 20 57 48 45 52 45 20 72 69 64 3d 73 72  ote WHERE rid=sr
05d0: 63 69 64 29 22 0a 20 20 20 20 20 20 22 20 20 46  cid)".      "  F
05e0: 52 4f 4d 20 64 65 6c 74 61 22 0a 20 20 20 20 20  ROM delta".     
05f0: 20 22 20 57 48 45 52 45 20 72 69 64 3d 3a 78 22   " WHERE rid=:x"
0600: 0a 20 20 20 20 20 20 22 20 20 20 41 4e 44 20 4e  .      "   AND N
0610: 4f 54 20 45 58 49 53 54 53 28 53 45 4c 45 43 54  OT EXISTS(SELECT
0620: 20 31 20 46 52 4f 4d 20 70 68 61 6e 74 6f 6d 20   1 FROM phantom 
0630: 57 48 45 52 45 20 72 69 64 3d 73 72 63 69 64 29  WHERE rid=srcid)
0640: 22 0a 20 20 20 20 20 20 22 20 55 4e 49 4f 4e 20  ".      " UNION 
0650: 41 4c 4c 20 22 0a 20 20 20 20 20 20 22 53 45 4c  ALL ".      "SEL
0660: 45 43 54 20 72 69 64 2c 20 45 58 49 53 54 53 28  ECT rid, EXISTS(
0670: 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20 6f 6e  SELECT 1 FROM on
0680: 72 65 6d 6f 74 65 20 57 48 45 52 45 20 72 69 64  remote WHERE rid
0690: 3d 64 65 6c 74 61 2e 72 69 64 29 22 0a 20 20 20  =delta.rid)".   
06a0: 20 20 20 22 20 20 46 52 4f 4d 20 64 65 6c 74 61     "  FROM delta
06b0: 22 0a 20 20 20 20 20 20 22 20 57 48 45 52 45 20  ".      " WHERE 
06c0: 73 72 63 69 64 3d 3a 78 22 0a 20 20 20 20 20 20  srcid=:x".      
06d0: 22 20 20 20 41 4e 44 20 4e 4f 54 20 45 58 49 53  "   AND NOT EXIS
06e0: 54 53 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d  TS(SELECT 1 FROM
06f0: 20 70 68 61 6e 74 6f 6d 20 57 48 45 52 45 20 72   phantom WHERE r
0700: 69 64 3d 64 65 6c 74 61 2e 72 69 64 29 22 2c 0a  id=delta.rid)",.
0710: 0a 20 20 20 20 20 20 2f 2a 20 54 68 65 6e 20 74  .      /* Then t
0720: 68 65 20 70 6c 69 6e 6b 20 74 61 62 6c 65 20 2a  he plink table *
0730: 2f 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20  /.      "SELECT 
0740: 70 69 64 2c 20 45 58 49 53 54 53 28 53 45 4c 45  pid, EXISTS(SELE
0750: 43 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65 6d 6f  CT 1 FROM onremo
0760: 74 65 20 57 48 45 52 45 20 72 69 64 3d 70 69 64  te WHERE rid=pid
0770: 29 22 0a 20 20 20 20 20 20 22 20 20 46 52 4f 4d  )".      "  FROM
0780: 20 70 6c 69 6e 6b 22 0a 20 20 20 20 20 20 22 20   plink".      " 
0790: 57 48 45 52 45 20 63 69 64 3d 3a 78 22 0a 20 20  WHERE cid=:x".  
07a0: 20 20 20 20 22 20 20 20 41 4e 44 20 4e 4f 54 20      "   AND NOT 
07b0: 45 58 49 53 54 53 28 53 45 4c 45 43 54 20 31 20  EXISTS(SELECT 1 
07c0: 46 52 4f 4d 20 70 68 61 6e 74 6f 6d 20 57 48 45  FROM phantom WHE
07d0: 52 45 20 72 69 64 3d 70 69 64 29 22 0a 20 20 20  RE rid=pid)".   
07e0: 20 20 20 22 20 55 4e 49 4f 4e 20 41 4c 4c 20 22     " UNION ALL "
07f0: 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 63  .      "SELECT c
0800: 69 64 2c 20 45 58 49 53 54 53 28 53 45 4c 45 43  id, EXISTS(SELEC
0810: 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65 6d 6f 74  T 1 FROM onremot
0820: 65 20 57 48 45 52 45 20 72 69 64 3d 63 69 64 29  e WHERE rid=cid)
0830: 22 0a 20 20 20 20 20 20 22 20 20 46 52 4f 4d 20  ".      "  FROM 
0840: 70 6c 69 6e 6b 22 0a 20 20 20 20 20 20 22 20 57  plink".      " W
0850: 48 45 52 45 20 70 69 64 3d 3a 78 22 0a 20 20 20  HERE pid=:x".   
0860: 20 20 20 22 20 20 20 41 4e 44 20 4e 4f 54 20 45     "   AND NOT E
0870: 58 49 53 54 53 28 53 45 4c 45 43 54 20 31 20 46  XISTS(SELECT 1 F
0880: 52 4f 4d 20 70 68 61 6e 74 6f 6d 20 57 48 45 52  ROM phantom WHER
0890: 45 20 72 69 64 3d 63 69 64 29 22 2c 0a 0a 20 20  E rid=cid)",..  
08a0: 20 20 20 20 2f 2a 20 46 69 6e 61 6c 6c 79 20 74      /* Finally t
08b0: 68 65 20 6d 6c 69 6e 6b 20 74 61 62 6c 65 20 2a  he mlink table *
08c0: 2f 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20  /.      "SELECT 
08d0: 70 69 64 2c 20 45 58 49 53 54 53 28 53 45 4c 45  pid, EXISTS(SELE
08e0: 43 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65 6d 6f  CT 1 FROM onremo
08f0: 74 65 20 57 48 45 52 45 20 72 69 64 3d 70 69 64  te WHERE rid=pid
0900: 29 22 0a 20 20 20 20 20 20 22 20 20 46 52 4f 4d  )".      "  FROM
0910: 20 6d 6c 69 6e 6b 22 0a 20 20 20 20 20 20 22 20   mlink".      " 
0920: 57 48 45 52 45 20 66 69 64 3d 3a 78 20 41 4e 44  WHERE fid=:x AND
0930: 20 70 69 64 3e 30 22 0a 20 20 20 20 20 20 22 20   pid>0".      " 
0940: 20 20 41 4e 44 20 4e 4f 54 20 45 58 49 53 54 53    AND NOT EXISTS
0950: 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20 70  (SELECT 1 FROM p
0960: 68 61 6e 74 6f 6d 20 57 48 45 52 45 20 72 69 64  hantom WHERE rid
0970: 3d 70 69 64 29 22 0a 20 20 20 20 20 20 22 20 55  =pid)".      " U
0980: 4e 49 4f 4e 20 41 4c 4c 20 22 0a 20 20 20 20 20  NION ALL ".     
0990: 20 22 53 45 4c 45 43 54 20 66 69 64 2c 20 45 58   "SELECT fid, EX
09a0: 49 53 54 53 28 53 45 4c 45 43 54 20 31 20 46 52  ISTS(SELECT 1 FR
09b0: 4f 4d 20 6f 6e 72 65 6d 6f 74 65 20 57 48 45 52  OM onremote WHER
09c0: 45 20 72 69 64 3d 66 69 64 29 22 0a 20 20 20 20  E rid=fid)".    
09d0: 20 20 22 20 20 46 52 4f 4d 20 6d 6c 69 6e 6b 22    "  FROM mlink"
09e0: 0a 20 20 20 20 20 20 22 20 57 48 45 52 45 20 70  .      " WHERE p
09f0: 69 64 3d 3a 78 20 41 4e 44 20 66 69 64 3e 30 22  id=:x AND fid>0"
0a00: 0a 20 20 20 20 20 20 22 20 20 20 41 4e 44 20 4e  .      "   AND N
0a10: 4f 54 20 45 58 49 53 54 53 28 53 45 4c 45 43 54  OT EXISTS(SELECT
0a20: 20 31 20 46 52 4f 4d 20 70 68 61 6e 74 6f 6d 20   1 FROM phantom 
0a30: 57 48 45 52 45 20 72 69 64 3d 66 69 64 29 22 2c  WHERE rid=fid)",
0a40: 0a 20 20 7d 3b 0a 0a 20 20 66 6f 72 28 69 3d 30  .  };..  for(i=0
0a50: 3b 20 69 3c 73 69 7a 65 6f 66 28 61 7a 51 75 65  ; i<sizeof(azQue
0a60: 72 79 29 2f 73 69 7a 65 6f 66 28 61 7a 51 75 65  ry)/sizeof(azQue
0a70: 72 79 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20  ry[0]); i++){.  
0a80: 20 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c    db_prepare(&q,
0a90: 20 61 7a 51 75 65 72 79 5b 69 5d 29 3b 0a 20 20   azQuery[i]);.  
0aa0: 20 20 71 75 65 75 65 5b 30 5d 20 3d 20 72 69 64    queue[0] = rid
0ab0: 3b 0a 20 20 20 20 69 6e 43 6e 74 20 3d 20 31 3b  ;.    inCnt = 1;
0ac0: 0a 20 20 20 20 6f 75 74 43 6e 74 20 3d 20 30 3b  .    outCnt = 0;
0ad0: 0a 20 20 20 20 69 66 28 20 74 72 61 63 65 46 6c  .    if( traceFl
0ae0: 61 67 20 29 20 70 72 69 6e 74 66 28 22 50 41 53  ag ) printf("PAS
0af0: 53 20 25 64 5c 6e 22 2c 20 69 2b 31 29 3b 0a 20  S %d\n", i+1);. 
0b00: 20 20 20 77 68 69 6c 65 28 20 6f 75 74 43 6e 74     while( outCnt
0b10: 3c 69 6e 43 6e 74 20 29 7b 0a 20 20 20 20 20 20  <inCnt ){.      
0b20: 69 6e 74 20 78 69 64 20 3d 20 71 75 65 75 65 5b  int xid = queue[
0b30: 6f 75 74 43 6e 74 25 36 34 5d 3b 0a 20 20 20 20  outCnt%64];.    
0b40: 20 20 6f 75 74 43 6e 74 2b 2b 3b 0a 20 20 20 20    outCnt++;.    
0b50: 20 20 64 62 5f 62 69 6e 64 5f 69 6e 74 28 26 71    db_bind_int(&q
0b60: 2c 20 22 3a 78 22 2c 20 78 69 64 29 3b 0a 20 20  , ":x", xid);.  
0b70: 20 20 20 20 69 66 28 20 74 72 61 63 65 46 6c 61      if( traceFla
0b80: 67 20 29 20 70 72 69 6e 74 66 28 22 78 69 64 3d  g ) printf("xid=
0b90: 25 64 5c 6e 22 2c 20 78 69 64 29 3b 0a 20 20 20  %d\n", xid);.   
0ba0: 20 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74 65     while( db_ste
0bb0: 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f  p(&q)==SQLITE_RO
0bc0: 57 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  W ){.        int
0bd0: 20 6e 69 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e   nid = db_column
0be0: 5f 69 6e 74 28 26 71 2c 20 30 29 3b 0a 20 20 20  _int(&q, 0);.   
0bf0: 20 20 20 20 20 69 6e 74 20 68 69 74 20 3d 20 64       int hit = d
0c00: 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c  b_column_int(&q,
0c10: 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28   1);.        if(
0c20: 20 74 72 61 63 65 46 6c 61 67 20 29 20 70 72 69   traceFlag ) pri
0c30: 6e 74 66 28 22 6e 69 64 3d 25 64 20 68 69 74 3d  ntf("nid=%d hit=
0c40: 25 64 5c 6e 22 2c 20 6e 69 64 2c 20 68 69 74 29  %d\n", nid, hit)
0c50: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 68 69  ;.        if( hi
0c60: 74 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  t  ){.          
0c70: 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b  db_finalize(&q);
0c80: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
0c90: 6e 20 6e 69 64 3b 0a 20 20 20 20 20 20 20 20 7d  n nid;.        }
0ca0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 6e 43  .        if( inC
0cb0: 6e 74 3c 73 69 7a 65 6f 66 28 71 75 65 75 65 29  nt<sizeof(queue)
0cc0: 2f 73 69 7a 65 6f 66 28 71 75 65 75 65 5b 30 5d  /sizeof(queue[0]
0cd0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ) ){.          i
0ce0: 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20  nt i;.          
0cf0: 66 6f 72 28 69 3d 30 3b 20 69 3c 69 6e 43 6e 74  for(i=0; i<inCnt
0d00: 20 26 26 20 71 75 65 75 65 5b 69 5d 21 3d 6e 69   && queue[i]!=ni
0d10: 64 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20 20 20  d; i++){}.      
0d20: 20 20 20 20 69 66 28 20 69 3e 3d 69 6e 43 6e 74      if( i>=inCnt
0d30: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
0d40: 71 75 65 75 65 5b 69 6e 43 6e 74 2b 2b 5d 20 3d  queue[inCnt++] =
0d50: 20 6e 69 64 3b 0a 20 20 20 20 20 20 20 20 20 20   nid;.          
0d60: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
0d70: 20 20 7d 0a 20 20 20 20 20 20 64 62 5f 72 65 73    }.      db_res
0d80: 65 74 28 26 71 29 3b 0a 20 20 20 20 7d 0a 20 20  et(&q);.    }.  
0d90: 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71    db_finalize(&q
0da0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
0db0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d  0;.}../*.** COMM
0dc0: 41 4e 44 3a 20 74 65 73 74 2d 73 69 6d 69 6c 61  AND: test-simila
0dd0: 72 2d 72 65 63 6f 72 64 0a 2a 2f 0a 76 6f 69 64  r-record.*/.void
0de0: 20 74 65 73 74 5f 73 69 6d 69 6c 61 72 5f 72 65   test_similar_re
0df0: 63 6f 72 64 28 76 6f 69 64 29 7b 0a 20 20 69 6e  cord(void){.  in
0e00: 74 20 69 3b 0a 20 20 69 66 28 20 67 2e 61 72 67  t i;.  if( g.arg
0e10: 63 3c 34 20 29 7b 0a 20 20 20 20 75 73 61 67 65  c<4 ){.    usage
0e20: 28 22 53 52 43 20 4f 4e 52 45 4d 4f 54 45 2e 2e  ("SRC ONREMOTE..
0e30: 2e 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d 75  .");.  }.  db_mu
0e40: 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65  st_be_within_tre
0e50: 65 28 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f  e();.  db_multi_
0e60: 65 78 65 63 28 0a 20 20 20 20 22 43 52 45 41 54  exec(.    "CREAT
0e70: 45 20 54 45 4d 50 20 54 41 42 4c 45 20 6f 6e 72  E TEMP TABLE onr
0e80: 65 6d 6f 74 65 28 72 69 64 20 49 4e 54 45 47 45  emote(rid INTEGE
0e90: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 29 3b 22  R PRIMARY KEY);"
0ea0: 0a 20 20 29 3b 0a 20 20 66 6f 72 28 69 3d 33 3b  .  );.  for(i=3;
0eb0: 20 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b   i<g.argc; i++){
0ec0: 0a 20 20 20 20 69 6e 74 20 72 69 64 20 3d 20 6e  .    int rid = n
0ed0: 61 6d 65 5f 74 6f 5f 72 69 64 28 67 2e 61 72 67  ame_to_rid(g.arg
0ee0: 76 5b 69 5d 29 3b 0a 20 20 20 20 70 72 69 6e 74  v[i]);.    print
0ef0: 66 28 22 25 73 20 2d 3e 20 25 64 5c 6e 22 2c 20  f("%s -> %d\n", 
0f00: 67 2e 61 72 67 76 5b 69 5d 2c 20 72 69 64 29 3b  g.argv[i], rid);
0f10: 0a 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78  .    db_multi_ex
0f20: 65 63 28 22 49 4e 53 45 52 54 20 49 4e 54 4f 20  ec("INSERT INTO 
0f30: 6f 6e 72 65 6d 6f 74 65 20 56 41 4c 55 45 53 28  onremote VALUES(
0f40: 25 64 29 22 2c 20 72 69 64 29 3b 0a 20 20 7d 0a  %d)", rid);.  }.
0f50: 20 20 70 72 69 6e 74 66 28 22 73 69 6d 69 6c 61    printf("simila
0f60: 72 3a 20 25 64 5c 6e 22 2c 20 73 69 6d 69 6c 61  r: %d\n", simila
0f70: 72 5f 72 65 63 6f 72 64 28 6e 61 6d 65 5f 74 6f  r_record(name_to
0f80: 5f 72 69 64 28 67 2e 61 72 67 76 5b 32 5d 29 2c  _rid(g.argv[2]),
0f90: 20 31 29 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20   1));.}.../*.** 
0fa0: 54 68 65 20 61 54 6f 6b 65 6e 5b 30 2e 2e 6e 54  The aToken[0..nT
0fb0: 6f 6b 65 6e 2d 31 5d 20 62 6c 6f 62 20 61 72 72  oken-1] blob arr
0fc0: 61 79 20 69 73 20 61 20 70 61 72 73 65 20 6f 66  ay is a parse of
0fd0: 20 61 20 22 66 69 6c 65 22 20 6c 69 6e 65 20 0a   a "file" line .
0fe0: 2a 2a 20 6d 65 73 73 61 67 65 2e 20 20 54 68 69  ** message.  Thi
0ff0: 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 73 68  s routine finish
1000: 65 73 20 70 61 72 73 69 6e 67 20 74 68 61 74 20  es parsing that 
1010: 6d 65 73 73 61 67 65 20 61 6e 64 20 64 6f 65 73  message and does
1020: 0a 2a 2a 20 61 20 72 65 63 6f 72 64 20 69 6e 73  .** a record ins
1030: 65 72 74 20 6f 66 20 74 68 65 20 66 69 6c 65 2e  ert of the file.
1040: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 6c 65 20  .**.** The file 
1050: 6c 69 6e 65 20 69 73 20 69 6e 20 6f 6e 65 20 6f  line is in one o
1060: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
1070: 74 77 6f 20 66 6f 72 6d 73 3a 0a 2a 2a 0a 2a 2a  two forms:.**.**
1080: 20 20 20 20 20 20 66 69 6c 65 20 55 55 49 44 20        file UUID 
1090: 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a  SIZE \n CONTENT.
10a0: 2a 2a 20 20 20 20 20 20 66 69 6c 65 20 55 55 49  **      file UUI
10b0: 44 20 44 45 4c 54 41 53 52 43 20 53 49 5a 45 20  D DELTASRC SIZE 
10c0: 5c 6e 20 43 4f 4e 54 45 4e 54 0a 2a 2a 0a 2a 2a  \n CONTENT.**.**
10d0: 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 69 73 20   The content is 
10e0: 53 49 5a 45 20 62 79 74 65 73 20 69 6d 6d 65 64  SIZE bytes immed
10f0: 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67  iately following
1100: 20 74 68 65 20 6e 65 77 6c 69 6e 65 2e 0a 2a 2a   the newline..**
1110: 20 49 66 20 44 45 4c 54 41 53 52 43 20 65 78 69   If DELTASRC exi
1120: 73 74 73 2c 20 74 68 65 6e 20 74 68 65 20 43 4f  sts, then the CO
1130: 4e 54 45 4e 54 20 69 73 20 61 20 64 65 6c 74 61  NTENT is a delta
1140: 20 61 67 61 69 6e 73 74 20 74 68 65 0a 2a 2a 20   against the.** 
1150: 63 6f 6e 74 65 6e 74 20 6f 66 20 44 45 4c 54 41  content of DELTA
1160: 53 52 43 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e  SRC..**.** If an
1170: 79 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  y error occurs, 
1180: 77 72 69 74 65 20 61 20 6d 65 73 73 61 67 65 20  write a message 
1190: 69 6e 74 6f 20 70 45 72 72 20 77 68 69 63 68 20  into pErr which 
11a0: 68 61 73 20 61 6c 72 65 61 64 79 0a 2a 2a 20 62  has already.** b
11b0: 65 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 74 6f  e initialized to
11c0: 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67   an empty string
11d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
11e0: 20 78 66 65 72 5f 61 63 63 65 70 74 5f 66 69 6c   xfer_accept_fil
11f0: 65 28 42 6c 6f 62 20 2a 70 49 6e 2c 20 42 6c 6f  e(Blob *pIn, Blo
1200: 62 20 2a 61 54 6f 6b 65 6e 2c 20 69 6e 74 20 6e  b *aToken, int n
1210: 54 6f 6b 65 6e 2c 20 42 6c 6f 62 20 2a 70 45 72  Token, Blob *pEr
1220: 72 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 69  r){.  int n;.  i
1230: 6e 74 20 72 69 64 3b 0a 20 20 42 6c 6f 62 20 63  nt rid;.  Blob c
1240: 6f 6e 74 65 6e 74 2c 20 68 61 73 68 3b 0a 20 20  ontent, hash;.  
1250: 0a 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3c 33 20  .  if( nToken<3 
1260: 7c 7c 20 6e 54 6f 6b 65 6e 3e 34 20 7c 7c 20 21  || nToken>4 || !
1270: 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54  blob_is_uuid(&aT
1280: 6f 6b 65 6e 5b 31 5d 29 0a 20 20 20 20 20 20 20  oken[1]).       
1290: 7c 7c 20 21 62 6c 6f 62 5f 69 73 5f 69 6e 74 28  || !blob_is_int(
12a0: 26 61 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 2d 31  &aToken[nToken-1
12b0: 5d 2c 20 26 6e 29 20 7c 7c 20 6e 3c 3d 30 0a 20  ], &n) || n<=0. 
12c0: 20 20 20 20 20 20 7c 7c 20 28 6e 54 6f 6b 65 6e        || (nToken
12d0: 3d 3d 34 20 26 26 20 21 62 6c 6f 62 5f 69 73 5f  ==4 && !blob_is_
12e0: 75 75 69 64 28 26 61 54 6f 6b 65 6e 5b 32 5d 29  uuid(&aToken[2])
12f0: 29 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  ) ){.    blob_ap
1300: 70 65 6e 64 66 28 70 45 72 72 2c 20 22 6d 61 6c  pendf(pErr, "mal
1310: 66 6f 72 6d 65 64 20 66 69 6c 65 20 6c 69 6e 65  formed file line
1320: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a  ");.    return;.
1330: 20 20 7d 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28    }.  blob_zero(
1340: 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 62 6c 6f  &content);.  blo
1350: 62 5f 7a 65 72 6f 28 26 68 61 73 68 29 3b 0a 20  b_zero(&hash);. 
1360: 20 62 6c 6f 62 5f 65 78 74 72 61 63 74 28 70 49   blob_extract(pI
1370: 6e 2c 20 6e 2c 20 26 63 6f 6e 74 65 6e 74 29 3b  n, n, &content);
1380: 0a 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3d 3d 34  .  if( nToken==4
1390: 20 29 7b 0a 20 20 20 20 42 6c 6f 62 20 73 72 63   ){.    Blob src
13a0: 3b 0a 20 20 20 20 69 6e 74 20 73 72 63 69 64 20  ;.    int srcid 
13b0: 3d 20 64 62 5f 69 6e 74 28 30 2c 20 22 53 45 4c  = db_int(0, "SEL
13c0: 45 43 54 20 72 69 64 20 46 52 4f 4d 20 62 6c 6f  ECT rid FROM blo
13d0: 62 20 57 48 45 52 45 20 75 75 69 64 3d 25 42 22  b WHERE uuid=%B"
13e0: 2c 20 26 61 54 6f 6b 65 6e 5b 32 5d 29 3b 0a 20  , &aToken[2]);. 
13f0: 20 20 20 69 66 28 20 73 72 63 69 64 3d 3d 30 20     if( srcid==0 
1400: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70  ){.      blob_ap
1410: 70 65 6e 64 66 28 70 45 72 72 2c 20 22 75 6e 6b  pendf(pErr, "unk
1420: 6e 6f 77 6e 20 64 65 6c 74 61 20 73 6f 75 72 63  nown delta sourc
1430: 65 3a 20 25 62 22 2c 20 26 61 54 6f 6b 65 6e 5b  e: %b", &aToken[
1440: 32 5d 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  2]);.      retur
1450: 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 6f 6e  n;.    }.    con
1460: 74 65 6e 74 5f 67 65 74 28 73 72 63 69 64 2c 20  tent_get(srcid, 
1470: 26 73 72 63 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  &src);.    blob_
1480: 64 65 6c 74 61 5f 61 70 70 6c 79 28 26 73 72 63  delta_apply(&src
1490: 2c 20 26 63 6f 6e 74 65 6e 74 2c 20 26 63 6f 6e  , &content, &con
14a0: 74 65 6e 74 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  tent);.    blob_
14b0: 72 65 73 65 74 28 26 73 72 63 29 3b 0a 20 20 7d  reset(&src);.  }
14c0: 0a 20 20 73 68 61 31 73 75 6d 5f 62 6c 6f 62 28  .  sha1sum_blob(
14d0: 26 63 6f 6e 74 65 6e 74 2c 20 26 68 61 73 68 29  &content, &hash)
14e0: 3b 0a 20 20 69 66 28 20 21 62 6c 6f 62 5f 65 71  ;.  if( !blob_eq
14f0: 5f 73 74 72 28 26 61 54 6f 6b 65 6e 5b 31 5d 2c  _str(&aToken[1],
1500: 20 62 6c 6f 62 5f 73 74 72 28 26 68 61 73 68 29   blob_str(&hash)
1510: 2c 20 2d 31 29 20 29 7b 0a 20 20 20 20 62 6c 6f  , -1) ){.    blo
1520: 62 5f 61 70 70 65 6e 64 66 28 70 45 72 72 2c 20  b_appendf(pErr, 
1530: 22 63 6f 6e 74 65 6e 74 20 64 6f 65 73 20 6e 6f  "content does no
1540: 74 20 6d 61 74 63 68 20 73 68 61 31 20 68 61 73  t match sha1 has
1550: 68 22 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f  h");.  }.  blob_
1560: 72 65 73 65 74 28 26 68 61 73 68 29 3b 0a 20 20  reset(&hash);.  
1570: 72 69 64 20 3d 20 63 6f 6e 74 65 6e 74 5f 70 75  rid = content_pu
1580: 74 28 26 63 6f 6e 74 65 6e 74 2c 20 30 29 3b 0a  t(&content, 0);.
1590: 20 20 6d 61 6e 69 66 65 73 74 5f 63 72 6f 73 73    manifest_cross
15a0: 6c 69 6e 6b 28 72 69 64 2c 20 26 63 6f 6e 74 65  link(rid, &conte
15b0: 6e 74 29 3b 0a 20 20 69 66 28 20 72 69 64 3d 3d  nt);.  if( rid==
15c0: 30 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  0 ){.    blob_ap
15d0: 70 65 6e 64 66 28 70 45 72 72 2c 20 22 25 73 22  pendf(pErr, "%s"
15e0: 2c 20 67 2e 7a 45 72 72 4d 73 67 29 3b 0a 20 20  , g.zErrMsg);.  
15f0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20  }.}../*.** Send 
1600: 74 68 65 20 66 69 6c 65 20 69 64 65 6e 74 69 66  the file identif
1610: 69 65 64 20 62 79 20 72 69 64 2e 0a 2a 2a 0a 2a  ied by rid..**.*
1620: 2a 20 49 66 20 70 4f 75 74 20 69 73 20 6e 6f 74  * If pOut is not
1630: 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 61 70 70 65   NULL, then appe
1640: 6e 64 20 74 68 65 20 74 65 78 74 20 6f 66 20 74  nd the text of t
1650: 68 65 20 73 65 6e 64 20 6d 65 73 73 61 67 65 0a  he send message.
1660: 2a 2a 20 74 6f 20 70 4f 75 74 2e 20 20 4f 74 68  ** to pOut.  Oth
1670: 65 72 77 69 73 65 2c 20 61 70 70 65 6e 64 20 74  erwise, append t
1680: 68 65 20 74 65 78 74 20 74 6f 20 74 68 65 20 43  he text to the C
1690: 47 49 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74  GI output..*/.st
16a0: 61 74 69 63 20 69 6e 74 20 73 65 6e 64 5f 66 69  atic int send_fi
16b0: 6c 65 28 69 6e 74 20 72 69 64 2c 20 42 6c 6f 62  le(int rid, Blob
16c0: 20 2a 70 4f 75 74 29 7b 0a 20 20 42 6c 6f 62 20   *pOut){.  Blob 
16d0: 63 6f 6e 74 65 6e 74 2c 20 75 75 69 64 3b 0a 20  content, uuid;. 
16e0: 20 69 6e 74 20 73 69 7a 65 3b 0a 20 20 69 6e 74   int size;.  int
16f0: 20 73 72 63 69 64 3b 0a 0a 0a 20 20 62 6c 6f 62   srcid;...  blob
1700: 5f 7a 65 72 6f 28 26 75 75 69 64 29 3b 0a 20 20  _zero(&uuid);.  
1710: 64 62 5f 62 6c 6f 62 28 26 75 75 69 64 2c 20 22  db_blob(&uuid, "
1720: 53 45 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d  SELECT uuid FROM
1730: 20 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64 3d   blob WHERE rid=
1740: 25 64 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22 2c  %d AND size>=0",
1750: 20 72 69 64 29 3b 0a 20 20 69 66 28 20 62 6c 6f   rid);.  if( blo
1760: 62 5f 73 69 7a 65 28 26 75 75 69 64 29 3d 3d 30  b_size(&uuid)==0
1770: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30   ){.    return 0
1780: 3b 0a 20 20 7d 0a 20 20 63 6f 6e 74 65 6e 74 5f  ;.  }.  content_
1790: 67 65 74 28 72 69 64 2c 20 26 63 6f 6e 74 65 6e  get(rid, &conten
17a0: 74 29 3b 0a 0a 20 20 69 66 28 20 62 6c 6f 62 5f  t);..  if( blob_
17b0: 73 69 7a 65 28 26 63 6f 6e 74 65 6e 74 29 3e 31  size(&content)>1
17c0: 30 30 20 29 7b 0a 20 20 20 20 73 72 63 69 64 20  00 ){.    srcid 
17d0: 3d 20 73 69 6d 69 6c 61 72 5f 72 65 63 6f 72 64  = similar_record
17e0: 28 72 69 64 2c 20 30 29 3b 0a 20 20 20 20 69 66  (rid, 0);.    if
17f0: 28 20 73 72 63 69 64 20 29 7b 0a 20 20 20 20 20  ( srcid ){.     
1800: 20 42 6c 6f 62 20 73 72 63 3b 0a 20 20 20 20 20   Blob src;.     
1810: 20 63 6f 6e 74 65 6e 74 5f 67 65 74 28 73 72 63   content_get(src
1820: 69 64 2c 20 26 73 72 63 29 3b 0a 20 20 20 20 20  id, &src);.     
1830: 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65 28 26   if( blob_size(&
1840: 73 72 63 29 3e 31 30 30 20 29 7b 0a 20 20 20 20  src)>100 ){.    
1850: 20 20 20 20 42 6c 6f 62 20 64 65 6c 74 61 3b 0a      Blob delta;.
1860: 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 64 65 6c          blob_del
1870: 74 61 5f 63 72 65 61 74 65 28 26 73 72 63 2c 20  ta_create(&src, 
1880: 26 63 6f 6e 74 65 6e 74 2c 20 26 64 65 6c 74 61  &content, &delta
1890: 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  );.        blob_
18a0: 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b  reset(&content);
18b0: 0a 20 20 20 20 20 20 20 20 63 6f 6e 74 65 6e 74  .        content
18c0: 20 3d 20 64 65 6c 74 61 3b 0a 20 20 20 20 20 20   = delta;.      
18d0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 75    blob_append(&u
18e0: 75 69 64 2c 20 22 20 22 2c 20 31 29 3b 0a 20 20  uid, " ", 1);.  
18f0: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
1900: 64 28 26 63 6f 6e 74 65 6e 74 2c 20 22 5c 6e 22  d(&content, "\n"
1910: 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 64 62  , 1);.        db
1920: 5f 62 6c 6f 62 28 26 75 75 69 64 2c 20 22 53 45  _blob(&uuid, "SE
1930: 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d 20 62  LECT uuid FROM b
1940: 6c 6f 62 20 57 48 45 52 45 20 72 69 64 3d 25 64  lob WHERE rid=%d
1950: 22 2c 20 73 72 63 69 64 29 3b 0a 20 20 20 20 20  ", srcid);.     
1960: 20 7d 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65   }.      blob_re
1970: 73 65 74 28 26 73 72 63 29 3b 0a 20 20 20 20 7d  set(&src);.    }
1980: 0a 20 20 7d 0a 20 20 73 69 7a 65 20 3d 20 62 6c  .  }.  size = bl
1990: 6f 62 5f 73 69 7a 65 28 26 63 6f 6e 74 65 6e 74  ob_size(&content
19a0: 29 3b 0a 20 20 69 66 28 20 70 4f 75 74 20 29 7b  );.  if( pOut ){
19b0: 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64  .    blob_append
19c0: 66 28 70 4f 75 74 2c 20 22 66 69 6c 65 20 25 62  f(pOut, "file %b
19d0: 20 25 64 5c 6e 22 2c 20 26 75 75 69 64 2c 20 73   %d\n", &uuid, s
19e0: 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61  ize);.    blob_a
19f0: 70 70 65 6e 64 28 70 4f 75 74 2c 20 62 6c 6f 62  ppend(pOut, blob
1a00: 5f 62 75 66 66 65 72 28 26 63 6f 6e 74 65 6e 74  _buffer(&content
1a10: 29 2c 20 73 69 7a 65 29 3b 0a 20 20 7d 65 6c 73  ), size);.  }els
1a20: 65 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74  e{.    cgi_print
1a30: 66 28 22 66 69 6c 65 20 25 62 20 25 64 5c 6e 22  f("file %b %d\n"
1a40: 2c 20 26 75 75 69 64 2c 20 73 69 7a 65 29 3b 0a  , &uuid, size);.
1a50: 20 20 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 63      cgi_append_c
1a60: 6f 6e 74 65 6e 74 28 62 6c 6f 62 5f 62 75 66 66  ontent(blob_buff
1a70: 65 72 28 26 63 6f 6e 74 65 6e 74 29 2c 20 73 69  er(&content), si
1a80: 7a 65 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f  ze);.  }.  blob_
1a90: 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b  reset(&content);
1aa0: 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 75  .  blob_reset(&u
1ab0: 75 69 64 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69  uid);.  db_multi
1ac0: 5f 65 78 65 63 28 22 49 4e 53 45 52 54 20 4f 52  _exec("INSERT OR
1ad0: 20 49 47 4e 4f 52 45 20 49 4e 54 4f 20 6f 6e 72   IGNORE INTO onr
1ae0: 65 6d 6f 74 65 20 56 41 4c 55 45 53 28 25 64 29  emote VALUES(%d)
1af0: 22 2c 20 72 69 64 29 3b 0a 20 20 72 65 74 75 72  ", rid);.  retur
1b00: 6e 20 73 69 7a 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  n size;.}.../*.*
1b10: 2a 20 53 65 6e 64 20 61 6c 6c 20 70 65 6e 64 69  * Send all pendi
1b20: 6e 67 20 66 69 6c 65 73 2e 0a 2a 2f 0a 73 74 61  ng files..*/.sta
1b30: 74 69 63 20 69 6e 74 20 73 65 6e 64 5f 61 6c 6c  tic int send_all
1b40: 5f 70 65 6e 64 69 6e 67 28 42 6c 6f 62 20 2a 70  _pending(Blob *p
1b50: 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69 52 69 64  Out){.  int iRid
1b60: 53 65 6e 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20  Sent = 0;.  int 
1b70: 73 65 6e 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20  sent = 0;.  int 
1b80: 6e 53 65 6e 74 20 3d 20 30 3b 0a 20 20 69 6e 74  nSent = 0;.  int
1b90: 20 6d 61 78 53 69 7a 65 20 3d 20 64 62 5f 67 65   maxSize = db_ge
1ba0: 74 5f 69 6e 74 28 22 68 74 74 70 2d 6d 73 67 2d  t_int("http-msg-
1bb0: 73 69 7a 65 22 2c 20 35 30 30 30 30 30 29 3b 0a  size", 500000);.
1bc0: 20 20 53 74 6d 74 20 71 3b 0a 0a 20 20 64 62 5f    Stmt q;..  db_
1bd0: 70 72 65 70 61 72 65 28 26 71 2c 20 22 53 45 4c  prepare(&q, "SEL
1be0: 45 43 54 20 72 69 64 20 46 52 4f 4d 20 70 65 6e  ECT rid FROM pen
1bf0: 64 69 6e 67 20 4f 52 44 45 52 20 42 59 20 72 69  ding ORDER BY ri
1c00: 64 22 29 3b 0a 20 20 77 68 69 6c 65 28 20 64 62  d");.  while( db
1c10: 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54  _step(&q)==SQLIT
1c20: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 69 6e 74  E_ROW ){.    int
1c30: 20 72 69 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e   rid = db_column
1c40: 5f 69 6e 74 28 26 71 2c 20 30 29 3b 0a 20 20 20  _int(&q, 0);.   
1c50: 20 69 66 28 20 73 65 6e 74 3c 6d 61 78 53 69 7a   if( sent<maxSiz
1c60: 65 20 29 7b 0a 20 20 20 20 20 20 73 65 6e 74 20  e ){.      sent 
1c70: 2b 3d 20 73 65 6e 64 5f 66 69 6c 65 28 72 69 64  += send_file(rid
1c80: 2c 20 70 4f 75 74 29 3b 0a 20 20 20 20 20 20 6e  , pOut);.      n
1c90: 53 65 6e 74 2b 2b 3b 0a 20 20 20 20 20 20 69 52  Sent++;.      iR
1ca0: 69 64 53 65 6e 74 20 3d 20 72 69 64 3b 0a 20 20  idSent = rid;.  
1cb0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63    }else{.      c
1cc0: 68 61 72 20 2a 7a 55 75 69 64 20 3d 20 64 62 5f  har *zUuid = db_
1cd0: 74 65 78 74 28 30 2c 0a 20 20 20 20 20 20 20 20  text(0,.        
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 53                "S
1cf0: 45 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d 20  ELECT uuid FROM 
1d00: 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64 3d 25  blob WHERE rid=%
1d10: 64 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22 2c 20  d AND size>=0", 
1d20: 72 69 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20  rid);.      if( 
1d30: 7a 55 75 69 64 20 29 7b 0a 20 20 20 20 20 20 20  zUuid ){.       
1d40: 20 69 66 28 20 70 4f 75 74 20 29 7b 0a 20 20 20   if( pOut ){.   
1d50: 20 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65         blob_appe
1d60: 6e 64 66 28 70 4f 75 74 2c 20 22 69 67 6f 74 20  ndf(pOut, "igot 
1d70: 25 73 5c 6e 22 2c 20 7a 55 75 69 64 29 3b 0a 20  %s\n", zUuid);. 
1d80: 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
1d90: 20 20 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e          cgi_prin
1da0: 74 66 28 22 69 67 6f 74 20 25 73 5c 6e 22 2c 20  tf("igot %s\n", 
1db0: 7a 55 75 69 64 29 3b 0a 20 20 20 20 20 20 20 20  zUuid);.        
1dc0: 7d 0a 20 20 20 20 20 20 20 20 66 72 65 65 28 7a  }.        free(z
1dd0: 55 75 69 64 29 3b 0a 20 20 20 20 20 20 7d 0a 20  Uuid);.      }. 
1de0: 20 20 20 7d 0a 20 20 7d 0a 20 20 64 62 5f 66 69     }.  }.  db_fi
1df0: 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 0a 20  nalize(&q);.  . 
1e00: 20 2f 2a 20 44 65 6c 65 74 65 20 74 68 65 20 27   /* Delete the '
1e10: 70 65 6e 64 69 6e 67 27 20 72 65 63 6f 72 64 73  pending' records
1e20: 20 66 6f 72 20 61 6c 6c 20 66 69 6c 65 73 20 6a   for all files j
1e30: 75 73 74 20 73 65 6e 74 2e 20 4f 74 68 65 72 77  ust sent. Otherw
1e40: 69 73 65 2c 0a 20 20 2a 2a 20 77 65 20 63 61 6e  ise,.  ** we can
1e50: 20 77 69 6e 64 20 75 70 20 73 65 6e 64 69 6e 67   wind up sending
1e60: 20 73 6f 6d 65 20 66 69 6c 65 73 20 6d 6f 72 65   some files more
1e70: 20 74 68 61 6e 20 6f 6e 63 65 2e 0a 20 20 2a 2f   than once..  */
1e80: 0a 20 20 69 66 28 20 6e 53 65 6e 74 3e 30 20 29  .  if( nSent>0 )
1e90: 7b 0a 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65  {.    db_multi_e
1ea0: 78 65 63 28 22 44 45 4c 45 54 45 20 46 52 4f 4d  xec("DELETE FROM
1eb0: 20 70 65 6e 64 69 6e 67 20 57 48 45 52 45 20 72   pending WHERE r
1ec0: 69 64 20 3c 3d 20 25 64 22 2c 20 69 52 69 64 53  id <= %d", iRidS
1ed0: 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  ent);.  }..  ret
1ee0: 75 72 6e 20 6e 53 65 6e 74 3b 0a 7d 0a 0a 0a 2f  urn nSent;.}.../
1ef0: 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65 20 73  *.** Check the s
1f00: 69 67 6e 61 74 75 72 65 20 6f 6e 20 61 6e 20 61  ignature on an a
1f10: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73  pplication/x-fos
1f20: 73 69 6c 20 70 61 79 6c 6f 61 64 20 72 65 63 65  sil payload rece
1f30: 69 76 65 64 20 62 79 0a 2a 2a 20 74 68 65 20 48  ived by.** the H
1f40: 54 54 50 20 73 65 72 76 65 72 2e 20 20 54 68 65  TTP server.  The
1f50: 20 73 69 67 6e 61 74 75 72 65 20 69 73 20 61 20   signature is a 
1f60: 6c 69 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  line of the foll
1f70: 6f 77 69 6e 67 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a  owing form:.**.*
1f80: 2a 20 20 20 20 20 20 20 20 6c 6f 67 69 6e 20 4c  *        login L
1f90: 4f 47 49 4e 20 4e 4f 4e 43 45 20 53 49 47 4e 41  OGIN NONCE SIGNA
1fa0: 54 55 52 45 0a 2a 2a 0a 2a 2a 20 54 68 65 20 4e  TURE.**.** The N
1fb0: 4f 4e 43 45 20 69 73 20 61 20 72 61 6e 64 6f 6d  ONCE is a random
1fc0: 20 73 74 72 69 6e 67 2e 20 20 54 68 65 20 73 65   string.  The se
1fd0: 72 76 65 72 20 77 69 6c 6c 20 6e 65 76 65 72 20  rver will never 
1fe0: 61 63 63 65 70 74 20 61 0a 2a 2a 20 72 65 70 65  accept a.** repe
1ff0: 61 74 20 4e 4f 4e 43 45 2e 20 20 53 49 47 4e 41  at NONCE.  SIGNA
2000: 54 55 52 45 20 69 73 20 74 68 65 20 53 48 41 31  TURE is the SHA1
2010: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65   checksum of the
2020: 20 4e 4f 4e 43 45 20 0a 2a 2a 20 63 6f 6e 63 61   NONCE .** conca
2030: 74 65 6e 61 74 65 64 20 77 69 74 68 20 74 68 65  tenated with the
2040: 20 75 73 65 72 73 20 70 61 73 73 77 6f 72 64 2e   users password.
2050: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 61 72 61 6d  .**.** The param
2060: 65 74 65 72 73 20 74 6f 20 74 68 69 73 20 72 6f  eters to this ro
2070: 75 74 69 6e 65 20 61 72 65 20 65 70 68 65 72 6d  utine are epherm
2080: 65 72 61 6c 20 62 6c 6f 62 73 20 68 6f 6c 64 69  eral blobs holdi
2090: 6e 67 20 74 68 65 0a 2a 2a 20 4c 4f 47 49 4e 2c  ng the.** LOGIN,
20a0: 20 4e 4f 4e 43 45 20 61 6e 64 20 53 49 47 4e 41   NONCE and SIGNA
20b0: 54 55 52 45 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  TURE..**.** This
20c0: 20 72 6f 75 74 69 6e 65 20 61 74 74 65 6d 70 74   routine attempt
20d0: 73 20 74 6f 20 6c 6f 63 61 74 65 20 74 68 65 20  s to locate the 
20e0: 75 73 65 72 20 61 6e 64 20 76 65 72 69 66 79 20  user and verify 
20f0: 74 68 65 20 73 69 67 6e 61 74 75 72 65 2e 0a 2a  the signature..*
2100: 2a 20 49 66 20 65 76 65 72 79 74 68 69 6e 67 20  * If everything 
2110: 63 68 65 63 6b 73 20 6f 75 74 2c 20 74 68 65 20  checks out, the 
2120: 55 53 45 52 2e 43 41 50 20 63 6f 6c 75 6d 6e 20  USER.CAP column 
2130: 66 6f 72 20 74 68 65 20 55 53 45 52 20 74 61 62  for the USER tab
2140: 6c 65 0a 2a 2a 20 69 73 20 63 6f 6e 73 75 6c 74  le.** is consult
2150: 65 64 20 74 6f 20 73 65 74 20 70 72 69 76 69 6c  ed to set privil
2160: 65 67 65 73 20 69 6e 20 74 68 65 20 67 6c 6f 62  eges in the glob
2170: 61 6c 20 67 20 76 61 72 69 61 62 6c 65 2e 0a 2a  al g variable..*
2180: 2a 0a 2a 2a 20 49 66 20 61 6e 79 74 68 69 6e 67  *.** If anything
2190: 20 66 61 69 6c 73 20 74 6f 20 63 68 65 63 6b 20   fails to check 
21a0: 6f 75 74 2c 20 6e 6f 20 63 68 61 6e 67 65 73 20  out, no changes 
21b0: 61 72 65 20 6d 61 64 65 20 74 6f 20 70 72 69 76  are made to priv
21c0: 69 6c 65 67 65 73 2e 0a 2a 2a 0a 2a 2a 20 53 69  ileges..**.** Si
21d0: 67 6e 61 74 75 72 65 20 67 65 6e 65 72 61 74 69  gnature generati
21e0: 6f 6e 20 6f 6e 20 74 68 65 20 63 6c 69 65 6e 74  on on the client
21f0: 20 73 69 64 65 20 69 73 20 68 61 6e 64 6c 65 64   side is handled
2200: 20 62 79 20 74 68 65 20 0a 2a 2a 20 68 74 74 70   by the .** http
2210: 5f 65 78 63 68 61 6e 67 65 28 29 20 72 6f 75 74  _exchange() rout
2220: 69 6e 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 68 65  ine..*/.void che
2230: 63 6b 5f 6c 6f 67 69 6e 28 42 6c 6f 62 20 2a 70  ck_login(Blob *p
2240: 4c 6f 67 69 6e 2c 20 42 6c 6f 62 20 2a 70 4e 6f  Login, Blob *pNo
2250: 6e 63 65 2c 20 42 6c 6f 62 20 2a 70 53 69 67 29  nce, Blob *pSig)
2260: 7b 0a 20 20 53 74 6d 74 20 71 3b 0a 20 20 69 6e  {.  Stmt q;.  in
2270: 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 64 62 5f  t rc;..  if( db_
2280: 65 78 69 73 74 73 28 22 53 45 4c 45 43 54 20 31  exists("SELECT 1
2290: 20 46 52 4f 4d 20 72 63 76 66 72 6f 6d 20 57 48   FROM rcvfrom WH
22a0: 45 52 45 20 6e 6f 6e 63 65 3d 25 42 22 2c 20 70  ERE nonce=%B", p
22b0: 4e 6f 6e 63 65 29 20 29 7b 0a 20 20 20 20 72 65  Nonce) ){.    re
22c0: 74 75 72 6e 3b 20 20 2f 2a 20 4e 65 76 65 72 20  turn;  /* Never 
22d0: 61 63 63 65 70 74 20 61 20 72 65 70 65 61 74 65  accept a repeate
22e0: 64 20 6e 6f 6e 63 65 20 2a 2f 0a 20 20 7d 0a 20  d nonce */.  }. 
22f0: 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20   db_prepare(&q, 
2300: 22 53 45 4c 45 43 54 20 70 77 2c 20 63 61 70 2c  "SELECT pw, cap,
2310: 20 75 69 64 20 46 52 4f 4d 20 75 73 65 72 20 57   uid FROM user W
2320: 48 45 52 45 20 6c 6f 67 69 6e 3d 25 42 22 2c 20  HERE login=%B", 
2330: 70 4c 6f 67 69 6e 29 3b 0a 20 20 69 66 28 20 64  pLogin);.  if( d
2340: 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49  b_step(&q)==SQLI
2350: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 42 6c  TE_ROW ){.    Bl
2360: 6f 62 20 70 77 2c 20 63 6f 6d 62 69 6e 65 64 2c  ob pw, combined,
2370: 20 68 61 73 68 3b 0a 20 20 20 20 62 6c 6f 62 5f   hash;.    blob_
2380: 7a 65 72 6f 28 26 70 77 29 3b 0a 20 20 20 20 64  zero(&pw);.    d
2390: 62 5f 65 70 68 65 6d 65 72 61 6c 5f 62 6c 6f 62  b_ephemeral_blob
23a0: 28 26 71 2c 20 30 2c 20 26 70 77 29 3b 0a 20 20  (&q, 0, &pw);.  
23b0: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 63 6f 6d    blob_zero(&com
23c0: 62 69 6e 65 64 29 3b 0a 20 20 20 20 62 6c 6f 62  bined);.    blob
23d0: 5f 63 6f 70 79 28 26 63 6f 6d 62 69 6e 65 64 2c  _copy(&combined,
23e0: 20 70 4e 6f 6e 63 65 29 3b 0a 20 20 20 20 62 6c   pNonce);.    bl
23f0: 6f 62 5f 61 70 70 65 6e 64 28 26 63 6f 6d 62 69  ob_append(&combi
2400: 6e 65 64 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72  ned, blob_buffer
2410: 28 26 70 77 29 2c 20 62 6c 6f 62 5f 73 69 7a 65  (&pw), blob_size
2420: 28 26 70 77 29 29 3b 0a 20 20 20 20 2f 2a 20 43  (&pw));.    /* C
2430: 47 49 44 45 42 55 47 28 28 22 70 72 65 73 69 67  GIDEBUG(("presig
2440: 3d 5b 25 73 5d 5c 6e 22 2c 20 62 6c 6f 62 5f 73  =[%s]\n", blob_s
2450: 74 72 28 26 63 6f 6d 62 69 6e 65 64 29 29 29 3b  tr(&combined)));
2460: 20 2a 2f 0a 20 20 20 20 73 68 61 31 73 75 6d 5f   */.    sha1sum_
2470: 62 6c 6f 62 28 26 63 6f 6d 62 69 6e 65 64 2c 20  blob(&combined, 
2480: 26 68 61 73 68 29 3b 0a 20 20 20 20 72 63 20 3d  &hash);.    rc =
2490: 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 26 68   blob_compare(&h
24a0: 61 73 68 2c 20 70 53 69 67 29 3b 0a 20 20 20 20  ash, pSig);.    
24b0: 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73 68  blob_reset(&hash
24c0: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
24d0: 74 28 26 63 6f 6d 62 69 6e 65 64 29 3b 0a 20 20  t(&combined);.  
24e0: 20 20 69 66 28 20 72 63 3d 3d 30 20 29 7b 0a 20    if( rc==0 ){. 
24f0: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
2500: 2a 7a 43 61 70 3b 0a 20 20 20 20 20 20 7a 43 61  *zCap;.      zCa
2510: 70 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65  p = db_column_te
2520: 78 74 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 20  xt(&q, 1);.     
2530: 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 62   login_set_capab
2540: 69 6c 69 74 69 65 73 28 7a 43 61 70 29 3b 0a 20  ilities(zCap);. 
2550: 20 20 20 20 20 67 2e 75 73 65 72 55 69 64 20 3d       g.userUid =
2560: 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26   db_column_int(&
2570: 71 2c 20 32 29 3b 0a 20 20 20 20 20 20 67 2e 7a  q, 2);.      g.z
2580: 4c 6f 67 69 6e 20 3d 20 6d 70 72 69 6e 74 66 28  Login = mprintf(
2590: 22 25 62 22 2c 20 70 4c 6f 67 69 6e 29 3b 0a 20  "%b", pLogin);. 
25a0: 20 20 20 20 20 67 2e 7a 4e 6f 6e 63 65 20 3d 20       g.zNonce = 
25b0: 6d 70 72 69 6e 74 66 28 22 25 62 22 2c 20 70 4e  mprintf("%b", pN
25c0: 6f 6e 63 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  once);.    }.  }
25d0: 0a 20 20 64 62 5f 72 65 73 65 74 28 26 71 29 3b  .  db_reset(&q);
25e0: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  .}.../*.** If th
25f0: 69 73 20 76 61 72 69 61 62 6c 65 20 69 73 20 73  is variable is s
2600: 65 74 2c 20 64 69 73 61 62 6c 65 20 6c 6f 67 69  et, disable logi
2610: 6e 20 63 68 65 63 6b 73 2e 20 20 55 73 65 64 20  n checks.  Used 
2620: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 0a 2a 2a  for debugging.**
2630: 20 6f 6e 6c 79 2e 0a 2a 2f 0a 73 74 61 74 69 63   only..*/.static
2640: 20 69 6e 74 20 64 69 73 61 62 6c 65 4c 6f 67 69   int disableLogi
2650: 6e 20 3d 20 30 3b 0a 0a 2f 2a 0a 2a 2a 20 57 45  n = 0;../*.** WE
2660: 42 50 41 47 45 3a 20 78 66 65 72 0a 2a 2a 0a 2a  BPAGE: xfer.**.*
2670: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 74 72  * This is the tr
2680: 61 6e 73 66 65 72 20 68 61 6e 64 6c 65 72 20 6f  ansfer handler o
2690: 6e 20 74 68 65 20 73 65 72 76 65 72 20 73 69 64  n the server sid
26a0: 65 2e 20 20 54 68 65 20 74 72 61 6e 73 66 65 72  e.  The transfer
26b0: 0a 2a 2a 20 6d 65 73 73 61 67 65 20 68 61 73 20  .** message has 
26c0: 62 65 65 6e 20 75 6e 63 6f 6d 70 72 65 73 73 65  been uncompresse
26d0: 64 20 61 6e 64 20 70 6c 61 63 65 64 20 69 6e 20  d and placed in 
26e0: 74 68 65 20 67 2e 63 67 69 49 6e 20 62 6c 6f 62  the g.cgiIn blob
26f0: 2e 0a 2a 2a 20 50 72 6f 63 65 73 73 20 74 68 69  ..** Process thi
2700: 73 20 6d 65 73 73 61 67 65 20 61 6e 64 20 66 6f  s message and fo
2710: 72 6d 20 61 6e 20 61 70 70 72 6f 70 72 69 61 74  rm an appropriat
2720: 65 20 72 65 70 6c 79 2e 0a 2a 2f 0a 76 6f 69 64  e reply..*/.void
2730: 20 70 61 67 65 5f 78 66 65 72 28 76 6f 69 64 29   page_xfer(void)
2740: 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 3b 0a  {.  int nToken;.
2750: 20 20 69 6e 74 20 69 73 50 75 6c 6c 20 3d 20 30    int isPull = 0
2760: 3b 0a 20 20 69 6e 74 20 69 73 50 75 73 68 20 3d  ;.  int isPush =
2770: 20 30 3b 0a 20 20 69 6e 74 20 6e 45 72 72 20 3d   0;.  int nErr =
2780: 20 30 3b 0a 20 20 42 6c 6f 62 20 6c 69 6e 65 2c   0;.  Blob line,
2790: 20 65 72 72 6d 73 67 2c 20 61 54 6f 6b 65 6e 5b   errmsg, aToken[
27a0: 35 5d 3b 0a 0a 20 20 64 62 5f 62 65 67 69 6e 5f  5];..  db_begin_
27b0: 74 72 61 6e 73 61 63 74 69 6f 6e 28 29 3b 0a 20  transaction();. 
27c0: 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72 6f 28   blobarray_zero(
27d0: 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28 61 54  aToken, count(aT
27e0: 6f 6b 65 6e 29 29 3b 0a 20 20 63 67 69 5f 73 65  oken));.  cgi_se
27f0: 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 28 67  t_content_type(g
2800: 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 65 29 3b 0a  .zContentType);.
2810: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 65 72 72    blob_zero(&err
2820: 6d 73 67 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69  msg);.  db_multi
2830: 5f 65 78 65 63 28 0a 20 20 20 20 20 22 43 52 45  _exec(.     "CRE
2840: 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45 20 6f  ATE TEMP TABLE o
2850: 6e 72 65 6d 6f 74 65 28 72 69 64 20 49 4e 54 45  nremote(rid INTE
2860: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 29  GER PRIMARY KEY)
2870: 3b 22 20 2f 2a 20 43 6c 69 65 6e 74 20 68 61 73  ;" /* Client has
2880: 20 2a 2f 0a 20 20 20 20 20 22 43 52 45 41 54 45   */.     "CREATE
2890: 20 54 45 4d 50 20 54 41 42 4c 45 20 70 65 6e 64   TEMP TABLE pend
28a0: 69 6e 67 28 72 69 64 20 49 4e 54 45 47 45 52 20  ing(rid INTEGER 
28b0: 50 52 49 4d 41 52 59 20 4b 45 59 29 3b 22 20 20  PRIMARY KEY);"  
28c0: 2f 2a 20 43 6c 69 65 6e 74 20 6e 65 65 64 73 20  /* Client needs 
28d0: 2a 2f 0a 20 20 29 3b 0a 20 20 77 68 69 6c 65 28  */.  );.  while(
28e0: 20 62 6c 6f 62 5f 6c 69 6e 65 28 26 67 2e 63 67   blob_line(&g.cg
28f0: 69 49 6e 2c 20 26 6c 69 6e 65 29 20 29 7b 0a 20  iIn, &line) ){. 
2900: 20 20 20 6e 54 6f 6b 65 6e 20 3d 20 62 6c 6f 62     nToken = blob
2910: 5f 74 6f 6b 65 6e 69 7a 65 28 26 6c 69 6e 65 2c  _tokenize(&line,
2920: 20 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28 61   aToken, count(a
2930: 54 6f 6b 65 6e 29 29 3b 0a 0a 20 20 20 20 2f 2a  Token));..    /*
2940: 20 20 20 66 69 6c 65 20 55 55 49 44 20 53 49 5a     file UUID SIZ
2950: 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20  E \n CONTENT.   
2960: 20 2a 2a 20 20 20 66 69 6c 65 20 55 55 49 44 20   **   file UUID 
2970: 44 45 4c 54 41 53 52 43 20 53 49 5a 45 20 5c 6e  DELTASRC SIZE \n
2980: 20 43 4f 4e 54 45 4e 54 0a 20 20 20 20 2a 2a 0a   CONTENT.    **.
2990: 20 20 20 20 2a 2a 20 41 63 63 65 70 74 20 61 20      ** Accept a 
29a0: 66 69 6c 65 20 66 72 6f 6d 20 74 68 65 20 63 6c  file from the cl
29b0: 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ient..    */.   
29c0: 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26 61 54   if( blob_eq(&aT
29d0: 6f 6b 65 6e 5b 30 5d 2c 20 22 66 69 6c 65 22 29  oken[0], "file")
29e0: 20 26 26 20 6e 54 6f 6b 65 6e 3e 3d 33 20 26 26   && nToken>=3 &&
29f0: 20 6e 54 6f 6b 65 6e 3c 3d 34 20 29 7b 0a 20 20   nToken<=4 ){.  
2a00: 20 20 20 20 69 66 28 20 21 69 73 50 75 73 68 20      if( !isPush 
2a10: 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f 72  ){.        cgi_r
2a20: 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a  eset_content();.
2a30: 20 20 20 20 20 20 20 20 40 20 65 72 72 6f 72 20          @ error 
2a40: 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a 65 64 5c  not\sauthorized\
2a50: 73 74 6f 5c 73 77 72 69 74 65 0a 20 20 20 20 20  sto\swrite.     
2a60: 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20     nErr++;.     
2a70: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
2a80: 7d 0a 20 20 20 20 20 20 78 66 65 72 5f 61 63 63  }.      xfer_acc
2a90: 65 70 74 5f 66 69 6c 65 28 26 67 2e 63 67 69 49  ept_file(&g.cgiI
2aa0: 6e 2c 20 61 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  n, aToken, nToke
2ab0: 6e 2c 20 26 65 72 72 6d 73 67 29 3b 0a 20 20 20  n, &errmsg);.   
2ac0: 20 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65     if( blob_size
2ad0: 28 26 65 72 72 6d 73 67 29 20 29 7b 0a 20 20 20  (&errmsg) ){.   
2ae0: 20 20 20 20 20 63 67 69 5f 72 65 73 65 74 5f 63       cgi_reset_c
2af0: 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20 20 20  ontent();.      
2b00: 20 20 40 20 65 72 72 6f 72 20 25 54 28 62 6c 6f    @ error %T(blo
2b10: 62 5f 73 74 72 28 26 65 72 72 6d 73 67 29 29 0a  b_str(&errmsg)).
2b20: 20 20 20 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a          nErr++;.
2b30: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
2b40: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
2b50: 0a 0a 20 20 20 20 2f 2a 20 20 20 67 69 6d 6d 65  ..    /*   gimme
2b60: 20 55 55 49 44 0a 20 20 20 20 2a 2a 0a 20 20 20   UUID.    **.   
2b70: 20 2a 2a 20 43 6c 69 65 6e 74 20 69 73 20 72 65   ** Client is re
2b80: 71 75 65 73 74 69 6e 67 20 61 20 66 69 6c 65 0a  questing a file.
2b90: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 62      */.    if( b
2ba0: 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30  lob_eq(&aToken[0
2bb0: 5d 2c 20 22 67 69 6d 6d 65 22 29 20 26 26 20 6e  ], "gimme") && n
2bc0: 54 6f 6b 65 6e 3d 3d 32 20 26 26 20 62 6c 6f 62  Token==2 && blob
2bd0: 5f 69 73 5f 75 75 69 64 28 26 61 54 6f 6b 65 6e  _is_uuid(&aToken
2be0: 5b 31 5d 29 20 29 7b 0a 20 20 20 20 20 20 69 66  [1]) ){.      if
2bf0: 28 20 69 73 50 75 6c 6c 20 29 7b 0a 20 20 20 20  ( isPull ){.    
2c00: 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65      db_multi_exe
2c10: 63 28 0a 20 20 20 20 20 20 20 20 20 20 22 49 4e  c(.          "IN
2c20: 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45 20 49  SERT OR IGNORE I
2c30: 4e 54 4f 20 70 65 6e 64 69 6e 67 28 72 69 64 29  NTO pending(rid)
2c40: 20 22 0a 20 20 20 20 20 20 20 20 20 20 22 53 45   ".          "SE
2c50: 4c 45 43 54 20 72 69 64 20 46 52 4f 4d 20 62 6c  LECT rid FROM bl
2c60: 6f 62 20 57 48 45 52 45 20 75 75 69 64 3d 25 42  ob WHERE uuid=%B
2c70: 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22 2c 20 26   AND size>=0", &
2c80: 61 54 6f 6b 65 6e 5b 31 5d 0a 20 20 20 20 20 20  aToken[1].      
2c90: 20 20 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20    );.      }.   
2ca0: 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f 2a 20 20   }else..    /*  
2cb0: 20 69 67 6f 74 20 55 55 49 44 0a 20 20 20 20 2a   igot UUID.    *
2cc0: 2a 20 20 20 6c 65 61 66 20 55 55 49 44 0a 20 20  *   leaf UUID.  
2cd0: 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 43 6c 69 65    **.    ** Clie
2ce0: 6e 74 20 61 6e 6e 6f 75 6e 63 65 73 20 74 68 61  nt announces tha
2cf0: 74 20 69 74 20 68 61 73 20 61 20 70 61 72 74 69  t it has a parti
2d00: 63 75 6c 61 72 20 66 69 6c 65 0a 20 20 20 20 2a  cular file.    *
2d10: 2f 0a 20 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e  /.    if( nToken
2d20: 3d 3d 32 0a 20 20 20 20 20 20 20 20 20 20 26 26  ==2.          &&
2d30: 20 28 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65   (blob_eq(&aToke
2d40: 6e 5b 30 5d 2c 20 22 69 67 6f 74 22 29 20 7c 7c  n[0], "igot") ||
2d50: 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e   blob_eq(&aToken
2d60: 5b 30 5d 2c 22 6c 65 61 66 22 29 29 0a 20 20 20  [0],"leaf")).   
2d70: 20 20 20 20 20 20 20 26 26 20 62 6c 6f 62 5f 69         && blob_i
2d80: 73 5f 75 75 69 64 28 26 61 54 6f 6b 65 6e 5b 31  s_uuid(&aToken[1
2d90: 5d 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ]) ){.      if( 
2da0: 69 73 50 75 6c 6c 20 7c 7c 20 69 73 50 75 73 68  isPull || isPush
2db0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
2dc0: 72 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20  rid = db_int(0, 
2dd0: 22 53 45 4c 45 43 54 20 72 69 64 20 46 52 4f 4d  "SELECT rid FROM
2de0: 20 62 6c 6f 62 20 57 48 45 52 45 20 75 75 69 64   blob WHERE uuid
2df0: 3d 25 42 22 2c 20 26 61 54 6f 6b 65 6e 5b 31 5d  =%B", &aToken[1]
2e00: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  );.        if( r
2e10: 69 64 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  id>0 ){.        
2e20: 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28    db_multi_exec(
2e30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 22 49 4e  .            "IN
2e40: 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45 20 49  SERT OR IGNORE I
2e50: 4e 54 4f 20 6f 6e 72 65 6d 6f 74 65 28 72 69 64  NTO onremote(rid
2e60: 29 20 56 41 4c 55 45 53 28 25 64 29 22 2c 20 72  ) VALUES(%d)", r
2e70: 69 64 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a  id.          );.
2e80: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 69 73            if( is
2e90: 50 75 6c 6c 20 26 26 20 62 6c 6f 62 5f 65 71 28  Pull && blob_eq(
2ea0: 26 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22 6c 65 61  &aToken[0], "lea
2eb0: 66 22 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  f") ){.         
2ec0: 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63     db_multi_exec
2ed0: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
2ee0: 22 49 4e 53 45 52 54 20 4f 52 20 49 47 4e 4f 52  "INSERT OR IGNOR
2ef0: 45 20 49 4e 54 4f 20 70 65 6e 64 69 6e 67 28 72  E INTO pending(r
2f00: 69 64 29 20 22 0a 20 20 20 20 20 20 20 20 20 20  id) ".          
2f10: 20 20 20 20 22 53 45 4c 45 43 54 20 63 69 64 20      "SELECT cid 
2f20: 46 52 4f 4d 20 70 6c 69 6e 6b 20 57 48 45 52 45  FROM plink WHERE
2f30: 20 70 69 64 3d 25 64 22 2c 20 72 69 64 0a 20 20   pid=%d", rid.  
2f40: 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
2f50: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
2f60: 20 7d 65 6c 73 65 20 69 66 28 20 69 73 50 75 73   }else if( isPus
2f70: 68 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63  h ){.          c
2f80: 6f 6e 74 65 6e 74 5f 70 75 74 28 30 2c 20 62 6c  ontent_put(0, bl
2f90: 6f 62 5f 73 74 72 28 26 61 54 6f 6b 65 6e 5b 31  ob_str(&aToken[1
2fa0: 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ]));.        }. 
2fb0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
2fc0: 0a 0a 20 20 20 20 2f 2a 20 20 20 20 70 75 6c 6c  ..    /*    pull
2fd0: 20 20 53 45 52 56 45 52 43 4f 44 45 20 20 50 52    SERVERCODE  PR
2fe0: 4f 4a 45 43 54 43 4f 44 45 0a 20 20 20 20 2a 2a  OJECTCODE.    **
2ff0: 20 20 20 20 70 75 73 68 20 20 53 45 52 56 45 52      push  SERVER
3000: 43 4f 44 45 20 20 50 52 4f 4a 45 43 54 43 4f 44  CODE  PROJECTCOD
3010: 45 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  E.    **.    ** 
3020: 54 68 65 20 63 6c 69 65 6e 74 20 77 61 6e 74 73  The client wants
3030: 20 65 69 74 68 65 72 20 73 65 6e 64 20 6f 72 20   either send or 
3040: 72 65 63 65 69 76 65 0a 20 20 20 20 2a 2f 0a 20  receive.    */. 
3050: 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3d 3d 33     if( nToken==3
3060: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3070: 26 26 20 28 62 6c 6f 62 5f 65 71 28 26 61 54 6f  && (blob_eq(&aTo
3080: 6b 65 6e 5b 30 5d 2c 20 22 70 75 6c 6c 22 29 20  ken[0], "pull") 
3090: 7c 7c 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b  || blob_eq(&aTok
30a0: 65 6e 5b 30 5d 2c 20 22 70 75 73 68 22 29 29 0a  en[0], "push")).
30b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26                 &
30c0: 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26  & blob_is_uuid(&
30d0: 61 54 6f 6b 65 6e 5b 31 5d 29 20 26 26 20 62 6c  aToken[1]) && bl
30e0: 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f 6b  ob_is_uuid(&aTok
30f0: 65 6e 5b 32 5d 29 20 29 7b 0a 20 20 20 20 20 20  en[2]) ){.      
3100: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 43 6f  const char *zSCo
3110: 64 65 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20  de;.      const 
3120: 63 68 61 72 20 2a 7a 50 43 6f 64 65 3b 0a 0a 20  char *zPCode;.. 
3130: 20 20 20 20 20 7a 53 43 6f 64 65 20 3d 20 64 62       zSCode = db
3140: 5f 67 65 74 28 22 73 65 72 76 65 72 2d 63 6f 64  _get("server-cod
3150: 65 22 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66  e", 0);.      if
3160: 28 20 7a 53 43 6f 64 65 3d 3d 30 20 29 7b 0a 20  ( zSCode==0 ){. 
3170: 20 20 20 20 20 20 20 66 6f 73 73 69 6c 5f 70 61         fossil_pa
3180: 6e 69 63 28 22 6d 69 73 73 69 6e 67 20 73 65 72  nic("missing ser
3190: 76 65 72 20 63 6f 64 65 22 29 3b 0a 20 20 20 20  ver code");.    
31a0: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 62 6c    }.      if( bl
31b0: 6f 62 5f 65 71 5f 73 74 72 28 26 61 54 6f 6b 65  ob_eq_str(&aToke
31c0: 6e 5b 31 5d 2c 20 7a 53 43 6f 64 65 2c 20 2d 31  n[1], zSCode, -1
31d0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69  ) ){.        cgi
31e0: 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29  _reset_content()
31f0: 3b 0a 20 20 20 20 20 20 20 20 40 20 65 72 72 6f  ;.        @ erro
3200: 72 20 73 65 72 76 65 72 5c 73 6c 6f 6f 70 0a 20  r server\sloop. 
3210: 20 20 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20         nErr++;. 
3220: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
3230: 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 50 43 6f      }.      zPCo
3240: 64 65 20 3d 20 64 62 5f 67 65 74 28 22 70 72 6f  de = db_get("pro
3250: 6a 65 63 74 2d 63 6f 64 65 22 2c 20 30 29 3b 0a  ject-code", 0);.
3260: 20 20 20 20 20 20 69 66 28 20 7a 50 43 6f 64 65        if( zPCode
3270: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 66  ==0 ){.        f
3280: 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 6d 69 73  ossil_panic("mis
3290: 73 69 6e 67 20 70 72 6f 6a 65 63 74 20 63 6f 64  sing project cod
32a0: 65 22 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  e");.      }.   
32b0: 20 20 20 69 66 28 20 21 62 6c 6f 62 5f 65 71 5f     if( !blob_eq_
32c0: 73 74 72 28 26 61 54 6f 6b 65 6e 5b 32 5d 2c 20  str(&aToken[2], 
32d0: 7a 50 43 6f 64 65 2c 20 2d 31 29 20 29 7b 0a 20  zPCode, -1) ){. 
32e0: 20 20 20 20 20 20 20 63 67 69 5f 72 65 73 65 74         cgi_reset
32f0: 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20  _content();.    
3300: 20 20 20 20 40 20 65 72 72 6f 72 20 77 72 6f 6e      @ error wron
3310: 67 5c 73 70 72 6f 6a 65 63 74 0a 20 20 20 20 20  g\sproject.     
3320: 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20     nErr++;.     
3330: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3340: 7d 0a 20 20 20 20 20 20 6c 6f 67 69 6e 5f 63 68  }.      login_ch
3350: 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c 73 28  eck_credentials(
3360: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f  );.      if( blo
3370: 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c  b_eq(&aToken[0],
3380: 20 22 70 75 6c 6c 22 29 20 29 7b 0a 20 20 20 20   "pull") ){.    
3390: 20 20 20 20 69 66 28 20 21 67 2e 6f 6b 52 65 61      if( !g.okRea
33a0: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63  d ){.          c
33b0: 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74  gi_reset_content
33c0: 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 40 20  ();.          @ 
33d0: 65 72 72 6f 72 20 6e 6f 74 5c 73 61 75 74 68 6f  error not\sautho
33e0: 72 69 7a 65 64 5c 73 74 6f 5c 73 72 65 61 64 0a  rized\sto\sread.
33f0: 20 20 20 20 20 20 20 20 20 20 6e 45 72 72 2b 2b            nErr++
3400: 3b 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61  ;.          brea
3410: 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  k;.        }.   
3420: 20 20 20 20 20 69 73 50 75 6c 6c 20 3d 20 31 3b       isPull = 1;
3430: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
3440: 20 20 20 20 20 20 69 66 28 20 21 67 2e 6f 6b 57        if( !g.okW
3450: 72 69 74 65 20 29 7b 0a 20 20 20 20 20 20 20 20  rite ){.        
3460: 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74    cgi_reset_cont
3470: 65 6e 74 28 29 3b 0a 20 20 20 20 20 20 20 20 20  ent();.         
3480: 20 40 20 65 72 72 6f 72 20 6e 6f 74 5c 73 61 75   @ error not\sau
3490: 74 68 6f 72 69 7a 65 64 5c 73 74 6f 5c 73 77 72  thorized\sto\swr
34a0: 69 74 65 0a 20 20 20 20 20 20 20 20 20 20 6e 45  ite.          nE
34b0: 72 72 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20  rr++;.          
34c0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
34d0: 0a 20 20 20 20 20 20 20 20 69 73 50 75 73 68 20  .        isPush 
34e0: 3d 20 31 3b 0a 0a 20 20 20 20 20 20 7d 0a 20 20  = 1;..      }.  
34f0: 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f 2a 20    }else..    /* 
3500: 20 20 20 63 6c 6f 6e 65 0a 20 20 20 20 2a 2a 0a     clone.    **.
3510: 20 20 20 20 2a 2a 20 54 68 65 20 63 6c 69 65 6e      ** The clien
3520: 74 20 6b 6e 6f 77 73 20 6e 6f 74 68 69 6e 67 2e  t knows nothing.
3530: 20 20 54 65 6c 6c 20 61 6c 6c 2e 0a 20 20 20 20    Tell all..    
3540: 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f 62 5f  */.    if( blob_
3550: 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22  eq(&aToken[0], "
3560: 63 6c 6f 6e 65 22 29 20 29 7b 0a 20 20 20 20 20  clone") ){.     
3570: 20 6c 6f 67 69 6e 5f 63 68 65 63 6b 5f 63 72 65   login_check_cre
3580: 64 65 6e 74 69 61 6c 73 28 29 3b 0a 20 20 20 20  dentials();.    
3590: 20 20 69 66 28 20 21 67 2e 6f 6b 52 65 61 64 20    if( !g.okRead 
35a0: 7c 7c 20 21 67 2e 6f 6b 48 69 73 74 6f 72 79 20  || !g.okHistory 
35b0: 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f 72  ){.        cgi_r
35c0: 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a  eset_content();.
35d0: 20 20 20 20 20 20 20 20 40 20 65 72 72 6f 72 20          @ error 
35e0: 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a 65 64 5c  not\sauthorized\
35f0: 73 74 6f 5c 73 63 6c 6f 6e 65 0a 20 20 20 20 20  sto\sclone.     
3600: 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20     nErr++;.     
3610: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3620: 7d 0a 20 20 20 20 20 20 69 73 50 75 6c 6c 20 3d  }.      isPull =
3630: 20 31 3b 0a 20 20 20 20 20 20 40 20 70 75 73 68   1;.      @ push
3640: 20 25 73 28 64 62 5f 67 65 74 28 22 73 65 72 76   %s(db_get("serv
3650: 65 72 2d 63 6f 64 65 22 2c 20 22 78 22 29 29 20  er-code", "x")) 
3660: 25 73 28 64 62 5f 67 65 74 28 22 70 72 6f 6a 65  %s(db_get("proje
3670: 63 74 2d 63 6f 64 65 22 2c 20 22 78 22 29 29 0a  ct-code", "x")).
3680: 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65        db_multi_e
3690: 78 65 63 28 0a 20 20 20 20 20 20 20 20 22 49 4e  xec(.        "IN
36a0: 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45 20 49  SERT OR IGNORE I
36b0: 4e 54 4f 20 70 65 6e 64 69 6e 67 28 72 69 64 29  NTO pending(rid)
36c0: 20 22 0a 20 20 20 20 20 20 20 20 22 53 45 4c 45   ".        "SELE
36d0: 43 54 20 6d 69 64 20 46 52 4f 4d 20 6d 6c 69 6e  CT mid FROM mlin
36e0: 6b 20 4a 4f 49 4e 20 62 6c 6f 62 20 4f 4e 20 6d  k JOIN blob ON m
36f0: 69 64 3d 72 69 64 22 0a 20 20 20 20 20 20 29 3b  id=rid".      );
3700: 0a 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20  .    }else..    
3710: 2f 2a 20 20 20 20 6c 6f 67 69 6e 20 20 55 53 45  /*    login  USE
3720: 52 20 20 4e 4f 4e 43 45 20 20 53 49 47 4e 41 54  R  NONCE  SIGNAT
3730: 55 52 45 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  URE.    **.    *
3740: 2a 20 43 68 65 63 6b 20 66 6f 72 20 61 20 76 61  * Check for a va
3750: 6c 69 64 20 6c 6f 67 69 6e 2e 20 20 54 68 69 73  lid login.  This
3760: 20 68 61 73 20 74 6f 20 68 61 70 70 65 6e 20 62   has to happen b
3770: 65 66 6f 72 65 20 61 6e 79 74 68 69 6e 67 20 65  efore anything e
3780: 6c 73 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  lse..    */.    
3790: 69 66 28 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f  if( blob_eq(&aTo
37a0: 6b 65 6e 5b 30 5d 2c 20 22 6c 6f 67 69 6e 22 29  ken[0], "login")
37b0: 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d 34 20 29 7b   && nToken==4 ){
37c0: 0a 20 20 20 20 20 20 69 66 28 20 64 69 73 61 62  .      if( disab
37d0: 6c 65 4c 6f 67 69 6e 20 29 7b 0a 20 20 20 20 20  leLogin ){.     
37e0: 20 20 20 67 2e 6f 6b 52 65 61 64 20 3d 20 67 2e     g.okRead = g.
37f0: 6f 6b 57 72 69 74 65 20 3d 20 31 3b 0a 20 20 20  okWrite = 1;.   
3800: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3810: 20 20 63 68 65 63 6b 5f 6c 6f 67 69 6e 28 26 61    check_login(&a
3820: 54 6f 6b 65 6e 5b 31 5d 2c 20 26 61 54 6f 6b 65  Token[1], &aToke
3830: 6e 5b 32 5d 2c 20 26 61 54 6f 6b 65 6e 5b 33 5d  n[2], &aToken[3]
3840: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
3850: 65 6c 73 65 0a 0a 20 20 20 20 2f 2a 20 55 6e 6b  else..    /* Unk
3860: 6e 6f 77 6e 20 6d 65 73 73 61 67 65 0a 20 20 20  nown message.   
3870: 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20 20   */.    {.      
3880: 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e  cgi_reset_conten
3890: 74 28 29 3b 0a 20 20 20 20 20 20 40 20 65 72 72  t();.      @ err
38a0: 6f 72 20 62 61 64 5c 73 63 6f 6d 6d 61 6e 64 3a  or bad\scommand:
38b0: 5c 73 25 46 28 62 6c 6f 62 5f 73 74 72 28 26 6c  \s%F(blob_str(&l
38c0: 69 6e 65 29 29 0a 20 20 20 20 7d 0a 20 20 20 20  ine)).    }.    
38d0: 62 6c 6f 62 61 72 72 61 79 5f 72 65 73 65 74 28  blobarray_reset(
38e0: 61 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3b  aToken, nToken);
38f0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 69  .  }..  /* The i
3900: 6e 70 75 74 20 6d 65 73 73 61 67 65 20 68 61 73  nput message has
3910: 20 6e 6f 77 20 62 65 65 6e 20 70 72 6f 63 65 73   now been proces
3920: 73 65 64 2e 20 20 47 65 6e 65 72 61 74 65 20 61  sed.  Generate a
3930: 20 72 65 70 6c 79 2e 20 2a 2f 0a 20 20 69 66 28   reply. */.  if(
3940: 20 69 73 50 75 73 68 20 29 7b 0a 20 20 20 20 53   isPush ){.    S
3950: 74 6d 74 20 71 3b 0a 20 20 20 20 69 6e 74 20 6e  tmt q;.    int n
3960: 52 65 71 20 3d 20 30 3b 0a 20 20 20 20 64 62 5f  Req = 0;.    db_
3970: 70 72 65 70 61 72 65 28 26 71 2c 20 22 53 45 4c  prepare(&q, "SEL
3980: 45 43 54 20 75 75 69 64 2c 20 72 69 64 20 46 52  ECT uuid, rid FR
3990: 4f 4d 20 70 68 61 6e 74 6f 6d 20 4a 4f 49 4e 20  OM phantom JOIN 
39a0: 62 6c 6f 62 20 55 53 49 4e 47 20 28 72 69 64 29  blob USING (rid)
39b0: 22 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 64  ");.    while( d
39c0: 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49  b_step(&q)==SQLI
39d0: 54 45 5f 52 4f 57 20 26 26 20 6e 52 65 71 2b 2b  TE_ROW && nReq++
39e0: 20 3c 20 32 30 30 20 29 7b 0a 20 20 20 20 20 20   < 200 ){.      
39f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 75 69  const char *zUui
3a00: 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65  d = db_column_te
3a10: 78 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20  xt(&q, 0);.     
3a20: 20 69 6e 74 20 72 69 64 20 3d 20 64 62 5f 63 6f   int rid = db_co
3a30: 6c 75 6d 6e 5f 69 6e 74 28 26 71 2c 20 31 29 3b  lumn_int(&q, 1);
3a40: 0a 20 20 20 20 20 20 69 6e 74 20 78 69 64 20 3d  .      int xid =
3a50: 20 73 69 6d 69 6c 61 72 5f 72 65 63 6f 72 64 28   similar_record(
3a60: 72 69 64 2c 20 30 29 3b 0a 20 20 20 20 20 20 40  rid, 0);.      @
3a70: 20 67 69 6d 6d 65 20 25 73 28 7a 55 75 69 64 29   gimme %s(zUuid)
3a80: 0a 20 20 20 20 20 20 69 66 28 20 78 69 64 20 29  .      if( xid )
3a90: 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a  {.        char *
3aa0: 7a 58 55 75 69 64 20 3d 20 64 62 5f 74 65 78 74  zXUuid = db_text
3ab0: 28 30 2c 20 22 53 45 4c 45 43 54 20 75 75 69 64  (0, "SELECT uuid
3ac0: 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45   FROM blob WHERE
3ad0: 20 72 69 64 3d 25 64 22 2c 20 78 69 64 29 3b 0a   rid=%d", xid);.
3ae0: 20 20 20 20 20 20 20 20 40 20 69 67 6f 74 20 25          @ igot %
3af0: 73 28 7a 58 55 75 69 64 29 3b 0a 20 20 20 20 20  s(zXUuid);.     
3b00: 20 20 20 66 72 65 65 28 7a 58 55 75 69 64 29 3b     free(zXUuid);
3b10: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3b20: 20 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26     db_finalize(&
3b30: 71 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 73  q);.  }.  if( is
3b40: 50 75 6c 6c 20 29 7b 0a 20 20 20 20 73 65 6e 64  Pull ){.    send
3b50: 5f 61 6c 6c 5f 70 65 6e 64 69 6e 67 28 30 29 3b  _all_pending(0);
3b60: 0a 20 20 7d 0a 20 20 69 66 28 20 69 73 50 75 73  .  }.  if( isPus
3b70: 68 20 7c 7c 20 69 73 50 75 6c 6c 20 29 7b 0a 20  h || isPull ){. 
3b80: 20 20 20 2f 2a 20 41 6c 77 61 79 73 20 73 65 6e     /* Always sen
3b90: 64 20 6f 75 72 20 6c 65 61 76 65 73 20 2a 2f 0a  d our leaves */.
3ba0: 20 20 20 20 53 74 6d 74 20 71 3b 0a 20 20 20 20      Stmt q;.    
3bb0: 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20 0a  db_prepare(&q, .
3bc0: 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 75         "SELECT u
3bd0: 75 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48  uid FROM blob WH
3be0: 45 52 45 20 72 69 64 20 49 4e 22 0a 20 20 20 20  ERE rid IN".    
3bf0: 20 20 20 22 20 20 28 53 45 4c 45 43 54 20 63 69     "  (SELECT ci
3c00: 64 20 46 52 4f 4d 20 70 6c 69 6e 6b 20 45 58 43  d FROM plink EXC
3c10: 45 50 54 20 53 45 4c 45 43 54 20 70 69 64 20 46  EPT SELECT pid F
3c20: 52 4f 4d 20 70 6c 69 6e 6b 29 22 0a 20 20 20 20  ROM plink)".    
3c30: 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 64 62  );.    while( db
3c40: 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54  _step(&q)==SQLIT
3c50: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 63  E_ROW ){.      c
3c60: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 75 69 64  onst char *zUuid
3c70: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78   = db_column_tex
3c80: 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20 20  t(&q, 0);.      
3c90: 40 20 6c 65 61 66 20 25 73 28 7a 55 75 69 64 29  @ leaf %s(zUuid)
3ca0: 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 5f 66 69  .    }.    db_fi
3cb0: 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 7d 0a  nalize(&q);.  }.
3cc0: 0a 20 20 64 62 5f 65 6e 64 5f 74 72 61 6e 73 61  .  db_end_transa
3cd0: 63 74 69 6f 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a  ction(0);.}../*.
3ce0: 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74  ** COMMAND: test
3cf0: 2d 78 66 65 72 0a 2a 2a 0a 2a 2a 20 54 68 69 73  -xfer.**.** This
3d00: 20 63 6f 6d 6d 61 6e 64 20 69 73 20 75 73 65 64   command is used
3d10: 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 74   for debugging t
3d20: 68 65 20 73 65 72 76 65 72 2e 20 20 54 68 65 72  he server.  Ther
3d30: 65 20 69 73 20 61 20 73 69 6e 67 6c 65 0a 2a 2a  e is a single.**
3d40: 20 61 72 67 75 6d 65 6e 74 20 77 68 69 63 68 20   argument which 
3d50: 69 73 20 74 68 65 20 75 6e 63 6f 6d 70 72 65 73  is the uncompres
3d60: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
3d70: 6e 20 22 78 66 65 72 22 20 6d 65 73 73 61 67 65  n "xfer" message
3d80: 0a 2a 2a 20 66 72 6f 6d 20 63 6c 69 65 6e 74 20  .** from client 
3d90: 74 6f 20 73 65 72 76 65 72 2e 20 20 54 68 69 73  to server.  This
3da0: 20 63 6f 6d 6d 61 6e 64 20 69 6e 74 65 72 70 72   command interpr
3db0: 65 74 73 20 74 68 61 74 20 6d 65 73 73 61 67 65  ets that message
3dc0: 20 61 73 0a 2a 2a 20 69 66 20 68 61 64 20 62 65   as.** if had be
3dd0: 65 6e 20 72 65 63 65 69 76 65 64 20 62 79 20 74  en received by t
3de0: 68 65 20 73 65 72 76 65 72 2e 0a 2a 2a 0a 2a 2a  he server..**.**
3df0: 20 4f 6e 20 74 68 65 20 63 6c 69 65 6e 74 20 73   On the client s
3e00: 69 64 65 2c 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20  ide, run:.**.** 
3e10: 20 20 20 20 20 66 6f 73 73 69 6c 20 70 75 73 68       fossil push
3e20: 20 68 74 74 70 3a 2f 2f 62 6f 67 75 73 2f 20 2d   http://bogus/ -
3e30: 2d 68 74 74 70 74 72 61 63 65 0a 2a 2a 0a 2a 2a  -httptrace.**.**
3e40: 20 4f 72 20 61 20 73 69 6d 69 6c 61 72 20 63 6f   Or a similar co
3e50: 6d 6d 61 6e 64 20 74 6f 20 70 72 6f 76 69 64 65  mmand to provide
3e60: 20 74 68 65 20 6f 75 74 70 75 74 2e 20 20 54 68   the output.  Th
3e70: 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65  e content of the
3e80: 0a 2a 2a 20 6d 65 73 73 61 67 65 20 77 69 6c 6c  .** message will
3e90: 20 61 70 70 65 61 72 20 6f 6e 20 73 74 61 6e 64   appear on stand
3ea0: 61 72 64 20 6f 75 74 70 75 74 2e 20 20 43 61 70  ard output.  Cap
3eb0: 74 75 72 65 20 74 68 69 73 20 6d 65 73 73 61 67  ture this messag
3ec0: 65 0a 2a 2a 20 69 6e 74 6f 20 61 20 66 69 6c 65  e.** into a file
3ed0: 20 6e 61 6d 65 64 20 28 66 6f 72 20 65 78 61 6d   named (for exam
3ee0: 70 6c 65 29 20 6f 75 74 2e 74 78 74 2e 20 20 54  ple) out.txt.  T
3ef0: 68 65 6e 20 72 75 6e 20 74 68 65 0a 2a 2a 20 73  hen run the.** s
3f00: 65 72 76 65 72 20 69 6e 20 67 64 62 3a 0a 2a 2a  erver in gdb:.**
3f10: 0a 2a 2a 20 20 20 20 20 67 64 62 20 66 6f 73 73  .**     gdb foss
3f20: 69 6c 0a 2a 2a 20 20 20 20 20 72 20 74 65 73 74  il.**     r test
3f30: 2d 78 66 65 72 20 6f 75 74 2e 74 78 74 0a 2a 2f  -xfer out.txt.*/
3f40: 0a 76 6f 69 64 20 63 6d 64 5f 74 65 73 74 5f 78  .void cmd_test_x
3f50: 66 65 72 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74  fer(void){.  int
3f60: 20 6e 6f 74 55 73 65 64 3b 0a 20 20 69 66 28 20   notUsed;.  if( 
3f70: 67 2e 61 72 67 63 21 3d 32 20 26 26 20 67 2e 61  g.argc!=2 && g.a
3f80: 72 67 63 21 3d 33 20 29 7b 0a 20 20 20 20 75 73  rgc!=3 ){.    us
3f90: 61 67 65 28 22 3f 4d 45 53 53 41 47 45 46 49 4c  age("?MESSAGEFIL
3fa0: 45 3f 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d  E?");.  }.  db_m
3fb0: 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72  ust_be_within_tr
3fc0: 65 65 28 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  ee();.  blob_zer
3fd0: 6f 28 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 62  o(&g.cgiIn);.  b
3fe0: 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69  lob_read_from_fi
3ff0: 6c 65 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e 61  le(&g.cgiIn, g.a
4000: 72 67 63 3d 3d 32 20 3f 20 22 2d 22 20 3a 20 67  rgc==2 ? "-" : g
4010: 2e 61 72 67 76 5b 32 5d 29 3b 0a 20 20 64 69 73  .argv[2]);.  dis
4020: 61 62 6c 65 4c 6f 67 69 6e 20 3d 20 31 3b 0a 20  ableLogin = 1;. 
4030: 20 70 61 67 65 5f 78 66 65 72 28 29 3b 0a 20 20   page_xfer();.  
4040: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 63  printf("%s\n", c
4050: 67 69 5f 65 78 74 72 61 63 74 5f 63 6f 6e 74 65  gi_extract_conte
4060: 6e 74 28 26 6e 6f 74 55 73 65 64 29 29 3b 0a 7d  nt(&notUsed));.}
4070: 0a 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74 6f  .../*.** Sync to
4080: 20 74 68 65 20 68 6f 73 74 20 69 64 65 6e 74 69   the host identi
4090: 66 69 65 64 20 69 6e 20 67 2e 75 72 6c 4e 61 6d  fied in g.urlNam
40a0: 65 20 61 6e 64 20 67 2e 75 72 6c 50 61 74 68 2e  e and g.urlPath.
40b0: 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e    This.** routin
40c0: 65 20 69 73 20 63 61 6c 6c 65 64 20 62 79 20 74  e is called by t
40d0: 68 65 20 63 6c 69 65 6e 74 2e 0a 2a 2a 0a 2a 2a  he client..**.**
40e0: 20 52 65 63 6f 72 64 73 20 61 72 65 20 70 75 73   Records are pus
40f0: 68 65 64 20 74 6f 20 74 68 65 20 73 65 72 76 65  hed to the serve
4100: 72 20 69 66 20 70 75 73 68 46 6c 61 67 20 69 73  r if pushFlag is
4110: 20 74 72 75 65 2e 20 20 52 65 63 6f 72 64 73 0a   true.  Records.
4120: 2a 2a 20 61 72 65 20 70 75 6c 6c 65 64 20 69 66  ** are pulled if
4130: 20 70 75 6c 6c 46 6c 61 67 20 69 73 20 74 72 75   pullFlag is tru
4140: 65 2e 20 20 41 20 66 75 6c 6c 20 73 79 6e 63 20  e.  A full sync 
4150: 6f 63 63 75 72 73 20 69 66 20 62 6f 74 68 20 61  occurs if both a
4160: 72 65 0a 2a 2a 20 74 72 75 65 2e 0a 2a 2f 0a 76  re.** true..*/.v
4170: 6f 69 64 20 63 6c 69 65 6e 74 5f 73 79 6e 63 28  oid client_sync(
4180: 69 6e 74 20 70 75 73 68 46 6c 61 67 2c 20 69 6e  int pushFlag, in
4190: 74 20 70 75 6c 6c 46 6c 61 67 2c 20 69 6e 74 20  t pullFlag, int 
41a0: 63 6c 6f 6e 65 46 6c 61 67 29 7b 0a 20 20 69 6e  cloneFlag){.  in
41b0: 74 20 67 6f 20 3d 20 31 3b 20 20 20 20 20 20 20  t go = 1;       
41c0: 20 2f 2a 20 4c 6f 6f 70 20 75 6e 74 69 6c 20 7a   /* Loop until z
41d0: 65 72 6f 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f  ero */.  int nTo
41e0: 6b 65 6e 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  ken;.  const cha
41f0: 72 20 2a 7a 53 43 6f 64 65 20 3d 20 64 62 5f 67  r *zSCode = db_g
4200: 65 74 28 22 73 65 72 76 65 72 2d 63 6f 64 65 22  et("server-code"
4210: 2c 20 22 78 22 29 3b 0a 20 20 63 6f 6e 73 74 20  , "x");.  const 
4220: 63 68 61 72 20 2a 7a 50 43 6f 64 65 20 3d 20 64  char *zPCode = d
4230: 62 5f 67 65 74 28 22 70 72 6f 6a 65 63 74 2d 63  b_get("project-c
4240: 6f 64 65 22 2c 20 30 29 3b 0a 20 20 69 6e 74 20  ode", 0);.  int 
4250: 6e 46 69 6c 65 20 3d 20 30 3b 0a 20 20 69 6e 74  nFile = 0;.  int
4260: 20 6e 4d 73 67 20 3d 20 30 3b 0a 20 20 69 6e 74   nMsg = 0;.  int
4270: 20 6e 52 65 71 20 3d 20 30 3b 0a 20 20 69 6e 74   nReq = 0;.  int
4280: 20 6e 46 69 6c 65 53 65 6e 64 3b 0a 20 20 69 6e   nFileSend;.  in
4290: 74 20 6e 4e 6f 46 69 6c 65 43 79 63 6c 65 20 3d  t nNoFileCycle =
42a0: 20 30 3b 0a 20 20 42 6c 6f 62 20 73 65 6e 64 3b   0;.  Blob send;
42b0: 20 20 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20          /* Text 
42c0: 77 65 20 61 72 65 20 73 65 6e 64 69 6e 67 20 74  we are sending t
42d0: 6f 20 74 68 65 20 73 65 72 76 65 72 20 2a 2f 0a  o the server */.
42e0: 20 20 42 6c 6f 62 20 72 65 63 76 3b 20 20 20 20    Blob recv;    
42f0: 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 77 65 20      /* Reply we 
4300: 67 6f 74 20 62 61 63 6b 20 66 72 6f 6d 20 74 68  got back from th
4310: 65 20 73 65 72 76 65 72 20 2a 2f 0a 20 20 42 6c  e server */.  Bl
4320: 6f 62 20 6c 69 6e 65 3b 20 20 20 20 20 20 20 20  ob line;        
4330: 2f 2a 20 41 20 73 69 6e 67 6c 65 20 6c 69 6e 65  /* A single line
4340: 20 6f 66 20 74 68 65 20 72 65 70 6c 79 20 2a 2f   of the reply */
4350: 0a 20 20 42 6c 6f 62 20 61 54 6f 6b 65 6e 5b 35  .  Blob aToken[5
4360: 5d 3b 20 20 20 2f 2a 20 41 20 74 6f 6b 65 6e 69  ];   /* A tokeni
4370: 7a 61 74 69 6f 6e 20 6f 66 20 6c 69 6e 65 20 2a  zation of line *
4380: 2f 0a 20 20 42 6c 6f 62 20 65 72 72 6d 73 67 3b  /.  Blob errmsg;
4390: 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 6d        /* Error m
43a0: 65 73 73 61 67 65 20 2a 2f 0a 0a 20 20 61 73 73  essage */..  ass
43b0: 65 72 74 28 20 70 75 73 68 46 6c 61 67 20 7c 7c  ert( pushFlag ||
43c0: 20 70 75 6c 6c 46 6c 61 67 20 7c 7c 20 63 6c 6f   pullFlag || clo
43d0: 6e 65 46 6c 61 67 20 29 3b 0a 20 20 61 73 73 65  neFlag );.  asse
43e0: 72 74 28 20 21 67 2e 75 72 6c 49 73 46 69 6c 65  rt( !g.urlIsFile
43f0: 20 29 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20   );          /* 
4400: 54 68 69 73 20 6f 6e 6c 79 20 77 6f 72 6b 73 20  This only works 
4410: 66 6f 72 20 6e 65 74 77 6f 72 6b 69 6e 67 20 2a  for networking *
4420: 2f 0a 0a 20 20 64 62 5f 62 65 67 69 6e 5f 74 72  /..  db_begin_tr
4430: 61 6e 73 61 63 74 69 6f 6e 28 29 3b 0a 20 20 64  ansaction();.  d
4440: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20  b_multi_exec(.  
4450: 20 20 2f 2a 20 52 65 63 6f 72 64 73 20 77 68 69    /* Records whi
4460: 63 68 20 77 65 20 6b 6e 6f 77 20 74 68 65 20 6f  ch we know the o
4470: 74 68 65 72 20 73 69 64 65 20 61 6c 73 6f 20 68  ther side also h
4480: 61 73 20 2a 2f 0a 20 20 20 20 22 43 52 45 41 54  as */.    "CREAT
4490: 45 20 54 45 4d 50 20 54 41 42 4c 45 20 6f 6e 72  E TEMP TABLE onr
44a0: 65 6d 6f 74 65 28 72 69 64 20 49 4e 54 45 47 45  emote(rid INTEGE
44b0: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 29 3b 22  R PRIMARY KEY);"
44c0: 0a 20 20 20 20 2f 2a 20 52 65 63 6f 72 64 73 20  .    /* Records 
44d0: 77 65 20 6b 6e 6f 77 20 74 68 65 20 6f 74 68 65  we know the othe
44e0: 72 20 73 69 64 65 20 6e 65 65 64 73 20 2a 2f 0a  r side needs */.
44f0: 20 20 20 20 22 43 52 45 41 54 45 20 54 45 4d 50      "CREATE TEMP
4500: 20 54 41 42 4c 45 20 70 65 6e 64 69 6e 67 28 72   TABLE pending(r
4510: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  id INTEGER PRIMA
4520: 52 59 20 4b 45 59 29 3b 22 0a 20 20 29 3b 0a 20  RY KEY);".  );. 
4530: 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72 6f 28   blobarray_zero(
4540: 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28 61 54  aToken, count(aT
4550: 6f 6b 65 6e 29 29 3b 0a 20 20 62 6c 6f 62 5f 7a  oken));.  blob_z
4560: 65 72 6f 28 26 73 65 6e 64 29 3b 0a 20 20 62 6c  ero(&send);.  bl
4570: 6f 62 5f 7a 65 72 6f 28 26 72 65 63 76 29 3b 0a  ob_zero(&recv);.
4580: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 65 72 72    blob_zero(&err
4590: 6d 73 67 29 3b 0a 0a 0a 20 20 77 68 69 6c 65 28  msg);...  while(
45a0: 20 67 6f 20 29 7b 0a 20 20 20 20 67 6f 20 3d 20   go ){.    go = 
45b0: 30 3b 0a 20 20 20 20 6e 46 69 6c 65 20 3d 20 6e  0;.    nFile = n
45c0: 52 65 71 20 3d 20 6e 4d 73 67 20 3d 20 30 3b 0a  Req = nMsg = 0;.
45d0: 0a 20 20 20 20 2f 2a 20 47 65 6e 65 72 61 74 65  .    /* Generate
45e0: 20 61 20 72 65 71 75 65 73 74 20 74 6f 20 62 65   a request to be
45f0: 20 73 65 6e 74 20 74 6f 20 74 68 65 20 73 65 72   sent to the ser
4600: 76 65 72 2e 0a 20 20 20 20 2a 2a 20 41 6c 77 61  ver..    ** Alwa
4610: 79 73 20 62 65 67 69 6e 20 77 69 74 68 20 61 20  ys begin with a 
4620: 63 6c 6f 6e 65 2c 20 70 75 6c 6c 2c 20 6f 72 20  clone, pull, or 
4630: 70 75 73 68 20 6d 65 73 73 61 67 65 0a 20 20 20  push message.   
4640: 20 2a 2f 0a 20 20 20 20 0a 20 20 20 20 69 66 28   */.    .    if(
4650: 20 63 6c 6f 6e 65 46 6c 61 67 20 29 7b 0a 20 20   cloneFlag ){.  
4660: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
4670: 28 26 73 65 6e 64 2c 20 22 63 6c 6f 6e 65 5c 6e  (&send, "clone\n
4680: 22 29 3b 0a 20 20 20 20 20 20 70 75 73 68 46 6c  ");.      pushFl
4690: 61 67 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 75  ag = 0;.      pu
46a0: 6c 6c 46 6c 61 67 20 3d 20 30 3b 0a 20 20 20 20  llFlag = 0;.    
46b0: 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20 20 7d 65    nMsg++;.    }e
46c0: 6c 73 65 20 69 66 28 20 70 75 6c 6c 46 6c 61 67  lse if( pullFlag
46d0: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61   ){.      blob_a
46e0: 70 70 65 6e 64 66 28 26 73 65 6e 64 2c 20 22 70  ppendf(&send, "p
46f0: 75 6c 6c 20 25 73 20 25 73 5c 6e 22 2c 20 7a 53  ull %s %s\n", zS
4700: 43 6f 64 65 2c 20 7a 50 43 6f 64 65 29 3b 0a 20  Code, zPCode);. 
4710: 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20       nMsg++;.   
4720: 20 7d 0a 20 20 20 20 69 66 28 20 70 75 73 68 46   }.    if( pushF
4730: 6c 61 67 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f  lag ){.      blo
4740: 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c  b_appendf(&send,
4750: 20 22 70 75 73 68 20 25 73 20 25 73 5c 6e 22 2c   "push %s %s\n",
4760: 20 7a 53 43 6f 64 65 2c 20 7a 50 43 6f 64 65 29   zSCode, zPCode)
4770: 3b 0a 20 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a  ;.      nMsg++;.
4780: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70      }..    if( p
4790: 75 6c 6c 46 6c 61 67 20 29 7b 0a 20 20 20 20 20  ullFlag ){.     
47a0: 20 2f 2a 20 53 65 6e 64 20 67 69 6d 6d 65 20 6d   /* Send gimme m
47b0: 65 73 73 61 67 65 20 66 6f 72 20 65 76 65 72 79  essage for every
47c0: 20 70 68 61 6e 74 6f 6d 20 74 68 61 74 20 77 65   phantom that we
47d0: 20 68 6f 6c 64 2e 0a 20 20 20 20 20 20 2a 2f 0a   hold..      */.
47e0: 20 20 20 20 20 20 53 74 6d 74 20 71 3b 0a 20 20        Stmt q;.  
47f0: 20 20 20 20 64 62 5f 70 72 65 70 61 72 65 28 26      db_prepare(&
4800: 71 2c 20 22 53 45 4c 45 43 54 20 75 75 69 64 2c  q, "SELECT uuid,
4810: 20 72 69 64 20 46 52 4f 4d 20 70 68 61 6e 74 6f   rid FROM phanto
4820: 6d 20 4a 4f 49 4e 20 62 6c 6f 62 20 55 53 49 4e  m JOIN blob USIN
4830: 47 20 28 72 69 64 29 22 29 3b 0a 20 20 20 20 20  G (rid)");.     
4840: 20 77 68 69 6c 65 28 20 64 62 5f 73 74 65 70 28   while( db_step(
4850: 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20  &q)==SQLITE_ROW 
4860: 26 26 20 6e 52 65 71 3c 32 30 30 20 29 7b 0a 20  && nReq<200 ){. 
4870: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
4880: 72 20 2a 7a 55 75 69 64 20 3d 20 64 62 5f 63 6f  r *zUuid = db_co
4890: 6c 75 6d 6e 5f 74 65 78 74 28 26 71 2c 20 30 29  lumn_text(&q, 0)
48a0: 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72 69  ;.        int ri
48b0: 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e  d = db_column_in
48c0: 74 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 20 20  t(&q, 1);.      
48d0: 20 20 69 6e 74 20 78 69 64 20 3d 20 73 69 6d 69    int xid = simi
48e0: 6c 61 72 5f 72 65 63 6f 72 64 28 72 69 64 2c 20  lar_record(rid, 
48f0: 30 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62  0);.        blob
4900: 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c 22  _appendf(&send,"
4910: 67 69 6d 6d 65 20 25 73 5c 6e 22 2c 20 7a 55 75  gimme %s\n", zUu
4920: 69 64 29 3b 0a 20 20 20 20 20 20 20 20 6e 52 65  id);.        nRe
4930: 71 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69 66 28  q++;.        if(
4940: 20 78 69 64 20 29 7b 0a 20 20 20 20 20 20 20 20   xid ){.        
4950: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26    blob_appendf(&
4960: 73 65 6e 64 2c 20 22 69 67 6f 74 20 25 7a 5c 6e  send, "igot %z\n
4970: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
4980: 64 62 5f 74 65 78 74 28 30 2c 20 22 53 45 4c 45  db_text(0, "SELE
4990: 43 54 20 75 75 69 64 20 46 52 4f 4d 20 62 6c 6f  CT uuid FROM blo
49a0: 62 20 57 48 45 52 45 20 72 69 64 3d 25 64 22 2c  b WHERE rid=%d",
49b0: 20 78 69 64 29 29 3b 0a 20 20 20 20 20 20 20 20   xid));.        
49c0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
49d0: 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b  db_finalize(&q);
49e0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
49f0: 70 75 73 68 46 6c 61 67 20 29 7b 0a 20 20 20 20  pushFlag ){.    
4a00: 20 20 2f 2a 20 53 65 6e 64 20 74 68 65 20 73 65    /* Send the se
4a10: 72 76 65 72 20 61 6e 79 20 66 69 6c 65 73 20 74  rver any files t
4a20: 68 61 74 20 74 68 65 20 73 65 72 76 65 72 20 68  hat the server h
4a30: 61 73 20 72 65 71 75 65 73 74 65 64 20 2a 2f 0a  as requested */.
4a40: 20 20 20 20 20 20 6e 46 69 6c 65 20 2b 3d 20 73        nFile += s
4a50: 65 6e 64 5f 61 6c 6c 5f 70 65 6e 64 69 6e 67 28  end_all_pending(
4a60: 26 73 65 6e 64 29 3b 0a 20 20 20 20 7d 0a 0a 20  &send);.    }.. 
4a70: 20 20 20 69 66 28 20 70 75 6c 6c 46 6c 61 67 20     if( pullFlag 
4a80: 7c 7c 20 70 75 73 68 46 6c 61 67 20 29 7b 0a 20  || pushFlag ){. 
4a90: 20 20 20 20 20 2f 2a 20 41 6c 77 61 79 73 20 73       /* Always s
4aa0: 65 6e 64 20 6f 75 72 20 6c 65 61 76 65 73 20 2a  end our leaves *
4ab0: 2f 0a 20 20 20 20 20 20 53 74 6d 74 20 71 3b 0a  /.      Stmt q;.
4ac0: 20 20 20 20 20 20 64 62 5f 70 72 65 70 61 72 65        db_prepare
4ad0: 28 26 71 2c 20 0a 20 20 20 20 20 20 20 20 20 22  (&q, .         "
4ae0: 53 45 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d  SELECT uuid FROM
4af0: 20 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64 20   blob WHERE rid 
4b00: 49 4e 22 0a 20 20 20 20 20 20 20 20 20 22 20 20  IN".         "  
4b10: 28 53 45 4c 45 43 54 20 63 69 64 20 46 52 4f 4d  (SELECT cid FROM
4b20: 20 70 6c 69 6e 6b 20 45 58 43 45 50 54 20 53 45   plink EXCEPT SE
4b30: 4c 45 43 54 20 70 69 64 20 46 52 4f 4d 20 70 6c  LECT pid FROM pl
4b40: 69 6e 6b 29 22 0a 20 20 20 20 20 20 29 3b 0a 20  ink)".      );. 
4b50: 20 20 20 20 20 77 68 69 6c 65 28 20 64 62 5f 73       while( db_s
4b60: 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f  tep(&q)==SQLITE_
4b70: 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 20 63  ROW ){.        c
4b80: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 75 69 64  onst char *zUuid
4b90: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78   = db_column_tex
4ba0: 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20 20  t(&q, 0);.      
4bb0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26    blob_appendf(&
4bc0: 73 65 6e 64 2c 20 22 6c 65 61 66 20 25 73 5c 6e  send, "leaf %s\n
4bd0: 22 2c 20 7a 55 75 69 64 29 3b 0a 20 20 20 20 20  ", zUuid);.     
4be0: 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20 20 20     nMsg++;.     
4bf0: 20 7d 0a 20 20 20 20 20 20 64 62 5f 66 69 6e 61   }.      db_fina
4c00: 6c 69 7a 65 28 26 71 29 3b 0a 20 20 20 20 7d 0a  lize(&q);.    }.
4c10: 0a 20 20 20 20 2f 2a 20 45 78 63 68 61 6e 67 65  .    /* Exchange
4c20: 20 6d 65 73 73 61 67 65 73 20 77 69 74 68 20 74   messages with t
4c30: 68 65 20 73 65 72 76 65 72 20 2a 2f 0a 20 20 20  he server */.   
4c40: 20 70 72 69 6e 74 66 28 22 53 65 6e 64 3a 20 20   printf("Send:  
4c50: 20 20 20 20 25 33 64 20 66 69 6c 65 73 2c 20 25      %3d files, %
4c60: 33 64 20 72 65 71 75 65 73 74 73 2c 20 25 33 64  3d requests, %3d
4c70: 20 6f 74 68 65 72 20 6d 73 67 73 2c 20 25 38 64   other msgs, %8d
4c80: 20 62 79 74 65 73 5c 6e 22 2c 0a 20 20 20 20 20   bytes\n",.     
4c90: 20 20 20 20 20 20 20 6e 46 69 6c 65 2c 20 6e 52         nFile, nR
4ca0: 65 71 2c 20 6e 4d 73 67 2c 20 62 6c 6f 62 5f 73  eq, nMsg, blob_s
4cb0: 69 7a 65 28 26 73 65 6e 64 29 29 3b 0a 20 20 20  ize(&send));.   
4cc0: 20 6e 46 69 6c 65 53 65 6e 64 20 3d 20 6e 46 69   nFileSend = nFi
4cd0: 6c 65 3b 0a 20 20 20 20 6e 46 69 6c 65 20 3d 20  le;.    nFile = 
4ce0: 6e 52 65 71 20 3d 20 6e 4d 73 67 20 3d 20 30 3b  nReq = nMsg = 0;
4cf0: 0a 20 20 20 20 68 74 74 70 5f 65 78 63 68 61 6e  .    http_exchan
4d00: 67 65 28 26 73 65 6e 64 2c 20 26 72 65 63 76 29  ge(&send, &recv)
4d10: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74  ;.    blob_reset
4d20: 28 26 73 65 6e 64 29 3b 0a 0a 20 20 20 20 2f 2a  (&send);..    /*
4d30: 20 50 72 6f 63 65 73 73 20 74 68 65 20 72 65 70   Process the rep
4d40: 6c 79 20 74 68 61 74 20 63 61 6d 65 20 62 61 63  ly that came bac
4d50: 6b 20 66 72 6f 6d 20 74 68 65 20 73 65 72 76 65  k from the serve
4d60: 72 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20  r */.    while( 
4d70: 62 6c 6f 62 5f 6c 69 6e 65 28 26 72 65 63 76 2c  blob_line(&recv,
4d80: 20 26 6c 69 6e 65 29 20 29 7b 0a 20 20 20 20 20   &line) ){.     
4d90: 20 6e 54 6f 6b 65 6e 20 3d 20 62 6c 6f 62 5f 74   nToken = blob_t
4da0: 6f 6b 65 6e 69 7a 65 28 26 6c 69 6e 65 2c 20 61  okenize(&line, a
4db0: 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28 61 54 6f  Token, count(aTo
4dc0: 6b 65 6e 29 29 3b 0a 0a 20 20 20 20 20 20 2f 2a  ken));..      /*
4dd0: 20 20 20 66 69 6c 65 20 55 55 49 44 20 53 49 5a     file UUID SIZ
4de0: 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20  E \n CONTENT.   
4df0: 20 20 20 2a 2a 20 20 20 66 69 6c 65 20 55 55 49     **   file UUI
4e00: 44 20 44 45 4c 54 41 53 52 43 20 53 49 5a 45 20  D DELTASRC SIZE 
4e10: 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20 20 20  \n CONTENT.     
4e20: 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 52 65 63   **.      ** Rec
4e30: 65 69 76 65 20 61 20 66 69 6c 65 20 74 72 61 6e  eive a file tran
4e40: 73 6d 69 74 74 65 64 20 66 72 6f 6d 20 74 68 65  smitted from the
4e50: 20 6f 74 68 65 72 20 73 69 64 65 0a 20 20 20 20   other side.    
4e60: 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 62    */.      if( b
4e70: 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30  lob_eq(&aToken[0
4e80: 5d 2c 22 66 69 6c 65 22 29 20 29 7b 0a 20 20 20  ],"file") ){.   
4e90: 20 20 20 20 20 78 66 65 72 5f 61 63 63 65 70 74       xfer_accept
4ea0: 5f 66 69 6c 65 28 26 72 65 63 76 2c 20 61 54 6f  _file(&recv, aTo
4eb0: 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 2c 20 26 65 72  ken, nToken, &er
4ec0: 72 6d 73 67 29 3b 0a 20 20 20 20 20 20 20 20 6e  rmsg);.        n
4ed0: 46 69 6c 65 2b 2b 3b 0a 20 20 20 20 20 20 20 20  File++;.        
4ee0: 67 6f 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65  go = 1;.      }e
4ef0: 6c 73 65 0a 0a 20 20 20 20 20 20 2f 2a 20 20 20  lse..      /*   
4f00: 67 69 6d 6d 65 20 55 55 49 44 0a 20 20 20 20 20  gimme UUID.     
4f10: 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 53 65 72   **.      ** Ser
4f20: 76 65 72 20 69 73 20 72 65 71 75 65 73 74 69 6e  ver is requestin
4f30: 67 20 61 20 66 69 6c 65 0a 20 20 20 20 20 20 2a  g a file.      *
4f40: 2f 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62  /.      if( blob
4f50: 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 20  _eq(&aToken[0], 
4f60: 22 67 69 6d 6d 65 22 29 20 26 26 20 6e 54 6f 6b  "gimme") && nTok
4f70: 65 6e 3d 3d 32 0a 20 20 20 20 20 20 20 20 20 20  en==2.          
4f80: 20 20 20 20 20 26 26 20 62 6c 6f 62 5f 69 73 5f       && blob_is_
4f90: 75 75 69 64 28 26 61 54 6f 6b 65 6e 5b 31 5d 29  uuid(&aToken[1])
4fa0: 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 52 65 71   ){.        nReq
4fb0: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ++;.        if( 
4fc0: 70 75 73 68 46 6c 61 67 20 29 7b 0a 20 20 20 20  pushFlag ){.    
4fd0: 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65        db_multi_e
4fe0: 78 65 63 28 0a 20 20 20 20 20 20 20 20 20 20 20  xec(.           
4ff0: 20 22 49 4e 53 45 52 54 20 4f 52 20 49 47 4e 4f   "INSERT OR IGNO
5000: 52 45 20 49 4e 54 4f 20 70 65 6e 64 69 6e 67 28  RE INTO pending(
5010: 72 69 64 29 20 22 0a 20 20 20 20 20 20 20 20 20  rid) ".         
5020: 20 20 20 22 53 45 4c 45 43 54 20 72 69 64 20 46     "SELECT rid F
5030: 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20 75  ROM blob WHERE u
5040: 75 69 64 3d 25 42 20 41 4e 44 20 73 69 7a 65 3e  uid=%B AND size>
5050: 3d 30 22 2c 20 26 61 54 6f 6b 65 6e 5b 31 5d 0a  =0", &aToken[1].
5060: 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
5070: 20 20 20 20 20 20 20 67 6f 20 3d 20 31 3b 0a 20         go = 1;. 
5080: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
5090: 65 6c 73 65 0a 20 20 0a 20 20 20 20 20 20 2f 2a  else.  .      /*
50a0: 20 20 20 69 67 6f 74 20 55 55 49 44 0a 20 20 20     igot UUID.   
50b0: 20 20 20 2a 2a 20 20 20 6c 65 61 66 20 55 55 49     **   leaf UUI
50c0: 44 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20  D.      **.     
50d0: 20 2a 2a 20 53 65 72 76 65 72 20 70 72 6f 63 6c   ** Server procl
50e0: 61 69 6d 73 20 74 68 61 74 20 69 74 20 68 61 73  aims that it has
50f0: 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 66 69   a particular fi
5100: 6c 65 2e 20 20 41 20 6c 65 61 66 20 6d 65 73 73  le.  A leaf mess
5110: 61 67 65 0a 20 20 20 20 20 20 2a 2a 20 6d 65 61  age.      ** mea
5120: 6e 73 20 74 68 61 74 20 74 68 65 20 66 69 6c 65  ns that the file
5130: 20 69 73 20 61 20 6c 65 61 66 20 6d 61 6e 69 66   is a leaf manif
5140: 65 73 74 20 6f 6e 20 74 68 65 20 73 65 72 76 65  est on the serve
5150: 72 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  r..      */.    
5160: 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3d 3d 32 0a    if( nToken==2.
5170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 26                &&
5180: 20 28 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65   (blob_eq(&aToke
5190: 6e 5b 30 5d 2c 20 22 69 67 6f 74 22 29 20 7c 7c  n[0], "igot") ||
51a0: 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e   blob_eq(&aToken
51b0: 5b 30 5d 2c 20 22 6c 65 61 66 22 29 29 0a 20 20  [0], "leaf")).  
51c0: 20 20 20 20 20 20 20 20 20 20 20 20 26 26 20 62              && b
51d0: 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f  lob_is_uuid(&aTo
51e0: 6b 65 6e 5b 31 5d 29 20 29 7b 0a 20 20 20 20 20  ken[1]) ){.     
51f0: 20 20 20 69 6e 74 20 72 69 64 20 3d 20 64 62 5f     int rid = db_
5200: 69 6e 74 28 30 2c 20 22 53 45 4c 45 43 54 20 72  int(0, "SELECT r
5210: 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45  id FROM blob WHE
5220: 52 45 20 75 75 69 64 3d 25 42 22 2c 20 26 61 54  RE uuid=%B", &aT
5230: 6f 6b 65 6e 5b 31 5d 29 3b 0a 20 20 20 20 20 20  oken[1]);.      
5240: 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20 20 20 20    nMsg++;.      
5250: 20 20 69 66 28 20 72 69 64 3e 30 20 29 7b 0a 20    if( rid>0 ){. 
5260: 20 20 20 20 20 20 20 20 20 64 62 5f 6d 75 6c 74           db_mult
5270: 69 5f 65 78 65 63 28 0a 20 20 20 20 20 20 20 20  i_exec(.        
5280: 20 20 20 20 22 49 4e 53 45 52 54 20 4f 52 20 49      "INSERT OR I
5290: 47 4e 4f 52 45 20 49 4e 54 4f 20 6f 6e 72 65 6d  GNORE INTO onrem
52a0: 6f 74 65 28 72 69 64 29 20 56 41 4c 55 45 53 28  ote(rid) VALUES(
52b0: 25 64 29 22 2c 20 72 69 64 0a 20 20 20 20 20 20  %d)", rid.      
52c0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20      );.         
52d0: 20 2f 2a 20 41 64 64 20 74 6f 20 74 68 65 20 70   /* Add to the p
52e0: 65 6e 64 69 6e 67 20 73 65 74 20 61 6c 6c 20 63  ending set all c
52f0: 68 69 6c 64 72 65 6e 20 6f 66 20 74 68 65 20 73  hildren of the s
5300: 65 72 76 65 72 27 73 20 6c 65 61 76 65 73 20 2a  erver's leaves *
5310: 2f 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  /.          if( 
5320: 70 75 73 68 46 6c 61 67 20 26 26 20 62 6c 6f 62  pushFlag && blob
5330: 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 20  _eq(&aToken[0], 
5340: 22 6c 65 61 66 22 29 20 29 7b 0a 20 20 20 20 20  "leaf") ){.     
5350: 20 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f         db_multi_
5360: 65 78 65 63 28 0a 20 20 20 20 20 20 20 20 20 20  exec(.          
5370: 20 20 20 20 22 49 4e 53 45 52 54 20 4f 52 20 49      "INSERT OR I
5380: 47 4e 4f 52 45 20 49 4e 54 4f 20 70 65 6e 64 69  GNORE INTO pendi
5390: 6e 67 28 72 69 64 29 20 22 0a 20 20 20 20 20 20  ng(rid) ".      
53a0: 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20          "SELECT 
53b0: 63 69 64 20 46 52 4f 4d 20 70 6c 69 6e 6b 20 57  cid FROM plink W
53c0: 48 45 52 45 20 70 69 64 3d 25 64 22 2c 20 72 69  HERE pid=%d", ri
53d0: 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 29 3b  d.            );
53e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
53f0: 20 64 62 5f 63 68 61 6e 67 65 73 28 29 3e 30 20   db_changes()>0 
5400: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
5410: 20 67 6f 20 3d 20 31 3b 0a 20 20 20 20 20 20 20   go = 1;.       
5420: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
5430: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66 28   }.          if(
5440: 20 70 75 6c 6c 46 6c 61 67 20 26 26 20 21 67 6f   pullFlag && !go
5450: 20 26 26 20 0a 20 20 20 20 20 20 20 20 20 20 20   && .           
5460: 20 20 20 64 62 5f 65 78 69 73 74 73 28 22 53 45     db_exists("SE
5470: 4c 45 43 54 20 31 20 46 52 4f 4d 20 70 68 61 6e  LECT 1 FROM phan
5480: 74 6f 6d 20 57 48 45 52 45 20 72 69 64 3d 25 64  tom WHERE rid=%d
5490: 22 2c 20 72 69 64 29 20 29 7b 0a 20 20 20 20 20  ", rid) ){.     
54a0: 20 20 20 20 20 20 20 67 6f 20 3d 20 31 3b 0a 20         go = 1;. 
54b0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
54c0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 75 6c     }else if( pul
54d0: 6c 46 6c 61 67 20 29 7b 0a 20 20 20 20 20 20 20  lFlag ){.       
54e0: 20 20 20 67 6f 20 3d 20 31 3b 0a 20 20 20 20 20     go = 1;.     
54f0: 20 20 20 20 20 63 6f 6e 74 65 6e 74 5f 70 75 74       content_put
5500: 28 30 2c 20 62 6c 6f 62 5f 73 74 72 28 26 61 54  (0, blob_str(&aT
5510: 6f 6b 65 6e 5b 31 5d 29 29 3b 0a 20 20 20 20 20  oken[1]));.     
5520: 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65     }.      }else
5530: 0a 20 20 0a 20 20 20 20 20 20 2f 2a 20 20 20 70  .  .      /*   p
5540: 75 73 68 20 20 53 45 52 56 45 52 43 4f 44 45 20  ush  SERVERCODE 
5550: 20 50 52 4f 44 55 43 54 43 4f 44 45 0a 20 20 20   PRODUCTCODE.   
5560: 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 53     **.      ** S
5570: 68 6f 75 6c 64 20 6f 6e 6c 79 20 68 61 70 70 65  hould only happe
5580: 6e 20 69 6e 20 72 65 73 70 6f 6e 73 65 20 74 6f  n in response to
5590: 20 61 20 63 6c 6f 6e 65 2e 0a 20 20 20 20 20 20   a clone..      
55a0: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f  */.      if( blo
55b0: 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c  b_eq(&aToken[0],
55c0: 22 70 75 73 68 22 29 20 26 26 20 6e 54 6f 6b 65  "push") && nToke
55d0: 6e 3d 3d 33 20 26 26 20 63 6c 6f 6e 65 46 6c 61  n==3 && cloneFla
55e0: 67 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g.              
55f0: 26 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28  && blob_is_uuid(
5600: 26 61 54 6f 6b 65 6e 5b 31 5d 29 20 26 26 20 62  &aToken[1]) && b
5610: 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f  lob_is_uuid(&aTo
5620: 6b 65 6e 5b 32 5d 29 20 29 7b 0a 0a 20 20 20 20  ken[2]) ){..    
5630: 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 5f      if( blob_eq_
5640: 73 74 72 28 26 61 54 6f 6b 65 6e 5b 31 5d 2c 20  str(&aToken[1], 
5650: 7a 53 43 6f 64 65 2c 20 2d 31 29 20 29 7b 0a 20  zSCode, -1) ){. 
5660: 20 20 20 20 20 20 20 20 20 66 6f 73 73 69 6c 5f           fossil_
5670: 66 61 74 61 6c 28 22 73 65 72 76 65 72 20 6c 6f  fatal("server lo
5680: 6f 70 22 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  op");.        }.
5690: 20 20 20 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a          nMsg++;.
56a0: 20 20 20 20 20 20 20 20 69 66 28 20 7a 50 43 6f          if( zPCo
56b0: 64 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  de==0 ){.       
56c0: 20 20 20 7a 50 43 6f 64 65 20 3d 20 6d 70 72 69     zPCode = mpri
56d0: 6e 74 66 28 22 25 62 22 2c 20 26 61 54 6f 6b 65  ntf("%b", &aToke
56e0: 6e 5b 32 5d 29 3b 0a 20 20 20 20 20 20 20 20 20  n[2]);.         
56f0: 20 64 62 5f 73 65 74 28 22 70 72 6f 6a 65 63 74   db_set("project
5700: 2d 63 6f 64 65 22 2c 20 7a 50 43 6f 64 65 29 3b  -code", zPCode);
5710: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
5720: 20 20 20 63 6c 6f 6e 65 46 6c 61 67 20 3d 20 30     cloneFlag = 0
5730: 3b 0a 20 20 20 20 20 20 20 20 70 75 6c 6c 46 6c  ;.        pullFl
5740: 61 67 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65  ag = 1;.      }e
5750: 6c 73 65 0a 0a 20 20 20 20 20 20 2f 2a 20 20 20  lse..      /*   
5760: 65 72 72 6f 72 20 4d 45 53 53 41 47 45 0a 20 20  error MESSAGE.  
5770: 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20      **.      ** 
5780: 52 65 70 6f 72 74 20 61 6e 20 65 72 72 6f 72 0a  Report an error.
5790: 20 20 20 20 20 20 2a 2f 20 20 20 20 20 20 20 20        */        
57a0: 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f  .      if( blob_
57b0: 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 22 65  eq(&aToken[0],"e
57c0: 72 72 6f 72 22 29 20 26 26 20 6e 54 6f 6b 65 6e  rror") && nToken
57d0: 3d 3d 32 20 29 7b 0a 20 20 20 20 20 20 20 20 63  ==2 ){.        c
57e0: 68 61 72 20 2a 7a 4d 73 67 20 3d 20 62 6c 6f 62  har *zMsg = blob
57f0: 5f 74 65 72 6d 69 6e 61 74 65 28 26 61 54 6f 6b  _terminate(&aTok
5800: 65 6e 5b 31 5d 29 3b 0a 20 20 20 20 20 20 20 20  en[1]);.        
5810: 64 65 66 6f 73 73 69 6c 69 7a 65 28 7a 4d 73 67  defossilize(zMsg
5820: 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  );.        blob_
5830: 61 70 70 65 6e 64 66 28 26 65 72 72 6d 73 67 2c  appendf(&errmsg,
5840: 20 22 73 65 72 76 65 72 20 73 61 79 73 3a 20 25   "server says: %
5850: 73 22 2c 20 7a 4d 73 67 29 3b 0a 20 20 20 20 20  s", zMsg);.     
5860: 20 7d 65 6c 73 65 0a 0a 20 20 20 20 20 20 2f 2a   }else..      /*
5870: 20 55 6e 6b 6e 6f 77 6e 20 6d 65 73 73 61 67 65   Unknown message
5880: 20 2a 2f 0a 20 20 20 20 20 20 7b 0a 20 20 20 20   */.      {.    
5890: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
58a0: 28 26 65 72 72 6d 73 67 2c 20 22 75 6e 6b 6e 6f  (&errmsg, "unkno
58b0: 77 6e 20 63 6f 6d 6d 61 6e 64 3a 20 25 62 22 2c  wn command: %b",
58c0: 20 26 61 54 6f 6b 65 6e 5b 30 5d 29 3b 0a 20 20   &aToken[0]);.  
58d0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28      }..      if(
58e0: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 65 72 72 6d   blob_size(&errm
58f0: 73 67 29 20 29 7b 0a 20 20 20 20 20 20 20 20 66  sg) ){.        f
5900: 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 25 62 22  ossil_fatal("%b"
5910: 2c 20 26 65 72 72 6d 73 67 29 3b 0a 20 20 20 20  , &errmsg);.    
5920: 20 20 7d 0a 20 20 20 20 20 20 62 6c 6f 62 61 72    }.      blobar
5930: 72 61 79 5f 72 65 73 65 74 28 61 54 6f 6b 65 6e  ray_reset(aToken
5940: 2c 20 6e 54 6f 6b 65 6e 29 3b 0a 20 20 20 20 7d  , nToken);.    }
5950: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 52 65 63  .    printf("Rec
5960: 65 69 76 65 64 3a 20 20 25 33 64 20 66 69 6c 65  eived:  %3d file
5970: 73 2c 20 25 33 64 20 72 65 71 75 65 73 74 73 2c  s, %3d requests,
5980: 20 25 33 64 20 6f 74 68 65 72 20 6d 73 67 73 2c   %3d other msgs,
5990: 20 25 38 64 20 62 79 74 65 73 5c 6e 22 2c 0a 20   %8d bytes\n",. 
59a0: 20 20 20 20 20 20 20 20 20 20 20 6e 46 69 6c 65             nFile
59b0: 2c 20 6e 52 65 71 2c 20 6e 4d 73 67 2c 20 62 6c  , nReq, nMsg, bl
59c0: 6f 62 5f 73 69 7a 65 28 26 72 65 63 76 29 29 3b  ob_size(&recv));
59d0: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  .    blob_reset(
59e0: 26 72 65 63 76 29 3b 0a 20 20 20 20 69 66 28 20  &recv);.    if( 
59f0: 6e 46 69 6c 65 53 65 6e 64 20 2b 20 6e 46 69 6c  nFileSend + nFil
5a00: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 6e 4e  e==0 ){.      nN
5a10: 6f 46 69 6c 65 43 79 63 6c 65 2b 2b 3b 0a 20 20  oFileCycle++;.  
5a20: 20 20 20 20 69 66 28 20 6e 4e 6f 46 69 6c 65 43      if( nNoFileC
5a30: 79 63 6c 65 3e 31 20 29 7b 0a 20 20 20 20 20 20  ycle>1 ){.      
5a40: 20 20 67 6f 20 3d 20 30 3b 0a 20 20 20 20 20 20    go = 0;.      
5a50: 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  }.    }else{.   
5a60: 20 20 20 6e 4e 6f 46 69 6c 65 43 79 63 6c 65 20     nNoFileCycle 
5a70: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e  = 0;.    }.    n
5a80: 46 69 6c 65 20 3d 20 6e 52 65 71 20 3d 20 6e 4d  File = nReq = nM
5a90: 73 67 20 3d 20 30 3b 0a 20 20 7d 3b 0a 20 20 68  sg = 0;.  };.  h
5aa0: 74 74 70 5f 63 6c 6f 73 65 28 29 3b 0a 20 20 64  ttp_close();.  d
5ab0: 62 5f 65 6e 64 5f 74 72 61 6e 73 61 63 74 69 6f  b_end_transactio
5ac0: 6e 28 30 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69  n(0);.  db_multi
5ad0: 5f 65 78 65 63 28 0a 20 20 20 20 22 44 52 4f 50  _exec(.    "DROP
5ae0: 20 54 41 42 4c 45 20 6f 6e 72 65 6d 6f 74 65 3b   TABLE onremote;
5af0: 22 0a 20 20 20 20 22 44 52 4f 50 20 54 41 42 4c  ".    "DROP TABL
5b00: 45 20 70 65 6e 64 69 6e 67 3b 22 0a 20 20 29 3b  E pending;".  );
5b10: 0a 7d 0a                                         .}.