Hex Artifact Content
Not logged in

Artifact 338dc3ed99050b343b0d72d608f44bcafd0a88c4:

File src/xfer.c part of check-in [eea381f416] - Progress toward delta compression on the xfer protocol. The compression works well. But the client is not telling the server what files it has so the server does not have anything to delta against. by drh on 2007-08-09 03:19:18.

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 53 74 6d 74 20 71 3b 0a 20 20 69 6e  ;.  Stmt q;.  in
0530: 74 20 71 75 65 75 65 5b 31 30 30 5d 3b 0a 0a 20  t queue[100];.. 
0540: 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 0a   db_prepare(&q,.
0550: 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 73 72        "SELECT sr
0560: 63 69 64 2c 20 45 58 49 53 54 53 28 53 45 4c 45  cid, EXISTS(SELE
0570: 43 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65 6d 6f  CT 1 FROM onremo
0580: 74 65 20 57 48 45 52 45 20 72 69 64 3d 73 72 63  te WHERE rid=src
0590: 69 64 29 22 0a 20 20 20 20 20 20 22 20 20 46 52  id)".      "  FR
05a0: 4f 4d 20 64 65 6c 74 61 22 0a 20 20 20 20 20 20  OM delta".      
05b0: 22 20 57 48 45 52 45 20 72 69 64 3d 3a 78 22 0a  " WHERE rid=:x".
05c0: 20 20 20 20 20 20 22 20 55 4e 49 4f 4e 20 41 4c        " UNION AL
05d0: 4c 20 22 0a 20 20 20 20 20 20 22 53 45 4c 45 43  L ".      "SELEC
05e0: 54 20 72 69 64 2c 20 45 58 49 53 54 53 28 53 45  T rid, EXISTS(SE
05f0: 4c 45 43 54 20 31 20 46 52 4f 4d 20 6f 6e 72 65  LECT 1 FROM onre
0600: 6d 6f 74 65 20 57 48 45 52 45 20 72 69 64 3d 64  mote WHERE rid=d
0610: 65 6c 74 61 2e 72 69 64 29 22 0a 20 20 20 20 20  elta.rid)".     
0620: 20 22 20 20 46 52 4f 4d 20 64 65 6c 74 61 22 0a   "  FROM delta".
0630: 20 20 20 20 20 20 22 20 57 48 45 52 45 20 73 72        " WHERE sr
0640: 63 69 64 3d 3a 78 22 0a 20 20 29 3b 0a 20 20 71  cid=:x".  );.  q
0650: 75 65 75 65 5b 30 5d 20 3d 20 72 69 64 3b 0a 20  ueue[0] = rid;. 
0660: 20 69 6e 43 6e 74 20 3d 20 31 3b 0a 20 20 6f 75   inCnt = 1;.  ou
0670: 74 43 6e 74 20 3d 20 30 3b 0a 20 20 77 68 69 6c  tCnt = 0;.  whil
0680: 65 28 20 6f 75 74 43 6e 74 3c 69 6e 43 6e 74 20  e( outCnt<inCnt 
0690: 29 7b 0a 20 20 20 20 69 6e 74 20 78 69 64 20 3d  ){.    int xid =
06a0: 20 71 75 65 75 65 5b 6f 75 74 43 6e 74 25 36 34   queue[outCnt%64
06b0: 5d 3b 0a 20 20 20 20 6f 75 74 43 6e 74 2b 2b 3b  ];.    outCnt++;
06c0: 0a 20 20 20 20 64 62 5f 62 69 6e 64 5f 69 6e 74  .    db_bind_int
06d0: 28 26 71 2c 20 22 3a 78 22 2c 20 78 69 64 29 3b  (&q, ":x", xid);
06e0: 0a 20 20 20 20 69 66 28 20 74 72 61 63 65 46 6c  .    if( traceFl
06f0: 61 67 20 29 20 70 72 69 6e 74 66 28 22 78 69 64  ag ) printf("xid
0700: 3d 25 64 5c 6e 22 2c 20 78 69 64 29 3b 0a 20 20  =%d\n", xid);.  
0710: 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74 65 70    while( db_step
0720: 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  (&q)==SQLITE_ROW
0730: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 69   ){.      int ni
0740: 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e  d = db_column_in
0750: 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20 20  t(&q, 0);.      
0760: 69 6e 74 20 68 69 74 20 3d 20 64 62 5f 63 6f 6c  int hit = db_col
0770: 75 6d 6e 5f 69 6e 74 28 26 71 2c 20 31 29 3b 0a  umn_int(&q, 1);.
0780: 20 20 20 20 20 20 69 66 28 20 74 72 61 63 65 46        if( traceF
0790: 6c 61 67 20 29 20 70 72 69 6e 74 66 28 22 6e 69  lag ) printf("ni
07a0: 64 3d 25 64 20 68 69 74 3d 25 64 5c 6e 22 2c 20  d=%d hit=%d\n", 
07b0: 6e 69 64 2c 20 68 69 74 29 3b 0a 20 20 20 20 20  nid, hit);.     
07c0: 20 69 66 28 20 68 69 74 20 20 29 7b 0a 20 20 20   if( hit  ){.   
07d0: 20 20 20 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65       db_finalize
07e0: 28 26 71 29 3b 0a 20 20 20 20 20 20 20 20 72 65  (&q);.        re
07f0: 74 75 72 6e 20 6e 69 64 3b 0a 20 20 20 20 20 20  turn nid;.      
0800: 7d 0a 20 20 20 20 20 20 69 66 28 20 69 6e 43 6e  }.      if( inCn
0810: 74 3c 73 69 7a 65 6f 66 28 71 75 65 75 65 29 2f  t<sizeof(queue)/
0820: 73 69 7a 65 6f 66 28 71 75 65 75 65 5b 30 5d 29  sizeof(queue[0])
0830: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
0840: 69 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69  i;.        for(i
0850: 3d 30 3b 20 69 3c 69 6e 43 6e 74 20 26 26 20 71  =0; i<inCnt && q
0860: 75 65 75 65 5b 69 5d 21 3d 6e 69 64 3b 20 69 2b  ueue[i]!=nid; i+
0870: 2b 29 7b 7d 0a 20 20 20 20 20 20 20 20 69 66 28  +){}.        if(
0880: 20 69 3e 3d 69 6e 43 6e 74 20 29 7b 0a 20 20 20   i>=inCnt ){.   
0890: 20 20 20 20 20 20 20 71 75 65 75 65 5b 69 6e 43         queue[inC
08a0: 6e 74 2b 2b 5d 20 3d 20 6e 69 64 3b 0a 20 20 20  nt++] = nid;.   
08b0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
08c0: 20 20 20 7d 0a 20 20 20 20 64 62 5f 72 65 73 65     }.    db_rese
08d0: 74 28 26 71 29 3b 0a 20 20 7d 0a 20 20 64 62 5f  t(&q);.  }.  db_
08e0: 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20  finalize(&q);.  
08f0: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a  return 0;.}../*.
0900: 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74  ** COMMAND: test
0910: 2d 73 69 6d 69 6c 61 72 2d 72 65 63 6f 72 64 0a  -similar-record.
0920: 2a 2f 0a 76 6f 69 64 20 74 65 73 74 5f 73 69 6d  */.void test_sim
0930: 69 6c 61 72 5f 72 65 63 6f 72 64 28 76 6f 69 64  ilar_record(void
0940: 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 66  ){.  int i;.  if
0950: 28 20 67 2e 61 72 67 63 3c 34 20 29 7b 0a 20 20  ( g.argc<4 ){.  
0960: 20 20 75 73 61 67 65 28 22 53 52 43 20 4f 4e 52    usage("SRC ONR
0970: 45 4d 4f 54 45 2e 2e 2e 22 29 3b 0a 20 20 7d 0a  EMOTE...");.  }.
0980: 20 20 64 62 5f 6d 75 73 74 5f 62 65 5f 77 69 74    db_must_be_wit
0990: 68 69 6e 5f 74 72 65 65 28 29 3b 0a 20 20 64 62  hin_tree();.  db
09a0: 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 20  _multi_exec(.   
09b0: 20 22 43 52 45 41 54 45 20 54 45 4d 50 20 54 41   "CREATE TEMP TA
09c0: 42 4c 45 20 6f 6e 72 65 6d 6f 74 65 28 72 69 64  BLE onremote(rid
09d0: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59   INTEGER PRIMARY
09e0: 20 4b 45 59 29 3b 22 0a 20 20 29 3b 0a 20 20 66   KEY);".  );.  f
09f0: 6f 72 28 69 3d 33 3b 20 69 3c 67 2e 61 72 67 63  or(i=3; i<g.argc
0a00: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20  ; i++){.    int 
0a10: 72 69 64 20 3d 20 6e 61 6d 65 5f 74 6f 5f 72 69  rid = name_to_ri
0a20: 64 28 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20  d(g.argv[i]);.  
0a30: 20 20 70 72 69 6e 74 66 28 22 25 73 20 2d 3e 20    printf("%s -> 
0a40: 25 64 5c 6e 22 2c 20 67 2e 61 72 67 76 5b 69 5d  %d\n", g.argv[i]
0a50: 2c 20 72 69 64 29 3b 0a 20 20 20 20 64 62 5f 6d  , rid);.    db_m
0a60: 75 6c 74 69 5f 65 78 65 63 28 22 49 4e 53 45 52  ulti_exec("INSER
0a70: 54 20 49 4e 54 4f 20 6f 6e 72 65 6d 6f 74 65 20  T INTO onremote 
0a80: 56 41 4c 55 45 53 28 25 64 29 22 2c 20 72 69 64  VALUES(%d)", rid
0a90: 29 3b 0a 20 20 7d 0a 20 20 70 72 69 6e 74 66 28  );.  }.  printf(
0aa0: 22 73 69 6d 69 6c 61 72 3a 20 25 64 5c 6e 22 2c  "similar: %d\n",
0ab0: 20 73 69 6d 69 6c 61 72 5f 72 65 63 6f 72 64 28   similar_record(
0ac0: 6e 61 6d 65 5f 74 6f 5f 72 69 64 28 67 2e 61 72  name_to_rid(g.ar
0ad0: 67 76 5b 32 5d 29 2c 20 31 29 29 3b 0a 7d 0a 0a  gv[2]), 1));.}..
0ae0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 54 6f 6b 65  ./*.** The aToke
0af0: 6e 5b 30 2e 2e 6e 54 6f 6b 65 6e 2d 31 5d 20 62  n[0..nToken-1] b
0b00: 6c 6f 62 20 61 72 72 61 79 20 69 73 20 61 20 70  lob array is a p
0b10: 61 72 73 65 20 6f 66 20 61 20 22 66 69 6c 65 22  arse of a "file"
0b20: 20 6c 69 6e 65 20 0a 2a 2a 20 6d 65 73 73 61 67   line .** messag
0b30: 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65  e.  This routine
0b40: 20 66 69 6e 69 73 68 65 73 20 70 61 72 73 69 6e   finishes parsin
0b50: 67 20 74 68 61 74 20 6d 65 73 73 61 67 65 20 61  g that message a
0b60: 6e 64 20 64 6f 65 73 0a 2a 2a 20 61 20 72 65 63  nd does.** a rec
0b70: 6f 72 64 20 69 6e 73 65 72 74 20 6f 66 20 74 68  ord insert of th
0b80: 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  e file..**.** Th
0b90: 65 20 66 69 6c 65 20 6c 69 6e 65 20 69 73 20 69  e file line is i
0ba0: 6e 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c  n one of the fol
0bb0: 6c 6f 77 69 6e 67 20 74 77 6f 20 66 6f 72 6d 73  lowing two forms
0bc0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 66 69 6c  :.**.**      fil
0bd0: 65 20 55 55 49 44 20 53 49 5a 45 20 5c 6e 20 43  e UUID SIZE \n C
0be0: 4f 4e 54 45 4e 54 0a 2a 2a 20 20 20 20 20 20 66  ONTENT.**      f
0bf0: 69 6c 65 20 55 55 49 44 20 44 45 4c 54 41 53 52  ile UUID DELTASR
0c00: 43 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e  C SIZE \n CONTEN
0c10: 54 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e 74  T.**.** The cont
0c20: 65 6e 74 20 69 73 20 53 49 5a 45 20 62 79 74 65  ent is SIZE byte
0c30: 73 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f  s immediately fo
0c40: 6c 6c 6f 77 69 6e 67 20 74 68 65 20 6e 65 77 6c  llowing the newl
0c50: 69 6e 65 2e 0a 2a 2a 20 49 66 20 44 45 4c 54 41  ine..** If DELTA
0c60: 53 52 43 20 65 78 69 73 74 73 2c 20 74 68 65 6e  SRC exists, then
0c70: 20 74 68 65 20 43 4f 4e 54 45 4e 54 20 69 73 20   the CONTENT is 
0c80: 61 20 64 65 6c 74 61 20 61 67 61 69 6e 73 74 20  a delta against 
0c90: 74 68 65 0a 2a 2a 20 63 6f 6e 74 65 6e 74 20 6f  the.** content o
0ca0: 66 20 44 45 4c 54 41 53 52 43 2e 0a 2a 2a 0a 2a  f DELTASRC..**.*
0cb0: 2a 20 49 66 20 61 6e 79 20 65 72 72 6f 72 20 6f  * If any error o
0cc0: 63 63 75 72 73 2c 20 77 72 69 74 65 20 61 20 6d  ccurs, write a m
0cd0: 65 73 73 61 67 65 20 69 6e 74 6f 20 70 45 72 72  essage into pErr
0ce0: 20 77 68 69 63 68 20 68 61 73 20 61 6c 72 65 61   which has alrea
0cf0: 64 79 0a 2a 2a 20 62 65 20 69 6e 69 74 69 61 6c  dy.** be initial
0d00: 69 7a 65 64 20 74 6f 20 61 6e 20 65 6d 70 74 79  ized to an empty
0d10: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74   string..*/.stat
0d20: 69 63 20 76 6f 69 64 20 78 66 65 72 5f 61 63 63  ic void xfer_acc
0d30: 65 70 74 5f 66 69 6c 65 28 42 6c 6f 62 20 2a 70  ept_file(Blob *p
0d40: 49 6e 2c 20 42 6c 6f 62 20 2a 61 54 6f 6b 65 6e  In, Blob *aToken
0d50: 2c 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 42 6c  , int nToken, Bl
0d60: 6f 62 20 2a 70 45 72 72 29 7b 0a 20 20 69 6e 74  ob *pErr){.  int
0d70: 20 6e 3b 0a 20 20 69 6e 74 20 72 69 64 3b 0a 20   n;.  int rid;. 
0d80: 20 42 6c 6f 62 20 63 6f 6e 74 65 6e 74 2c 20 68   Blob content, h
0d90: 61 73 68 3b 0a 20 20 0a 20 20 69 66 28 20 6e 54  ash;.  .  if( nT
0da0: 6f 6b 65 6e 3c 33 20 7c 7c 20 6e 54 6f 6b 65 6e  oken<3 || nToken
0db0: 3e 34 20 7c 7c 20 21 62 6c 6f 62 5f 69 73 5f 75  >4 || !blob_is_u
0dc0: 75 69 64 28 26 61 54 6f 6b 65 6e 5b 31 5d 29 0a  uid(&aToken[1]).
0dd0: 20 20 20 20 20 20 20 7c 7c 20 21 62 6c 6f 62 5f         || !blob_
0de0: 69 73 5f 69 6e 74 28 26 61 54 6f 6b 65 6e 5b 6e  is_int(&aToken[n
0df0: 54 6f 6b 65 6e 2d 31 5d 2c 20 26 6e 29 20 7c 7c  Token-1], &n) ||
0e00: 20 6e 3c 3d 30 0a 20 20 20 20 20 20 20 7c 7c 20   n<=0.       || 
0e10: 28 6e 54 6f 6b 65 6e 3d 3d 34 20 26 26 20 21 62  (nToken==4 && !b
0e20: 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f  lob_is_uuid(&aTo
0e30: 6b 65 6e 5b 32 5d 29 29 20 29 7b 0a 20 20 20 20  ken[2])) ){.    
0e40: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70 45 72  blob_appendf(pEr
0e50: 72 2c 20 22 6d 61 6c 66 6f 72 6d 65 64 20 66 69  r, "malformed fi
0e60: 6c 65 20 6c 69 6e 65 22 29 3b 0a 20 20 20 20 72  le line");.    r
0e70: 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c 6f  eturn;.  }.  blo
0e80: 62 5f 7a 65 72 6f 28 26 63 6f 6e 74 65 6e 74 29  b_zero(&content)
0e90: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 68  ;.  blob_zero(&h
0ea0: 61 73 68 29 3b 0a 20 20 62 6c 6f 62 5f 65 78 74  ash);.  blob_ext
0eb0: 72 61 63 74 28 70 49 6e 2c 20 6e 2c 20 26 63 6f  ract(pIn, n, &co
0ec0: 6e 74 65 6e 74 29 3b 0a 20 20 69 66 28 20 6e 54  ntent);.  if( nT
0ed0: 6f 6b 65 6e 3d 3d 34 20 29 7b 0a 20 20 20 20 42  oken==4 ){.    B
0ee0: 6c 6f 62 20 73 72 63 3b 0a 20 20 20 20 69 6e 74  lob src;.    int
0ef0: 20 73 72 63 69 64 20 3d 20 64 62 5f 69 6e 74 28   srcid = db_int(
0f00: 30 2c 20 22 53 45 4c 45 43 54 20 72 69 64 20 46  0, "SELECT rid F
0f10: 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20 75  ROM blob WHERE u
0f20: 75 69 64 3d 25 42 22 2c 20 26 61 54 6f 6b 65 6e  uid=%B", &aToken
0f30: 5b 32 5d 29 3b 0a 20 20 20 20 69 66 28 20 73 72  [2]);.    if( sr
0f40: 63 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  cid==0 ){.      
0f50: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70 45 72  blob_appendf(pEr
0f60: 72 2c 20 22 75 6e 6b 6e 6f 77 6e 20 64 65 6c 74  r, "unknown delt
0f70: 61 20 73 6f 75 72 63 65 3a 20 25 62 22 2c 20 26  a source: %b", &
0f80: 61 54 6f 6b 65 6e 5b 32 5d 29 3b 0a 20 20 20 20  aToken[2]);.    
0f90: 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a    return;.    }.
0fa0: 20 20 20 20 63 6f 6e 74 65 6e 74 5f 67 65 74 28      content_get(
0fb0: 73 72 63 69 64 2c 20 26 73 72 63 29 3b 0a 20 20  srcid, &src);.  
0fc0: 20 20 62 6c 6f 62 5f 64 65 6c 74 61 5f 61 70 70    blob_delta_app
0fd0: 6c 79 28 26 73 72 63 2c 20 26 63 6f 6e 74 65 6e  ly(&src, &conten
0fe0: 74 2c 20 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20  t, &content);.  
0ff0: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 73 72    blob_reset(&sr
1000: 63 29 3b 0a 20 20 7d 0a 20 20 73 68 61 31 73 75  c);.  }.  sha1su
1010: 6d 5f 62 6c 6f 62 28 26 63 6f 6e 74 65 6e 74 2c  m_blob(&content,
1020: 20 26 68 61 73 68 29 3b 0a 20 20 69 66 28 20 21   &hash);.  if( !
1030: 62 6c 6f 62 5f 65 71 5f 73 74 72 28 26 61 54 6f  blob_eq_str(&aTo
1040: 6b 65 6e 5b 31 5d 2c 20 62 6c 6f 62 5f 73 74 72  ken[1], blob_str
1050: 28 26 68 61 73 68 29 2c 20 2d 31 29 20 29 7b 0a  (&hash), -1) ){.
1060: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
1070: 28 70 45 72 72 2c 20 22 63 6f 6e 74 65 6e 74 20  (pErr, "content 
1080: 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 73  does not match s
1090: 68 61 31 20 68 61 73 68 22 29 3b 0a 20 20 7d 0a  ha1 hash");.  }.
10a0: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61    blob_reset(&ha
10b0: 73 68 29 3b 0a 20 20 72 69 64 20 3d 20 63 6f 6e  sh);.  rid = con
10c0: 74 65 6e 74 5f 70 75 74 28 26 63 6f 6e 74 65 6e  tent_put(&conten
10d0: 74 2c 20 30 29 3b 0a 20 20 6d 61 6e 69 66 65 73  t, 0);.  manifes
10e0: 74 5f 63 72 6f 73 73 6c 69 6e 6b 28 72 69 64 2c  t_crosslink(rid,
10f0: 20 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 69 66   &content);.  if
1100: 28 20 72 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20  ( rid==0 ){.    
1110: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70 45 72  blob_appendf(pEr
1120: 72 2c 20 22 25 73 22 2c 20 67 2e 7a 45 72 72 4d  r, "%s", g.zErrM
1130: 73 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  sg);.  }.}../*.*
1140: 2a 20 53 65 6e 64 20 74 68 65 20 66 69 6c 65 20  * Send the file 
1150: 69 64 65 6e 74 69 66 69 65 64 20 62 79 20 72 69  identified by ri
1160: 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 4f 75 74  d..**.** If pOut
1170: 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68   is not NULL, th
1180: 65 6e 20 61 70 70 65 6e 64 20 74 68 65 20 74 65  en append the te
1190: 78 74 20 6f 66 20 74 68 65 20 73 65 6e 64 20 6d  xt of the send m
11a0: 65 73 73 61 67 65 0a 2a 2a 20 74 6f 20 70 4f 75  essage.** to pOu
11b0: 74 2e 20 20 4f 74 68 65 72 77 69 73 65 2c 20 61  t.  Otherwise, a
11c0: 70 70 65 6e 64 20 74 68 65 20 74 65 78 74 20 74  ppend the text t
11d0: 6f 20 74 68 65 20 43 47 49 20 6f 75 74 70 75 74  o the CGI output
11e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
11f0: 73 65 6e 64 5f 66 69 6c 65 28 69 6e 74 20 72 69  send_file(int ri
1200: 64 2c 20 42 6c 6f 62 20 2a 70 4f 75 74 29 7b 0a  d, Blob *pOut){.
1210: 20 20 42 6c 6f 62 20 63 6f 6e 74 65 6e 74 2c 20    Blob content, 
1220: 75 75 69 64 3b 0a 20 20 69 6e 74 20 73 69 7a 65  uuid;.  int size
1230: 3b 0a 20 20 69 6e 74 20 73 72 63 69 64 3b 0a 0a  ;.  int srcid;..
1240: 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 75 75  .  blob_zero(&uu
1250: 69 64 29 3b 0a 20 20 64 62 5f 62 6c 6f 62 28 26  id);.  db_blob(&
1260: 75 75 69 64 2c 20 22 53 45 4c 45 43 54 20 75 75  uuid, "SELECT uu
1270: 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45  id FROM blob WHE
1280: 52 45 20 72 69 64 3d 25 64 20 41 4e 44 20 73 69  RE rid=%d AND si
1290: 7a 65 3e 3d 30 22 2c 20 72 69 64 29 3b 0a 20 20  ze>=0", rid);.  
12a0: 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65 28 26 75  if( blob_size(&u
12b0: 75 69 64 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72  uid)==0 ){.    r
12c0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 63  eturn 0;.  }.  c
12d0: 6f 6e 74 65 6e 74 5f 67 65 74 28 72 69 64 2c 20  ontent_get(rid, 
12e0: 26 63 6f 6e 74 65 6e 74 29 3b 0a 0a 20 20 73 72  &content);..  sr
12f0: 63 69 64 20 3d 20 73 69 6d 69 6c 61 72 5f 72 65  cid = similar_re
1300: 63 6f 72 64 28 72 69 64 2c 20 30 29 3b 0a 20 20  cord(rid, 0);.  
1310: 69 66 28 20 73 72 63 69 64 20 29 7b 0a 20 20 20  if( srcid ){.   
1320: 20 42 6c 6f 62 20 73 72 63 2c 20 64 65 6c 74 61   Blob src, delta
1330: 3b 0a 20 20 20 20 42 6c 6f 62 20 73 72 63 75 75  ;.    Blob srcuu
1340: 69 64 3b 0a 20 20 20 20 63 6f 6e 74 65 6e 74 5f  id;.    content_
1350: 67 65 74 28 73 72 63 69 64 2c 20 26 73 72 63 29  get(srcid, &src)
1360: 3b 0a 20 20 20 20 62 6c 6f 62 5f 64 65 6c 74 61  ;.    blob_delta
1370: 5f 63 72 65 61 74 65 28 26 73 72 63 2c 20 26 63  _create(&src, &c
1380: 6f 6e 74 65 6e 74 2c 20 26 64 65 6c 74 61 29 3b  ontent, &delta);
1390: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  .    blob_reset(
13a0: 26 73 72 63 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  &src);.    blob_
13b0: 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b  reset(&content);
13c0: 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  .    blob_zero(&
13d0: 73 72 63 75 75 69 64 29 3b 0a 20 20 20 20 64 62  srcuuid);.    db
13e0: 5f 62 6c 6f 62 28 26 73 72 63 75 75 69 64 2c 20  _blob(&srcuuid, 
13f0: 22 53 45 4c 45 43 54 20 75 75 69 64 20 46 52 4f  "SELECT uuid FRO
1400: 4d 20 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64  M blob WHERE rid
1410: 3d 25 64 22 2c 20 73 72 63 69 64 29 3b 0a 20 20  =%d", srcid);.  
1420: 20 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69    size = blob_si
1430: 7a 65 28 26 64 65 6c 74 61 29 3b 0a 20 20 20 20  ze(&delta);.    
1440: 69 66 28 20 70 4f 75 74 20 29 7b 0a 20 20 20 20  if( pOut ){.    
1450: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70    blob_appendf(p
1460: 4f 75 74 2c 20 22 66 69 6c 65 20 25 62 20 25 62  Out, "file %b %b
1470: 20 25 64 5c 6e 22 2c 20 26 75 75 69 64 2c 20 26   %d\n", &uuid, &
1480: 73 72 63 75 75 69 64 2c 20 73 69 7a 65 29 3b 0a  srcuuid, size);.
1490: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
14a0: 64 28 70 4f 75 74 2c 20 62 6c 6f 62 5f 62 75 66  d(pOut, blob_buf
14b0: 66 65 72 28 26 64 65 6c 74 61 29 2c 20 73 69 7a  fer(&delta), siz
14c0: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  e);.    }else{. 
14d0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
14e0: 22 66 69 6c 65 20 25 62 20 25 62 20 25 64 5c 6e  "file %b %b %d\n
14f0: 22 2c 20 26 75 75 69 64 2c 20 26 73 72 63 75 75  ", &uuid, &srcuu
1500: 69 64 2c 20 73 69 7a 65 29 3b 0a 20 20 20 20 20  id, size);.     
1510: 20 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74   cgi_append_cont
1520: 65 6e 74 28 62 6c 6f 62 5f 62 75 66 66 65 72 28  ent(blob_buffer(
1530: 26 64 65 6c 74 61 29 2c 20 73 69 7a 65 29 3b 0a  &delta), size);.
1540: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
1550: 20 20 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73     size = blob_s
1560: 69 7a 65 28 26 63 6f 6e 74 65 6e 74 29 3b 0a 20  ize(&content);. 
1570: 20 20 20 69 66 28 20 70 4f 75 74 20 29 7b 0a 20     if( pOut ){. 
1580: 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64       blob_append
1590: 66 28 70 4f 75 74 2c 20 22 66 69 6c 65 20 25 62  f(pOut, "file %b
15a0: 20 25 64 5c 6e 22 2c 20 26 75 75 69 64 2c 20 73   %d\n", &uuid, s
15b0: 69 7a 65 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62  ize);.      blob
15c0: 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 62 6c  _append(pOut, bl
15d0: 6f 62 5f 62 75 66 66 65 72 28 26 63 6f 6e 74 65  ob_buffer(&conte
15e0: 6e 74 29 2c 20 73 69 7a 65 29 3b 0a 20 20 20 20  nt), size);.    
15f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69  }else{.      cgi
1600: 5f 70 72 69 6e 74 66 28 22 66 69 6c 65 20 25 62  _printf("file %b
1610: 20 25 64 5c 6e 22 2c 20 26 75 75 69 64 2c 20 73   %d\n", &uuid, s
1620: 69 7a 65 29 3b 0a 20 20 20 20 20 20 63 67 69 5f  ize);.      cgi_
1630: 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74 28 62  append_content(b
1640: 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 6f 6e 74  lob_buffer(&cont
1650: 65 6e 74 29 2c 20 73 69 7a 65 29 3b 0a 20 20 20  ent), size);.   
1660: 20 7d 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65   }.    blob_rese
1670: 74 28 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 20  t(&content);.   
1680: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 75 75 69   blob_reset(&uui
1690: 64 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d 75 6c  d);.  }.  db_mul
16a0: 74 69 5f 65 78 65 63 28 22 49 4e 53 45 52 54 20  ti_exec("INSERT 
16b0: 4f 52 20 49 47 4e 4f 52 45 20 49 4e 54 4f 20 6f  OR IGNORE INTO o
16c0: 6e 72 65 6d 6f 74 65 20 56 41 4c 55 45 53 28 25  nremote VALUES(%
16d0: 64 29 22 2c 20 72 69 64 29 3b 0a 20 20 72 65 74  d)", rid);.  ret
16e0: 75 72 6e 20 73 69 7a 65 3b 0a 7d 0a 0a 0a 2f 2a  urn size;.}.../*
16f0: 0a 2a 2a 20 53 65 6e 64 20 61 6c 6c 20 70 65 6e  .** Send all pen
1700: 64 69 6e 67 20 66 69 6c 65 73 2e 0a 2a 2f 0a 73  ding files..*/.s
1710: 74 61 74 69 63 20 69 6e 74 20 73 65 6e 64 5f 61  tatic int send_a
1720: 6c 6c 5f 70 65 6e 64 69 6e 67 28 42 6c 6f 62 20  ll_pending(Blob 
1730: 2a 70 4f 75 74 29 7b 0a 20 20 69 6e 74 20 69 52  *pOut){.  int iR
1740: 69 64 53 65 6e 74 20 3d 20 30 3b 0a 20 20 69 6e  idSent = 0;.  in
1750: 74 20 73 65 6e 74 20 3d 20 30 3b 0a 20 20 69 6e  t sent = 0;.  in
1760: 74 20 6e 53 65 6e 74 20 3d 20 30 3b 0a 20 20 69  t nSent = 0;.  i
1770: 6e 74 20 6d 61 78 53 69 7a 65 20 3d 20 64 62 5f  nt maxSize = db_
1780: 67 65 74 5f 69 6e 74 28 22 68 74 74 70 2d 6d 73  get_int("http-ms
1790: 67 2d 73 69 7a 65 22 2c 20 35 30 30 30 30 30 29  g-size", 500000)
17a0: 3b 0a 20 20 53 74 6d 74 20 71 3b 0a 0a 20 20 64  ;.  Stmt q;..  d
17b0: 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20 22 53  b_prepare(&q, "S
17c0: 45 4c 45 43 54 20 72 69 64 20 46 52 4f 4d 20 70  ELECT rid FROM p
17d0: 65 6e 64 69 6e 67 20 4f 52 44 45 52 20 42 59 20  ending ORDER BY 
17e0: 72 69 64 22 29 3b 0a 20 20 77 68 69 6c 65 28 20  rid");.  while( 
17f0: 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c  db_step(&q)==SQL
1800: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 69  ITE_ROW ){.    i
1810: 6e 74 20 72 69 64 20 3d 20 64 62 5f 63 6f 6c 75  nt rid = db_colu
1820: 6d 6e 5f 69 6e 74 28 26 71 2c 20 30 29 3b 0a 20  mn_int(&q, 0);. 
1830: 20 20 20 69 66 28 20 73 65 6e 74 3c 6d 61 78 53     if( sent<maxS
1840: 69 7a 65 20 29 7b 0a 20 20 20 20 20 20 73 65 6e  ize ){.      sen
1850: 74 20 2b 3d 20 73 65 6e 64 5f 66 69 6c 65 28 72  t += send_file(r
1860: 69 64 2c 20 70 4f 75 74 29 3b 0a 20 20 20 20 20  id, pOut);.     
1870: 20 6e 53 65 6e 74 2b 2b 3b 0a 20 20 20 20 20 20   nSent++;.      
1880: 69 52 69 64 53 65 6e 74 20 3d 20 72 69 64 3b 0a  iRidSent = rid;.
1890: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
18a0: 20 63 68 61 72 20 2a 7a 55 75 69 64 20 3d 20 64   char *zUuid = d
18b0: 62 5f 74 65 78 74 28 30 2c 0a 20 20 20 20 20 20  b_text(0,.      
18c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18d0: 22 53 45 4c 45 43 54 20 75 75 69 64 20 46 52 4f  "SELECT uuid FRO
18e0: 4d 20 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64  M blob WHERE rid
18f0: 3d 25 64 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22  =%d AND size>=0"
1900: 2c 20 72 69 64 29 3b 0a 20 20 20 20 20 20 69 66  , rid);.      if
1910: 28 20 7a 55 75 69 64 20 29 7b 0a 20 20 20 20 20  ( zUuid ){.     
1920: 20 20 20 69 66 28 20 70 4f 75 74 20 29 7b 0a 20     if( pOut ){. 
1930: 20 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 61 70           blob_ap
1940: 70 65 6e 64 66 28 70 4f 75 74 2c 20 22 69 67 6f  pendf(pOut, "igo
1950: 74 20 25 73 5c 6e 22 2c 20 7a 55 75 69 64 29 3b  t %s\n", zUuid);
1960: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
1970: 20 20 20 20 20 20 20 20 20 20 63 67 69 5f 70 72            cgi_pr
1980: 69 6e 74 66 28 22 69 67 6f 74 20 25 73 5c 6e 22  intf("igot %s\n"
1990: 2c 20 7a 55 75 69 64 29 3b 0a 20 20 20 20 20 20  , zUuid);.      
19a0: 20 20 7d 0a 20 20 20 20 20 20 20 20 66 72 65 65    }.        free
19b0: 28 7a 55 75 69 64 29 3b 0a 20 20 20 20 20 20 7d  (zUuid);.      }
19c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 64 62 5f  .    }.  }.  db_
19d0: 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20  finalize(&q);.  
19e0: 0a 20 20 2f 2a 20 44 65 6c 65 74 65 20 74 68 65  .  /* Delete the
19f0: 20 27 70 65 6e 64 69 6e 67 27 20 72 65 63 6f 72   'pending' recor
1a00: 64 73 20 66 6f 72 20 61 6c 6c 20 66 69 6c 65 73  ds for all files
1a10: 20 6a 75 73 74 20 73 65 6e 74 2e 20 4f 74 68 65   just sent. Othe
1a20: 72 77 69 73 65 2c 0a 20 20 2a 2a 20 77 65 20 63  rwise,.  ** we c
1a30: 61 6e 20 77 69 6e 64 20 75 70 20 73 65 6e 64 69  an wind up sendi
1a40: 6e 67 20 73 6f 6d 65 20 66 69 6c 65 73 20 6d 6f  ng some files mo
1a50: 72 65 20 74 68 61 6e 20 6f 6e 63 65 2e 0a 20 20  re than once..  
1a60: 2a 2f 0a 20 20 69 66 28 20 6e 53 65 6e 74 3e 30  */.  if( nSent>0
1a70: 20 29 7b 0a 20 20 20 20 64 62 5f 6d 75 6c 74 69   ){.    db_multi
1a80: 5f 65 78 65 63 28 22 44 45 4c 45 54 45 20 46 52  _exec("DELETE FR
1a90: 4f 4d 20 70 65 6e 64 69 6e 67 20 57 48 45 52 45  OM pending WHERE
1aa0: 20 72 69 64 20 3c 3d 20 25 64 22 2c 20 69 52 69   rid <= %d", iRi
1ab0: 64 53 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20 72  dSent);.  }..  r
1ac0: 65 74 75 72 6e 20 6e 53 65 6e 74 3b 0a 7d 0a 0a  eturn nSent;.}..
1ad0: 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65  ./*.** Check the
1ae0: 20 73 69 67 6e 61 74 75 72 65 20 6f 6e 20 61 6e   signature on an
1af0: 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66   application/x-f
1b00: 6f 73 73 69 6c 20 70 61 79 6c 6f 61 64 20 72 65  ossil payload re
1b10: 63 65 69 76 65 64 20 62 79 0a 2a 2a 20 74 68 65  ceived by.** the
1b20: 20 48 54 54 50 20 73 65 72 76 65 72 2e 20 20 54   HTTP server.  T
1b30: 68 65 20 73 69 67 6e 61 74 75 72 65 20 69 73 20  he signature is 
1b40: 61 20 6c 69 6e 65 20 6f 66 20 74 68 65 20 66 6f  a line of the fo
1b50: 6c 6c 6f 77 69 6e 67 20 66 6f 72 6d 3a 0a 2a 2a  llowing form:.**
1b60: 0a 2a 2a 20 20 20 20 20 20 20 20 6c 6f 67 69 6e  .**        login
1b70: 20 4c 4f 47 49 4e 20 4e 4f 4e 43 45 20 53 49 47   LOGIN NONCE SIG
1b80: 4e 41 54 55 52 45 0a 2a 2a 0a 2a 2a 20 54 68 65  NATURE.**.** The
1b90: 20 4e 4f 4e 43 45 20 69 73 20 61 20 72 61 6e 64   NONCE is a rand
1ba0: 6f 6d 20 73 74 72 69 6e 67 2e 20 20 54 68 65 20  om string.  The 
1bb0: 73 65 72 76 65 72 20 77 69 6c 6c 20 6e 65 76 65  server will neve
1bc0: 72 20 61 63 63 65 70 74 20 61 0a 2a 2a 20 72 65  r accept a.** re
1bd0: 70 65 61 74 20 4e 4f 4e 43 45 2e 20 20 53 49 47  peat NONCE.  SIG
1be0: 4e 41 54 55 52 45 20 69 73 20 74 68 65 20 53 48  NATURE is the SH
1bf0: 41 31 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74  A1 checksum of t
1c00: 68 65 20 4e 4f 4e 43 45 20 0a 2a 2a 20 63 6f 6e  he NONCE .** con
1c10: 63 61 74 65 6e 61 74 65 64 20 77 69 74 68 20 74  catenated with t
1c20: 68 65 20 75 73 65 72 73 20 70 61 73 73 77 6f 72  he users passwor
1c30: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 61 72  d..**.** The par
1c40: 61 6d 65 74 65 72 73 20 74 6f 20 74 68 69 73 20  ameters to this 
1c50: 72 6f 75 74 69 6e 65 20 61 72 65 20 65 70 68 65  routine are ephe
1c60: 72 6d 65 72 61 6c 20 62 6c 6f 62 73 20 68 6f 6c  rmeral blobs hol
1c70: 64 69 6e 67 20 74 68 65 0a 2a 2a 20 4c 4f 47 49  ding the.** LOGI
1c80: 4e 2c 20 4e 4f 4e 43 45 20 61 6e 64 20 53 49 47  N, NONCE and SIG
1c90: 4e 41 54 55 52 45 2e 0a 2a 2a 0a 2a 2a 20 54 68  NATURE..**.** Th
1ca0: 69 73 20 72 6f 75 74 69 6e 65 20 61 74 74 65 6d  is routine attem
1cb0: 70 74 73 20 74 6f 20 6c 6f 63 61 74 65 20 74 68  pts to locate th
1cc0: 65 20 75 73 65 72 20 61 6e 64 20 76 65 72 69 66  e user and verif
1cd0: 79 20 74 68 65 20 73 69 67 6e 61 74 75 72 65 2e  y the signature.
1ce0: 0a 2a 2a 20 49 66 20 65 76 65 72 79 74 68 69 6e  .** If everythin
1cf0: 67 20 63 68 65 63 6b 73 20 6f 75 74 2c 20 74 68  g checks out, th
1d00: 65 20 55 53 45 52 2e 43 41 50 20 63 6f 6c 75 6d  e USER.CAP colum
1d10: 6e 20 66 6f 72 20 74 68 65 20 55 53 45 52 20 74  n for the USER t
1d20: 61 62 6c 65 0a 2a 2a 20 69 73 20 63 6f 6e 73 75  able.** is consu
1d30: 6c 74 65 64 20 74 6f 20 73 65 74 20 70 72 69 76  lted to set priv
1d40: 69 6c 65 67 65 73 20 69 6e 20 74 68 65 20 67 6c  ileges in the gl
1d50: 6f 62 61 6c 20 67 20 76 61 72 69 61 62 6c 65 2e  obal g variable.
1d60: 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 79 74 68 69  .**.** If anythi
1d70: 6e 67 20 66 61 69 6c 73 20 74 6f 20 63 68 65 63  ng fails to chec
1d80: 6b 20 6f 75 74 2c 20 6e 6f 20 63 68 61 6e 67 65  k out, no change
1d90: 73 20 61 72 65 20 6d 61 64 65 20 74 6f 20 70 72  s are made to pr
1da0: 69 76 69 6c 65 67 65 73 2e 0a 2a 2a 0a 2a 2a 20  ivileges..**.** 
1db0: 53 69 67 6e 61 74 75 72 65 20 67 65 6e 65 72 61  Signature genera
1dc0: 74 69 6f 6e 20 6f 6e 20 74 68 65 20 63 6c 69 65  tion on the clie
1dd0: 6e 74 20 73 69 64 65 20 69 73 20 68 61 6e 64 6c  nt side is handl
1de0: 65 64 20 62 79 20 74 68 65 20 0a 2a 2a 20 68 74  ed by the .** ht
1df0: 74 70 5f 65 78 63 68 61 6e 67 65 28 29 20 72 6f  tp_exchange() ro
1e00: 75 74 69 6e 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63  utine..*/.void c
1e10: 68 65 63 6b 5f 6c 6f 67 69 6e 28 42 6c 6f 62 20  heck_login(Blob 
1e20: 2a 70 4c 6f 67 69 6e 2c 20 42 6c 6f 62 20 2a 70  *pLogin, Blob *p
1e30: 4e 6f 6e 63 65 2c 20 42 6c 6f 62 20 2a 70 53 69  Nonce, Blob *pSi
1e40: 67 29 7b 0a 20 20 53 74 6d 74 20 71 3b 0a 20 20  g){.  Stmt q;.  
1e50: 69 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 64  int rc;..  if( d
1e60: 62 5f 65 78 69 73 74 73 28 22 53 45 4c 45 43 54  b_exists("SELECT
1e70: 20 31 20 46 52 4f 4d 20 72 63 76 66 72 6f 6d 20   1 FROM rcvfrom 
1e80: 57 48 45 52 45 20 6e 6f 6e 63 65 3d 25 42 22 2c  WHERE nonce=%B",
1e90: 20 70 4e 6f 6e 63 65 29 20 29 7b 0a 20 20 20 20   pNonce) ){.    
1ea0: 72 65 74 75 72 6e 3b 20 20 2f 2a 20 4e 65 76 65  return;  /* Neve
1eb0: 72 20 61 63 63 65 70 74 20 61 20 72 65 70 65 61  r accept a repea
1ec0: 74 65 64 20 6e 6f 6e 63 65 20 2a 2f 0a 20 20 7d  ted nonce */.  }
1ed0: 0a 20 20 64 62 5f 70 72 65 70 61 72 65 28 26 71  .  db_prepare(&q
1ee0: 2c 20 22 53 45 4c 45 43 54 20 70 77 2c 20 63 61  , "SELECT pw, ca
1ef0: 70 2c 20 75 69 64 20 46 52 4f 4d 20 75 73 65 72  p, uid FROM user
1f00: 20 57 48 45 52 45 20 6c 6f 67 69 6e 3d 25 42 22   WHERE login=%B"
1f10: 2c 20 70 4c 6f 67 69 6e 29 3b 0a 20 20 69 66 28  , pLogin);.  if(
1f20: 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51   db_step(&q)==SQ
1f30: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
1f40: 42 6c 6f 62 20 70 77 2c 20 63 6f 6d 62 69 6e 65  Blob pw, combine
1f50: 64 2c 20 68 61 73 68 3b 0a 20 20 20 20 62 6c 6f  d, hash;.    blo
1f60: 62 5f 7a 65 72 6f 28 26 70 77 29 3b 0a 20 20 20  b_zero(&pw);.   
1f70: 20 64 62 5f 65 70 68 65 6d 65 72 61 6c 5f 62 6c   db_ephemeral_bl
1f80: 6f 62 28 26 71 2c 20 30 2c 20 26 70 77 29 3b 0a  ob(&q, 0, &pw);.
1f90: 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 63      blob_zero(&c
1fa0: 6f 6d 62 69 6e 65 64 29 3b 0a 20 20 20 20 62 6c  ombined);.    bl
1fb0: 6f 62 5f 63 6f 70 79 28 26 63 6f 6d 62 69 6e 65  ob_copy(&combine
1fc0: 64 2c 20 70 4e 6f 6e 63 65 29 3b 0a 20 20 20 20  d, pNonce);.    
1fd0: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 63 6f 6d  blob_append(&com
1fe0: 62 69 6e 65 64 2c 20 62 6c 6f 62 5f 62 75 66 66  bined, blob_buff
1ff0: 65 72 28 26 70 77 29 2c 20 62 6c 6f 62 5f 73 69  er(&pw), blob_si
2000: 7a 65 28 26 70 77 29 29 3b 0a 20 20 20 20 2f 2a  ze(&pw));.    /*
2010: 20 43 47 49 44 45 42 55 47 28 28 22 70 72 65 73   CGIDEBUG(("pres
2020: 69 67 3d 5b 25 73 5d 5c 6e 22 2c 20 62 6c 6f 62  ig=[%s]\n", blob
2030: 5f 73 74 72 28 26 63 6f 6d 62 69 6e 65 64 29 29  _str(&combined))
2040: 29 3b 20 2a 2f 0a 20 20 20 20 73 68 61 31 73 75  ); */.    sha1su
2050: 6d 5f 62 6c 6f 62 28 26 63 6f 6d 62 69 6e 65 64  m_blob(&combined
2060: 2c 20 26 68 61 73 68 29 3b 0a 20 20 20 20 72 63  , &hash);.    rc
2070: 20 3d 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28   = blob_compare(
2080: 26 68 61 73 68 2c 20 70 53 69 67 29 3b 0a 20 20  &hash, pSig);.  
2090: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61    blob_reset(&ha
20a0: 73 68 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65  sh);.    blob_re
20b0: 73 65 74 28 26 63 6f 6d 62 69 6e 65 64 29 3b 0a  set(&combined);.
20c0: 20 20 20 20 69 66 28 20 72 63 3d 3d 30 20 29 7b      if( rc==0 ){
20d0: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
20e0: 72 20 2a 7a 43 61 70 3b 0a 20 20 20 20 20 20 7a  r *zCap;.      z
20f0: 43 61 70 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f  Cap = db_column_
2100: 74 65 78 74 28 26 71 2c 20 31 29 3b 0a 20 20 20  text(&q, 1);.   
2110: 20 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70     login_set_cap
2120: 61 62 69 6c 69 74 69 65 73 28 7a 43 61 70 29 3b  abilities(zCap);
2130: 0a 20 20 20 20 20 20 67 2e 75 73 65 72 55 69 64  .      g.userUid
2140: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74   = db_column_int
2150: 28 26 71 2c 20 32 29 3b 0a 20 20 20 20 20 20 67  (&q, 2);.      g
2160: 2e 7a 4c 6f 67 69 6e 20 3d 20 6d 70 72 69 6e 74  .zLogin = mprint
2170: 66 28 22 25 62 22 2c 20 70 4c 6f 67 69 6e 29 3b  f("%b", pLogin);
2180: 0a 20 20 20 20 20 20 67 2e 7a 4e 6f 6e 63 65 20  .      g.zNonce 
2190: 3d 20 6d 70 72 69 6e 74 66 28 22 25 62 22 2c 20  = mprintf("%b", 
21a0: 70 4e 6f 6e 63 65 29 3b 0a 20 20 20 20 7d 0a 20  pNonce);.    }. 
21b0: 20 7d 0a 20 20 64 62 5f 72 65 73 65 74 28 26 71   }.  db_reset(&q
21c0: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  );.}.../*.** If 
21d0: 74 68 69 73 20 76 61 72 69 61 62 6c 65 20 69 73  this variable is
21e0: 20 73 65 74 2c 20 64 69 73 61 62 6c 65 20 6c 6f   set, disable lo
21f0: 67 69 6e 20 63 68 65 63 6b 73 2e 20 20 55 73 65  gin checks.  Use
2200: 64 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 0a  d for debugging.
2210: 2a 2a 20 6f 6e 6c 79 2e 0a 2a 2f 0a 73 74 61 74  ** only..*/.stat
2220: 69 63 20 69 6e 74 20 64 69 73 61 62 6c 65 4c 6f  ic int disableLo
2230: 67 69 6e 20 3d 20 30 3b 0a 0a 2f 2a 0a 2a 2a 20  gin = 0;../*.** 
2240: 57 45 42 50 41 47 45 3a 20 78 66 65 72 0a 2a 2a  WEBPAGE: xfer.**
2250: 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20  .** This is the 
2260: 74 72 61 6e 73 66 65 72 20 68 61 6e 64 6c 65 72  transfer handler
2270: 20 6f 6e 20 74 68 65 20 73 65 72 76 65 72 20 73   on the server s
2280: 69 64 65 2e 20 20 54 68 65 20 74 72 61 6e 73 66  ide.  The transf
2290: 65 72 0a 2a 2a 20 6d 65 73 73 61 67 65 20 68 61  er.** message ha
22a0: 73 20 62 65 65 6e 20 75 6e 63 6f 6d 70 72 65 73  s been uncompres
22b0: 73 65 64 20 61 6e 64 20 70 6c 61 63 65 64 20 69  sed and placed i
22c0: 6e 20 74 68 65 20 67 2e 63 67 69 49 6e 20 62 6c  n the g.cgiIn bl
22d0: 6f 62 2e 0a 2a 2a 20 50 72 6f 63 65 73 73 20 74  ob..** Process t
22e0: 68 69 73 20 6d 65 73 73 61 67 65 20 61 6e 64 20  his message and 
22f0: 66 6f 72 6d 20 61 6e 20 61 70 70 72 6f 70 72 69  form an appropri
2300: 61 74 65 20 72 65 70 6c 79 2e 0a 2a 2f 0a 76 6f  ate reply..*/.vo
2310: 69 64 20 70 61 67 65 5f 78 66 65 72 28 76 6f 69  id page_xfer(voi
2320: 64 29 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e  d){.  int nToken
2330: 3b 0a 20 20 69 6e 74 20 69 73 50 75 6c 6c 20 3d  ;.  int isPull =
2340: 20 30 3b 0a 20 20 69 6e 74 20 69 73 50 75 73 68   0;.  int isPush
2350: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 45 72 72   = 0;.  int nErr
2360: 20 3d 20 30 3b 0a 20 20 42 6c 6f 62 20 6c 69 6e   = 0;.  Blob lin
2370: 65 2c 20 65 72 72 6d 73 67 2c 20 61 54 6f 6b 65  e, errmsg, aToke
2380: 6e 5b 35 5d 3b 0a 0a 20 20 64 62 5f 62 65 67 69  n[5];..  db_begi
2390: 6e 5f 74 72 61 6e 73 61 63 74 69 6f 6e 28 29 3b  n_transaction();
23a0: 0a 20 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72  .  blobarray_zer
23b0: 6f 28 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28  o(aToken, count(
23c0: 61 54 6f 6b 65 6e 29 29 3b 0a 20 20 63 67 69 5f  aToken));.  cgi_
23d0: 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65  set_content_type
23e0: 28 67 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 65 29  (g.zContentType)
23f0: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 65  ;.  blob_zero(&e
2400: 72 72 6d 73 67 29 3b 0a 20 20 64 62 5f 6d 75 6c  rrmsg);.  db_mul
2410: 74 69 5f 65 78 65 63 28 0a 20 20 20 20 20 22 43  ti_exec(.     "C
2420: 52 45 41 54 45 20 54 45 4d 50 20 54 41 42 4c 45  REATE TEMP TABLE
2430: 20 6f 6e 72 65 6d 6f 74 65 28 72 69 64 20 49 4e   onremote(rid IN
2440: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45  TEGER PRIMARY KE
2450: 59 29 3b 22 20 2f 2a 20 43 6c 69 65 6e 74 20 68  Y);" /* Client h
2460: 61 73 20 2a 2f 0a 20 20 20 20 20 22 43 52 45 41  as */.     "CREA
2470: 54 45 20 54 45 4d 50 20 54 41 42 4c 45 20 70 65  TE TEMP TABLE pe
2480: 6e 64 69 6e 67 28 72 69 64 20 49 4e 54 45 47 45  nding(rid INTEGE
2490: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 29 3b 22  R PRIMARY KEY);"
24a0: 20 20 2f 2a 20 43 6c 69 65 6e 74 20 6e 65 65 64    /* Client need
24b0: 73 20 2a 2f 0a 20 20 29 3b 0a 20 20 77 68 69 6c  s */.  );.  whil
24c0: 65 28 20 62 6c 6f 62 5f 6c 69 6e 65 28 26 67 2e  e( blob_line(&g.
24d0: 63 67 69 49 6e 2c 20 26 6c 69 6e 65 29 20 29 7b  cgiIn, &line) ){
24e0: 0a 20 20 20 20 6e 54 6f 6b 65 6e 20 3d 20 62 6c  .    nToken = bl
24f0: 6f 62 5f 74 6f 6b 65 6e 69 7a 65 28 26 6c 69 6e  ob_tokenize(&lin
2500: 65 2c 20 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74  e, aToken, count
2510: 28 61 54 6f 6b 65 6e 29 29 3b 0a 0a 20 20 20 20  (aToken));..    
2520: 2f 2a 20 20 20 66 69 6c 65 20 55 55 49 44 20 53  /*   file UUID S
2530: 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20  IZE \n CONTENT. 
2540: 20 20 20 2a 2a 20 20 20 66 69 6c 65 20 55 55 49     **   file UUI
2550: 44 20 44 45 4c 54 41 53 52 43 20 53 49 5a 45 20  D DELTASRC SIZE 
2560: 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20 20 2a  \n CONTENT.    *
2570: 2a 0a 20 20 20 20 2a 2a 20 41 63 63 65 70 74 20  *.    ** Accept 
2580: 61 20 66 69 6c 65 20 66 72 6f 6d 20 74 68 65 20  a file from the 
2590: 63 6c 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20  client..    */. 
25a0: 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26     if( blob_eq(&
25b0: 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22 66 69 6c 65  aToken[0], "file
25c0: 22 29 20 26 26 20 6e 54 6f 6b 65 6e 3e 3d 32 20  ") && nToken>=2 
25d0: 26 26 20 6e 54 6f 6b 65 6e 3c 3d 33 20 29 7b 0a  && nToken<=3 ){.
25e0: 20 20 20 20 20 20 69 66 28 20 21 69 73 50 75 73        if( !isPus
25f0: 68 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69  h ){.        cgi
2600: 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29  _reset_content()
2610: 3b 0a 20 20 20 20 20 20 20 20 40 20 65 72 72 6f  ;.        @ erro
2620: 72 20 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a 65  r not\sauthorize
2630: 64 5c 73 74 6f 5c 73 77 72 69 74 65 0a 20 20 20  d\sto\swrite.   
2640: 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20       nErr++;.   
2650: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2660: 20 20 7d 0a 20 20 20 20 20 20 78 66 65 72 5f 61    }.      xfer_a
2670: 63 63 65 70 74 5f 66 69 6c 65 28 26 67 2e 63 67  ccept_file(&g.cg
2680: 69 49 6e 2c 20 61 54 6f 6b 65 6e 2c 20 6e 54 6f  iIn, aToken, nTo
2690: 6b 65 6e 2c 20 26 65 72 72 6d 73 67 29 3b 0a 20  ken, &errmsg);. 
26a0: 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 73 69       if( blob_si
26b0: 7a 65 28 26 65 72 72 6d 73 67 29 20 29 7b 0a 20  ze(&errmsg) ){. 
26c0: 20 20 20 20 20 20 20 63 67 69 5f 72 65 73 65 74         cgi_reset
26d0: 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20  _content();.    
26e0: 20 20 20 20 40 20 65 72 72 6f 72 20 25 54 28 62      @ error %T(b
26f0: 6c 6f 62 5f 73 74 72 28 26 65 72 72 6d 73 67 29  lob_str(&errmsg)
2700: 29 0a 20 20 20 20 20 20 20 20 6e 45 72 72 2b 2b  ).        nErr++
2710: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
2720: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
2730: 73 65 0a 0a 20 20 20 20 2f 2a 20 20 20 67 69 6d  se..    /*   gim
2740: 6d 65 20 55 55 49 44 0a 20 20 20 20 2a 2a 0a 20  me UUID.    **. 
2750: 20 20 20 2a 2a 20 43 6c 69 65 6e 74 20 69 73 20     ** Client is 
2760: 72 65 71 75 65 73 74 69 6e 67 20 61 20 66 69 6c  requesting a fil
2770: 65 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  e.    */.    if(
2780: 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e   blob_eq(&aToken
2790: 5b 30 5d 2c 20 22 67 69 6d 6d 65 22 29 20 26 26  [0], "gimme") &&
27a0: 20 6e 54 6f 6b 65 6e 3d 3d 32 20 26 26 20 62 6c   nToken==2 && bl
27b0: 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f 6b  ob_is_uuid(&aTok
27c0: 65 6e 5b 31 5d 29 20 29 7b 0a 20 20 20 20 20 20  en[1]) ){.      
27d0: 69 66 28 20 69 73 50 75 6c 6c 20 29 7b 0a 20 20  if( isPull ){.  
27e0: 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65        db_multi_e
27f0: 78 65 63 28 0a 20 20 20 20 20 20 20 20 20 20 22  xec(.          "
2800: 49 4e 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45  INSERT OR IGNORE
2810: 20 49 4e 54 4f 20 70 65 6e 64 69 6e 67 28 72 69   INTO pending(ri
2820: 64 29 20 22 0a 20 20 20 20 20 20 20 20 20 20 22  d) ".          "
2830: 53 45 4c 45 43 54 20 72 69 64 20 46 52 4f 4d 20  SELECT rid FROM 
2840: 62 6c 6f 62 20 57 48 45 52 45 20 75 75 69 64 3d  blob WHERE uuid=
2850: 25 42 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22 2c  %B AND size>=0",
2860: 20 26 61 54 6f 6b 65 6e 5b 31 5d 0a 20 20 20 20   &aToken[1].    
2870: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 7d 0a 20      );.      }. 
2880: 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f 2a     }else..    /*
2890: 20 20 20 69 67 6f 74 20 55 55 49 44 0a 20 20 20     igot UUID.   
28a0: 20 2a 2a 20 20 20 6c 65 61 66 20 55 55 49 44 0a   **   leaf UUID.
28b0: 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 43 6c      **.    ** Cl
28c0: 69 65 6e 74 20 61 6e 6e 6f 75 6e 63 65 73 20 74  ient announces t
28d0: 68 61 74 20 69 74 20 68 61 73 20 61 20 70 61 72  hat it has a par
28e0: 74 69 63 75 6c 61 72 20 66 69 6c 65 0a 20 20 20  ticular file.   
28f0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 6e 54 6f 6b   */.    if( nTok
2900: 65 6e 3d 3d 32 0a 20 20 20 20 20 20 20 20 20 20  en==2.          
2910: 26 26 20 28 62 6c 6f 62 5f 65 71 28 26 61 54 6f  && (blob_eq(&aTo
2920: 6b 65 6e 5b 30 5d 2c 20 22 69 67 6f 74 22 29 20  ken[0], "igot") 
2930: 7c 7c 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b  || blob_eq(&aTok
2940: 65 6e 5b 30 5d 2c 22 6c 65 61 66 22 29 29 0a 20  en[0],"leaf")). 
2950: 20 20 20 20 20 20 20 20 20 26 26 20 62 6c 6f 62           && blob
2960: 5f 69 73 5f 75 75 69 64 28 26 61 54 6f 6b 65 6e  _is_uuid(&aToken
2970: 5b 31 5d 29 20 29 7b 0a 20 20 20 20 20 20 69 66  [1]) ){.      if
2980: 28 20 69 73 50 75 6c 6c 20 7c 7c 20 69 73 50 75  ( isPull || isPu
2990: 73 68 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  sh ){.        in
29a0: 74 20 72 69 64 20 3d 20 64 62 5f 69 6e 74 28 30  t rid = db_int(0
29b0: 2c 20 22 53 45 4c 45 43 54 20 72 69 64 20 46 52  , "SELECT rid FR
29c0: 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20 75 75  OM blob WHERE uu
29d0: 69 64 3d 25 42 22 2c 20 26 61 54 6f 6b 65 6e 5b  id=%B", &aToken[
29e0: 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  1]);.        if(
29f0: 20 72 69 64 3e 30 20 29 7b 0a 20 20 20 20 20 20   rid>0 ){.      
2a00: 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65      db_multi_exe
2a10: 63 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 22  c(.            "
2a20: 49 4e 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45  INSERT OR IGNORE
2a30: 20 49 4e 54 4f 20 6f 6e 72 65 6d 6f 74 65 28 72   INTO onremote(r
2a40: 69 64 29 20 56 41 4c 55 45 53 28 25 64 29 22 2c  id) VALUES(%d)",
2a50: 20 72 69 64 0a 20 20 20 20 20 20 20 20 20 20 29   rid.          )
2a60: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
2a70: 69 73 50 75 6c 6c 20 26 26 20 62 6c 6f 62 5f 65  isPull && blob_e
2a80: 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22 6c  q(&aToken[0], "l
2a90: 65 61 66 22 29 20 29 7b 0a 20 20 20 20 20 20 20  eaf") ){.       
2aa0: 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78       db_multi_ex
2ab0: 65 63 28 0a 20 20 20 20 20 20 20 20 20 20 20 20  ec(.            
2ac0: 20 20 22 49 4e 53 45 52 54 20 4f 52 20 49 47 4e    "INSERT OR IGN
2ad0: 4f 52 45 20 49 4e 54 4f 20 70 65 6e 64 69 6e 67  ORE INTO pending
2ae0: 28 72 69 64 29 20 22 0a 20 20 20 20 20 20 20 20  (rid) ".        
2af0: 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 63 69        "SELECT ci
2b00: 64 20 46 52 4f 4d 20 70 6c 69 6e 6b 20 57 48 45  d FROM plink WHE
2b10: 52 45 20 70 69 64 3d 25 64 22 2c 20 72 69 64 0a  RE pid=%d", rid.
2b20: 20 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20              );. 
2b30: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
2b40: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69 73 50     }else if( isP
2b50: 75 73 68 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ush ){.         
2b60: 20 63 6f 6e 74 65 6e 74 5f 70 75 74 28 30 2c 20   content_put(0, 
2b70: 62 6c 6f 62 5f 73 74 72 28 26 61 54 6f 6b 65 6e  blob_str(&aToken
2b80: 5b 31 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 7d  [1]));.        }
2b90: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
2ba0: 73 65 0a 0a 20 20 20 20 2f 2a 20 20 20 20 70 75  se..    /*    pu
2bb0: 6c 6c 20 20 53 45 52 56 45 52 43 4f 44 45 20 20  ll  SERVERCODE  
2bc0: 50 52 4f 4a 45 43 54 43 4f 44 45 0a 20 20 20 20  PROJECTCODE.    
2bd0: 2a 2a 20 20 20 20 70 75 73 68 20 20 53 45 52 56  **    push  SERV
2be0: 45 52 43 4f 44 45 20 20 50 52 4f 4a 45 43 54 43  ERCODE  PROJECTC
2bf0: 4f 44 45 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  ODE.    **.    *
2c00: 2a 20 54 68 65 20 63 6c 69 65 6e 74 20 77 61 6e  * The client wan
2c10: 74 73 20 65 69 74 68 65 72 20 73 65 6e 64 20 6f  ts either send o
2c20: 72 20 72 65 63 65 69 76 65 0a 20 20 20 20 2a 2f  r receive.    */
2c30: 0a 20 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3d  .    if( nToken=
2c40: 3d 33 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  =3.             
2c50: 20 20 26 26 20 28 62 6c 6f 62 5f 65 71 28 26 61    && (blob_eq(&a
2c60: 54 6f 6b 65 6e 5b 30 5d 2c 20 22 70 75 6c 6c 22  Token[0], "pull"
2c70: 29 20 7c 7c 20 62 6c 6f 62 5f 65 71 28 26 61 54  ) || blob_eq(&aT
2c80: 6f 6b 65 6e 5b 30 5d 2c 20 22 70 75 73 68 22 29  oken[0], "push")
2c90: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
2ca0: 20 26 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64   && blob_is_uuid
2cb0: 28 26 61 54 6f 6b 65 6e 5b 31 5d 29 20 26 26 20  (&aToken[1]) && 
2cc0: 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54  blob_is_uuid(&aT
2cd0: 6f 6b 65 6e 5b 32 5d 29 20 29 7b 0a 20 20 20 20  oken[2]) ){.    
2ce0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
2cf0: 43 6f 64 65 3b 0a 20 20 20 20 20 20 63 6f 6e 73  Code;.      cons
2d00: 74 20 63 68 61 72 20 2a 7a 50 43 6f 64 65 3b 0a  t char *zPCode;.
2d10: 0a 20 20 20 20 20 20 7a 53 43 6f 64 65 20 3d 20  .      zSCode = 
2d20: 64 62 5f 67 65 74 28 22 73 65 72 76 65 72 2d 63  db_get("server-c
2d30: 6f 64 65 22 2c 20 30 29 3b 0a 20 20 20 20 20 20  ode", 0);.      
2d40: 69 66 28 20 7a 53 43 6f 64 65 3d 3d 30 20 29 7b  if( zSCode==0 ){
2d50: 0a 20 20 20 20 20 20 20 20 66 6f 73 73 69 6c 5f  .        fossil_
2d60: 70 61 6e 69 63 28 22 6d 69 73 73 69 6e 67 20 73  panic("missing s
2d70: 65 72 76 65 72 20 63 6f 64 65 22 29 3b 0a 20 20  erver code");.  
2d80: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
2d90: 62 6c 6f 62 5f 65 71 5f 73 74 72 28 26 61 54 6f  blob_eq_str(&aTo
2da0: 6b 65 6e 5b 31 5d 2c 20 7a 53 43 6f 64 65 2c 20  ken[1], zSCode, 
2db0: 2d 31 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63  -1) ){.        c
2dc0: 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74  gi_reset_content
2dd0: 28 29 3b 0a 20 20 20 20 20 20 20 20 40 20 65 72  ();.        @ er
2de0: 72 6f 72 20 73 65 72 76 65 72 5c 73 6c 6f 6f 70  ror server\sloop
2df0: 0a 20 20 20 20 20 20 20 20 6e 45 72 72 2b 2b 3b  .        nErr++;
2e00: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
2e10: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 50        }.      zP
2e20: 43 6f 64 65 20 3d 20 64 62 5f 67 65 74 28 22 70  Code = db_get("p
2e30: 72 6f 6a 65 63 74 2d 63 6f 64 65 22 2c 20 30 29  roject-code", 0)
2e40: 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 50 43 6f  ;.      if( zPCo
2e50: 64 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  de==0 ){.       
2e60: 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 6d   fossil_panic("m
2e70: 69 73 73 69 6e 67 20 70 72 6f 6a 65 63 74 20 63  issing project c
2e80: 6f 64 65 22 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ode");.      }. 
2e90: 20 20 20 20 20 69 66 28 20 21 62 6c 6f 62 5f 65       if( !blob_e
2ea0: 71 5f 73 74 72 28 26 61 54 6f 6b 65 6e 5b 32 5d  q_str(&aToken[2]
2eb0: 2c 20 7a 50 43 6f 64 65 2c 20 2d 31 29 20 29 7b  , zPCode, -1) ){
2ec0: 0a 20 20 20 20 20 20 20 20 63 67 69 5f 72 65 73  .        cgi_res
2ed0: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20  et_content();.  
2ee0: 20 20 20 20 20 20 40 20 65 72 72 6f 72 20 77 72        @ error wr
2ef0: 6f 6e 67 5c 73 70 72 6f 6a 65 63 74 0a 20 20 20  ong\sproject.   
2f00: 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20       nErr++;.   
2f10: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2f20: 20 20 7d 0a 20 20 20 20 20 20 6c 6f 67 69 6e 5f    }.      login_
2f30: 63 68 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c  check_credential
2f40: 73 28 29 3b 0a 20 20 20 20 20 20 69 66 28 20 62  s();.      if( b
2f50: 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30  lob_eq(&aToken[0
2f60: 5d 2c 20 22 70 75 6c 6c 22 29 20 29 7b 0a 20 20  ], "pull") ){.  
2f70: 20 20 20 20 20 20 69 66 28 20 21 67 2e 6f 6b 52        if( !g.okR
2f80: 65 61 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ead ){.         
2f90: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65   cgi_reset_conte
2fa0: 6e 74 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20  nt();.          
2fb0: 40 20 65 72 72 6f 72 20 6e 6f 74 5c 73 61 75 74  @ error not\saut
2fc0: 68 6f 72 69 7a 65 64 5c 73 74 6f 5c 73 72 65 61  horized\sto\srea
2fd0: 64 0a 20 20 20 20 20 20 20 20 20 20 6e 45 72 72  d.          nErr
2fe0: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 62 72  ++;.          br
2ff0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  eak;.        }. 
3000: 20 20 20 20 20 20 20 69 73 50 75 6c 6c 20 3d 20         isPull = 
3010: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  1;.      }else{.
3020: 20 20 20 20 20 20 20 20 69 66 28 20 21 67 2e 6f          if( !g.o
3030: 6b 57 72 69 74 65 20 29 7b 0a 20 20 20 20 20 20  kWrite ){.      
3040: 20 20 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f      cgi_reset_co
3050: 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20 20 20 20  ntent();.       
3060: 20 20 20 40 20 65 72 72 6f 72 20 6e 6f 74 5c 73     @ error not\s
3070: 61 75 74 68 6f 72 69 7a 65 64 5c 73 74 6f 5c 73  authorized\sto\s
3080: 77 72 69 74 65 0a 20 20 20 20 20 20 20 20 20 20  write.          
3090: 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20 20 20 20  nErr++;.        
30a0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
30b0: 20 7d 0a 20 20 20 20 20 20 20 20 69 73 50 75 73   }.        isPus
30c0: 68 20 3d 20 31 3b 0a 0a 20 20 20 20 20 20 7d 0a  h = 1;..      }.
30d0: 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f      }else..    /
30e0: 2a 20 20 20 20 63 6c 6f 6e 65 0a 20 20 20 20 2a  *    clone.    *
30f0: 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20 63 6c 69  *.    ** The cli
3100: 65 6e 74 20 6b 6e 6f 77 73 20 6e 6f 74 68 69 6e  ent knows nothin
3110: 67 2e 20 20 54 65 6c 6c 20 61 6c 6c 2e 0a 20 20  g.  Tell all..  
3120: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f    */.    if( blo
3130: 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c  b_eq(&aToken[0],
3140: 20 22 63 6c 6f 6e 65 22 29 20 29 7b 0a 20 20 20   "clone") ){.   
3150: 20 20 20 6c 6f 67 69 6e 5f 63 68 65 63 6b 5f 63     login_check_c
3160: 72 65 64 65 6e 74 69 61 6c 73 28 29 3b 0a 20 20  redentials();.  
3170: 20 20 20 20 69 66 28 20 21 67 2e 6f 6b 52 65 61      if( !g.okRea
3180: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69  d ){.        cgi
3190: 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29  _reset_content()
31a0: 3b 0a 20 20 20 20 20 20 20 20 40 20 65 72 72 6f  ;.        @ erro
31b0: 72 20 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a 65  r not\sauthorize
31c0: 64 5c 73 74 6f 5c 73 72 65 61 64 0a 20 20 20 20  d\sto\sread.    
31d0: 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20      nErr++;.    
31e0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
31f0: 20 7d 0a 20 20 20 20 20 20 69 73 50 75 6c 6c 20   }.      isPull 
3200: 3d 20 31 3b 0a 20 20 20 20 20 20 40 20 70 75 73  = 1;.      @ pus
3210: 68 20 25 73 28 64 62 5f 67 65 74 28 22 73 65 72  h %s(db_get("ser
3220: 76 65 72 2d 63 6f 64 65 22 2c 20 22 78 22 29 29  ver-code", "x"))
3230: 20 25 73 28 64 62 5f 67 65 74 28 22 70 72 6f 6a   %s(db_get("proj
3240: 65 63 74 2d 63 6f 64 65 22 2c 20 22 78 22 29 29  ect-code", "x"))
3250: 0a 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f  .      db_multi_
3260: 65 78 65 63 28 0a 20 20 20 20 20 20 20 20 22 49  exec(.        "I
3270: 4e 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45 20  NSERT OR IGNORE 
3280: 49 4e 54 4f 20 70 65 6e 64 69 6e 67 28 72 69 64  INTO pending(rid
3290: 29 20 22 0a 20 20 20 20 20 20 20 20 22 53 45 4c  ) ".        "SEL
32a0: 45 43 54 20 72 69 64 20 46 52 4f 4d 20 62 6c 6f  ECT rid FROM blo
32b0: 62 20 57 48 45 52 45 20 73 69 7a 65 3e 3d 30 22  b WHERE size>=0"
32c0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65  .      );.    }e
32d0: 6c 73 65 0a 0a 20 20 20 20 2f 2a 20 20 20 20 6c  lse..    /*    l
32e0: 6f 67 69 6e 20 20 55 53 45 52 20 20 4e 4f 4e 43  ogin  USER  NONC
32f0: 45 20 20 53 49 47 4e 41 54 55 52 45 0a 20 20 20  E  SIGNATURE.   
3300: 20 2a 2a 0a 20 20 20 20 2a 2a 20 43 68 65 63 6b   **.    ** Check
3310: 20 66 6f 72 20 61 20 76 61 6c 69 64 20 6c 6f 67   for a valid log
3320: 69 6e 2e 20 20 54 68 69 73 20 68 61 73 20 74 6f  in.  This has to
3330: 20 68 61 70 70 65 6e 20 62 65 66 6f 72 65 20 61   happen before a
3340: 6e 79 74 68 69 6e 67 20 65 6c 73 65 2e 0a 20 20  nything else..  
3350: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f    */.    if( blo
3360: 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c  b_eq(&aToken[0],
3370: 20 22 6c 6f 67 69 6e 22 29 20 26 26 20 6e 54 6f   "login") && nTo
3380: 6b 65 6e 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20  ken==4 ){.      
3390: 69 66 28 20 64 69 73 61 62 6c 65 4c 6f 67 69 6e  if( disableLogin
33a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 67 2e 6f 6b   ){.        g.ok
33b0: 52 65 61 64 20 3d 20 67 2e 6f 6b 57 72 69 74 65  Read = g.okWrite
33c0: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73   = 1;.      }els
33d0: 65 7b 0a 20 20 20 20 20 20 20 20 63 68 65 63 6b  e{.        check
33e0: 5f 6c 6f 67 69 6e 28 26 61 54 6f 6b 65 6e 5b 31  _login(&aToken[1
33f0: 5d 2c 20 26 61 54 6f 6b 65 6e 5b 32 5d 2c 20 26  ], &aToken[2], &
3400: 61 54 6f 6b 65 6e 5b 33 5d 29 3b 0a 20 20 20 20  aToken[3]);.    
3410: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 0a 20    }.    }else.. 
3420: 20 20 20 2f 2a 20 55 6e 6b 6e 6f 77 6e 20 6d 65     /* Unknown me
3430: 73 73 61 67 65 0a 20 20 20 20 2a 2f 0a 20 20 20  ssage.    */.   
3440: 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 72 65 73   {.      cgi_res
3450: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20  et_content();.  
3460: 20 20 20 20 40 20 65 72 72 6f 72 20 62 61 64 5c      @ error bad\
3470: 73 63 6f 6d 6d 61 6e 64 3a 5c 73 25 46 28 62 6c  scommand:\s%F(bl
3480: 6f 62 5f 73 74 72 28 26 6c 69 6e 65 29 29 0a 20  ob_str(&line)). 
3490: 20 20 20 7d 0a 20 20 20 20 62 6c 6f 62 61 72 72     }.    blobarr
34a0: 61 79 5f 72 65 73 65 74 28 61 54 6f 6b 65 6e 2c  ay_reset(aToken,
34b0: 20 6e 54 6f 6b 65 6e 29 3b 0a 20 20 7d 0a 0a 20   nToken);.  }.. 
34c0: 20 2f 2a 20 54 68 65 20 69 6e 70 75 74 20 6d 65   /* The input me
34d0: 73 73 61 67 65 20 68 61 73 20 6e 6f 77 20 62 65  ssage has now be
34e0: 65 6e 20 70 72 6f 63 65 73 73 65 64 2e 20 20 47  en processed.  G
34f0: 65 6e 65 72 61 74 65 20 61 20 72 65 70 6c 79 2e  enerate a reply.
3500: 20 2a 2f 0a 20 20 69 66 28 20 69 73 50 75 73 68   */.  if( isPush
3510: 20 29 7b 0a 20 20 20 20 53 74 6d 74 20 71 3b 0a   ){.    Stmt q;.
3520: 20 20 20 20 64 62 5f 70 72 65 70 61 72 65 28 26      db_prepare(&
3530: 71 2c 20 22 53 45 4c 45 43 54 20 75 75 69 64 20  q, "SELECT uuid 
3540: 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20  FROM blob WHERE 
3550: 73 69 7a 65 3c 30 22 29 3b 0a 20 20 20 20 77 68  size<0");.    wh
3560: 69 6c 65 28 20 64 62 5f 73 74 65 70 28 26 71 29  ile( db_step(&q)
3570: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
3580: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
3590: 20 2a 7a 55 75 69 64 20 3d 20 64 62 5f 63 6f 6c   *zUuid = db_col
35a0: 75 6d 6e 5f 74 65 78 74 28 26 71 2c 20 30 29 3b  umn_text(&q, 0);
35b0: 0a 20 20 20 20 20 20 40 20 67 69 6d 6d 65 20 25  .      @ gimme %
35c0: 73 28 7a 55 75 69 64 29 0a 20 20 20 20 7d 0a 20  s(zUuid).    }. 
35d0: 20 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26     db_finalize(&
35e0: 71 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 73  q);.  }.  if( is
35f0: 50 75 6c 6c 20 29 7b 0a 20 20 20 20 73 65 6e 64  Pull ){.    send
3600: 5f 61 6c 6c 5f 70 65 6e 64 69 6e 67 28 30 29 3b  _all_pending(0);
3610: 0a 20 20 7d 0a 20 20 69 66 28 20 69 73 50 75 73  .  }.  if( isPus
3620: 68 20 7c 7c 20 69 73 50 75 6c 6c 20 29 7b 0a 20  h || isPull ){. 
3630: 20 20 20 2f 2a 20 41 6c 77 61 79 73 20 73 65 6e     /* Always sen
3640: 64 20 6f 75 72 20 6c 65 61 76 65 73 20 2a 2f 0a  d our leaves */.
3650: 20 20 20 20 53 74 6d 74 20 71 3b 0a 20 20 20 20      Stmt q;.    
3660: 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20 0a  db_prepare(&q, .
3670: 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 75         "SELECT u
3680: 75 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48  uid FROM blob WH
3690: 45 52 45 20 72 69 64 20 49 4e 22 0a 20 20 20 20  ERE rid IN".    
36a0: 20 20 20 22 20 20 28 53 45 4c 45 43 54 20 63 69     "  (SELECT ci
36b0: 64 20 46 52 4f 4d 20 70 6c 69 6e 6b 20 45 58 43  d FROM plink EXC
36c0: 45 50 54 20 53 45 4c 45 43 54 20 70 69 64 20 46  EPT SELECT pid F
36d0: 52 4f 4d 20 70 6c 69 6e 6b 29 22 0a 20 20 20 20  ROM plink)".    
36e0: 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 64 62  );.    while( db
36f0: 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54  _step(&q)==SQLIT
3700: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 63  E_ROW ){.      c
3710: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 75 69 64  onst char *zUuid
3720: 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78   = db_column_tex
3730: 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20 20  t(&q, 0);.      
3740: 40 20 6c 65 61 66 20 25 73 28 7a 55 75 69 64 29  @ leaf %s(zUuid)
3750: 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 5f 66 69  .    }.    db_fi
3760: 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 7d 0a  nalize(&q);.  }.
3770: 0a 20 20 64 62 5f 65 6e 64 5f 74 72 61 6e 73 61  .  db_end_transa
3780: 63 74 69 6f 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a  ction(0);.}../*.
3790: 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74  ** COMMAND: test
37a0: 2d 78 66 65 72 0a 2a 2a 0a 2a 2a 20 54 68 69 73  -xfer.**.** This
37b0: 20 63 6f 6d 6d 61 6e 64 20 69 73 20 75 73 65 64   command is used
37c0: 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 74   for debugging t
37d0: 68 65 20 73 65 72 76 65 72 2e 20 20 54 68 65 72  he server.  Ther
37e0: 65 20 69 73 20 61 20 73 69 6e 67 6c 65 0a 2a 2a  e is a single.**
37f0: 20 61 72 67 75 6d 65 6e 74 20 77 68 69 63 68 20   argument which 
3800: 69 73 20 74 68 65 20 75 6e 63 6f 6d 70 72 65 73  is the uncompres
3810: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
3820: 6e 20 22 78 66 65 72 22 20 6d 65 73 73 61 67 65  n "xfer" message
3830: 0a 2a 2a 20 66 72 6f 6d 20 63 6c 69 65 6e 74 20  .** from client 
3840: 74 6f 20 73 65 72 76 65 72 2e 20 20 54 68 69 73  to server.  This
3850: 20 63 6f 6d 6d 61 6e 64 20 69 6e 74 65 72 70 72   command interpr
3860: 65 74 73 20 74 68 61 74 20 6d 65 73 73 61 67 65  ets that message
3870: 20 61 73 0a 2a 2a 20 69 66 20 68 61 64 20 62 65   as.** if had be
3880: 65 6e 20 72 65 63 65 69 76 65 64 20 62 79 20 74  en received by t
3890: 68 65 20 73 65 72 76 65 72 2e 0a 2a 2a 0a 2a 2a  he server..**.**
38a0: 20 4f 6e 20 74 68 65 20 63 6c 69 65 6e 74 20 73   On the client s
38b0: 69 64 65 2c 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20  ide, run:.**.** 
38c0: 20 20 20 20 20 66 6f 73 73 69 6c 20 70 75 73 68       fossil push
38d0: 20 68 74 74 70 3a 2f 2f 62 6f 67 75 73 2f 20 2d   http://bogus/ -
38e0: 2d 68 74 74 70 74 72 61 63 65 0a 2a 2a 0a 2a 2a  -httptrace.**.**
38f0: 20 4f 72 20 61 20 73 69 6d 69 6c 61 72 20 63 6f   Or a similar co
3900: 6d 6d 61 6e 64 20 74 6f 20 70 72 6f 76 69 64 65  mmand to provide
3910: 20 74 68 65 20 6f 75 74 70 75 74 2e 20 20 54 68   the output.  Th
3920: 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65  e content of the
3930: 0a 2a 2a 20 6d 65 73 73 61 67 65 20 77 69 6c 6c  .** message will
3940: 20 61 70 70 65 61 72 20 6f 6e 20 73 74 61 6e 64   appear on stand
3950: 61 72 64 20 6f 75 74 70 75 74 2e 20 20 43 61 70  ard output.  Cap
3960: 74 75 72 65 20 74 68 69 73 20 6d 65 73 73 61 67  ture this messag
3970: 65 0a 2a 2a 20 69 6e 74 6f 20 61 20 66 69 6c 65  e.** into a file
3980: 20 6e 61 6d 65 64 20 28 66 6f 72 20 65 78 61 6d   named (for exam
3990: 70 6c 65 29 20 6f 75 74 2e 74 78 74 2e 20 20 54  ple) out.txt.  T
39a0: 68 65 6e 20 72 75 6e 20 74 68 65 0a 2a 2a 20 73  hen run the.** s
39b0: 65 72 76 65 72 20 69 6e 20 67 64 62 3a 0a 2a 2a  erver in gdb:.**
39c0: 0a 2a 2a 20 20 20 20 20 67 64 62 20 66 6f 73 73  .**     gdb foss
39d0: 69 6c 0a 2a 2a 20 20 20 20 20 72 20 74 65 73 74  il.**     r test
39e0: 2d 78 66 65 72 20 6f 75 74 2e 74 78 74 0a 2a 2f  -xfer out.txt.*/
39f0: 0a 76 6f 69 64 20 63 6d 64 5f 74 65 73 74 5f 78  .void cmd_test_x
3a00: 66 65 72 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74  fer(void){.  int
3a10: 20 6e 6f 74 55 73 65 64 3b 0a 20 20 69 66 28 20   notUsed;.  if( 
3a20: 67 2e 61 72 67 63 21 3d 32 20 26 26 20 67 2e 61  g.argc!=2 && g.a
3a30: 72 67 63 21 3d 33 20 29 7b 0a 20 20 20 20 75 73  rgc!=3 ){.    us
3a40: 61 67 65 28 22 3f 4d 45 53 53 41 47 45 46 49 4c  age("?MESSAGEFIL
3a50: 45 3f 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d  E?");.  }.  db_m
3a60: 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72  ust_be_within_tr
3a70: 65 65 28 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  ee();.  blob_zer
3a80: 6f 28 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 62  o(&g.cgiIn);.  b
3a90: 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69  lob_read_from_fi
3aa0: 6c 65 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e 61  le(&g.cgiIn, g.a
3ab0: 72 67 63 3d 3d 32 20 3f 20 22 2d 22 20 3a 20 67  rgc==2 ? "-" : g
3ac0: 2e 61 72 67 76 5b 32 5d 29 3b 0a 20 20 64 69 73  .argv[2]);.  dis
3ad0: 61 62 6c 65 4c 6f 67 69 6e 20 3d 20 31 3b 0a 20  ableLogin = 1;. 
3ae0: 20 70 61 67 65 5f 78 66 65 72 28 29 3b 0a 20 20   page_xfer();.  
3af0: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 63  printf("%s\n", c
3b00: 67 69 5f 65 78 74 72 61 63 74 5f 63 6f 6e 74 65  gi_extract_conte
3b10: 6e 74 28 26 6e 6f 74 55 73 65 64 29 29 3b 0a 7d  nt(&notUsed));.}
3b20: 0a 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74 6f  .../*.** Sync to
3b30: 20 74 68 65 20 68 6f 73 74 20 69 64 65 6e 74 69   the host identi
3b40: 66 69 65 64 20 69 6e 20 67 2e 75 72 6c 4e 61 6d  fied in g.urlNam
3b50: 65 20 61 6e 64 20 67 2e 75 72 6c 50 61 74 68 2e  e and g.urlPath.
3b60: 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e    This.** routin
3b70: 65 20 69 73 20 63 61 6c 6c 65 64 20 62 79 20 74  e is called by t
3b80: 68 65 20 63 6c 69 65 6e 74 2e 0a 2a 2a 0a 2a 2a  he client..**.**
3b90: 20 52 65 63 6f 72 64 73 20 61 72 65 20 70 75 73   Records are pus
3ba0: 68 65 64 20 74 6f 20 74 68 65 20 73 65 72 76 65  hed to the serve
3bb0: 72 20 69 66 20 70 75 73 68 46 6c 61 67 20 69 73  r if pushFlag is
3bc0: 20 74 72 75 65 2e 20 20 52 65 63 6f 72 64 73 0a   true.  Records.
3bd0: 2a 2a 20 61 72 65 20 70 75 6c 6c 65 64 20 69 66  ** are pulled if
3be0: 20 70 75 6c 6c 46 6c 61 67 20 69 73 20 74 72 75   pullFlag is tru
3bf0: 65 2e 20 20 41 20 66 75 6c 6c 20 73 79 6e 63 20  e.  A full sync 
3c00: 6f 63 63 75 72 73 20 69 66 20 62 6f 74 68 20 61  occurs if both a
3c10: 72 65 0a 2a 2a 20 74 72 75 65 2e 0a 2a 2f 0a 76  re.** true..*/.v
3c20: 6f 69 64 20 63 6c 69 65 6e 74 5f 73 79 6e 63 28  oid client_sync(
3c30: 69 6e 74 20 70 75 73 68 46 6c 61 67 2c 20 69 6e  int pushFlag, in
3c40: 74 20 70 75 6c 6c 46 6c 61 67 2c 20 69 6e 74 20  t pullFlag, int 
3c50: 63 6c 6f 6e 65 46 6c 61 67 29 7b 0a 20 20 69 6e  cloneFlag){.  in
3c60: 74 20 67 6f 20 3d 20 31 3b 20 20 20 20 20 20 20  t go = 1;       
3c70: 20 2f 2a 20 4c 6f 6f 70 20 75 6e 74 69 6c 20 7a   /* Loop until z
3c80: 65 72 6f 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f  ero */.  int nTo
3c90: 6b 65 6e 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  ken;.  const cha
3ca0: 72 20 2a 7a 53 43 6f 64 65 20 3d 20 64 62 5f 67  r *zSCode = db_g
3cb0: 65 74 28 22 73 65 72 76 65 72 2d 63 6f 64 65 22  et("server-code"
3cc0: 2c 20 22 78 22 29 3b 0a 20 20 63 6f 6e 73 74 20  , "x");.  const 
3cd0: 63 68 61 72 20 2a 7a 50 43 6f 64 65 20 3d 20 64  char *zPCode = d
3ce0: 62 5f 67 65 74 28 22 70 72 6f 6a 65 63 74 2d 63  b_get("project-c
3cf0: 6f 64 65 22 2c 20 30 29 3b 0a 20 20 69 6e 74 20  ode", 0);.  int 
3d00: 6e 46 69 6c 65 20 3d 20 30 3b 0a 20 20 69 6e 74  nFile = 0;.  int
3d10: 20 6e 4d 73 67 20 3d 20 30 3b 0a 20 20 69 6e 74   nMsg = 0;.  int
3d20: 20 6e 52 65 71 20 3d 20 30 3b 0a 20 20 69 6e 74   nReq = 0;.  int
3d30: 20 6e 46 69 6c 65 53 65 6e 64 3b 0a 20 20 69 6e   nFileSend;.  in
3d40: 74 20 6e 4e 6f 46 69 6c 65 43 79 63 6c 65 20 3d  t nNoFileCycle =
3d50: 20 30 3b 0a 20 20 42 6c 6f 62 20 73 65 6e 64 3b   0;.  Blob send;
3d60: 20 20 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20          /* Text 
3d70: 77 65 20 61 72 65 20 73 65 6e 64 69 6e 67 20 74  we are sending t
3d80: 6f 20 74 68 65 20 73 65 72 76 65 72 20 2a 2f 0a  o the server */.
3d90: 20 20 42 6c 6f 62 20 72 65 63 76 3b 20 20 20 20    Blob recv;    
3da0: 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 77 65 20      /* Reply we 
3db0: 67 6f 74 20 62 61 63 6b 20 66 72 6f 6d 20 74 68  got back from th
3dc0: 65 20 73 65 72 76 65 72 20 2a 2f 0a 20 20 42 6c  e server */.  Bl
3dd0: 6f 62 20 6c 69 6e 65 3b 20 20 20 20 20 20 20 20  ob line;        
3de0: 2f 2a 20 41 20 73 69 6e 67 6c 65 20 6c 69 6e 65  /* A single line
3df0: 20 6f 66 20 74 68 65 20 72 65 70 6c 79 20 2a 2f   of the reply */
3e00: 0a 20 20 42 6c 6f 62 20 61 54 6f 6b 65 6e 5b 35  .  Blob aToken[5
3e10: 5d 3b 20 20 20 2f 2a 20 41 20 74 6f 6b 65 6e 69  ];   /* A tokeni
3e20: 7a 61 74 69 6f 6e 20 6f 66 20 6c 69 6e 65 20 2a  zation of line *
3e30: 2f 0a 20 20 42 6c 6f 62 20 65 72 72 6d 73 67 3b  /.  Blob errmsg;
3e40: 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 6d        /* Error m
3e50: 65 73 73 61 67 65 20 2a 2f 0a 0a 20 20 61 73 73  essage */..  ass
3e60: 65 72 74 28 20 70 75 73 68 46 6c 61 67 20 7c 7c  ert( pushFlag ||
3e70: 20 70 75 6c 6c 46 6c 61 67 20 7c 7c 20 63 6c 6f   pullFlag || clo
3e80: 6e 65 46 6c 61 67 20 29 3b 0a 20 20 61 73 73 65  neFlag );.  asse
3e90: 72 74 28 20 21 67 2e 75 72 6c 49 73 46 69 6c 65  rt( !g.urlIsFile
3ea0: 20 29 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20   );          /* 
3eb0: 54 68 69 73 20 6f 6e 6c 79 20 77 6f 72 6b 73 20  This only works 
3ec0: 66 6f 72 20 6e 65 74 77 6f 72 6b 69 6e 67 20 2a  for networking *
3ed0: 2f 0a 0a 20 20 64 62 5f 62 65 67 69 6e 5f 74 72  /..  db_begin_tr
3ee0: 61 6e 73 61 63 74 69 6f 6e 28 29 3b 0a 20 20 64  ansaction();.  d
3ef0: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20  b_multi_exec(.  
3f00: 20 20 2f 2a 20 52 65 63 6f 72 64 73 20 77 68 69    /* Records whi
3f10: 63 68 20 77 65 20 6b 6e 6f 77 20 74 68 65 20 6f  ch we know the o
3f20: 74 68 65 72 20 73 69 64 65 20 61 6c 73 6f 20 68  ther side also h
3f30: 61 73 20 2a 2f 0a 20 20 20 20 22 43 52 45 41 54  as */.    "CREAT
3f40: 45 20 54 45 4d 50 20 54 41 42 4c 45 20 6f 6e 72  E TEMP TABLE onr
3f50: 65 6d 6f 74 65 28 72 69 64 20 49 4e 54 45 47 45  emote(rid INTEGE
3f60: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 29 3b 22  R PRIMARY KEY);"
3f70: 0a 20 20 20 20 2f 2a 20 52 65 63 6f 72 64 73 20  .    /* Records 
3f80: 77 65 20 6b 6e 6f 77 20 74 68 65 20 6f 74 68 65  we know the othe
3f90: 72 20 73 69 64 65 20 6e 65 65 64 73 20 2a 2f 0a  r side needs */.
3fa0: 20 20 20 20 22 43 52 45 41 54 45 20 54 45 4d 50      "CREATE TEMP
3fb0: 20 54 41 42 4c 45 20 70 65 6e 64 69 6e 67 28 72   TABLE pending(r
3fc0: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  id INTEGER PRIMA
3fd0: 52 59 20 4b 45 59 29 3b 22 0a 20 20 29 3b 0a 20  RY KEY);".  );. 
3fe0: 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72 6f 28   blobarray_zero(
3ff0: 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28 61 54  aToken, count(aT
4000: 6f 6b 65 6e 29 29 3b 0a 20 20 62 6c 6f 62 5f 7a  oken));.  blob_z
4010: 65 72 6f 28 26 73 65 6e 64 29 3b 0a 20 20 62 6c  ero(&send);.  bl
4020: 6f 62 5f 7a 65 72 6f 28 26 72 65 63 76 29 3b 0a  ob_zero(&recv);.
4030: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 65 72 72    blob_zero(&err
4040: 6d 73 67 29 3b 0a 0a 0a 20 20 77 68 69 6c 65 28  msg);...  while(
4050: 20 67 6f 20 29 7b 0a 20 20 20 20 67 6f 20 3d 20   go ){.    go = 
4060: 30 3b 0a 20 20 20 20 6e 46 69 6c 65 20 3d 20 6e  0;.    nFile = n
4070: 52 65 71 20 3d 20 6e 4d 73 67 20 3d 20 30 3b 0a  Req = nMsg = 0;.
4080: 0a 20 20 20 20 2f 2a 20 47 65 6e 65 72 61 74 65  .    /* Generate
4090: 20 61 20 72 65 71 75 65 73 74 20 74 6f 20 62 65   a request to be
40a0: 20 73 65 6e 74 20 74 6f 20 74 68 65 20 73 65 72   sent to the ser
40b0: 76 65 72 2e 0a 20 20 20 20 2a 2a 20 41 6c 77 61  ver..    ** Alwa
40c0: 79 73 20 62 65 67 69 6e 20 77 69 74 68 20 61 20  ys begin with a 
40d0: 63 6c 6f 6e 65 2c 20 70 75 6c 6c 2c 20 6f 72 20  clone, pull, or 
40e0: 70 75 73 68 20 6d 65 73 73 61 67 65 0a 20 20 20  push message.   
40f0: 20 2a 2f 0a 20 20 20 20 0a 20 20 20 20 69 66 28   */.    .    if(
4100: 20 63 6c 6f 6e 65 46 6c 61 67 20 29 7b 0a 20 20   cloneFlag ){.  
4110: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
4120: 28 26 73 65 6e 64 2c 20 22 63 6c 6f 6e 65 5c 6e  (&send, "clone\n
4130: 22 29 3b 0a 20 20 20 20 20 20 70 75 73 68 46 6c  ");.      pushFl
4140: 61 67 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 75  ag = 0;.      pu
4150: 6c 6c 46 6c 61 67 20 3d 20 30 3b 0a 20 20 20 20  llFlag = 0;.    
4160: 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20 20 7d 65    nMsg++;.    }e
4170: 6c 73 65 20 69 66 28 20 70 75 6c 6c 46 6c 61 67  lse if( pullFlag
4180: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61   ){.      blob_a
4190: 70 70 65 6e 64 66 28 26 73 65 6e 64 2c 20 22 70  ppendf(&send, "p
41a0: 75 6c 6c 20 25 73 20 25 73 5c 6e 22 2c 20 7a 53  ull %s %s\n", zS
41b0: 43 6f 64 65 2c 20 7a 50 43 6f 64 65 29 3b 0a 20  Code, zPCode);. 
41c0: 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20       nMsg++;.   
41d0: 20 7d 0a 20 20 20 20 69 66 28 20 70 75 73 68 46   }.    if( pushF
41e0: 6c 61 67 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f  lag ){.      blo
41f0: 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c  b_appendf(&send,
4200: 20 22 70 75 73 68 20 25 73 20 25 73 5c 6e 22 2c   "push %s %s\n",
4210: 20 7a 53 43 6f 64 65 2c 20 7a 50 43 6f 64 65 29   zSCode, zPCode)
4220: 3b 0a 20 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a  ;.      nMsg++;.
4230: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70      }..    if( p
4240: 75 6c 6c 46 6c 61 67 20 29 7b 0a 20 20 20 20 20  ullFlag ){.     
4250: 20 2f 2a 20 53 65 6e 64 20 67 69 6d 6d 65 20 6d   /* Send gimme m
4260: 65 73 73 61 67 65 20 66 6f 72 20 65 76 65 72 79  essage for every
4270: 20 70 68 61 6e 74 6f 6d 20 74 68 61 74 20 77 65   phantom that we
4280: 20 68 6f 6c 64 2e 0a 20 20 20 20 20 20 2a 2f 0a   hold..      */.
4290: 20 20 20 20 20 20 53 74 6d 74 20 71 3b 0a 20 20        Stmt q;.  
42a0: 20 20 20 20 64 62 5f 70 72 65 70 61 72 65 28 26      db_prepare(&
42b0: 71 2c 20 22 53 45 4c 45 43 54 20 75 75 69 64 20  q, "SELECT uuid 
42c0: 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20  FROM blob WHERE 
42d0: 73 69 7a 65 3c 30 22 29 3b 0a 20 20 20 20 20 20  size<0");.      
42e0: 77 68 69 6c 65 28 20 64 62 5f 73 74 65 70 28 26  while( db_step(&
42f0: 71 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  q)==SQLITE_ROW )
4300: 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20  {.        const 
4310: 63 68 61 72 20 2a 7a 55 75 69 64 20 3d 20 64 62  char *zUuid = db
4320: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 26 71 2c  _column_text(&q,
4330: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f   0);.        blo
4340: 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c  b_appendf(&send,
4350: 22 67 69 6d 6d 65 20 25 73 5c 6e 22 2c 20 7a 55  "gimme %s\n", zU
4360: 75 69 64 29 3b 0a 20 20 20 20 20 20 20 20 6e 52  uid);.        nR
4370: 65 71 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  eq++;.      }.  
4380: 20 20 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28      db_finalize(
4390: 26 71 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  &q);.    }..    
43a0: 69 66 28 20 70 75 73 68 46 6c 61 67 20 29 7b 0a  if( pushFlag ){.
43b0: 20 20 20 20 20 20 2f 2a 20 53 65 6e 64 20 74 68        /* Send th
43c0: 65 20 73 65 72 76 65 72 20 61 6e 79 20 66 69 6c  e server any fil
43d0: 65 73 20 74 68 61 74 20 74 68 65 20 73 65 72 76  es that the serv
43e0: 65 72 20 68 61 73 20 72 65 71 75 65 73 74 65 64  er has requested
43f0: 20 2a 2f 0a 20 20 20 20 20 20 6e 46 69 6c 65 20   */.      nFile 
4400: 2b 3d 20 73 65 6e 64 5f 61 6c 6c 5f 70 65 6e 64  += send_all_pend
4410: 69 6e 67 28 26 73 65 6e 64 29 3b 0a 20 20 20 20  ing(&send);.    
4420: 7d 0a 0a 20 20 20 20 69 66 28 20 70 75 6c 6c 46  }..    if( pullF
4430: 6c 61 67 20 7c 7c 20 70 75 73 68 46 6c 61 67 20  lag || pushFlag 
4440: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c 77 61  ){.      /* Alwa
4450: 79 73 20 73 65 6e 64 20 6f 75 72 20 6c 65 61 76  ys send our leav
4460: 65 73 20 2a 2f 0a 20 20 20 20 20 20 53 74 6d 74  es */.      Stmt
4470: 20 71 3b 0a 20 20 20 20 20 20 64 62 5f 70 72 65   q;.      db_pre
4480: 70 61 72 65 28 26 71 2c 20 0a 20 20 20 20 20 20  pare(&q, .      
4490: 20 20 20 22 53 45 4c 45 43 54 20 75 75 69 64 20     "SELECT uuid 
44a0: 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45 52 45 20  FROM blob WHERE 
44b0: 72 69 64 20 49 4e 22 0a 20 20 20 20 20 20 20 20  rid IN".        
44c0: 20 22 20 20 28 53 45 4c 45 43 54 20 63 69 64 20   "  (SELECT cid 
44d0: 46 52 4f 4d 20 70 6c 69 6e 6b 20 45 58 43 45 50  FROM plink EXCEP
44e0: 54 20 53 45 4c 45 43 54 20 70 69 64 20 46 52 4f  T SELECT pid FRO
44f0: 4d 20 70 6c 69 6e 6b 29 22 0a 20 20 20 20 20 20  M plink)".      
4500: 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  );.      while( 
4510: 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c  db_step(&q)==SQL
4520: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
4530: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
4540: 55 75 69 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e  Uuid = db_column
4550: 5f 74 65 78 74 28 26 71 2c 20 30 29 3b 0a 20 20  _text(&q, 0);.  
4560: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
4570: 64 66 28 26 73 65 6e 64 2c 20 22 6c 65 61 66 20  df(&send, "leaf 
4580: 25 73 5c 6e 22 2c 20 7a 55 75 69 64 29 3b 0a 20  %s\n", zUuid);. 
4590: 20 20 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20         nMsg++;. 
45a0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64 62 5f       }.      db_
45b0: 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20  finalize(&q);.  
45c0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 45 78 63 68    }..    /* Exch
45d0: 61 6e 67 65 20 6d 65 73 73 61 67 65 73 20 77 69  ange messages wi
45e0: 74 68 20 74 68 65 20 73 65 72 76 65 72 20 2a 2f  th the server */
45f0: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 53 65 6e  .    printf("Sen
4600: 64 3a 20 20 20 20 20 20 25 33 64 20 66 69 6c 65  d:      %3d file
4610: 73 2c 20 25 33 64 20 72 65 71 75 65 73 74 73 2c  s, %3d requests,
4620: 20 25 33 64 20 6f 74 68 65 72 20 6d 73 67 73 2c   %3d other msgs,
4630: 20 25 38 64 20 62 79 74 65 73 5c 6e 22 2c 0a 20   %8d bytes\n",. 
4640: 20 20 20 20 20 20 20 20 20 20 20 6e 46 69 6c 65             nFile
4650: 2c 20 6e 52 65 71 2c 20 6e 4d 73 67 2c 20 62 6c  , nReq, nMsg, bl
4660: 6f 62 5f 73 69 7a 65 28 26 73 65 6e 64 29 29 3b  ob_size(&send));
4670: 0a 20 20 20 20 6e 46 69 6c 65 53 65 6e 64 20 3d  .    nFileSend =
4680: 20 6e 46 69 6c 65 3b 0a 20 20 20 20 6e 46 69 6c   nFile;.    nFil
4690: 65 20 3d 20 6e 52 65 71 20 3d 20 6e 4d 73 67 20  e = nReq = nMsg 
46a0: 3d 20 30 3b 0a 20 20 20 20 68 74 74 70 5f 65 78  = 0;.    http_ex
46b0: 63 68 61 6e 67 65 28 26 73 65 6e 64 2c 20 26 72  change(&send, &r
46c0: 65 63 76 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  ecv);.    blob_r
46d0: 65 73 65 74 28 26 73 65 6e 64 29 3b 0a 0a 20 20  eset(&send);..  
46e0: 20 20 2f 2a 20 50 72 6f 63 65 73 73 20 74 68 65    /* Process the
46f0: 20 72 65 70 6c 79 20 74 68 61 74 20 63 61 6d 65   reply that came
4700: 20 62 61 63 6b 20 66 72 6f 6d 20 74 68 65 20 73   back from the s
4710: 65 72 76 65 72 20 2a 2f 0a 20 20 20 20 77 68 69  erver */.    whi
4720: 6c 65 28 20 62 6c 6f 62 5f 6c 69 6e 65 28 26 72  le( blob_line(&r
4730: 65 63 76 2c 20 26 6c 69 6e 65 29 20 29 7b 0a 20  ecv, &line) ){. 
4740: 20 20 20 20 20 6e 54 6f 6b 65 6e 20 3d 20 62 6c       nToken = bl
4750: 6f 62 5f 74 6f 6b 65 6e 69 7a 65 28 26 6c 69 6e  ob_tokenize(&lin
4760: 65 2c 20 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74  e, aToken, count
4770: 28 61 54 6f 6b 65 6e 29 29 3b 0a 0a 20 20 20 20  (aToken));..    
4780: 20 20 2f 2a 20 20 20 66 69 6c 65 20 55 55 49 44    /*   file UUID
4790: 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54   SIZE \n CONTENT
47a0: 0a 20 20 20 20 20 20 2a 2a 20 20 20 66 69 6c 65  .      **   file
47b0: 20 55 55 49 44 20 44 45 4c 54 41 53 52 43 20 53   UUID DELTASRC S
47c0: 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20  IZE \n CONTENT. 
47d0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
47e0: 20 52 65 63 65 69 76 65 20 61 20 66 69 6c 65 20   Receive a file 
47f0: 74 72 61 6e 73 6d 69 74 74 65 64 20 66 72 6f 6d  transmitted from
4800: 20 74 68 65 20 6f 74 68 65 72 20 73 69 64 65 0a   the other side.
4810: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69        */.      i
4820: 66 28 20 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b  f( blob_eq(&aTok
4830: 65 6e 5b 30 5d 2c 22 66 69 6c 65 22 29 20 29 7b  en[0],"file") ){
4840: 0a 20 20 20 20 20 20 20 20 78 66 65 72 5f 61 63  .        xfer_ac
4850: 63 65 70 74 5f 66 69 6c 65 28 26 72 65 63 76 2c  cept_file(&recv,
4860: 20 61 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 2c   aToken, nToken,
4870: 20 26 65 72 72 6d 73 67 29 3b 0a 20 20 20 20 20   &errmsg);.     
4880: 20 20 20 6e 46 69 6c 65 2b 2b 3b 0a 20 20 20 20     nFile++;.    
4890: 20 20 20 20 67 6f 20 3d 20 31 3b 0a 20 20 20 20      go = 1;.    
48a0: 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 20 20 2f    }else..      /
48b0: 2a 20 20 20 67 69 6d 6d 65 20 55 55 49 44 0a 20  *   gimme UUID. 
48c0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
48d0: 20 53 65 72 76 65 72 20 69 73 20 72 65 71 75 65   Server is reque
48e0: 73 74 69 6e 67 20 61 20 66 69 6c 65 0a 20 20 20  sting a file.   
48f0: 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20     */.      if( 
4900: 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b  blob_eq(&aToken[
4910: 30 5d 2c 20 22 67 69 6d 6d 65 22 29 20 26 26 20  0], "gimme") && 
4920: 6e 54 6f 6b 65 6e 3d 3d 32 0a 20 20 20 20 20 20  nToken==2.      
4930: 20 20 20 20 20 20 20 20 20 26 26 20 62 6c 6f 62           && blob
4940: 5f 69 73 5f 75 75 69 64 28 26 61 54 6f 6b 65 6e  _is_uuid(&aToken
4950: 5b 31 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  [1]) ){.        
4960: 6e 52 65 71 2b 2b 3b 0a 20 20 20 20 20 20 20 20  nReq++;.        
4970: 69 66 28 20 70 75 73 68 46 6c 61 67 20 29 7b 0a  if( pushFlag ){.
4980: 20 20 20 20 20 20 20 20 20 20 64 62 5f 6d 75 6c            db_mul
4990: 74 69 5f 65 78 65 63 28 0a 20 20 20 20 20 20 20  ti_exec(.       
49a0: 20 20 20 20 20 22 49 4e 53 45 52 54 20 4f 52 20       "INSERT OR 
49b0: 49 47 4e 4f 52 45 20 49 4e 54 4f 20 70 65 6e 64  IGNORE INTO pend
49c0: 69 6e 67 28 72 69 64 29 20 22 0a 20 20 20 20 20  ing(rid) ".     
49d0: 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 72         "SELECT r
49e0: 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45  id FROM blob WHE
49f0: 52 45 20 75 75 69 64 3d 25 42 20 41 4e 44 20 73  RE uuid=%B AND s
4a00: 69 7a 65 3e 3d 30 22 2c 20 26 61 54 6f 6b 65 6e  ize>=0", &aToken
4a10: 5b 31 5d 0a 20 20 20 20 20 20 20 20 20 20 29 3b  [1].          );
4a20: 0a 20 20 20 20 20 20 20 20 20 20 67 6f 20 3d 20  .          go = 
4a30: 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  1;.        }.   
4a40: 20 20 20 7d 65 6c 73 65 0a 20 20 0a 20 20 20 20     }else.  .    
4a50: 20 20 2f 2a 20 20 20 69 67 6f 74 20 55 55 49 44    /*   igot UUID
4a60: 0a 20 20 20 20 20 20 2a 2a 20 20 20 6c 65 61 66  .      **   leaf
4a70: 20 55 55 49 44 0a 20 20 20 20 20 20 2a 2a 0a 20   UUID.      **. 
4a80: 20 20 20 20 20 2a 2a 20 53 65 72 76 65 72 20 70       ** Server p
4a90: 72 6f 63 6c 61 69 6d 73 20 74 68 61 74 20 69 74  roclaims that it
4aa0: 20 68 61 73 20 61 20 70 61 72 74 69 63 75 6c 61   has a particula
4ab0: 72 20 66 69 6c 65 2e 20 20 41 20 6c 65 61 66 20  r file.  A leaf 
4ac0: 6d 65 73 73 61 67 65 0a 20 20 20 20 20 20 2a 2a  message.      **
4ad0: 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65 20   means that the 
4ae0: 66 69 6c 65 20 69 73 20 61 20 6c 65 61 66 20 6d  file is a leaf m
4af0: 61 6e 69 66 65 73 74 20 6f 6e 20 74 68 65 20 73  anifest on the s
4b00: 65 72 76 65 72 2e 0a 20 20 20 20 20 20 2a 2f 0a  erver..      */.
4b10: 20 20 20 20 20 20 69 66 28 20 6e 54 6f 6b 65 6e        if( nToken
4b20: 3d 3d 32 0a 20 20 20 20 20 20 20 20 20 20 20 20  ==2.            
4b30: 20 20 26 26 20 28 62 6c 6f 62 5f 65 71 28 26 61    && (blob_eq(&a
4b40: 54 6f 6b 65 6e 5b 30 5d 2c 20 22 69 67 6f 74 22  Token[0], "igot"
4b50: 29 20 7c 7c 20 62 6c 6f 62 5f 65 71 28 26 61 54  ) || blob_eq(&aT
4b60: 6f 6b 65 6e 5b 30 5d 2c 20 22 6c 65 61 66 22 29  oken[0], "leaf")
4b70: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
4b80: 26 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28  && blob_is_uuid(
4b90: 26 61 54 6f 6b 65 6e 5b 31 5d 29 20 29 7b 0a 20  &aToken[1]) ){. 
4ba0: 20 20 20 20 20 20 20 69 6e 74 20 72 69 64 20 3d         int rid =
4bb0: 20 64 62 5f 69 6e 74 28 30 2c 20 22 53 45 4c 45   db_int(0, "SELE
4bc0: 43 54 20 72 69 64 20 46 52 4f 4d 20 62 6c 6f 62  CT rid FROM blob
4bd0: 20 57 48 45 52 45 20 75 75 69 64 3d 25 42 22 2c   WHERE uuid=%B",
4be0: 20 26 61 54 6f 6b 65 6e 5b 31 5d 29 3b 0a 20 20   &aToken[1]);.  
4bf0: 20 20 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20        nMsg++;.  
4c00: 20 20 20 20 20 20 69 66 28 20 72 69 64 3e 30 20        if( rid>0 
4c10: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 64 62 5f  ){.          db_
4c20: 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 20  multi_exec(.    
4c30: 20 20 20 20 20 20 20 20 22 49 4e 53 45 52 54 20          "INSERT 
4c40: 4f 52 20 49 47 4e 4f 52 45 20 49 4e 54 4f 20 6f  OR IGNORE INTO o
4c50: 6e 72 65 6d 6f 74 65 28 72 69 64 29 20 56 41 4c  nremote(rid) VAL
4c60: 55 45 53 28 25 64 29 22 2c 20 72 69 64 0a 20 20  UES(%d)", rid.  
4c70: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
4c80: 20 20 20 20 20 2f 2a 20 41 64 64 20 74 6f 20 74       /* Add to t
4c90: 68 65 20 70 65 6e 64 69 6e 67 20 73 65 74 20 61  he pending set a
4ca0: 6c 6c 20 63 68 69 6c 64 72 65 6e 20 6f 66 20 74  ll children of t
4cb0: 68 65 20 73 65 72 76 65 72 27 73 20 6c 65 61 76  he server's leav
4cc0: 65 73 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  es */.          
4cd0: 69 66 28 20 70 75 73 68 46 6c 61 67 20 26 26 20  if( pushFlag && 
4ce0: 62 6c 6f 62 5f 65 71 28 26 61 54 6f 6b 65 6e 5b  blob_eq(&aToken[
4cf0: 30 5d 2c 20 22 6c 65 61 66 22 29 20 29 7b 0a 20  0], "leaf") ){. 
4d00: 20 20 20 20 20 20 20 20 20 20 20 64 62 5f 6d 75             db_mu
4d10: 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 20 20 20  lti_exec(.      
4d20: 20 20 20 20 20 20 20 20 22 49 4e 53 45 52 54 20          "INSERT 
4d30: 4f 52 20 49 47 4e 4f 52 45 20 49 4e 54 4f 20 70  OR IGNORE INTO p
4d40: 65 6e 64 69 6e 67 28 72 69 64 29 20 22 0a 20 20  ending(rid) ".  
4d50: 20 20 20 20 20 20 20 20 20 20 20 20 22 53 45 4c              "SEL
4d60: 45 43 54 20 63 69 64 20 46 52 4f 4d 20 70 6c 69  ECT cid FROM pli
4d70: 6e 6b 20 57 48 45 52 45 20 70 69 64 3d 25 64 22  nk WHERE pid=%d"
4d80: 2c 20 72 69 64 0a 20 20 20 20 20 20 20 20 20 20  , rid.          
4d90: 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20    );.           
4da0: 20 69 66 28 20 64 62 5f 63 68 61 6e 67 65 73 28   if( db_changes(
4db0: 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  )>0 ){.         
4dc0: 20 20 20 20 20 67 6f 20 3d 20 31 3b 0a 20 20 20       go = 1;.   
4dd0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
4de0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
4df0: 20 69 66 28 20 70 75 6c 6c 46 6c 61 67 20 26 26   if( pullFlag &&
4e00: 20 21 67 6f 20 26 26 20 0a 20 20 20 20 20 20 20   !go && .       
4e10: 20 20 20 20 20 20 20 64 62 5f 65 78 69 73 74 73         db_exists
4e20: 28 22 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20  ("SELECT 1 FROM 
4e30: 62 6c 6f 62 20 57 48 45 52 45 20 72 69 64 3d 25  blob WHERE rid=%
4e40: 64 20 41 4e 44 20 73 69 7a 65 3c 30 22 2c 20 72  d AND size<0", r
4e50: 69 64 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  id) ){.         
4e60: 20 20 20 67 6f 20 3d 20 31 3b 0a 20 20 20 20 20     go = 1;.     
4e70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
4e80: 65 6c 73 65 20 69 66 28 20 70 75 6c 6c 46 6c 61  else if( pullFla
4e90: 67 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 67  g ){.          g
4ea0: 6f 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20  o = 1;.         
4eb0: 20 63 6f 6e 74 65 6e 74 5f 70 75 74 28 30 2c 20   content_put(0, 
4ec0: 62 6c 6f 62 5f 73 74 72 28 26 61 54 6f 6b 65 6e  blob_str(&aToken
4ed0: 5b 31 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 7d  [1]));.        }
4ee0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a 20 20 0a  .      }else.  .
4ef0: 20 20 20 20 20 20 2f 2a 20 20 20 70 75 73 68 20        /*   push 
4f00: 20 53 45 52 56 45 52 43 4f 44 45 20 20 50 52 4f   SERVERCODE  PRO
4f10: 44 55 43 54 43 4f 44 45 0a 20 20 20 20 20 20 2a  DUCTCODE.      *
4f20: 2a 0a 20 20 20 20 20 20 2a 2a 20 53 68 6f 75 6c  *.      ** Shoul
4f30: 64 20 6f 6e 6c 79 20 68 61 70 70 65 6e 20 69 6e  d only happen in
4f40: 20 72 65 73 70 6f 6e 73 65 20 74 6f 20 61 20 63   response to a c
4f50: 6c 6f 6e 65 2e 0a 20 20 20 20 20 20 2a 2f 0a 20  lone..      */. 
4f60: 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71       if( blob_eq
4f70: 28 26 61 54 6f 6b 65 6e 5b 30 5d 2c 22 70 75 73  (&aToken[0],"pus
4f80: 68 22 29 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d 33  h") && nToken==3
4f90: 20 26 26 20 63 6c 6f 6e 65 46 6c 61 67 0a 20 20   && cloneFlag.  
4fa0: 20 20 20 20 20 20 20 20 20 20 20 20 26 26 20 62              && b
4fb0: 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 61 54 6f  lob_is_uuid(&aTo
4fc0: 6b 65 6e 5b 31 5d 29 20 26 26 20 62 6c 6f 62 5f  ken[1]) && blob_
4fd0: 69 73 5f 75 75 69 64 28 26 61 54 6f 6b 65 6e 5b  is_uuid(&aToken[
4fe0: 32 5d 29 20 29 7b 0a 0a 20 20 20 20 20 20 20 20  2]) ){..        
4ff0: 69 66 28 20 62 6c 6f 62 5f 65 71 5f 73 74 72 28  if( blob_eq_str(
5000: 26 61 54 6f 6b 65 6e 5b 31 5d 2c 20 7a 53 43 6f  &aToken[1], zSCo
5010: 64 65 2c 20 2d 31 29 20 29 7b 0a 20 20 20 20 20  de, -1) ){.     
5020: 20 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61       fossil_fata
5030: 6c 28 22 73 65 72 76 65 72 20 6c 6f 6f 70 22 29  l("server loop")
5040: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
5050: 20 20 20 20 6e 4d 73 67 2b 2b 3b 0a 20 20 20 20      nMsg++;.    
5060: 20 20 20 20 69 66 28 20 7a 50 43 6f 64 65 3d 3d      if( zPCode==
5070: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a  0 ){.          z
5080: 50 43 6f 64 65 20 3d 20 6d 70 72 69 6e 74 66 28  PCode = mprintf(
5090: 22 25 62 22 2c 20 26 61 54 6f 6b 65 6e 5b 32 5d  "%b", &aToken[2]
50a0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 62 5f  );.          db_
50b0: 73 65 74 28 22 70 72 6f 6a 65 63 74 2d 63 6f 64  set("project-cod
50c0: 65 22 2c 20 7a 50 43 6f 64 65 29 3b 0a 20 20 20  e", zPCode);.   
50d0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 63       }.        c
50e0: 6c 6f 6e 65 46 6c 61 67 20 3d 20 30 3b 0a 20 20  loneFlag = 0;.  
50f0: 20 20 20 20 20 20 70 75 6c 6c 46 6c 61 67 20 3d        pullFlag =
5100: 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a   1;.      }else.
5110: 0a 20 20 20 20 20 20 2f 2a 20 20 20 65 72 72 6f  .      /*   erro
5120: 72 20 4d 45 53 53 41 47 45 0a 20 20 20 20 20 20  r MESSAGE.      
5130: 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 52 65 70 6f  **.      ** Repo
5140: 72 74 20 61 6e 20 65 72 72 6f 72 0a 20 20 20 20  rt an error.    
5150: 20 20 2a 2f 20 20 20 20 20 20 20 20 0a 20 20 20    */        .   
5160: 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26     if( blob_eq(&
5170: 61 54 6f 6b 65 6e 5b 30 5d 2c 22 65 72 72 6f 72  aToken[0],"error
5180: 22 29 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d 32 20  ") && nToken==2 
5190: 29 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20  ){.        char 
51a0: 2a 7a 4d 73 67 20 3d 20 62 6c 6f 62 5f 74 65 72  *zMsg = blob_ter
51b0: 6d 69 6e 61 74 65 28 26 61 54 6f 6b 65 6e 5b 31  minate(&aToken[1
51c0: 5d 29 3b 0a 20 20 20 20 20 20 20 20 64 65 66 6f  ]);.        defo
51d0: 73 73 69 6c 69 7a 65 28 7a 4d 73 67 29 3b 0a 20  ssilize(zMsg);. 
51e0: 20 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65         blob_appe
51f0: 6e 64 66 28 26 65 72 72 6d 73 67 2c 20 22 73 65  ndf(&errmsg, "se
5200: 72 76 65 72 20 73 61 79 73 3a 20 25 73 22 2c 20  rver says: %s", 
5210: 7a 4d 73 67 29 3b 0a 20 20 20 20 20 20 7d 65 6c  zMsg);.      }el
5220: 73 65 0a 0a 20 20 20 20 20 20 2f 2a 20 55 6e 6b  se..      /* Unk
5230: 6e 6f 77 6e 20 6d 65 73 73 61 67 65 20 2a 2f 0a  nown message */.
5240: 20 20 20 20 20 20 7b 0a 20 20 20 20 20 20 20 20        {.        
5250: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 72  blob_appendf(&er
5260: 72 6d 73 67 2c 20 22 75 6e 6b 6e 6f 77 6e 20 63  rmsg, "unknown c
5270: 6f 6d 6d 61 6e 64 3a 20 25 62 22 2c 20 26 61 54  ommand: %b", &aT
5280: 6f 6b 65 6e 5b 30 5d 29 3b 0a 20 20 20 20 20 20  oken[0]);.      
5290: 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f  }..      if( blo
52a0: 62 5f 73 69 7a 65 28 26 65 72 72 6d 73 67 29 20  b_size(&errmsg) 
52b0: 29 7b 0a 20 20 20 20 20 20 20 20 66 6f 73 73 69  ){.        fossi
52c0: 6c 5f 66 61 74 61 6c 28 22 25 62 22 2c 20 26 65  l_fatal("%b", &e
52d0: 72 72 6d 73 67 29 3b 0a 20 20 20 20 20 20 7d 0a  rrmsg);.      }.
52e0: 20 20 20 20 20 20 62 6c 6f 62 61 72 72 61 79 5f        blobarray_
52f0: 72 65 73 65 74 28 61 54 6f 6b 65 6e 2c 20 6e 54  reset(aToken, nT
5300: 6f 6b 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 20  oken);.    }.   
5310: 20 70 72 69 6e 74 66 28 22 52 65 63 65 69 76 65   printf("Receive
5320: 64 3a 20 20 25 33 64 20 66 69 6c 65 73 2c 20 25  d:  %3d files, %
5330: 33 64 20 72 65 71 75 65 73 74 73 2c 20 25 33 64  3d requests, %3d
5340: 20 6f 74 68 65 72 20 6d 73 67 73 2c 20 25 38 64   other msgs, %8d
5350: 20 62 79 74 65 73 5c 6e 22 2c 0a 20 20 20 20 20   bytes\n",.     
5360: 20 20 20 20 20 20 20 6e 46 69 6c 65 2c 20 6e 52         nFile, nR
5370: 65 71 2c 20 6e 4d 73 67 2c 20 62 6c 6f 62 5f 73  eq, nMsg, blob_s
5380: 69 7a 65 28 26 72 65 63 76 29 29 3b 0a 20 20 20  ize(&recv));.   
5390: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 72 65 63   blob_reset(&rec
53a0: 76 29 3b 0a 20 20 20 20 69 66 28 20 6e 46 69 6c  v);.    if( nFil
53b0: 65 53 65 6e 64 20 2b 20 6e 46 69 6c 65 3d 3d 30  eSend + nFile==0
53c0: 20 29 7b 0a 20 20 20 20 20 20 6e 4e 6f 46 69 6c   ){.      nNoFil
53d0: 65 43 79 63 6c 65 2b 2b 3b 0a 20 20 20 20 20 20  eCycle++;.      
53e0: 69 66 28 20 6e 4e 6f 46 69 6c 65 43 79 63 6c 65  if( nNoFileCycle
53f0: 3e 31 20 29 7b 0a 20 20 20 20 20 20 20 20 67 6f  >1 ){.        go
5400: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 0;.      }.  
5410: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e    }else{.      n
5420: 4e 6f 46 69 6c 65 43 79 63 6c 65 20 3d 20 30 3b  NoFileCycle = 0;
5430: 0a 20 20 20 20 7d 0a 20 20 20 20 6e 46 69 6c 65  .    }.    nFile
5440: 20 3d 20 6e 52 65 71 20 3d 20 6e 4d 73 67 20 3d   = nReq = nMsg =
5450: 20 30 3b 0a 20 20 7d 3b 0a 20 20 68 74 74 70 5f   0;.  };.  http_
5460: 63 6c 6f 73 65 28 29 3b 0a 20 20 64 62 5f 65 6e  close();.  db_en
5470: 64 5f 74 72 61 6e 73 61 63 74 69 6f 6e 28 30 29  d_transaction(0)
5480: 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65  ;.  db_multi_exe
5490: 63 28 0a 20 20 20 20 22 44 52 4f 50 20 54 41 42  c(.    "DROP TAB
54a0: 4c 45 20 6f 6e 72 65 6d 6f 74 65 3b 22 0a 20 20  LE onremote;".  
54b0: 20 20 22 44 52 4f 50 20 54 41 42 4c 45 20 70 65    "DROP TABLE pe
54c0: 6e 64 69 6e 67 3b 22 0a 20 20 29 3b 0a 7d 0a     nding;".  );.}.