Hex Artifact Content
Not logged in

Artifact cc749b7254e32e52f34eefc965e900c5f526e1ef:

File src/xfer.c part of check-in [ba837fd294] - Add randomness in the form of a comment to each sync protocol request. This will break older servers which do not understand comments. But comments have been understood by servers for months now, so hopefully everybody has upgraded. by drh on 2008-12-16 18:39:29.

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 68 69 73 20 73 74 72  ../*.** This str
03e0: 75 63 74 75 72 65 20 68 6f 6c 64 73 20 69 6e 66  ucture holds inf
03f0: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74  ormation about t
0400: 68 65 20 63 75 72 72 65 6e 74 20 73 74 61 74 65  he current state
0410: 20 6f 66 20 65 69 74 68 65 72 0a 2a 2a 20 61 20   of either.** a 
0420: 63 6c 69 65 6e 74 20 6f 72 20 61 20 73 65 72 76  client or a serv
0430: 65 72 20 74 68 61 74 20 69 73 20 70 61 72 74 69  er that is parti
0440: 63 69 70 61 74 69 6e 67 20 69 6e 20 78 66 65 72  cipating in xfer
0450: 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  ..*/.typedef str
0460: 75 63 74 20 58 66 65 72 20 58 66 65 72 3b 0a 73  uct Xfer Xfer;.s
0470: 74 72 75 63 74 20 58 66 65 72 20 7b 0a 20 20 42  truct Xfer {.  B
0480: 6c 6f 62 20 2a 70 49 6e 3b 20 20 20 20 20 20 20  lob *pIn;       
0490: 20 20 20 2f 2a 20 49 6e 70 75 74 20 74 65 78 74     /* Input text
04a0: 20 66 72 6f 6d 20 74 68 65 20 6f 74 68 65 72 20   from the other 
04b0: 73 69 64 65 20 2a 2f 0a 20 20 42 6c 6f 62 20 2a  side */.  Blob *
04c0: 70 4f 75 74 3b 20 20 20 20 20 20 20 20 20 2f 2a  pOut;         /*
04d0: 20 43 6f 6d 70 6f 73 65 20 6f 75 72 20 72 65 70   Compose our rep
04e0: 6c 79 20 68 65 72 65 20 2a 2f 0a 20 20 42 6c 6f  ly here */.  Blo
04f0: 62 20 6c 69 6e 65 3b 20 20 20 20 20 20 20 20 20  b line;         
0500: 20 2f 2a 20 54 68 65 20 63 75 72 72 65 6e 74 20   /* The current 
0510: 6c 69 6e 65 20 6f 66 20 69 6e 70 75 74 20 2a 2f  line of input */
0520: 0a 20 20 42 6c 6f 62 20 61 54 6f 6b 65 6e 5b 35  .  Blob aToken[5
0530: 5d 3b 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69  ];     /* Tokeni
0540: 7a 65 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 6c  zed version of l
0550: 69 6e 65 20 2a 2f 0a 20 20 42 6c 6f 62 20 65 72  ine */.  Blob er
0560: 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  r;           /* 
0570: 45 72 72 6f 72 20 6d 65 73 73 61 67 65 20 74 65  Error message te
0580: 78 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b  xt */.  int nTok
0590: 65 6e 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  en;         /* N
05a0: 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20  umber of tokens 
05b0: 69 6e 20 6c 69 6e 65 20 2a 2f 0a 20 20 69 6e 74  in line */.  int
05c0: 20 6e 49 47 6f 74 53 65 6e 74 3b 20 20 20 20 20   nIGotSent;     
05d0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 22 69   /* Number of "i
05e0: 67 6f 74 22 20 63 61 72 64 73 20 73 65 6e 74 20  got" cards sent 
05f0: 2a 2f 0a 20 20 69 6e 74 20 6e 47 69 6d 6d 65 53  */.  int nGimmeS
0600: 65 6e 74 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62  ent;     /* Numb
0610: 65 72 20 6f 66 20 67 69 6d 6d 65 20 63 61 72 64  er of gimme card
0620: 73 20 73 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20  s sent */.  int 
0630: 6e 46 69 6c 65 53 65 6e 74 3b 20 20 20 20 20 20  nFileSent;      
0640: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 66 69 6c  /* Number of fil
0650: 65 73 20 73 65 6e 74 20 2a 2f 0a 20 20 69 6e 74  es sent */.  int
0660: 20 6e 44 65 6c 74 61 53 65 6e 74 3b 20 20 20 20   nDeltaSent;    
0670: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 64 65   /* Number of de
0680: 6c 74 61 73 20 73 65 6e 74 20 2a 2f 0a 20 20 69  ltas sent */.  i
0690: 6e 74 20 6e 46 69 6c 65 52 63 76 64 3b 20 20 20  nt nFileRcvd;   
06a0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
06b0: 66 69 6c 65 73 20 72 65 63 65 69 76 65 64 20 2a  files received *
06c0: 2f 0a 20 20 69 6e 74 20 6e 44 65 6c 74 61 52 63  /.  int nDeltaRc
06d0: 76 64 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65  vd;     /* Numbe
06e0: 72 20 6f 66 20 64 65 6c 74 61 73 20 72 65 63 65  r of deltas rece
06f0: 69 76 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 44  ived */.  int nD
0700: 61 6e 67 6c 69 6e 67 46 69 6c 65 3b 20 20 2f 2a  anglingFile;  /*
0710: 20 4e 75 6d 62 65 72 20 6f 66 20 64 61 6e 67 6c   Number of dangl
0720: 69 6e 67 20 64 65 6c 74 61 73 20 72 65 63 65 69  ing deltas recei
0730: 76 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 53  ved */.  int mxS
0740: 65 6e 64 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  end;         /* 
0750: 53 74 6f 70 20 73 65 6e 64 69 6e 67 20 22 66 69  Stop sending "fi
0760: 6c 65 22 20 77 69 74 68 20 70 4f 75 74 20 72 65  le" with pOut re
0770: 61 63 68 65 73 20 74 68 69 73 20 73 69 7a 65 20  aches this size 
0780: 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68  */.};.../*.** Th
0790: 65 20 69 6e 70 75 74 20 62 6c 6f 62 20 63 6f 6e  e input blob con
07a0: 74 61 69 6e 73 20 61 20 55 55 49 44 2e 20 20 43  tains a UUID.  C
07b0: 6f 6e 76 65 72 74 20 69 74 20 69 6e 74 6f 20 61  onvert it into a
07c0: 20 72 65 63 6f 72 64 20 49 44 2e 0a 2a 2a 20 43   record ID..** C
07d0: 72 65 61 74 65 20 61 20 70 68 61 6e 74 6f 6d 20  reate a phantom 
07e0: 72 65 63 6f 72 64 20 69 66 20 6e 6f 20 70 72 69  record if no pri
07f0: 6f 72 20 72 65 63 6f 72 64 20 65 78 69 73 74 73  or record exists
0800: 20 61 6e 64 0a 2a 2a 20 70 68 61 6e 74 6f 6d 69   and.** phantomi
0810: 7a 65 20 69 73 20 74 72 75 65 2e 0a 2a 2a 0a 2a  ze is true..**.*
0820: 2a 20 43 6f 6d 70 61 72 65 20 74 6f 20 75 75 69  * Compare to uui
0830: 64 5f 74 6f 5f 72 69 64 28 29 2e 20 20 54 68 69  d_to_rid().  Thi
0840: 73 20 72 6f 75 74 69 6e 65 20 74 61 6b 65 73 20  s routine takes 
0850: 61 20 62 6c 6f 62 20 61 72 67 75 6d 65 6e 74 0a  a blob argument.
0860: 2a 2a 20 61 6e 64 20 64 6f 65 73 20 6c 65 73 73  ** and does less
0870: 20 65 72 72 6f 72 20 63 68 65 63 6b 69 6e 67 2e   error checking.
0880: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 72  .*/.static int r
0890: 69 64 5f 66 72 6f 6d 5f 75 75 69 64 28 42 6c 6f  id_from_uuid(Blo
08a0: 62 20 2a 70 55 75 69 64 2c 20 69 6e 74 20 70 68  b *pUuid, int ph
08b0: 61 6e 74 6f 6d 69 7a 65 29 7b 0a 20 20 73 74 61  antomize){.  sta
08c0: 74 69 63 20 53 74 6d 74 20 71 3b 0a 20 20 69 6e  tic Stmt q;.  in
08d0: 74 20 72 69 64 3b 0a 0a 20 20 64 62 5f 73 74 61  t rid;..  db_sta
08e0: 74 69 63 5f 70 72 65 70 61 72 65 28 26 71 2c 20  tic_prepare(&q, 
08f0: 22 53 45 4c 45 43 54 20 72 69 64 20 46 52 4f 4d  "SELECT rid FROM
0900: 20 62 6c 6f 62 20 57 48 45 52 45 20 75 75 69 64   blob WHERE uuid
0910: 3d 3a 75 75 69 64 22 29 3b 0a 20 20 64 62 5f 62  =:uuid");.  db_b
0920: 69 6e 64 5f 73 74 72 28 26 71 2c 20 22 3a 75 75  ind_str(&q, ":uu
0930: 69 64 22 2c 20 70 55 75 69 64 29 3b 0a 20 20 69  id", pUuid);.  i
0940: 66 28 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d  f( db_step(&q)==
0950: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
0960: 20 20 72 69 64 20 3d 20 64 62 5f 63 6f 6c 75 6d    rid = db_colum
0970: 6e 5f 69 6e 74 28 26 71 2c 20 30 29 3b 0a 20 20  n_int(&q, 0);.  
0980: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 69 64 20 3d  }else{.    rid =
0990: 20 30 3b 0a 20 20 7d 0a 20 20 64 62 5f 72 65 73   0;.  }.  db_res
09a0: 65 74 28 26 71 29 3b 0a 20 20 69 66 28 20 72 69  et(&q);.  if( ri
09b0: 64 3d 3d 30 20 26 26 20 70 68 61 6e 74 6f 6d 69  d==0 && phantomi
09c0: 7a 65 20 29 7b 0a 20 20 20 20 72 69 64 20 3d 20  ze ){.    rid = 
09d0: 63 6f 6e 74 65 6e 74 5f 6e 65 77 28 62 6c 6f 62  content_new(blob
09e0: 5f 73 74 72 28 70 55 75 69 64 29 29 3b 0a 20 20  _str(pUuid));.  
09f0: 7d 0a 20 20 72 65 74 75 72 6e 20 72 69 64 3b 0a  }.  return rid;.
0a00: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 65 6d 62 65  }../*.** Remembe
0a10: 72 20 74 68 61 74 20 74 68 65 20 6f 74 68 65 72  r that the other
0a20: 20 73 69 64 65 20 6f 66 20 74 68 65 20 63 6f 6e   side of the con
0a30: 6e 65 63 74 69 6f 6e 20 61 6c 72 65 61 64 79 20  nection already 
0a40: 68 61 73 20 61 20 63 6f 70 79 0a 2a 2a 20 6f 66  has a copy.** of
0a50: 20 74 68 65 20 66 69 6c 65 20 72 69 64 2e 0a 2a   the file rid..*
0a60: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 72 65  /.static void re
0a70: 6d 6f 74 65 5f 68 61 73 28 69 6e 74 20 72 69 64  mote_has(int rid
0a80: 29 7b 0a 20 20 69 66 28 20 72 69 64 20 29 20 64  ){.  if( rid ) d
0a90: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 22 49 4e  b_multi_exec("IN
0aa0: 53 45 52 54 20 4f 52 20 49 47 4e 4f 52 45 20 49  SERT OR IGNORE I
0ab0: 4e 54 4f 20 6f 6e 72 65 6d 6f 74 65 20 56 41 4c  NTO onremote VAL
0ac0: 55 45 53 28 25 64 29 22 2c 20 72 69 64 29 3b 0a  UES(%d)", rid);.
0ad0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 54 6f  }../*.** The aTo
0ae0: 6b 65 6e 5b 30 2e 2e 6e 54 6f 6b 65 6e 2d 31 5d  ken[0..nToken-1]
0af0: 20 62 6c 6f 62 20 61 72 72 61 79 20 69 73 20 61   blob array is a
0b00: 20 70 61 72 73 65 20 6f 66 20 61 20 22 66 69 6c   parse of a "fil
0b10: 65 22 20 6c 69 6e 65 20 0a 2a 2a 20 6d 65 73 73  e" line .** mess
0b20: 61 67 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69  age.  This routi
0b30: 6e 65 20 66 69 6e 69 73 68 65 73 20 70 61 72 73  ne finishes pars
0b40: 69 6e 67 20 74 68 61 74 20 6d 65 73 73 61 67 65  ing that message
0b50: 20 61 6e 64 20 64 6f 65 73 0a 2a 2a 20 61 20 72   and does.** a r
0b60: 65 63 6f 72 64 20 69 6e 73 65 72 74 20 6f 66 20  ecord insert of 
0b70: 74 68 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20  the file..**.** 
0b80: 54 68 65 20 66 69 6c 65 20 6c 69 6e 65 20 69 73  The file line is
0b90: 20 69 6e 20 6f 6e 65 20 6f 66 20 74 68 65 20 66   in one of the f
0ba0: 6f 6c 6c 6f 77 69 6e 67 20 74 77 6f 20 66 6f 72  ollowing two for
0bb0: 6d 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 66  ms:.**.**      f
0bc0: 69 6c 65 20 55 55 49 44 20 53 49 5a 45 20 5c 6e  ile UUID SIZE \n
0bd0: 20 43 4f 4e 54 45 4e 54 0a 2a 2a 20 20 20 20 20   CONTENT.**     
0be0: 20 66 69 6c 65 20 55 55 49 44 20 44 45 4c 54 41   file UUID DELTA
0bf0: 53 52 43 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54  SRC SIZE \n CONT
0c00: 45 4e 54 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f  ENT.**.** The co
0c10: 6e 74 65 6e 74 20 69 73 20 53 49 5a 45 20 62 79  ntent is SIZE by
0c20: 74 65 73 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  tes immediately 
0c30: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 6e 65  following the ne
0c40: 77 6c 69 6e 65 2e 0a 2a 2a 20 49 66 20 44 45 4c  wline..** If DEL
0c50: 54 41 53 52 43 20 65 78 69 73 74 73 2c 20 74 68  TASRC exists, th
0c60: 65 6e 20 74 68 65 20 43 4f 4e 54 45 4e 54 20 69  en the CONTENT i
0c70: 73 20 61 20 64 65 6c 74 61 20 61 67 61 69 6e 73  s a delta agains
0c80: 74 20 74 68 65 0a 2a 2a 20 63 6f 6e 74 65 6e 74  t the.** content
0c90: 20 6f 66 20 44 45 4c 54 41 53 52 43 2e 0a 2a 2a   of DELTASRC..**
0ca0: 0a 2a 2a 20 49 66 20 61 6e 79 20 65 72 72 6f 72  .** If any error
0cb0: 20 6f 63 63 75 72 73 2c 20 77 72 69 74 65 20 61   occurs, write a
0cc0: 20 6d 65 73 73 61 67 65 20 69 6e 74 6f 20 70 45   message into pE
0cd0: 72 72 20 77 68 69 63 68 20 68 61 73 20 61 6c 72  rr which has alr
0ce0: 65 61 64 79 0a 2a 2a 20 62 65 20 69 6e 69 74 69  eady.** be initi
0cf0: 61 6c 69 7a 65 64 20 74 6f 20 61 6e 20 65 6d 70  alized to an emp
0d00: 74 79 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74  ty string..*/.st
0d10: 61 74 69 63 20 76 6f 69 64 20 78 66 65 72 5f 61  atic void xfer_a
0d20: 63 63 65 70 74 5f 66 69 6c 65 28 58 66 65 72 20  ccept_file(Xfer 
0d30: 2a 70 58 66 65 72 29 7b 0a 20 20 69 6e 74 20 6e  *pXfer){.  int n
0d40: 3b 0a 20 20 69 6e 74 20 72 69 64 3b 0a 20 20 69  ;.  int rid;.  i
0d50: 6e 74 20 73 72 63 69 64 20 3d 20 30 3b 0a 20 20  nt srcid = 0;.  
0d60: 42 6c 6f 62 20 63 6f 6e 74 65 6e 74 2c 20 68 61  Blob content, ha
0d70: 73 68 3b 0a 20 20 0a 20 20 69 66 28 20 70 58 66  sh;.  .  if( pXf
0d80: 65 72 2d 3e 6e 54 6f 6b 65 6e 3c 33 20 0a 20 20  er->nToken<3 .  
0d90: 20 7c 7c 20 70 58 66 65 72 2d 3e 6e 54 6f 6b 65   || pXfer->nToke
0da0: 6e 3e 34 0a 20 20 20 7c 7c 20 21 62 6c 6f 62 5f  n>4.   || !blob_
0db0: 69 73 5f 75 75 69 64 28 26 70 58 66 65 72 2d 3e  is_uuid(&pXfer->
0dc0: 61 54 6f 6b 65 6e 5b 31 5d 29 0a 20 20 20 7c 7c  aToken[1]).   ||
0dd0: 20 21 62 6c 6f 62 5f 69 73 5f 69 6e 74 28 26 70   !blob_is_int(&p
0de0: 58 66 65 72 2d 3e 61 54 6f 6b 65 6e 5b 70 58 66  Xfer->aToken[pXf
0df0: 65 72 2d 3e 6e 54 6f 6b 65 6e 2d 31 5d 2c 20 26  er->nToken-1], &
0e00: 6e 29 0a 20 20 20 7c 7c 20 6e 3c 30 0a 20 20 20  n).   || n<0.   
0e10: 7c 7c 20 28 70 58 66 65 72 2d 3e 6e 54 6f 6b 65  || (pXfer->nToke
0e20: 6e 3d 3d 34 20 26 26 20 21 62 6c 6f 62 5f 69 73  n==4 && !blob_is
0e30: 5f 75 75 69 64 28 26 70 58 66 65 72 2d 3e 61 54  _uuid(&pXfer->aT
0e40: 6f 6b 65 6e 5b 32 5d 29 29 0a 20 20 29 7b 0a 20  oken[2])).  ){. 
0e50: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28     blob_appendf(
0e60: 26 70 58 66 65 72 2d 3e 65 72 72 2c 20 22 6d 61  &pXfer->err, "ma
0e70: 6c 66 6f 72 6d 65 64 20 66 69 6c 65 20 6c 69 6e  lformed file lin
0e80: 65 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b  e");.    return;
0e90: 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f  .  }.  blob_zero
0ea0: 28 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 62 6c  (&content);.  bl
0eb0: 6f 62 5f 7a 65 72 6f 28 26 68 61 73 68 29 3b 0a  ob_zero(&hash);.
0ec0: 20 20 62 6c 6f 62 5f 65 78 74 72 61 63 74 28 70    blob_extract(p
0ed0: 58 66 65 72 2d 3e 70 49 6e 2c 20 6e 2c 20 26 63  Xfer->pIn, n, &c
0ee0: 6f 6e 74 65 6e 74 29 3b 0a 20 20 69 66 28 20 75  ontent);.  if( u
0ef0: 75 69 64 5f 69 73 5f 73 68 75 6e 6e 65 64 28 62  uid_is_shunned(b
0f00: 6c 6f 62 5f 73 74 72 28 26 70 58 66 65 72 2d 3e  lob_str(&pXfer->
0f10: 61 54 6f 6b 65 6e 5b 31 5d 29 29 20 29 7b 0a 20  aToken[1])) ){. 
0f20: 20 20 20 2f 2a 20 49 67 6e 6f 72 65 20 66 69 6c     /* Ignore fil
0f30: 65 73 20 74 68 61 74 20 68 61 76 65 20 62 65 65  es that have bee
0f40: 6e 20 73 68 75 6e 6e 65 64 20 2a 2f 0a 20 20 20  n shunned */.   
0f50: 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 69   return;.  }.  i
0f60: 66 28 20 70 58 66 65 72 2d 3e 6e 54 6f 6b 65 6e  f( pXfer->nToken
0f70: 3d 3d 34 20 29 7b 0a 20 20 20 20 42 6c 6f 62 20  ==4 ){.    Blob 
0f80: 73 72 63 3b 0a 20 20 20 20 73 72 63 69 64 20 3d  src;.    srcid =
0f90: 20 72 69 64 5f 66 72 6f 6d 5f 75 75 69 64 28 26   rid_from_uuid(&
0fa0: 70 58 66 65 72 2d 3e 61 54 6f 6b 65 6e 5b 32 5d  pXfer->aToken[2]
0fb0: 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20 63 6f  , 1);.    if( co
0fc0: 6e 74 65 6e 74 5f 67 65 74 28 73 72 63 69 64 2c  ntent_get(srcid,
0fd0: 20 26 73 72 63 29 3d 3d 30 20 29 7b 0a 20 20 20   &src)==0 ){.   
0fe0: 20 20 20 63 6f 6e 74 65 6e 74 5f 70 75 74 28 26     content_put(&
0ff0: 63 6f 6e 74 65 6e 74 2c 20 62 6c 6f 62 5f 73 74  content, blob_st
1000: 72 28 26 70 58 66 65 72 2d 3e 61 54 6f 6b 65 6e  r(&pXfer->aToken
1010: 5b 31 5d 29 2c 20 73 72 63 69 64 29 3b 0a 20 20  [1]), srcid);.  
1020: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
1030: 28 70 58 66 65 72 2d 3e 70 4f 75 74 2c 20 22 67  (pXfer->pOut, "g
1040: 69 6d 6d 65 20 25 62 5c 6e 22 2c 20 26 70 58 66  imme %b\n", &pXf
1050: 65 72 2d 3e 61 54 6f 6b 65 6e 5b 32 5d 29 3b 0a  er->aToken[2]);.
1060: 20 20 20 20 20 20 70 58 66 65 72 2d 3e 6e 47 69        pXfer->nGi
1070: 6d 6d 65 53 65 6e 74 2b 2b 3b 0a 20 20 20 20 20  mmeSent++;.     
1080: 20 70 58 66 65 72 2d 3e 6e 44 61 6e 67 6c 69 6e   pXfer->nDanglin
1090: 67 46 69 6c 65 2b 2b 3b 0a 20 20 20 20 20 20 72  gFile++;.      r
10a0: 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20  eturn;.    }.   
10b0: 20 70 58 66 65 72 2d 3e 6e 44 65 6c 74 61 52 63   pXfer->nDeltaRc
10c0: 76 64 2b 2b 3b 0a 20 20 20 20 62 6c 6f 62 5f 64  vd++;.    blob_d
10d0: 65 6c 74 61 5f 61 70 70 6c 79 28 26 73 72 63 2c  elta_apply(&src,
10e0: 20 26 63 6f 6e 74 65 6e 74 2c 20 26 63 6f 6e 74   &content, &cont
10f0: 65 6e 74 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  ent);.    blob_r
1100: 65 73 65 74 28 26 73 72 63 29 3b 0a 20 20 7d 65  eset(&src);.  }e
1110: 6c 73 65 7b 0a 20 20 20 20 70 58 66 65 72 2d 3e  lse{.    pXfer->
1120: 6e 46 69 6c 65 52 63 76 64 2b 2b 3b 0a 20 20 7d  nFileRcvd++;.  }
1130: 0a 20 20 73 68 61 31 73 75 6d 5f 62 6c 6f 62 28  .  sha1sum_blob(
1140: 26 63 6f 6e 74 65 6e 74 2c 20 26 68 61 73 68 29  &content, &hash)
1150: 3b 0a 20 20 69 66 28 20 21 62 6c 6f 62 5f 65 71  ;.  if( !blob_eq
1160: 5f 73 74 72 28 26 70 58 66 65 72 2d 3e 61 54 6f  _str(&pXfer->aTo
1170: 6b 65 6e 5b 31 5d 2c 20 62 6c 6f 62 5f 73 74 72  ken[1], blob_str
1180: 28 26 68 61 73 68 29 2c 20 2d 31 29 20 29 7b 0a  (&hash), -1) ){.
1190: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
11a0: 28 26 70 58 66 65 72 2d 3e 65 72 72 2c 20 22 63  (&pXfer->err, "c
11b0: 6f 6e 74 65 6e 74 20 64 6f 65 73 20 6e 6f 74 20  ontent does not 
11c0: 6d 61 74 63 68 20 73 68 61 31 20 68 61 73 68 22  match sha1 hash"
11d0: 29 3b 0a 20 20 7d 0a 20 20 72 69 64 20 3d 20 63  );.  }.  rid = c
11e0: 6f 6e 74 65 6e 74 5f 70 75 74 28 26 63 6f 6e 74  ontent_put(&cont
11f0: 65 6e 74 2c 20 62 6c 6f 62 5f 73 74 72 28 26 68  ent, blob_str(&h
1200: 61 73 68 29 2c 20 30 29 3b 0a 20 20 62 6c 6f 62  ash), 0);.  blob
1210: 5f 72 65 73 65 74 28 26 68 61 73 68 29 3b 0a 20  _reset(&hash);. 
1220: 20 69 66 28 20 72 69 64 3d 3d 30 20 29 7b 0a 20   if( rid==0 ){. 
1230: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28     blob_appendf(
1240: 26 70 58 66 65 72 2d 3e 65 72 72 2c 20 22 25 73  &pXfer->err, "%s
1250: 22 2c 20 67 2e 7a 45 72 72 4d 73 67 29 3b 0a 20  ", g.zErrMsg);. 
1260: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 64   }else{.    /* d
1270: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 22 44 45  b_multi_exec("DE
1280: 4c 45 54 45 20 46 52 4f 4d 20 70 68 61 6e 74 6f  LETE FROM phanto
1290: 6d 20 57 48 45 52 45 20 72 69 64 3d 25 64 22 2c  m WHERE rid=%d",
12a0: 20 72 69 64 29 3b 20 2a 2f 0a 20 20 20 20 6d 61   rid); */.    ma
12b0: 6e 69 66 65 73 74 5f 63 72 6f 73 73 6c 69 6e 6b  nifest_crosslink
12c0: 28 72 69 64 2c 20 26 63 6f 6e 74 65 6e 74 29 3b  (rid, &content);
12d0: 0a 20 20 7d 0a 20 20 72 65 6d 6f 74 65 5f 68 61  .  }.  remote_ha
12e0: 73 28 72 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  s(rid);.}../*.**
12f0: 20 54 72 79 20 74 6f 20 73 65 6e 64 20 61 20 66   Try to send a f
1300: 69 6c 65 20 61 73 20 61 20 64 65 6c 74 61 20 61  ile as a delta a
1310: 67 61 69 6e 73 74 20 69 74 73 20 70 61 72 65 6e  gainst its paren
1320: 74 2e 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  t..** If success
1330: 66 75 6c 2c 20 72 65 74 75 72 6e 20 74 68 65 20  ful, return the 
1340: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
1350: 69 6e 20 74 68 65 20 64 65 6c 74 61 2e 0a 2a 2a  in the delta..**
1360: 20 49 66 20 77 65 20 63 61 6e 6e 6f 74 20 67 65   If we cannot ge
1370: 6e 65 72 61 74 65 20 61 6e 20 61 70 70 72 6f 70  nerate an approp
1380: 72 69 61 74 65 20 64 65 6c 74 61 2c 20 74 68 65  riate delta, the
1390: 6e 20 73 65 6e 64 0a 2a 2a 20 6e 6f 74 68 69 6e  n send.** nothin
13a0: 67 20 61 6e 64 20 72 65 74 75 72 6e 20 7a 65 72  g and return zer
13b0: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  o..*/.static int
13c0: 20 73 65 6e 64 5f 64 65 6c 74 61 5f 70 61 72 65   send_delta_pare
13d0: 6e 74 28 0a 20 20 58 66 65 72 20 2a 70 58 66 65  nt(.  Xfer *pXfe
13e0: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  r,            /*
13f0: 20 54 68 65 20 74 72 61 6e 73 66 65 72 20 63 6f   The transfer co
1400: 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 72  ntext */.  int r
1410: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  id,             
1420: 20 20 20 2f 2a 20 72 65 63 6f 72 64 20 69 64 20     /* record id 
1430: 6f 66 20 74 68 65 20 66 69 6c 65 20 74 6f 20 73  of the file to s
1440: 65 6e 64 20 2a 2f 0a 20 20 42 6c 6f 62 20 2a 70  end */.  Blob *p
1450: 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20  Content,        
1460: 20 2f 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 20   /* The content 
1470: 6f 66 20 74 68 65 20 66 69 6c 65 20 74 6f 20 73  of the file to s
1480: 65 6e 64 20 2a 2f 0a 20 20 42 6c 6f 62 20 2a 70  end */.  Blob *p
1490: 55 75 69 64 20 20 20 20 20 20 20 20 20 20 20 20  Uuid            
14a0: 20 2f 2a 20 54 68 65 20 55 55 49 44 20 6f 66 20   /* The UUID of 
14b0: 74 68 65 20 66 69 6c 65 20 74 6f 20 73 65 6e 64  the file to send
14c0: 20 2a 2f 0a 29 7b 0a 20 20 73 74 61 74 69 63 20   */.){.  static 
14d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a 51 75  const char *azQu
14e0: 65 72 79 5b 5d 20 3d 20 7b 0a 20 20 20 20 22 53  ery[] = {.    "S
14f0: 45 4c 45 43 54 20 70 69 64 20 46 52 4f 4d 20 70  ELECT pid FROM p
1500: 6c 69 6e 6b 20 78 22 0a 20 20 20 20 22 20 57 48  link x".    " WH
1510: 45 52 45 20 63 69 64 3d 25 64 22 0a 20 20 20 20  ERE cid=%d".    
1520: 22 20 20 20 41 4e 44 20 4e 4f 54 20 45 58 49 53  "   AND NOT EXIS
1530: 54 53 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d  TS(SELECT 1 FROM
1540: 20 70 68 61 6e 74 6f 6d 20 57 48 45 52 45 20 72   phantom WHERE r
1550: 69 64 3d 70 69 64 29 22 0a 20 20 20 20 22 20 20  id=pid)".    "  
1560: 20 41 4e 44 20 4e 4f 54 20 45 58 49 53 54 53 28   AND NOT EXISTS(
1570: 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20 70 6c  SELECT 1 FROM pl
1580: 69 6e 6b 20 79 22 0a 20 20 20 20 20 20 20 20 20  ink y".         
1590: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 20 57               " W
15a0: 48 45 52 45 20 79 2e 70 69 64 3d 78 2e 63 69 64  HERE y.pid=x.cid
15b0: 20 41 4e 44 20 79 2e 63 69 64 3d 78 2e 70 69 64   AND y.cid=x.pid
15c0: 29 22 2c 0a 0a 20 20 20 20 22 53 45 4c 45 43 54  )",..    "SELECT
15d0: 20 70 69 64 20 46 52 4f 4d 20 6d 6c 69 6e 6b 20   pid FROM mlink 
15e0: 78 22 0a 20 20 20 20 22 20 57 48 45 52 45 20 66  x".    " WHERE f
15f0: 69 64 3d 25 64 22 0a 20 20 20 20 22 20 20 20 41  id=%d".    "   A
1600: 4e 44 20 4e 4f 54 20 45 58 49 53 54 53 28 53 45  ND NOT EXISTS(SE
1610: 4c 45 43 54 20 31 20 46 52 4f 4d 20 70 68 61 6e  LECT 1 FROM phan
1620: 74 6f 6d 20 57 48 45 52 45 20 72 69 64 3d 70 69  tom WHERE rid=pi
1630: 64 29 22 0a 20 20 20 20 22 20 20 20 41 4e 44 20  d)".    "   AND 
1640: 4e 4f 54 20 45 58 49 53 54 53 28 53 45 4c 45 43  NOT EXISTS(SELEC
1650: 54 20 31 20 46 52 4f 4d 20 6d 6c 69 6e 6b 20 79  T 1 FROM mlink y
1660: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
1670: 20 20 20 20 20 20 20 22 20 20 57 48 45 52 45 20         "  WHERE 
1680: 79 2e 70 69 64 3d 78 2e 66 69 64 20 41 4e 44 20  y.pid=x.fid AND 
1690: 79 2e 66 69 64 3d 78 2e 70 69 64 29 22 0a 20 20  y.fid=x.pid)".  
16a0: 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 42 6c  };.  int i;.  Bl
16b0: 6f 62 20 73 72 63 2c 20 64 65 6c 74 61 3b 0a 20  ob src, delta;. 
16c0: 20 69 6e 74 20 73 69 7a 65 20 3d 20 30 3b 0a 20   int size = 0;. 
16d0: 20 69 6e 74 20 73 72 63 49 64 20 3d 20 30 3b 0a   int srcId = 0;.
16e0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 73 72 63 49  .  for(i=0; srcI
16f0: 64 3d 3d 30 20 26 26 20 69 3c 63 6f 75 6e 74 28  d==0 && i<count(
1700: 61 7a 51 75 65 72 79 29 3b 20 69 2b 2b 29 7b 0a  azQuery); i++){.
1710: 20 20 20 20 73 72 63 49 64 20 3d 20 64 62 5f 69      srcId = db_i
1720: 6e 74 28 30 2c 20 61 7a 51 75 65 72 79 5b 69 5d  nt(0, azQuery[i]
1730: 2c 20 72 69 64 29 3b 0a 20 20 7d 0a 20 20 69 66  , rid);.  }.  if
1740: 28 20 73 72 63 49 64 3e 30 20 26 26 20 63 6f 6e  ( srcId>0 && con
1750: 74 65 6e 74 5f 67 65 74 28 73 72 63 49 64 2c 20  tent_get(srcId, 
1760: 26 73 72 63 29 20 29 7b 0a 20 20 20 20 63 68 61  &src) ){.    cha
1770: 72 20 2a 7a 55 75 69 64 20 3d 20 64 62 5f 74 65  r *zUuid = db_te
1780: 78 74 28 30 2c 20 22 53 45 4c 45 43 54 20 75 75  xt(0, "SELECT uu
1790: 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48 45  id FROM blob WHE
17a0: 52 45 20 72 69 64 3d 25 64 22 2c 20 73 72 63 49  RE rid=%d", srcI
17b0: 64 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 64 65 6c  d);.    blob_del
17c0: 74 61 5f 63 72 65 61 74 65 28 26 73 72 63 2c 20  ta_create(&src, 
17d0: 70 43 6f 6e 74 65 6e 74 2c 20 26 64 65 6c 74 61  pContent, &delta
17e0: 29 3b 0a 20 20 20 20 73 69 7a 65 20 3d 20 62 6c  );.    size = bl
17f0: 6f 62 5f 73 69 7a 65 28 26 64 65 6c 74 61 29 3b  ob_size(&delta);
1800: 0a 20 20 20 20 69 66 28 20 73 69 7a 65 3e 3d 62  .    if( size>=b
1810: 6c 6f 62 5f 73 69 7a 65 28 70 43 6f 6e 74 65 6e  lob_size(pConten
1820: 74 29 2d 35 30 20 29 7b 0a 20 20 20 20 20 20 73  t)-50 ){.      s
1830: 69 7a 65 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  ize = 0;.    }el
1840: 73 65 20 69 66 28 20 75 75 69 64 5f 69 73 5f 73  se if( uuid_is_s
1850: 68 75 6e 6e 65 64 28 7a 55 75 69 64 29 20 29 7b  hunned(zUuid) ){
1860: 0a 20 20 20 20 20 20 73 69 7a 65 20 3d 20 30 3b  .      size = 0;
1870: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
1880: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70    blob_appendf(p
1890: 58 66 65 72 2d 3e 70 4f 75 74 2c 20 22 66 69 6c  Xfer->pOut, "fil
18a0: 65 20 25 62 20 25 73 20 25 64 5c 6e 22 2c 20 70  e %b %s %d\n", p
18b0: 55 75 69 64 2c 20 7a 55 75 69 64 2c 20 73 69 7a  Uuid, zUuid, siz
18c0: 65 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61  e);.      blob_a
18d0: 70 70 65 6e 64 28 70 58 66 65 72 2d 3e 70 4f 75  ppend(pXfer->pOu
18e0: 74 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  t, blob_buffer(&
18f0: 64 65 6c 74 61 29 2c 20 73 69 7a 65 29 3b 0a 20  delta), size);. 
1900: 20 20 20 20 20 2f 2a 20 62 6c 6f 62 5f 61 70 70       /* blob_app
1910: 65 6e 64 66 28 70 58 66 65 72 2d 3e 70 4f 75 74  endf(pXfer->pOut
1920: 2c 20 22 5c 6e 22 2c 20 31 29 3b 20 2a 2f 0a 20  , "\n", 1); */. 
1930: 20 20 20 7d 0a 20 20 20 20 62 6c 6f 62 5f 72 65     }.    blob_re
1940: 73 65 74 28 26 64 65 6c 74 61 29 3b 0a 20 20 20  set(&delta);.   
1950: 20 66 72 65 65 28 7a 55 75 69 64 29 3b 0a 20 20   free(zUuid);.  
1960: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 73 72    blob_reset(&sr
1970: 63 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  c);.  }.  return
1980: 20 73 69 7a 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   size;.}../*.** 
1990: 54 72 79 20 74 6f 20 73 65 6e 64 20 61 20 66 69  Try to send a fi
19a0: 6c 65 20 61 73 20 61 20 6e 61 74 69 76 65 20 64  le as a native d
19b0: 65 6c 74 61 2e 20 20 0a 2a 2a 20 49 66 20 73 75  elta.  .** If su
19c0: 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75 72 6e  ccessful, return
19d0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
19e0: 79 74 65 73 20 69 6e 20 74 68 65 20 64 65 6c 74  ytes in the delt
19f0: 61 2e 0a 2a 2a 20 49 66 20 77 65 20 63 61 6e 6e  a..** If we cann
1a00: 6f 74 20 67 65 6e 65 72 61 74 65 20 61 6e 20 61  ot generate an a
1a10: 70 70 72 6f 70 72 69 61 74 65 20 64 65 6c 74 61  ppropriate delta
1a20: 2c 20 74 68 65 6e 20 73 65 6e 64 0a 2a 2a 20 6e  , then send.** n
1a30: 6f 74 68 69 6e 67 20 61 6e 64 20 72 65 74 75 72  othing and retur
1a40: 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69  n zero..*/.stati
1a50: 63 20 69 6e 74 20 73 65 6e 64 5f 64 65 6c 74 61  c int send_delta
1a60: 5f 6e 61 74 69 76 65 28 0a 20 20 58 66 65 72 20  _native(.  Xfer 
1a70: 2a 70 58 66 65 72 2c 20 20 20 20 20 20 20 20 20  *pXfer,         
1a80: 20 20 20 2f 2a 20 54 68 65 20 74 72 61 6e 73 66     /* The transf
1a90: 65 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20  er context */.  
1aa0: 69 6e 74 20 72 69 64 2c 20 20 20 20 20 20 20 20  int rid,        
1ab0: 20 20 20 20 20 20 20 20 2f 2a 20 72 65 63 6f 72          /* recor
1ac0: 64 20 69 64 20 6f 66 20 74 68 65 20 66 69 6c 65  d id of the file
1ad0: 20 74 6f 20 73 65 6e 64 20 2a 2f 0a 20 20 42 6c   to send */.  Bl
1ae0: 6f 62 20 2a 70 55 75 69 64 20 20 20 20 20 20 20  ob *pUuid       
1af0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 55 55 49        /* The UUI
1b00: 44 20 6f 66 20 74 68 65 20 66 69 6c 65 20 74 6f  D of the file to
1b10: 20 73 65 6e 64 20 2a 2f 0a 29 7b 0a 20 20 42 6c   send */.){.  Bl
1b20: 6f 62 20 73 72 63 2c 20 64 65 6c 74 61 3b 0a 20  ob src, delta;. 
1b30: 20 69 6e 74 20 73 69 7a 65 20 3d 20 30 3b 0a 20   int size = 0;. 
1b40: 20 69 6e 74 20 73 72 63 49 64 3b 0a 0a 20 20 73   int srcId;..  s
1b50: 72 63 49 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c  rcId = db_int(0,
1b60: 20 22 53 45 4c 45 43 54 20 73 72 63 69 64 20 46   "SELECT srcid F
1b70: 52 4f 4d 20 64 65 6c 74 61 20 57 48 45 52 45 20  ROM delta WHERE 
1b80: 72 69 64 3d 25 64 22 2c 20 72 69 64 29 3b 0a 20  rid=%d", rid);. 
1b90: 20 69 66 28 20 73 72 63 49 64 3e 30 20 29 7b 0a   if( srcId>0 ){.
1ba0: 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 73      blob_zero(&s
1bb0: 72 63 29 3b 0a 20 20 20 20 64 62 5f 62 6c 6f 62  rc);.    db_blob
1bc0: 28 26 73 72 63 2c 20 22 53 45 4c 45 43 54 20 75  (&src, "SELECT u
1bd0: 75 69 64 20 46 52 4f 4d 20 62 6c 6f 62 20 57 48  uid FROM blob WH
1be0: 45 52 45 20 72 69 64 3d 25 64 22 2c 20 73 72 63  ERE rid=%d", src
1bf0: 49 64 29 3b 0a 20 20 20 20 69 66 28 20 75 75 69  Id);.    if( uui
1c00: 64 5f 69 73 5f 73 68 75 6e 6e 65 64 28 62 6c 6f  d_is_shunned(blo
1c10: 62 5f 73 74 72 28 26 73 72 63 29 29 20 29 7b 0a  b_str(&src)) ){.
1c20: 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74        blob_reset
1c30: 28 26 73 72 63 29 3b 0a 20 20 20 20 20 20 72 65  (&src);.      re
1c40: 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20  turn 0;.    }.  
1c50: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 64 65 6c    blob_zero(&del
1c60: 74 61 29 3b 0a 20 20 20 20 64 62 5f 62 6c 6f 62  ta);.    db_blob
1c70: 28 26 64 65 6c 74 61 2c 20 22 53 45 4c 45 43 54  (&delta, "SELECT
1c80: 20 63 6f 6e 74 65 6e 74 20 46 52 4f 4d 20 62 6c   content FROM bl
1c90: 6f 62 20 57 48 45 52 45 20 72 69 64 3d 25 64 22  ob WHERE rid=%d"
1ca0: 2c 20 72 69 64 29 3b 0a 20 20 20 20 62 6c 6f 62  , rid);.    blob
1cb0: 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 64 65 6c  _uncompress(&del
1cc0: 74 61 2c 20 26 64 65 6c 74 61 29 3b 0a 20 20 20  ta, &delta);.   
1cd0: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 70 58   blob_appendf(pX
1ce0: 66 65 72 2d 3e 70 4f 75 74 2c 20 22 66 69 6c 65  fer->pOut, "file
1cf0: 20 25 62 20 25 62 20 25 64 5c 6e 22 2c 0a 20 20   %b %b %d\n",.  
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 55                pU
1d10: 75 69 64 2c 20 26 73 72 63 2c 20 62 6c 6f 62 5f  uid, &src, blob_
1d20: 73 69 7a 65 28 26 64 65 6c 74 61 29 29 3b 0a 20  size(&delta));. 
1d30: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70     blob_append(p
1d40: 58 66 65 72 2d 3e 70 4f 75 74 2c 20 62 6c 6f 62  Xfer->pOut, blob
1d50: 5f 62 75 66 66 65 72 28 26 64 65 6c 74 61 29 2c  _buffer(&delta),
1d60: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 64 65 6c 74   blob_size(&delt
1d70: 61 29 29 3b 0a 20 20 20 20 73 69 7a 65 20 3d 20  a));.    size = 
1d80: 62 6c 6f 62 5f 73 69 7a 65 28 26 64 65 6c 74 61  blob_size(&delta
1d90: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
1da0: 74 28 26 64 65 6c 74 61 29 3b 0a 20 20 20 20 62  t(&delta);.    b
1db0: 6c 6f 62 5f 72 65 73 65 74 28 26 73 72 63 29 3b  lob_reset(&src);
1dc0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 69  .  }else{.    si
1dd0: 7a 65 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65  ze = 0;.  }.  re
1de0: 74 75 72 6e 20 73 69 7a 65 3b 0a 7d 0a 0a 2f 2a  turn size;.}../*
1df0: 0a 2a 2a 20 53 65 6e 64 20 74 68 65 20 66 69 6c  .** Send the fil
1e00: 65 20 69 64 65 6e 74 69 66 69 65 64 20 62 79 20  e identified by 
1e10: 72 69 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70  rid..**.** The p
1e20: 55 75 69 64 20 63 61 6e 20 62 65 20 4e 55 4c 4c  Uuid can be NULL
1e30: 20 69 6e 20 77 68 69 63 68 20 63 61 73 65 20 74   in which case t
1e40: 68 65 20 63 6f 72 72 65 63 74 20 55 55 49 44 20  he correct UUID 
1e50: 69 73 20 63 6f 6d 70 75 74 65 64 0a 2a 2a 20 66  is computed.** f
1e60: 72 6f 6d 20 74 68 65 20 72 69 64 2e 0a 2a 2a 0a  rom the rid..**.
1e70: 2a 2a 20 54 72 79 20 74 6f 20 73 65 6e 64 20 74  ** Try to send t
1e80: 68 65 20 66 69 6c 65 20 61 73 20 61 20 6e 61 74  he file as a nat
1e90: 69 76 65 20 64 65 6c 74 61 20 69 66 20 6e 61 74  ive delta if nat
1ea0: 69 76 65 44 65 6c 74 61 20 69 73 20 74 72 75 65  iveDelta is true
1eb0: 2c 20 6f 72 0a 2a 2a 20 61 73 20 61 20 70 61 72  , or.** as a par
1ec0: 65 6e 74 20 64 65 6c 74 61 20 69 66 20 6e 61 74  ent delta if nat
1ed0: 69 76 65 44 65 6c 74 61 20 69 73 20 66 61 6c 73  iveDelta is fals
1ee0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
1ef0: 64 20 73 65 6e 64 5f 66 69 6c 65 28 58 66 65 72  d send_file(Xfer
1f00: 20 2a 70 58 66 65 72 2c 20 69 6e 74 20 72 69 64   *pXfer, int rid
1f10: 2c 20 42 6c 6f 62 20 2a 70 55 75 69 64 2c 20 69  , Blob *pUuid, i
1f20: 6e 74 20 6e 61 74 69 76 65 44 65 6c 74 61 29 7b  nt nativeDelta){
1f30: 0a 20 20 42 6c 6f 62 20 63 6f 6e 74 65 6e 74 2c  .  Blob content,
1f40: 20 75 75 69 64 3b 0a 20 20 69 6e 74 20 73 69 7a   uuid;.  int siz
1f50: 65 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 64 62  e = 0;..  if( db
1f60: 5f 65 78 69 73 74 73 28 22 53 45 4c 45 43 54 20  _exists("SELECT 
1f70: 31 20 46 52 4f 4d 20 6f 6e 72 65 6d 6f 74 65 20  1 FROM onremote 
1f80: 57 48 45 52 45 20 72 69 64 3d 25 64 22 2c 20 72  WHERE rid=%d", r
1f90: 69 64 29 20 29 7b 0a 20 20 20 20 20 72 65 74 75  id) ){.     retu
1fa0: 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f 7a  rn;.  }.  blob_z
1fb0: 65 72 6f 28 26 75 75 69 64 29 3b 0a 20 20 64 62  ero(&uuid);.  db
1fc0: 5f 62 6c 6f 62 28 26 75 75 69 64 2c 20 22 53 45  _blob(&uuid, "SE
1fd0: 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d 20 62  LECT uuid FROM b
1fe0: 6c 6f 62 20 57 48 45 52 45 20 72 69 64 3d 25 64  lob WHERE rid=%d
1ff0: 20 41 4e 44 20 73 69 7a 65 3e 3d 30 22 2c 20 72   AND size>=0", r
2000: 69 64 29 3b 0a 20 20 69 66 28 20 62 6c 6f 62 5f  id);.  if( blob_
2010: 73 69 7a 65 28 26 75 75 69 64 29 3d 3d 30 20 29  size(&uuid)==0 )
2020: 7b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20  {.    return;.  
2030: 7d 0a 20 20 69 66 28 20 70 55 75 69 64 20 29 7b  }.  if( pUuid ){
2040: 0a 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 63 6f  .    if( blob_co
2050: 6d 70 61 72 65 28 70 55 75 69 64 2c 20 26 75 75  mpare(pUuid, &uu
2060: 69 64 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  id)!=0 ){.      
2070: 62 6c 6f 62 5f 72 65 73 65 74 28 26 75 75 69 64  blob_reset(&uuid
2080: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 3b  );.      return;
2090: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
20a0: 20 20 20 20 70 55 75 69 64 20 3d 20 26 75 75 69      pUuid = &uui
20b0: 64 3b 0a 20 20 7d 0a 20 20 69 66 28 20 75 75 69  d;.  }.  if( uui
20c0: 64 5f 69 73 5f 73 68 75 6e 6e 65 64 28 62 6c 6f  d_is_shunned(blo
20d0: 62 5f 73 74 72 28 70 55 75 69 64 29 29 20 29 7b  b_str(pUuid)) ){
20e0: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  .    blob_reset(
20f0: 26 75 75 69 64 29 3b 0a 20 20 20 20 72 65 74 75  &uuid);.    retu
2100: 72 6e 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 58  rn;.  }.  if( pX
2110: 66 65 72 2d 3e 6d 78 53 65 6e 64 3c 3d 62 6c 6f  fer->mxSend<=blo
2120: 62 5f 73 69 7a 65 28 70 58 66 65 72 2d 3e 70 4f  b_size(pXfer->pO
2130: 75 74 29 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f  ut) ){.    blob_
2140: 61 70 70 65 6e 64 66 28 70 58 66 65 72 2d 3e 70  appendf(pXfer->p
2150: 4f 75 74 2c 20 22 69 67 6f 74 20 25 62 5c 6e 22  Out, "igot %b\n"
2160: 2c 20 70 55 75 69 64 29 3b 0a 20 20 20 20 70 58  , pUuid);.    pX
2170: 66 65 72 2d 3e 6e 49 47 6f 74 53 65 6e 74 2b 2b  fer->nIGotSent++
2180: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74  ;.    blob_reset
2190: 28 26 75 75 69 64 29 3b 0a 20 20 20 20 72 65 74  (&uuid);.    ret
21a0: 75 72 6e 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6e  urn;.  }.  if( n
21b0: 61 74 69 76 65 44 65 6c 74 61 20 29 7b 0a 20 20  ativeDelta ){.  
21c0: 20 20 73 69 7a 65 20 3d 20 73 65 6e 64 5f 64 65    size = send_de
21d0: 6c 74 61 5f 6e 61 74 69 76 65 28 70 58 66 65 72  lta_native(pXfer
21e0: 2c 20 72 69 64 2c 20 70 55 75 69 64 29 3b 0a 20  , rid, pUuid);. 
21f0: 20 20 20 69 66 28 20 73 69 7a 65 20 29 7b 0a 20     if( size ){. 
2200: 20 20 20 20 20 70 58 66 65 72 2d 3e 6e 44 65 6c       pXfer->nDel
2210: 74 61 53 65 6e 74 2b 2b 3b 0a 20 20 20 20 7d 0a  taSent++;.    }.
2220: 20 20 7d 0a 20 20 69 66 28 20 73 69 7a 65 3d 3d    }.  if( size==
2230: 30 20 29 7b 0a 20 20 20 20 63 6f 6e 74 65 6e 74  0 ){.    content
2240: 5f 67 65 74 28 72 69 64 2c 20 26 63 6f 6e 74 65  _get(rid, &conte
2250: 6e 74 29 3b 0a 0a 20 20 20 20 69 66 28 20 21 6e  nt);..    if( !n
2260: 61 74 69 76 65 44 65 6c 74 61 20 26 26 20 62 6c  ativeDelta && bl
2270: 6f 62 5f 73 69 7a 65 28 26 63 6f 6e 74 65 6e 74  ob_size(&content
2280: 29 3e 31 30 30 20 29 7b 0a 20 20 20 20 20 20 73  )>100 ){.      s
2290: 69 7a 65 20 3d 20 73 65 6e 64 5f 64 65 6c 74 61  ize = send_delta
22a0: 5f 70 61 72 65 6e 74 28 70 58 66 65 72 2c 20 72  _parent(pXfer, r
22b0: 69 64 2c 20 26 63 6f 6e 74 65 6e 74 2c 20 70 55  id, &content, pU
22c0: 75 69 64 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  uid);.    }.    
22d0: 69 66 28 20 73 69 7a 65 3d 3d 30 20 29 7b 0a 20  if( size==0 ){. 
22e0: 20 20 20 20 20 69 6e 74 20 73 69 7a 65 20 3d 20       int size = 
22f0: 62 6c 6f 62 5f 73 69 7a 65 28 26 63 6f 6e 74 65  blob_size(&conte
2300: 6e 74 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f  nt);.      blob_
2310: 61 70 70 65 6e 64 66 28 70 58 66 65 72 2d 3e 70  appendf(pXfer->p
2320: 4f 75 74 2c 20 22 66 69 6c 65 20 25 62 20 25 64  Out, "file %b %d
2330: 5c 6e 22 2c 20 70 55 75 69 64 2c 20 73 69 7a 65  \n", pUuid, size
2340: 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70  );.      blob_ap
2350: 70 65 6e 64 28 70 58 66 65 72 2d 3e 70 4f 75 74  pend(pXfer->pOut
2360: 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63  , blob_buffer(&c
2370: 6f 6e 74 65 6e 74 29 2c 20 73 69 7a 65 29 3b 0a  ontent), size);.
2380: 20 20 20 20 20 20 70 58 66 65 72 2d 3e 6e 46 69        pXfer->nFi
2390: 6c 65 53 65 6e 74 2b 2b 3b 0a 20 20 20 20 7d 65  leSent++;.    }e
23a0: 6c 73 65 7b 0a 20 20 20 20 20 20 70 58 66 65 72  lse{.      pXfer
23b0: 2d 3e 6e 44 65 6c 74 61 53 65 6e 74 2b 2b 3b 0a  ->nDeltaSent++;.
23c0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 6d 6f      }.  }.  remo
23d0: 74 65 5f 68 61 73 28 72 69 64 29 3b 0a 20 20 62  te_has(rid);.  b
23e0: 6c 6f 62 5f 72 65 73 65 74 28 26 75 75 69 64 29  lob_reset(&uuid)
23f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20  ;.}../*.** Send 
2400: 61 20 67 69 6d 6d 65 20 6d 65 73 73 61 67 65 20  a gimme message 
2410: 66 6f 72 20 65 76 65 72 79 20 70 68 61 6e 74 6f  for every phanto
2420: 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  m..*/.static voi
2430: 64 20 72 65 71 75 65 73 74 5f 70 68 61 6e 74 6f  d request_phanto
2440: 6d 73 28 58 66 65 72 20 2a 70 58 66 65 72 2c 20  ms(Xfer *pXfer, 
2450: 69 6e 74 20 6d 61 78 52 65 71 29 7b 0a 20 20 53  int maxReq){.  S
2460: 74 6d 74 20 71 3b 0a 20 20 64 62 5f 70 72 65 70  tmt q;.  db_prep
2470: 61 72 65 28 26 71 2c 20 0a 20 20 20 20 22 53 45  are(&q, .    "SE
2480: 4c 45 43 54 20 75 75 69 64 20 46 52 4f 4d 20 70  LECT uuid FROM p
2490: 68 61 6e 74 6f 6d 20 4a 4f 49 4e 20 62 6c 6f 62  hantom JOIN blob
24a0: 20 55 53 49 4e 47 28 72 69 64 29 22 0a 20 20 20   USING(rid)".   
24b0: 20 22 20 57 48 45 52 45 20 4e 4f 54 20 45 58 49   " WHERE NOT EXI
24c0: 53 54 53 28 53 45 4c 45 43 54 20 31 20 46 52 4f  STS(SELECT 1 FRO
24d0: 4d 20 73 68 75 6e 20 57 48 45 52 45 20 75 75 69  M shun WHERE uui
24e0: 64 3d 62 6c 6f 62 2e 75 75 69 64 29 22 0a 20 20  d=blob.uuid)".  
24f0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 64 62 5f 73  );.  while( db_s
2500: 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f  tep(&q)==SQLITE_
2510: 52 4f 57 20 26 26 20 6d 61 78 52 65 71 2d 2d 20  ROW && maxReq-- 
2520: 3e 20 30 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  > 0 ){.    const
2530: 20 63 68 61 72 20 2a 7a 55 75 69 64 20 3d 20 64   char *zUuid = d
2540: 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 26 71  b_column_text(&q
2550: 2c 20 30 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61  , 0);.    blob_a
2560: 70 70 65 6e 64 66 28 70 58 66 65 72 2d 3e 70 4f  ppendf(pXfer->pO
2570: 75 74 2c 20 22 67 69 6d 6d 65 20 25 73 5c 6e 22  ut, "gimme %s\n"
2580: 2c 20 7a 55 75 69 64 29 3b 0a 20 20 20 20 70 58  , zUuid);.    pX
2590: 66 65 72 2d 3e 6e 47 69 6d 6d 65 53 65 6e 74 2b  fer->nGimmeSent+
25a0: 2b 3b 0a 20 20 7d 0a 20 20 64 62 5f 66 69 6e 61  +;.  }.  db_fina
25b0: 6c 69 7a 65 28 26 71 29 3b 0a 7d 0a 0a 2f 2a 0a  lize(&q);.}../*.
25c0: 2a 2a 20 43 6f 6d 70 75 74 65 20 61 6e 20 53 48  ** Compute an SH
25d0: 41 31 20 68 61 73 68 20 6f 6e 20 74 68 65 20 74  A1 hash on the t
25e0: 61 69 6c 20 6f 66 20 70 4d 73 67 2e 20 20 56 65  ail of pMsg.  Ve
25f0: 72 69 66 79 20 74 68 61 74 20 69 74 20 6d 61 74  rify that it mat
2600: 63 68 65 73 20 74 68 65 0a 2a 2a 20 74 68 65 20  ches the.** the 
2610: 68 61 73 68 20 67 69 76 65 6e 20 69 6e 20 70 48  hash given in pH
2620: 61 73 68 2e 20 20 52 65 74 75 72 6e 20 31 20 6f  ash.  Return 1 o
2630: 6e 20 61 20 73 75 63 63 65 73 73 66 75 6c 20 6d  n a successful m
2640: 61 74 63 68 2e 20 20 52 65 74 75 72 6e 20 30 0a  atch.  Return 0.
2650: 2a 2a 20 69 66 20 74 68 65 72 65 20 69 73 20 61  ** if there is a
2660: 20 6d 69 73 6d 61 74 63 68 2e 0a 2a 2f 0a 73 74   mismatch..*/.st
2670: 61 74 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 74  atic int check_t
2680: 61 69 6c 5f 68 61 73 68 28 42 6c 6f 62 20 2a 70  ail_hash(Blob *p
2690: 48 61 73 68 2c 20 42 6c 6f 62 20 2a 70 4d 73 67  Hash, Blob *pMsg
26a0: 29 7b 0a 20 20 42 6c 6f 62 20 74 61 69 6c 3b 0a  ){.  Blob tail;.
26b0: 20 20 42 6c 6f 62 20 68 32 3b 0a 20 20 69 6e 74    Blob h2;.  int
26c0: 20 72 63 3b 0a 20 20 62 6c 6f 62 5f 74 61 69 6c   rc;.  blob_tail
26d0: 28 70 4d 73 67 2c 20 26 74 61 69 6c 29 3b 0a 20  (pMsg, &tail);. 
26e0: 20 73 68 61 31 73 75 6d 5f 62 6c 6f 62 28 26 74   sha1sum_blob(&t
26f0: 61 69 6c 2c 20 26 68 32 29 3b 0a 20 20 72 63 20  ail, &h2);.  rc 
2700: 3d 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 70  = blob_compare(p
2710: 48 61 73 68 2c 20 26 68 32 29 3b 0a 20 20 62 6c  Hash, &h2);.  bl
2720: 6f 62 5f 72 65 73 65 74 28 26 68 32 29 3b 0a 20  ob_reset(&h2);. 
2730: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 74 61 69   blob_reset(&tai
2740: 6c 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3d  l);.  return rc=
2750: 3d 30 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 68  =0;.}.../*.** Ch
2760: 65 63 6b 20 74 68 65 20 73 69 67 6e 61 74 75 72  eck the signatur
2770: 65 20 6f 6e 20 61 6e 20 61 70 70 6c 69 63 61 74  e on an applicat
2780: 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 20 70 61 79  ion/x-fossil pay
2790: 6c 6f 61 64 20 72 65 63 65 69 76 65 64 20 62 79  load received by
27a0: 0a 2a 2a 20 74 68 65 20 48 54 54 50 20 73 65 72  .** the HTTP ser
27b0: 76 65 72 2e 20 20 54 68 65 20 73 69 67 6e 61 74  ver.  The signat
27c0: 75 72 65 20 69 73 20 61 20 6c 69 6e 65 20 6f 66  ure is a line of
27d0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66   the following f
27e0: 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  orm:.**.**      
27f0: 20 20 6c 6f 67 69 6e 20 4c 4f 47 49 4e 20 4e 4f    login LOGIN NO
2800: 4e 43 45 20 53 49 47 4e 41 54 55 52 45 0a 2a 2a  NCE SIGNATURE.**
2810: 0a 2a 2a 20 54 68 65 20 4e 4f 4e 43 45 20 69 73  .** The NONCE is
2820: 20 74 68 65 20 53 48 41 31 20 68 61 73 68 20 6f   the SHA1 hash o
2830: 66 20 74 68 65 20 72 65 6d 61 69 6e 64 65 72 20  f the remainder 
2840: 6f 66 20 74 68 65 20 69 6e 70 75 74 2e 20 20 0a  of the input.  .
2850: 2a 2a 20 53 49 47 4e 41 54 55 52 45 20 69 73 20  ** SIGNATURE is 
2860: 74 68 65 20 53 48 41 31 20 63 68 65 63 6b 73 75  the SHA1 checksu
2870: 6d 20 6f 66 20 74 68 65 20 4e 4f 4e 43 45 20 63  m of the NONCE c
2880: 6f 6e 63 61 74 65 6e 61 74 65 64 20 0a 2a 2a 20  oncatenated .** 
2890: 77 69 74 68 20 74 68 65 20 75 73 65 72 73 20 70  with the users p
28a0: 61 73 73 77 6f 72 64 2e 0a 2a 2a 0a 2a 2a 20 54  assword..**.** T
28b0: 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 74 6f  he parameters to
28c0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 61 72   this routine ar
28d0: 65 20 65 70 68 65 72 6d 65 72 61 6c 20 62 6c 6f  e ephermeral blo
28e0: 62 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 0a 2a  bs holding the.*
28f0: 2a 20 4c 4f 47 49 4e 2c 20 4e 4f 4e 43 45 20 61  * LOGIN, NONCE a
2900: 6e 64 20 53 49 47 4e 41 54 55 52 45 2e 0a 2a 2a  nd SIGNATURE..**
2910: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
2920: 20 61 74 74 65 6d 70 74 73 20 74 6f 20 6c 6f 63   attempts to loc
2930: 61 74 65 20 74 68 65 20 75 73 65 72 20 61 6e 64  ate the user and
2940: 20 76 65 72 69 66 79 20 74 68 65 20 73 69 67 6e   verify the sign
2950: 61 74 75 72 65 2e 0a 2a 2a 20 49 66 20 65 76 65  ature..** If eve
2960: 72 79 74 68 69 6e 67 20 63 68 65 63 6b 73 20 6f  rything checks o
2970: 75 74 2c 20 74 68 65 20 55 53 45 52 2e 43 41 50  ut, the USER.CAP
2980: 20 63 6f 6c 75 6d 6e 20 66 6f 72 20 74 68 65 20   column for the 
2990: 55 53 45 52 20 74 61 62 6c 65 0a 2a 2a 20 69 73  USER table.** is
29a0: 20 63 6f 6e 73 75 6c 74 65 64 20 74 6f 20 73 65   consulted to se
29b0: 74 20 70 72 69 76 69 6c 65 67 65 73 20 69 6e 20  t privileges in 
29c0: 74 68 65 20 67 6c 6f 62 61 6c 20 67 20 76 61 72  the global g var
29d0: 69 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  iable..**.** If 
29e0: 61 6e 79 74 68 69 6e 67 20 66 61 69 6c 73 20 74  anything fails t
29f0: 6f 20 63 68 65 63 6b 20 6f 75 74 2c 20 6e 6f 20  o check out, no 
2a00: 63 68 61 6e 67 65 73 20 61 72 65 20 6d 61 64 65  changes are made
2a10: 20 74 6f 20 70 72 69 76 69 6c 65 67 65 73 2e 0a   to privileges..
2a20: 2a 2a 0a 2a 2a 20 53 69 67 6e 61 74 75 72 65 20  **.** Signature 
2a30: 67 65 6e 65 72 61 74 69 6f 6e 20 6f 6e 20 74 68  generation on th
2a40: 65 20 63 6c 69 65 6e 74 20 73 69 64 65 20 69 73  e client side is
2a50: 20 68 61 6e 64 6c 65 64 20 62 79 20 74 68 65 20   handled by the 
2a60: 0a 2a 2a 20 68 74 74 70 5f 65 78 63 68 61 6e 67  .** http_exchang
2a70: 65 28 29 20 72 6f 75 74 69 6e 65 2e 0a 2a 2f 0a  e() routine..*/.
2a80: 76 6f 69 64 20 63 68 65 63 6b 5f 6c 6f 67 69 6e  void check_login
2a90: 28 42 6c 6f 62 20 2a 70 4c 6f 67 69 6e 2c 20 42  (Blob *pLogin, B
2aa0: 6c 6f 62 20 2a 70 4e 6f 6e 63 65 2c 20 42 6c 6f  lob *pNonce, Blo
2ab0: 62 20 2a 70 53 69 67 29 7b 0a 20 20 53 74 6d 74  b *pSig){.  Stmt
2ac0: 20 71 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20   q;.  int rc;.. 
2ad0: 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20   db_prepare(&q, 
2ae0: 22 53 45 4c 45 43 54 20 70 77 2c 20 63 61 70 2c  "SELECT pw, cap,
2af0: 20 75 69 64 20 46 52 4f 4d 20 75 73 65 72 20 57   uid FROM user W
2b00: 48 45 52 45 20 6c 6f 67 69 6e 3d 25 42 22 2c 20  HERE login=%B", 
2b10: 70 4c 6f 67 69 6e 29 3b 0a 20 20 69 66 28 20 64  pLogin);.  if( d
2b20: 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49  b_step(&q)==SQLI
2b30: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 42 6c  TE_ROW ){.    Bl
2b40: 6f 62 20 70 77 2c 20 63 6f 6d 62 69 6e 65 64 2c  ob pw, combined,
2b50: 20 68 61 73 68 3b 0a 20 20 20 20 62 6c 6f 62 5f   hash;.    blob_
2b60: 7a 65 72 6f 28 26 70 77 29 3b 0a 20 20 20 20 64  zero(&pw);.    d
2b70: 62 5f 65 70 68 65 6d 65 72 61 6c 5f 62 6c 6f 62  b_ephemeral_blob
2b80: 28 26 71 2c 20 30 2c 20 26 70 77 29 3b 0a 20 20  (&q, 0, &pw);.  
2b90: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 63 6f 6d    blob_zero(&com
2ba0: 62 69 6e 65 64 29 3b 0a 20 20 20 20 62 6c 6f 62  bined);.    blob
2bb0: 5f 63 6f 70 79 28 26 63 6f 6d 62 69 6e 65 64 2c  _copy(&combined,
2bc0: 20 70 4e 6f 6e 63 65 29 3b 0a 20 20 20 20 62 6c   pNonce);.    bl
2bd0: 6f 62 5f 61 70 70 65 6e 64 28 26 63 6f 6d 62 69  ob_append(&combi
2be0: 6e 65 64 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72  ned, blob_buffer
2bf0: 28 26 70 77 29 2c 20 62 6c 6f 62 5f 73 69 7a 65  (&pw), blob_size
2c00: 28 26 70 77 29 29 3b 0a 20 20 20 20 2f 2a 20 43  (&pw));.    /* C
2c10: 47 49 44 45 42 55 47 28 28 22 70 72 65 73 69 67  GIDEBUG(("presig
2c20: 3d 5b 25 73 5d 5c 6e 22 2c 20 62 6c 6f 62 5f 73  =[%s]\n", blob_s
2c30: 74 72 28 26 63 6f 6d 62 69 6e 65 64 29 29 29 3b  tr(&combined)));
2c40: 20 2a 2f 0a 20 20 20 20 73 68 61 31 73 75 6d 5f   */.    sha1sum_
2c50: 62 6c 6f 62 28 26 63 6f 6d 62 69 6e 65 64 2c 20  blob(&combined, 
2c60: 26 68 61 73 68 29 3b 0a 20 20 20 20 72 63 20 3d  &hash);.    rc =
2c70: 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 26 68   blob_compare(&h
2c80: 61 73 68 2c 20 70 53 69 67 29 3b 0a 20 20 20 20  ash, pSig);.    
2c90: 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73 68  blob_reset(&hash
2ca0: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
2cb0: 74 28 26 63 6f 6d 62 69 6e 65 64 29 3b 0a 20 20  t(&combined);.  
2cc0: 20 20 69 66 28 20 72 63 3d 3d 30 20 29 7b 0a 20    if( rc==0 ){. 
2cd0: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
2ce0: 2a 7a 43 61 70 3b 0a 20 20 20 20 20 20 7a 43 61  *zCap;.      zCa
2cf0: 70 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65  p = db_column_te
2d00: 78 74 28 26 71 2c 20 31 29 3b 0a 20 20 20 20 20  xt(&q, 1);.     
2d10: 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 62   login_set_capab
2d20: 69 6c 69 74 69 65 73 28 7a 43 61 70 29 3b 0a 20  ilities(zCap);. 
2d30: 20 20 20 20 20 67 2e 75 73 65 72 55 69 64 20 3d       g.userUid =
2d40: 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 26   db_column_int(&
2d50: 71 2c 20 32 29 3b 0a 20 20 20 20 20 20 67 2e 7a  q, 2);.      g.z
2d60: 4c 6f 67 69 6e 20 3d 20 6d 70 72 69 6e 74 66 28  Login = mprintf(
2d70: 22 25 62 22 2c 20 70 4c 6f 67 69 6e 29 3b 0a 20  "%b", pLogin);. 
2d80: 20 20 20 20 20 67 2e 7a 4e 6f 6e 63 65 20 3d 20       g.zNonce = 
2d90: 6d 70 72 69 6e 74 66 28 22 25 62 22 2c 20 70 4e  mprintf("%b", pN
2da0: 6f 6e 63 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  once);.    }.  }
2db0: 0a 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26  .  db_finalize(&
2dc0: 71 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e  q);.}../*.** Sen
2dd0: 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66  d the content of
2de0: 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20 74 68   all files in th
2df0: 65 20 75 6e 73 65 6e 74 20 74 61 62 6c 65 2e 0a  e unsent table..
2e00: 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 72 65  **.** This is re
2e10: 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74  ally just an opt
2e20: 69 6d 69 7a 61 74 69 6f 6e 2e 20 20 49 66 20 79  imization.  If y
2e30: 6f 75 20 63 6c 65 61 72 20 74 68 65 0a 2a 2a 20  ou clear the.** 
2e40: 75 6e 73 65 6e 74 20 74 61 62 6c 65 2c 20 61 6c  unsent table, al
2e50: 6c 20 74 68 65 20 72 69 67 68 74 20 66 69 6c 65  l the right file
2e60: 73 20 77 69 6c 6c 20 73 74 69 6c 6c 20 67 65 74  s will still get
2e70: 20 74 72 61 6e 73 66 65 72 72 65 64 2e 0a 2a 2a   transferred..**
2e80: 20 49 74 20 6a 75 73 74 20 6d 69 67 68 74 20 72   It just might r
2e90: 65 71 75 69 72 65 20 61 6e 20 65 78 74 72 61 20  equire an extra 
2ea0: 72 6f 75 6e 64 20 74 72 69 70 20 6f 72 20 74 77  round trip or tw
2eb0: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  o..*/.static voi
2ec0: 64 20 73 65 6e 64 5f 75 6e 73 65 6e 74 28 58 66  d send_unsent(Xf
2ed0: 65 72 20 2a 70 58 66 65 72 29 7b 0a 20 20 53 74  er *pXfer){.  St
2ee0: 6d 74 20 71 3b 0a 20 20 64 62 5f 70 72 65 70 61  mt q;.  db_prepa
2ef0: 72 65 28 26 71 2c 20 22 53 45 4c 45 43 54 20 72  re(&q, "SELECT r
2f00: 69 64 20 46 52 4f 4d 20 75 6e 73 65 6e 74 22 29  id FROM unsent")
2f10: 3b 0a 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74  ;.  while( db_st
2f20: 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52  ep(&q)==SQLITE_R
2f30: 4f 57 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 69  OW ){.    int ri
2f40: 64 20 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 69 6e  d = db_column_in
2f50: 74 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 73 65  t(&q, 0);.    se
2f60: 6e 64 5f 66 69 6c 65 28 70 58 66 65 72 2c 20 72  nd_file(pXfer, r
2f70: 69 64 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 20  id, 0, 0);.  }. 
2f80: 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29   db_finalize(&q)
2f90: 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65  ;.  db_multi_exe
2fa0: 63 28 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 75  c("DELETE FROM u
2fb0: 6e 73 65 6e 74 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  nsent");.}../*.*
2fc0: 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65 20 69  * Check to see i
2fd0: 66 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  f the number of 
2fe0: 75 6e 63 6c 75 73 74 65 72 65 64 20 65 6e 74 72  unclustered entr
2ff0: 69 65 73 20 69 73 20 67 72 65 61 74 65 72 20 74  ies is greater t
3000: 68 61 6e 0a 2a 2a 20 31 30 30 20 61 6e 64 20 69  han.** 100 and i
3010: 66 20 69 74 20 69 73 2c 20 66 6f 72 6d 20 61 20  f it is, form a 
3020: 6e 65 77 20 63 6c 75 73 74 65 72 2e 20 20 55 6e  new cluster.  Un
3030: 63 6c 75 73 74 65 72 65 64 20 70 68 61 6e 74 6f  clustered phanto
3040: 6d 73 20 64 6f 20 6e 6f 74 0a 2a 2a 20 63 6f 75  ms do not.** cou
3050: 6e 74 20 74 6f 77 61 72 64 20 74 68 65 20 31 30  nt toward the 10
3060: 30 20 74 6f 74 61 6c 2e 20 20 41 6e 64 20 70 68  0 total.  And ph
3070: 61 6e 74 6f 6d 73 20 61 72 65 20 6e 65 76 65 72  antoms are never
3080: 20 61 64 64 65 64 20 74 6f 20 61 20 6e 65 77 0a   added to a new.
3090: 2a 2a 20 63 6c 75 73 74 65 72 2e 0a 2a 2f 0a 73  ** cluster..*/.s
30a0: 74 61 74 69 63 20 76 6f 69 64 20 63 72 65 61 74  tatic void creat
30b0: 65 5f 63 6c 75 73 74 65 72 28 76 6f 69 64 29 7b  e_cluster(void){
30c0: 0a 20 20 42 6c 6f 62 20 63 6c 75 73 74 65 72 2c  .  Blob cluster,
30d0: 20 63 6b 73 75 6d 3b 0a 20 20 53 74 6d 74 20 71   cksum;.  Stmt q
30e0: 3b 0a 20 20 69 6e 74 20 6e 55 6e 63 6c 3b 0a 20  ;.  int nUncl;. 
30f0: 20 6e 55 6e 63 6c 20 3d 20 64 62 5f 69 6e 74 28   nUncl = db_int(
3100: 30 2c 20 22 53 45 4c 45 43 54 20 63 6f 75 6e 74  0, "SELECT count
3110: 28 2a 29 20 46 52 4f 4d 20 75 6e 63 6c 75 73 74  (*) FROM unclust
3120: 65 72 65 64 22 0a 20 20 20 20 20 20 20 20 20 20  ered".          
3130: 20 20 20 20 20 20 20 20 20 20 22 20 57 48 45 52            " WHER
3140: 45 20 4e 4f 54 20 45 58 49 53 54 53 28 53 45 4c  E NOT EXISTS(SEL
3150: 45 43 54 20 31 20 46 52 4f 4d 20 70 68 61 6e 74  ECT 1 FROM phant
3160: 6f 6d 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  om".            
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3180: 20 20 20 20 20 20 20 20 20 20 22 20 57 48 45 52            " WHER
3190: 45 20 72 69 64 3d 75 6e 63 6c 75 73 74 65 72 65  E rid=unclustere
31a0: 64 2e 72 69 64 29 22 29 3b 0a 20 20 69 66 28 20  d.rid)");.  if( 
31b0: 6e 55 6e 63 6c 3c 31 30 30 20 29 7b 0a 20 20 20  nUncl<100 ){.   
31c0: 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62   return;.  }.  b
31d0: 6c 6f 62 5f 7a 65 72 6f 28 26 63 6c 75 73 74 65  lob_zero(&cluste
31e0: 72 29 3b 0a 20 20 64 62 5f 70 72 65 70 61 72 65  r);.  db_prepare
31f0: 28 26 71 2c 20 22 53 45 4c 45 43 54 20 75 75 69  (&q, "SELECT uui
3200: 64 20 46 52 4f 4d 20 75 6e 63 6c 75 73 74 65 72  d FROM uncluster
3210: 65 64 2c 20 62 6c 6f 62 22 0a 20 20 20 20 20 20  ed, blob".      
3220: 20 20 20 20 20 20 20 20 20 20 20 22 20 57 48 45             " WHE
3230: 52 45 20 4e 4f 54 20 45 58 49 53 54 53 28 53 45  RE NOT EXISTS(SE
3240: 4c 45 43 54 20 31 20 46 52 4f 4d 20 70 68 61 6e  LECT 1 FROM phan
3250: 74 6f 6d 22 0a 20 20 20 20 20 20 20 20 20 20 20  tom".           
3260: 20 20 20 20 20 20 22 20 20 20 20 20 20 20 20 20        "         
3270: 20 20 20 20 20 20 20 20 20 20 57 48 45 52 45 20            WHERE 
3280: 72 69 64 3d 75 6e 63 6c 75 73 74 65 72 65 64 2e  rid=unclustered.
3290: 72 69 64 29 22 0a 20 20 20 20 20 20 20 20 20 20  rid)".          
32a0: 20 20 20 20 20 20 20 22 20 20 20 41 4e 44 20 75         "   AND u
32b0: 6e 63 6c 75 73 74 65 72 65 64 2e 72 69 64 3d 62  nclustered.rid=b
32c0: 6c 6f 62 2e 72 69 64 22 0a 20 20 20 20 20 20 20  lob.rid".       
32d0: 20 20 20 20 20 20 20 20 20 20 22 20 20 20 41 4e            "   AN
32e0: 44 20 4e 4f 54 20 45 58 49 53 54 53 28 53 45 4c  D NOT EXISTS(SEL
32f0: 45 43 54 20 31 20 46 52 4f 4d 20 73 68 75 6e 20  ECT 1 FROM shun 
3300: 57 48 45 52 45 20 75 75 69 64 3d 62 6c 6f 62 2e  WHERE uuid=blob.
3310: 75 75 69 64 29 22 0a 20 20 20 20 20 20 20 20 20  uuid)".         
3320: 20 20 20 20 20 20 20 20 22 20 4f 52 44 45 52 20          " ORDER 
3330: 42 59 20 31 22 29 3b 0a 20 20 77 68 69 6c 65 28  BY 1");.  while(
3340: 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 51   db_step(&q)==SQ
3350: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
3360: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 63 6c  blob_appendf(&cl
3370: 75 73 74 65 72 2c 20 22 4d 20 25 73 5c 6e 22 2c  uster, "M %s\n",
3380: 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28   db_column_text(
3390: 26 71 2c 20 30 29 29 3b 0a 20 20 7d 0a 20 20 64  &q, 0));.  }.  d
33a0: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a  b_finalize(&q);.
33b0: 20 20 6d 64 35 73 75 6d 5f 62 6c 6f 62 28 26 63    md5sum_blob(&c
33c0: 6c 75 73 74 65 72 2c 20 26 63 6b 73 75 6d 29 3b  luster, &cksum);
33d0: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28  .  blob_appendf(
33e0: 26 63 6c 75 73 74 65 72 2c 20 22 5a 20 25 62 5c  &cluster, "Z %b\
33f0: 6e 22 2c 20 26 63 6b 73 75 6d 29 3b 0a 20 20 62  n", &cksum);.  b
3400: 6c 6f 62 5f 72 65 73 65 74 28 26 63 6b 73 75 6d  lob_reset(&cksum
3410: 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78  );.  db_multi_ex
3420: 65 63 28 22 44 45 4c 45 54 45 20 46 52 4f 4d 20  ec("DELETE FROM 
3430: 75 6e 63 6c 75 73 74 65 72 65 64 22 29 3b 0a 20  unclustered");. 
3440: 20 63 6f 6e 74 65 6e 74 5f 70 75 74 28 26 63 6c   content_put(&cl
3450: 75 73 74 65 72 2c 20 30 2c 20 30 29 3b 0a 20 20  uster, 0, 0);.  
3460: 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 6c 75 73  blob_reset(&clus
3470: 74 65 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ter);.}../*.** S
3480: 65 6e 64 20 61 6e 20 69 67 6f 74 20 6d 65 73 73  end an igot mess
3490: 61 67 65 20 66 6f 72 20 65 76 65 72 79 20 65 6e  age for every en
34a0: 74 72 79 20 69 6e 20 75 6e 63 6c 75 73 74 65 72  try in uncluster
34b0: 65 64 20 74 61 62 6c 65 2e 0a 2a 2a 20 52 65 74  ed table..** Ret
34c0: 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
34d0: 66 20 63 61 72 64 73 20 73 65 6e 74 2e 0a 2a 2f  f cards sent..*/
34e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 6e 64  .static int send
34f0: 5f 75 6e 63 6c 75 73 74 65 72 65 64 28 58 66 65  _unclustered(Xfe
3500: 72 20 2a 70 58 66 65 72 29 7b 0a 20 20 53 74 6d  r *pXfer){.  Stm
3510: 74 20 71 3b 0a 20 20 69 6e 74 20 63 6e 74 20 3d  t q;.  int cnt =
3520: 20 30 3b 0a 20 20 64 62 5f 70 72 65 70 61 72 65   0;.  db_prepare
3530: 28 26 71 2c 20 0a 20 20 20 20 22 53 45 4c 45 43  (&q, .    "SELEC
3540: 54 20 75 75 69 64 20 46 52 4f 4d 20 75 6e 63 6c  T uuid FROM uncl
3550: 75 73 74 65 72 65 64 20 4a 4f 49 4e 20 62 6c 6f  ustered JOIN blo
3560: 62 20 55 53 49 4e 47 28 72 69 64 29 22 0a 20 20  b USING(rid)".  
3570: 20 20 22 20 57 48 45 52 45 20 4e 4f 54 20 45 58    " WHERE NOT EX
3580: 49 53 54 53 28 53 45 4c 45 43 54 20 31 20 46 52  ISTS(SELECT 1 FR
3590: 4f 4d 20 73 68 75 6e 20 57 48 45 52 45 20 75 75  OM shun WHERE uu
35a0: 69 64 3d 62 6c 6f 62 2e 75 75 69 64 29 22 0a 20  id=blob.uuid)". 
35b0: 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 64 62 5f   );.  while( db_
35c0: 73 74 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45  step(&q)==SQLITE
35d0: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 62 6c 6f 62  _ROW ){.    blob
35e0: 5f 61 70 70 65 6e 64 66 28 70 58 66 65 72 2d 3e  _appendf(pXfer->
35f0: 70 4f 75 74 2c 20 22 69 67 6f 74 20 25 73 5c 6e  pOut, "igot %s\n
3600: 22 2c 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78  ", db_column_tex
3610: 74 28 26 71 2c 20 30 29 29 3b 0a 20 20 20 20 63  t(&q, 0));.    c
3620: 6e 74 2b 2b 3b 0a 20 20 7d 0a 20 20 64 62 5f 66  nt++;.  }.  db_f
3630: 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 72  inalize(&q);.  r
3640: 65 74 75 72 6e 20 63 6e 74 3b 0a 7d 0a 0a 2f 2a  eturn cnt;.}../*
3650: 0a 2a 2a 20 53 65 6e 64 20 61 6e 20 69 67 6f 74  .** Send an igot
3660: 20 6d 65 73 73 61 67 65 20 66 6f 72 20 65 76 65   message for eve
3670: 72 79 20 61 72 74 69 66 61 63 74 2e 0a 2a 2f 0a  ry artifact..*/.
3680: 73 74 61 74 69 63 20 76 6f 69 64 20 73 65 6e 64  static void send
3690: 5f 61 6c 6c 28 58 66 65 72 20 2a 70 58 66 65 72  _all(Xfer *pXfer
36a0: 29 7b 0a 20 20 53 74 6d 74 20 71 3b 0a 20 20 64  ){.  Stmt q;.  d
36b0: 62 5f 70 72 65 70 61 72 65 28 26 71 2c 20 0a 20  b_prepare(&q, . 
36c0: 20 20 20 22 53 45 4c 45 43 54 20 75 75 69 64 20     "SELECT uuid 
36d0: 46 52 4f 4d 20 62 6c 6f 62 20 22 0a 20 20 20 20  FROM blob ".    
36e0: 22 20 57 48 45 52 45 20 4e 4f 54 20 45 58 49 53  " WHERE NOT EXIS
36f0: 54 53 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d  TS(SELECT 1 FROM
3700: 20 73 68 75 6e 20 57 48 45 52 45 20 75 75 69 64   shun WHERE uuid
3710: 3d 62 6c 6f 62 2e 75 75 69 64 29 22 0a 20 20 29  =blob.uuid)".  )
3720: 3b 0a 20 20 77 68 69 6c 65 28 20 64 62 5f 73 74  ;.  while( db_st
3730: 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52  ep(&q)==SQLITE_R
3740: 4f 57 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61  OW ){.    blob_a
3750: 70 70 65 6e 64 66 28 70 58 66 65 72 2d 3e 70 4f  ppendf(pXfer->pO
3760: 75 74 2c 20 22 69 67 6f 74 20 25 73 5c 6e 22 2c  ut, "igot %s\n",
3770: 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28   db_column_text(
3780: 26 71 2c 20 30 29 29 3b 0a 20 20 7d 0a 20 20 64  &q, 0));.  }.  d
3790: 62 5f 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a  b_finalize(&q);.
37a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20  }../*.** Send a 
37b0: 73 69 6e 67 6c 65 20 63 6f 6e 66 69 67 20 63 61  single config ca
37c0: 72 64 20 66 6f 72 20 63 6f 6e 66 69 67 75 72 61  rd for configura
37d0: 74 69 6f 6e 20 69 74 65 6d 20 7a 4e 61 6d 65 0a  tion item zName.
37e0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
37f0: 65 6e 64 5f 63 6f 6e 66 69 67 5f 63 61 72 64 28  end_config_card(
3800: 58 66 65 72 20 2a 70 58 66 65 72 2c 20 63 6f 6e  Xfer *pXfer, con
3810: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b  st char *zName){
3820: 0a 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 21  .  if( zName[0]!
3830: 3d 27 40 27 20 29 7b 0a 20 20 20 20 63 68 61 72  ='@' ){.    char
3840: 20 2a 7a 56 61 6c 75 65 20 3d 20 64 62 5f 67 65   *zValue = db_ge
3850: 74 28 7a 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 20  t(zName, 0);.   
3860: 20 69 66 28 20 7a 56 61 6c 75 65 20 29 7b 0a 20   if( zValue ){. 
3870: 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64       blob_append
3880: 66 28 70 58 66 65 72 2d 3e 70 4f 75 74 2c 20 22  f(pXfer->pOut, "
3890: 63 6f 6e 66 69 67 20 25 73 20 25 64 5c 6e 25 73  config %s %d\n%s
38a0: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  \n",.           
38b0: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 73          zName, s
38c0: 74 72 6c 65 6e 28 7a 56 61 6c 75 65 29 2c 20 7a  trlen(zValue), z
38d0: 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 66 72  Value);.      fr
38e0: 65 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20  ee(zValue);.    
38f0: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 42  }.  }else{.    B
3900: 6c 6f 62 20 63 6f 6e 74 65 6e 74 3b 0a 20 20 20  lob content;.   
3910: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 63 6f 6e 74   blob_zero(&cont
3920: 65 6e 74 29 3b 0a 20 20 20 20 63 6f 6e 66 69 67  ent);.    config
3930: 75 72 65 5f 72 65 6e 64 65 72 5f 73 70 65 63 69  ure_render_speci
3940: 61 6c 5f 6e 61 6d 65 28 7a 4e 61 6d 65 2c 20 26  al_name(zName, &
3950: 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20 62 6c  content);.    bl
3960: 6f 62 5f 61 70 70 65 6e 64 66 28 70 58 66 65 72  ob_appendf(pXfer
3970: 2d 3e 70 4f 75 74 2c 20 22 63 6f 6e 66 69 67 20  ->pOut, "config 
3980: 25 73 20 25 64 5c 6e 25 73 5c 6e 22 2c 20 7a 4e  %s %d\n%s\n", zN
3990: 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ame,.           
39a0: 20 20 20 20 20 20 62 6c 6f 62 5f 73 69 7a 65 28        blob_size(
39b0: 26 63 6f 6e 74 65 6e 74 29 2c 20 62 6c 6f 62 5f  &content), blob_
39c0: 73 74 72 28 26 63 6f 6e 74 65 6e 74 29 29 3b 0a  str(&content));.
39d0: 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26      blob_reset(&
39e0: 63 6f 6e 74 65 6e 74 29 3b 0a 20 20 7d 0a 7d 0a  content);.  }.}.
39f0: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 69 73 20  ../*.** If this 
3a00: 76 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 2c  variable is set,
3a10: 20 64 69 73 61 62 6c 65 20 6c 6f 67 69 6e 20 63   disable login c
3a20: 68 65 63 6b 73 2e 20 20 55 73 65 64 20 66 6f 72  hecks.  Used for
3a30: 20 64 65 62 75 67 67 69 6e 67 0a 2a 2a 20 6f 6e   debugging.** on
3a40: 6c 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ly..*/.static in
3a50: 74 20 64 69 73 61 62 6c 65 4c 6f 67 69 6e 20 3d  t disableLogin =
3a60: 20 30 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 43   0;../*.** The C
3a70: 47 49 2f 48 54 54 50 20 70 72 65 70 72 6f 63 65  GI/HTTP preproce
3a80: 73 73 6f 72 20 61 6c 77 61 79 73 20 72 65 64 69  ssor always redi
3a90: 72 65 63 74 73 20 72 65 71 75 65 73 74 73 20 77  rects requests w
3aa0: 69 74 68 20 61 20 63 6f 6e 74 65 6e 74 2d 74 79  ith a content-ty
3ab0: 70 65 0a 2a 2a 20 6f 66 20 61 70 70 6c 69 63 61  pe.** of applica
3ac0: 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 20 6f 72  tion/x-fossil or
3ad0: 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66   application/x-f
3ae0: 6f 73 73 69 6c 2d 64 65 62 75 67 20 74 6f 20 74  ossil-debug to t
3af0: 68 69 73 20 70 61 67 65 2c 0a 2a 2a 20 72 65 67  his page,.** reg
3b00: 61 72 64 6c 65 73 73 20 6f 66 20 77 68 61 74 20  ardless of what 
3b10: 70 61 74 68 20 77 61 73 20 73 70 65 63 69 66 69  path was specifi
3b20: 65 64 20 69 6e 20 74 68 65 20 48 54 54 50 20 68  ed in the HTTP h
3b30: 65 61 64 65 72 2e 20 20 54 68 69 73 20 61 6c 6c  eader.  This all
3b40: 6f 77 73 0a 2a 2a 20 63 6c 6f 6e 65 20 63 6c 69  ows.** clone cli
3b50: 65 6e 74 73 20 74 6f 20 73 70 65 63 69 66 79 20  ents to specify 
3b60: 61 20 55 52 4c 20 74 68 61 74 20 6f 6d 69 74 73  a URL that omits
3b70: 20 64 65 66 61 75 6c 74 20 70 61 74 68 6e 61 6d   default pathnam
3b80: 65 73 2c 20 73 75 63 68 0a 2a 2a 20 61 73 20 22  es, such.** as "
3b90: 68 74 74 70 3a 2f 2f 66 6f 73 73 69 6c 2d 73 63  http://fossil-sc
3ba0: 6d 2e 6d 6f 72 67 2f 22 20 69 6e 73 74 65 61 64  m.morg/" instead
3bb0: 20 6f 66 20 22 68 74 74 70 3a 2f 2f 66 6f 73 73   of "http://foss
3bc0: 69 6c 2d 73 63 6d 2e 6f 72 67 2f 69 6e 64 65 78  il-scm.org/index
3bd0: 2e 63 67 69 22 2e 0a 2a 2a 0a 2a 2a 20 57 45 42  .cgi"..**.** WEB
3be0: 50 41 47 45 3a 20 78 66 65 72 0a 2a 2a 0a 2a 2a  PAGE: xfer.**.**
3bf0: 20 54 68 69 73 20 69 73 20 74 68 65 20 74 72 61   This is the tra
3c00: 6e 73 66 65 72 20 68 61 6e 64 6c 65 72 20 6f 6e  nsfer handler on
3c10: 20 74 68 65 20 73 65 72 76 65 72 20 73 69 64 65   the server side
3c20: 2e 20 20 54 68 65 20 74 72 61 6e 73 66 65 72 0a  .  The transfer.
3c30: 2a 2a 20 6d 65 73 73 61 67 65 20 68 61 73 20 62  ** message has b
3c40: 65 65 6e 20 75 6e 63 6f 6d 70 72 65 73 73 65 64  een uncompressed
3c50: 20 61 6e 64 20 70 6c 61 63 65 64 20 69 6e 20 74   and placed in t
3c60: 68 65 20 67 2e 63 67 69 49 6e 20 62 6c 6f 62 2e  he g.cgiIn blob.
3c70: 0a 2a 2a 20 50 72 6f 63 65 73 73 20 74 68 69 73  .** Process this
3c80: 20 6d 65 73 73 61 67 65 20 61 6e 64 20 66 6f 72   message and for
3c90: 6d 20 61 6e 20 61 70 70 72 6f 70 72 69 61 74 65  m an appropriate
3ca0: 20 72 65 70 6c 79 2e 0a 2a 2f 0a 76 6f 69 64 20   reply..*/.void 
3cb0: 70 61 67 65 5f 78 66 65 72 28 76 6f 69 64 29 7b  page_xfer(void){
3cc0: 0a 20 20 69 6e 74 20 69 73 50 75 6c 6c 20 3d 20  .  int isPull = 
3cd0: 30 3b 0a 20 20 69 6e 74 20 69 73 50 75 73 68 20  0;.  int isPush 
3ce0: 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 45 72 72 20  = 0;.  int nErr 
3cf0: 3d 20 30 3b 0a 20 20 58 66 65 72 20 78 66 65 72  = 0;.  Xfer xfer
3d00: 3b 0a 20 20 69 6e 74 20 64 65 6c 74 61 46 6c 61  ;.  int deltaFla
3d10: 67 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69 73 43  g = 0;.  int isC
3d20: 6c 6f 6e 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20  lone = 0;.  int 
3d30: 6e 47 69 6d 6d 65 20 3d 20 30 3b 0a 20 20 69 6e  nGimme = 0;.  in
3d40: 74 20 73 69 7a 65 3b 0a 20 20 69 6e 74 20 72 65  t size;.  int re
3d50: 63 76 43 6f 6e 66 69 67 20 3d 20 30 3b 0a 0a 20  cvConfig = 0;.. 
3d60: 20 6d 65 6d 73 65 74 28 26 78 66 65 72 2c 20 30   memset(&xfer, 0
3d70: 2c 20 73 69 7a 65 6f 66 28 78 66 65 72 29 29 3b  , sizeof(xfer));
3d80: 0a 20 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72  .  blobarray_zer
3d90: 6f 28 78 66 65 72 2e 61 54 6f 6b 65 6e 2c 20 63  o(xfer.aToken, c
3da0: 6f 75 6e 74 28 78 66 65 72 2e 61 54 6f 6b 65 6e  ount(xfer.aToken
3db0: 29 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 63 6f  ));.  cgi_set_co
3dc0: 6e 74 65 6e 74 5f 74 79 70 65 28 67 2e 7a 43 6f  ntent_type(g.zCo
3dd0: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 20 20 62 6c  ntentType);.  bl
3de0: 6f 62 5f 7a 65 72 6f 28 26 78 66 65 72 2e 65 72  ob_zero(&xfer.er
3df0: 72 29 3b 0a 20 20 78 66 65 72 2e 70 49 6e 20 3d  r);.  xfer.pIn =
3e00: 20 26 67 2e 63 67 69 49 6e 3b 0a 20 20 78 66 65   &g.cgiIn;.  xfe
3e10: 72 2e 70 4f 75 74 20 3d 20 63 67 69 5f 6f 75 74  r.pOut = cgi_out
3e20: 70 75 74 5f 62 6c 6f 62 28 29 3b 0a 20 20 78 66  put_blob();.  xf
3e30: 65 72 2e 6d 78 53 65 6e 64 20 3d 20 64 62 5f 67  er.mxSend = db_g
3e40: 65 74 5f 69 6e 74 28 22 6d 61 78 2d 64 6f 77 6e  et_int("max-down
3e50: 6c 6f 61 64 22 2c 20 35 30 30 30 30 30 30 29 3b  load", 5000000);
3e60: 0a 20 20 67 2e 78 66 65 72 50 61 6e 69 63 20 3d  .  g.xferPanic =
3e70: 20 31 3b 0a 0a 20 20 64 62 5f 62 65 67 69 6e 5f   1;..  db_begin_
3e80: 74 72 61 6e 73 61 63 74 69 6f 6e 28 29 3b 0a 20  transaction();. 
3e90: 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a   db_multi_exec(.
3ea0: 20 20 20 20 20 22 43 52 45 41 54 45 20 54 45 4d       "CREATE TEM
3eb0: 50 20 54 41 42 4c 45 20 6f 6e 72 65 6d 6f 74 65  P TABLE onremote
3ec0: 28 72 69 64 20 49 4e 54 45 47 45 52 20 50 52 49  (rid INTEGER PRI
3ed0: 4d 41 52 59 20 4b 45 59 29 3b 22 0a 20 20 29 3b  MARY KEY);".  );
3ee0: 0a 20 20 77 68 69 6c 65 28 20 62 6c 6f 62 5f 6c  .  while( blob_l
3ef0: 69 6e 65 28 78 66 65 72 2e 70 49 6e 2c 20 26 78  ine(xfer.pIn, &x
3f00: 66 65 72 2e 6c 69 6e 65 29 20 29 7b 0a 20 20 20  fer.line) ){.   
3f10: 20 69 66 28 20 62 6c 6f 62 5f 62 75 66 66 65 72   if( blob_buffer
3f20: 28 26 78 66 65 72 2e 6c 69 6e 65 29 5b 30 5d 3d  (&xfer.line)[0]=
3f30: 3d 27 23 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b  ='#' ) continue;
3f40: 0a 20 20 20 20 78 66 65 72 2e 6e 54 6f 6b 65 6e  .    xfer.nToken
3f50: 20 3d 20 62 6c 6f 62 5f 74 6f 6b 65 6e 69 7a 65   = blob_tokenize
3f60: 28 26 78 66 65 72 2e 6c 69 6e 65 2c 20 78 66 65  (&xfer.line, xfe
3f70: 72 2e 61 54 6f 6b 65 6e 2c 20 63 6f 75 6e 74 28  r.aToken, count(
3f80: 78 66 65 72 2e 61 54 6f 6b 65 6e 29 29 3b 0a 0a  xfer.aToken));..
3f90: 20 20 20 20 2f 2a 20 20 20 66 69 6c 65 20 55 55      /*   file UU
3fa0: 49 44 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45  ID SIZE \n CONTE
3fb0: 4e 54 0a 20 20 20 20 2a 2a 20 20 20 66 69 6c 65  NT.    **   file
3fc0: 20 55 55 49 44 20 44 45 4c 54 41 53 52 43 20 53   UUID DELTASRC S
3fd0: 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20  IZE \n CONTENT. 
3fe0: 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 41 63 63     **.    ** Acc
3ff0: 65 70 74 20 61 20 66 69 6c 65 20 66 72 6f 6d 20  ept a file from 
4000: 74 68 65 20 63 6c 69 65 6e 74 2e 0a 20 20 20 20  the client..    
4010: 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f 62 5f  */.    if( blob_
4020: 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  eq(&xfer.aToken[
4030: 30 5d 2c 20 22 66 69 6c 65 22 29 20 29 7b 0a 20  0], "file") ){. 
4040: 20 20 20 20 20 69 66 28 20 21 69 73 50 75 73 68       if( !isPush
4050: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f   ){.        cgi_
4060: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b  reset_content();
4070: 0a 20 20 20 20 20 20 20 20 40 20 65 72 72 6f 72  .        @ error
4080: 20 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a 65 64   not\sauthorized
4090: 5c 73 74 6f 5c 73 77 72 69 74 65 0a 20 20 20 20  \sto\swrite.    
40a0: 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20      nErr++;.    
40b0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
40c0: 20 7d 0a 20 20 20 20 20 20 78 66 65 72 5f 61 63   }.      xfer_ac
40d0: 63 65 70 74 5f 66 69 6c 65 28 26 78 66 65 72 29  cept_file(&xfer)
40e0: 3b 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62  ;.      if( blob
40f0: 5f 73 69 7a 65 28 26 78 66 65 72 2e 65 72 72 29  _size(&xfer.err)
4100: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f   ){.        cgi_
4110: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b  reset_content();
4120: 0a 20 20 20 20 20 20 20 20 40 20 65 72 72 6f 72  .        @ error
4130: 20 25 54 28 62 6c 6f 62 5f 73 74 72 28 26 78 66   %T(blob_str(&xf
4140: 65 72 2e 65 72 72 29 29 0a 20 20 20 20 20 20 20  er.err)).       
4150: 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20 20 20   nErr++;.       
4160: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
4170: 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f      }else..    /
4180: 2a 20 20 20 67 69 6d 6d 65 20 55 55 49 44 0a 20  *   gimme UUID. 
4190: 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 43 6c 69     **.    ** Cli
41a0: 65 6e 74 20 69 73 20 72 65 71 75 65 73 74 69 6e  ent is requestin
41b0: 67 20 61 20 66 69 6c 65 2e 20 20 53 65 6e 64 20  g a file.  Send 
41c0: 69 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  it..    */.    i
41d0: 66 28 20 62 6c 6f 62 5f 65 71 28 26 78 66 65 72  f( blob_eq(&xfer
41e0: 2e 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22 67 69 6d  .aToken[0], "gim
41f0: 6d 65 22 29 0a 20 20 20 20 20 26 26 20 78 66 65  me").     && xfe
4200: 72 2e 6e 54 6f 6b 65 6e 3d 3d 32 0a 20 20 20 20  r.nToken==2.    
4210: 20 26 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64   && blob_is_uuid
4220: 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d  (&xfer.aToken[1]
4230: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6e  ).    ){.      n
4240: 47 69 6d 6d 65 2b 2b 3b 0a 20 20 20 20 20 20 69  Gimme++;.      i
4250: 66 28 20 69 73 50 75 6c 6c 20 29 7b 0a 20 20 20  f( isPull ){.   
4260: 20 20 20 20 20 69 6e 74 20 72 69 64 20 3d 20 72       int rid = r
4270: 69 64 5f 66 72 6f 6d 5f 75 75 69 64 28 26 78 66  id_from_uuid(&xf
4280: 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 2c 20 30 29  er.aToken[1], 0)
4290: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 69  ;.        if( ri
42a0: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73  d ){.          s
42b0: 65 6e 64 5f 66 69 6c 65 28 26 78 66 65 72 2c 20  end_file(&xfer, 
42c0: 72 69 64 2c 20 26 78 66 65 72 2e 61 54 6f 6b 65  rid, &xfer.aToke
42d0: 6e 5b 31 5d 2c 20 64 65 6c 74 61 46 6c 61 67 29  n[1], deltaFlag)
42e0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
42f0: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 0a 20    }.    }else.. 
4300: 20 20 20 2f 2a 20 20 20 69 67 6f 74 20 55 55 49     /*   igot UUI
4310: 44 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  D.    **.    ** 
4320: 43 6c 69 65 6e 74 20 61 6e 6e 6f 75 6e 63 65 73  Client announces
4330: 20 74 68 61 74 20 69 74 20 68 61 73 20 61 20 70   that it has a p
4340: 61 72 74 69 63 75 6c 61 72 20 66 69 6c 65 2e 0a  articular file..
4350: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 78      */.    if( x
4360: 66 65 72 2e 6e 54 6f 6b 65 6e 3d 3d 32 0a 20 20  fer.nToken==2.  
4370: 20 20 20 26 26 20 62 6c 6f 62 5f 65 71 28 26 78     && blob_eq(&x
4380: 66 65 72 2e 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22  fer.aToken[0], "
4390: 69 67 6f 74 22 29 0a 20 20 20 20 20 26 26 20 62  igot").     && b
43a0: 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 78 66 65  lob_is_uuid(&xfe
43b0: 72 2e 61 54 6f 6b 65 6e 5b 31 5d 29 0a 20 20 20  r.aToken[1]).   
43c0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 73   ){.      if( is
43d0: 50 75 73 68 20 29 7b 0a 20 20 20 20 20 20 20 20  Push ){.        
43e0: 72 69 64 5f 66 72 6f 6d 5f 75 75 69 64 28 26 78  rid_from_uuid(&x
43f0: 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 2c 20 31  fer.aToken[1], 1
4400: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
4410: 65 6c 73 65 0a 20 20 0a 20 20 20 20 0a 20 20 20  else.  .    .   
4420: 20 2f 2a 20 20 20 20 70 75 6c 6c 20 20 53 45 52   /*    pull  SER
4430: 56 45 52 43 4f 44 45 20 20 50 52 4f 4a 45 43 54  VERCODE  PROJECT
4440: 43 4f 44 45 0a 20 20 20 20 2a 2a 20 20 20 20 70  CODE.    **    p
4450: 75 73 68 20 20 53 45 52 56 45 52 43 4f 44 45 20  ush  SERVERCODE 
4460: 20 50 52 4f 4a 45 43 54 43 4f 44 45 0a 20 20 20   PROJECTCODE.   
4470: 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20 63   **.    ** The c
4480: 6c 69 65 6e 74 20 77 61 6e 74 73 20 65 69 74 68  lient wants eith
4490: 65 72 20 73 65 6e 64 20 6f 72 20 72 65 63 65 69  er send or recei
44a0: 76 65 2e 20 20 54 68 65 20 73 65 72 76 65 72 20  ve.  The server 
44b0: 73 68 6f 75 6c 64 0a 20 20 20 20 2a 2a 20 76 65  should.    ** ve
44c0: 72 69 66 79 20 74 68 61 74 20 74 68 65 20 70 72  rify that the pr
44d0: 6f 6a 65 63 74 20 63 6f 64 65 20 6d 61 74 63 68  oject code match
44e0: 65 73 20 61 6e 64 20 74 68 61 74 20 74 68 65 20  es and that the 
44f0: 73 65 72 76 65 72 20 63 6f 64 65 0a 20 20 20 20  server code.    
4500: 2a 2a 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63  ** does not matc
4510: 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  h..    */.    if
4520: 28 20 78 66 65 72 2e 6e 54 6f 6b 65 6e 3d 3d 33  ( xfer.nToken==3
4530: 0a 20 20 20 20 20 26 26 20 28 62 6c 6f 62 5f 65  .     && (blob_e
4540: 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 30  q(&xfer.aToken[0
4550: 5d 2c 20 22 70 75 6c 6c 22 29 20 7c 7c 20 62 6c  ], "pull") || bl
4560: 6f 62 5f 65 71 28 26 78 66 65 72 2e 61 54 6f 6b  ob_eq(&xfer.aTok
4570: 65 6e 5b 30 5d 2c 20 22 70 75 73 68 22 29 29 0a  en[0], "push")).
4580: 20 20 20 20 20 26 26 20 62 6c 6f 62 5f 69 73 5f       && blob_is_
4590: 75 75 69 64 28 26 78 66 65 72 2e 61 54 6f 6b 65  uuid(&xfer.aToke
45a0: 6e 5b 31 5d 29 0a 20 20 20 20 20 26 26 20 62 6c  n[1]).     && bl
45b0: 6f 62 5f 69 73 5f 75 75 69 64 28 26 78 66 65 72  ob_is_uuid(&xfer
45c0: 2e 61 54 6f 6b 65 6e 5b 32 5d 29 0a 20 20 20 20  .aToken[2]).    
45d0: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
45e0: 68 61 72 20 2a 7a 53 43 6f 64 65 3b 0a 20 20 20  har *zSCode;.   
45f0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
4600: 50 43 6f 64 65 3b 0a 0a 20 20 20 20 20 20 7a 53  PCode;..      zS
4610: 43 6f 64 65 20 3d 20 64 62 5f 67 65 74 28 22 73  Code = db_get("s
4620: 65 72 76 65 72 2d 63 6f 64 65 22 2c 20 30 29 3b  erver-code", 0);
4630: 0a 20 20 20 20 20 20 69 66 28 20 7a 53 43 6f 64  .      if( zSCod
4640: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  e==0 ){.        
4650: 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 6d 69  fossil_panic("mi
4660: 73 73 69 6e 67 20 73 65 72 76 65 72 20 63 6f 64  ssing server cod
4670: 65 22 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  e");.      }.   
4680: 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 5f 73     if( blob_eq_s
4690: 74 72 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  tr(&xfer.aToken[
46a0: 31 5d 2c 20 7a 53 43 6f 64 65 2c 20 2d 31 29 20  1], zSCode, -1) 
46b0: 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f 72  ){.        cgi_r
46c0: 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a  eset_content();.
46d0: 20 20 20 20 20 20 20 20 40 20 65 72 72 6f 72 20          @ error 
46e0: 73 65 72 76 65 72 5c 73 6c 6f 6f 70 0a 20 20 20  server\sloop.   
46f0: 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20       nErr++;.   
4700: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
4710: 20 20 7d 0a 20 20 20 20 20 20 7a 50 43 6f 64 65    }.      zPCode
4720: 20 3d 20 64 62 5f 67 65 74 28 22 70 72 6f 6a 65   = db_get("proje
4730: 63 74 2d 63 6f 64 65 22 2c 20 30 29 3b 0a 20 20  ct-code", 0);.  
4740: 20 20 20 20 69 66 28 20 7a 50 43 6f 64 65 3d 3d      if( zPCode==
4750: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 66 6f 73  0 ){.        fos
4760: 73 69 6c 5f 70 61 6e 69 63 28 22 6d 69 73 73 69  sil_panic("missi
4770: 6e 67 20 70 72 6f 6a 65 63 74 20 63 6f 64 65 22  ng project code"
4780: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
4790: 20 69 66 28 20 21 62 6c 6f 62 5f 65 71 5f 73 74   if( !blob_eq_st
47a0: 72 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 32  r(&xfer.aToken[2
47b0: 5d 2c 20 7a 50 43 6f 64 65 2c 20 2d 31 29 20 29  ], zPCode, -1) )
47c0: 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f 72 65  {.        cgi_re
47d0: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20  set_content();. 
47e0: 20 20 20 20 20 20 20 40 20 65 72 72 6f 72 20 77         @ error w
47f0: 72 6f 6e 67 5c 73 70 72 6f 6a 65 63 74 0a 20 20  rong\sproject.  
4800: 20 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20        nErr++;.  
4810: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
4820: 20 20 20 7d 0a 20 20 20 20 20 20 6c 6f 67 69 6e     }.      login
4830: 5f 63 68 65 63 6b 5f 63 72 65 64 65 6e 74 69 61  _check_credentia
4840: 6c 73 28 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ls();.      if( 
4850: 62 6c 6f 62 5f 65 71 28 26 78 66 65 72 2e 61 54  blob_eq(&xfer.aT
4860: 6f 6b 65 6e 5b 30 5d 2c 20 22 70 75 6c 6c 22 29  oken[0], "pull")
4870: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
4880: 21 67 2e 6f 6b 52 65 61 64 20 29 7b 0a 20 20 20  !g.okRead ){.   
4890: 20 20 20 20 20 20 20 63 67 69 5f 72 65 73 65 74         cgi_reset
48a0: 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20  _content();.    
48b0: 20 20 20 20 20 20 40 20 65 72 72 6f 72 20 6e 6f        @ error no
48c0: 74 5c 73 61 75 74 68 6f 72 69 7a 65 64 5c 73 74  t\sauthorized\st
48d0: 6f 5c 73 72 65 61 64 0a 20 20 20 20 20 20 20 20  o\sread.        
48e0: 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 20 20    nErr++;.      
48f0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
4900: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 73 50     }.        isP
4910: 75 6c 6c 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ull = 1;.      }
4920: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69 66  else{.        if
4930: 28 20 21 67 2e 6f 6b 57 72 69 74 65 20 29 7b 0a  ( !g.okWrite ){.
4940: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 21 69            if( !i
4950: 73 50 75 6c 6c 20 29 7b 0a 20 20 20 20 20 20 20  sPull ){.       
4960: 20 20 20 20 20 63 67 69 5f 72 65 73 65 74 5f 63       cgi_reset_c
4970: 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 20 20 20 20  ontent();.      
4980: 20 20 20 20 20 20 40 20 65 72 72 6f 72 20 6e 6f        @ error no
4990: 74 5c 73 61 75 74 68 6f 72 69 7a 65 64 5c 73 74  t\sauthorized\st
49a0: 6f 5c 73 77 72 69 74 65 0a 20 20 20 20 20 20 20  o\swrite.       
49b0: 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20       nErr++;.   
49c0: 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
49d0: 20 20 20 20 20 20 20 20 20 20 40 20 6d 65 73 73            @ mess
49e0: 61 67 65 20 70 75 6c 6c 5c 73 6f 6e 6c 79 5c 73  age pull\sonly\s
49f0: 2d 5c 73 6e 6f 74 5c 73 61 75 74 68 6f 72 69 7a  -\snot\sauthoriz
4a00: 65 64 5c 73 74 6f 5c 73 70 75 73 68 0a 20 20 20  ed\sto\spush.   
4a10: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
4a20: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
4a30: 20 20 69 73 50 75 73 68 20 3d 20 31 3b 0a 20 20    isPush = 1;.  
4a40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
4a50: 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f      }else..    /
4a60: 2a 20 20 20 20 63 6c 6f 6e 65 0a 20 20 20 20 2a  *    clone.    *
4a70: 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20 63 6c 69  *.    ** The cli
4a80: 65 6e 74 20 6b 6e 6f 77 73 20 6e 6f 74 68 69 6e  ent knows nothin
4a90: 67 2e 20 20 54 65 6c 6c 20 61 6c 6c 2e 0a 20 20  g.  Tell all..  
4aa0: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f    */.    if( blo
4ab0: 62 5f 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65  b_eq(&xfer.aToke
4ac0: 6e 5b 30 5d 2c 20 22 63 6c 6f 6e 65 22 29 20 29  n[0], "clone") )
4ad0: 7b 0a 20 20 20 20 20 20 6c 6f 67 69 6e 5f 63 68  {.      login_ch
4ae0: 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c 73 28  eck_credentials(
4af0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 67 2e  );.      if( !g.
4b00: 6f 6b 43 6c 6f 6e 65 20 29 7b 0a 20 20 20 20 20  okClone ){.     
4b10: 20 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e     cgi_reset_con
4b20: 74 65 6e 74 28 29 3b 0a 20 20 20 20 20 20 20 20  tent();.        
4b30: 40 20 65 72 72 6f 72 20 6e 6f 74 5c 73 61 75 74  @ error not\saut
4b40: 68 6f 72 69 7a 65 64 5c 73 74 6f 5c 73 63 6c 6f  horized\sto\sclo
4b50: 6e 65 0a 20 20 20 20 20 20 20 20 6e 45 72 72 2b  ne.        nErr+
4b60: 2b 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  +;.        break
4b70: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
4b80: 69 73 43 6c 6f 6e 65 20 3d 20 31 3b 0a 20 20 20  isClone = 1;.   
4b90: 20 20 20 69 73 50 75 6c 6c 20 3d 20 31 3b 0a 20     isPull = 1;. 
4ba0: 20 20 20 20 20 64 65 6c 74 61 46 6c 61 67 20 3d       deltaFlag =
4bb0: 20 31 3b 0a 20 20 20 20 20 20 40 20 70 75 73 68   1;.      @ push
4bc0: 20 25 73 28 64 62 5f 67 65 74 28 22 73 65 72 76   %s(db_get("serv
4bd0: 65 72 2d 63 6f 64 65 22 2c 20 22 78 22 29 29 20  er-code", "x")) 
4be0: 25 73 28 64 62 5f 67 65 74 28 22 70 72 6f 6a 65  %s(db_get("proje
4bf0: 63 74 2d 63 6f 64 65 22 2c 20 22 78 22 29 29 0a  ct-code", "x")).
4c00: 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f      }else..    /
4c10: 2a 20 20 20 20 6c 6f 67 69 6e 20 20 55 53 45 52  *    login  USER
4c20: 20 20 4e 4f 4e 43 45 20 20 53 49 47 4e 41 54 55    NONCE  SIGNATU
4c30: 52 45 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  RE.    **.    **
4c40: 20 43 68 65 63 6b 20 66 6f 72 20 61 20 76 61 6c   Check for a val
4c50: 69 64 20 6c 6f 67 69 6e 2e 20 20 54 68 69 73 20  id login.  This 
4c60: 68 61 73 20 74 6f 20 68 61 70 70 65 6e 20 62 65  has to happen be
4c70: 66 6f 72 65 20 61 6e 79 74 68 69 6e 67 20 65 6c  fore anything el
4c80: 73 65 2e 0a 20 20 20 20 2a 2a 20 54 68 65 20 63  se..    ** The c
4c90: 6c 69 65 6e 74 20 63 61 6e 20 73 65 6e 64 20 6d  lient can send m
4ca0: 75 6c 74 69 70 6c 65 20 6c 6f 67 69 6e 73 2e 20  ultiple logins. 
4cb0: 20 50 65 72 6d 69 73 73 69 6f 6e 73 20 61 72 65   Permissions are
4cc0: 20 63 75 6d 75 6c 61 74 69 76 65 2e 0a 20 20 20   cumulative..   
4cd0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f 62   */.    if( blob
4ce0: 5f 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e  _eq(&xfer.aToken
4cf0: 5b 30 5d 2c 20 22 6c 6f 67 69 6e 22 29 0a 20 20  [0], "login").  
4d00: 20 20 20 26 26 20 78 66 65 72 2e 6e 54 6f 6b 65     && xfer.nToke
4d10: 6e 3d 3d 34 0a 20 20 20 20 29 7b 0a 20 20 20 20  n==4.    ){.    
4d20: 20 20 69 66 28 20 64 69 73 61 62 6c 65 4c 6f 67    if( disableLog
4d30: 69 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 67 2e  in ){.        g.
4d40: 6f 6b 52 65 61 64 20 3d 20 67 2e 6f 6b 57 72 69  okRead = g.okWri
4d50: 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65  te = 1;.      }e
4d60: 6c 73 65 20 69 66 28 20 63 68 65 63 6b 5f 74 61  lse if( check_ta
4d70: 69 6c 5f 68 61 73 68 28 26 78 66 65 72 2e 61 54  il_hash(&xfer.aT
4d80: 6f 6b 65 6e 5b 32 5d 2c 20 78 66 65 72 2e 70 49  oken[2], xfer.pI
4d90: 6e 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63 68  n) ){.        ch
4da0: 65 63 6b 5f 6c 6f 67 69 6e 28 26 78 66 65 72 2e  eck_login(&xfer.
4db0: 61 54 6f 6b 65 6e 5b 31 5d 2c 20 26 78 66 65 72  aToken[1], &xfer
4dc0: 2e 61 54 6f 6b 65 6e 5b 32 5d 2c 20 26 78 66 65  .aToken[2], &xfe
4dd0: 72 2e 61 54 6f 6b 65 6e 5b 33 5d 29 3b 0a 20 20  r.aToken[3]);.  
4de0: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a      }.    }else.
4df0: 20 20 20 20 0a 20 20 20 20 2f 2a 20 20 20 20 72      .    /*    r
4e00: 65 71 63 6f 6e 66 69 67 20 20 4e 41 4d 45 0a 20  eqconfig  NAME. 
4e10: 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 52 65 71     **.    ** Req
4e20: 75 65 73 74 20 61 20 63 6f 6e 66 69 67 75 72 61  uest a configura
4e30: 74 69 6f 6e 20 76 61 6c 75 65 0a 20 20 20 20 2a  tion value.    *
4e40: 2f 0a 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 65  /.    if( blob_e
4e50: 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 30  q(&xfer.aToken[0
4e60: 5d 2c 20 22 72 65 71 63 6f 6e 66 69 67 22 29 0a  ], "reqconfig").
4e70: 20 20 20 20 20 26 26 20 78 66 65 72 2e 6e 54 6f       && xfer.nTo
4e80: 6b 65 6e 3d 3d 32 0a 20 20 20 20 29 7b 0a 20 20  ken==2.    ){.  
4e90: 20 20 20 20 69 66 28 20 67 2e 6f 6b 52 65 61 64      if( g.okRead
4ea0: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72   ){.        char
4eb0: 20 2a 7a 4e 61 6d 65 20 3d 20 62 6c 6f 62 5f 73   *zName = blob_s
4ec0: 74 72 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  tr(&xfer.aToken[
4ed0: 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  1]);.        if(
4ee0: 20 63 6f 6e 66 69 67 75 72 65 5f 69 73 5f 65 78   configure_is_ex
4ef0: 70 6f 72 74 61 62 6c 65 28 7a 4e 61 6d 65 29 20  portable(zName) 
4f00: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 6e  ){.          sen
4f10: 64 5f 63 6f 6e 66 69 67 5f 63 61 72 64 28 26 78  d_config_card(&x
4f20: 66 65 72 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20  fer, zName);.   
4f30: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
4f40: 20 20 20 7d 65 6c 73 65 0a 20 20 20 20 0a 20 20     }else.    .  
4f50: 20 20 2f 2a 20 20 20 63 6f 6e 66 69 67 20 4e 41    /*   config NA
4f60: 4d 45 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45  ME SIZE \n CONTE
4f70: 4e 54 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  NT.    **.    **
4f80: 20 52 65 63 65 69 76 65 20 61 20 63 6f 6e 66 69   Receive a confi
4f90: 67 75 72 61 74 69 6f 6e 20 76 61 6c 75 65 20 66  guration value f
4fa0: 72 6f 6d 20 74 68 65 20 63 6c 69 65 6e 74 2e 20  rom the client. 
4fb0: 20 54 68 69 73 20 69 73 20 6f 6e 6c 79 0a 20 20   This is only.  
4fc0: 20 20 2a 2a 20 70 65 72 6d 69 74 74 65 64 20 66    ** permitted f
4fd0: 6f 72 20 68 69 67 68 2d 70 72 69 76 69 6c 65 67  or high-privileg
4fe0: 65 20 75 73 65 72 73 2e 0a 20 20 20 20 2a 2f 0a  e users..    */.
4ff0: 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 28      if( blob_eq(
5000: 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 30 5d 2c  &xfer.aToken[0],
5010: 22 63 6f 6e 66 69 67 22 29 20 26 26 20 78 66 65  "config") && xfe
5020: 72 2e 6e 54 6f 6b 65 6e 3d 3d 33 0a 20 20 20 20  r.nToken==3.    
5030: 20 20 20 20 26 26 20 62 6c 6f 62 5f 69 73 5f 69      && blob_is_i
5040: 6e 74 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  nt(&xfer.aToken[
5050: 32 5d 2c 20 26 73 69 7a 65 29 20 29 7b 0a 20 20  2], &size) ){.  
5060: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
5070: 7a 4e 61 6d 65 20 3d 20 62 6c 6f 62 5f 73 74 72  zName = blob_str
5080: 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d  (&xfer.aToken[1]
5090: 29 3b 0a 20 20 20 20 20 20 42 6c 6f 62 20 63 6f  );.      Blob co
50a0: 6e 74 65 6e 74 3b 0a 20 20 20 20 20 20 62 6c 6f  ntent;.      blo
50b0: 62 5f 7a 65 72 6f 28 26 63 6f 6e 74 65 6e 74 29  b_zero(&content)
50c0: 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 65 78 74  ;.      blob_ext
50d0: 72 61 63 74 28 78 66 65 72 2e 70 49 6e 2c 20 73  ract(xfer.pIn, s
50e0: 69 7a 65 2c 20 26 63 6f 6e 74 65 6e 74 29 3b 0a  ize, &content);.
50f0: 20 20 20 20 20 20 69 66 28 20 21 67 2e 6f 6b 41        if( !g.okA
5100: 64 6d 69 6e 20 29 7b 0a 20 20 20 20 20 20 20 20  dmin ){.        
5110: 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e  cgi_reset_conten
5120: 74 28 29 3b 0a 20 20 20 20 20 20 20 20 40 20 65  t();.        @ e
5130: 72 72 6f 72 20 6e 6f 74 5c 73 61 75 74 68 6f 72  rror not\sauthor
5140: 69 7a 65 64 5c 73 74 6f 5c 73 70 75 73 68 5c 73  ized\sto\spush\s
5150: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 0a 20 20  configuration.  
5160: 20 20 20 20 20 20 6e 45 72 72 2b 2b 3b 0a 20 20        nErr++;.  
5170: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
5180: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 7a     }.      if( z
5190: 4e 61 6d 65 5b 30 5d 21 3d 27 40 27 20 29 7b 0a  Name[0]!='@' ){.
51a0: 20 20 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69          db_multi
51b0: 5f 65 78 65 63 28 0a 20 20 20 20 20 20 20 20 20  _exec(.         
51c0: 20 20 20 22 52 45 50 4c 41 43 45 20 49 4e 54 4f     "REPLACE INTO
51d0: 20 63 6f 6e 66 69 67 28 6e 61 6d 65 2c 76 61 6c   config(name,val
51e0: 75 65 29 20 56 41 4c 55 45 53 28 25 51 2c 25 51  ue) VALUES(%Q,%Q
51f0: 29 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  )",.            
5200: 7a 4e 61 6d 65 2c 20 62 6c 6f 62 5f 73 74 72 28  zName, blob_str(
5210: 26 63 6f 6e 74 65 6e 74 29 0a 20 20 20 20 20 20  &content).      
5220: 20 20 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65    );.      }else
5230: 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 74  {.        /* Not
5240: 69 63 65 20 74 68 61 74 20 77 65 20 61 72 65 20  ice that we are 
5250: 65 76 61 6c 75 61 74 69 6e 67 20 61 72 62 69 74  evaluating arbit
5260: 72 61 72 79 20 53 51 4c 20 72 65 63 65 69 76 65  rary SQL receive
5270: 64 20 66 72 6f 6d 20 74 68 65 0a 20 20 20 20 20  d from the.     
5280: 20 20 20 2a 2a 20 63 6c 69 65 6e 74 2e 20 20 42     ** client.  B
5290: 75 74 20 74 68 69 73 20 63 61 6e 20 6f 6e 6c 79  ut this can only
52a0: 20 68 61 70 70 65 6e 20 69 66 20 74 68 65 20 63   happen if the c
52b0: 6c 69 65 6e 74 20 68 61 73 20 61 75 74 68 65 6e  lient has authen
52c0: 74 69 63 61 74 65 64 0a 20 20 20 20 20 20 20 20  ticated.        
52d0: 2a 2a 20 61 73 20 61 6e 20 61 64 6d 69 6e 69 73  ** as an adminis
52e0: 74 72 61 74 6f 72 2c 20 73 6f 20 70 72 65 73 75  trator, so presu
52f0: 6d 61 62 6c 79 20 77 65 20 74 72 75 73 74 20 74  mably we trust t
5300: 68 65 20 63 6c 69 65 6e 74 20 61 74 20 74 68 69  he client at thi
5310: 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 70 6f 69  s.        ** poi
5320: 6e 74 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  nt..        */. 
5330: 20 20 20 20 20 20 20 69 66 28 20 21 72 65 63 76         if( !recv
5340: 43 6f 6e 66 69 67 20 29 7b 0a 20 20 20 20 20 20  Config ){.      
5350: 20 20 20 20 63 6f 6e 66 69 67 75 72 65 5f 70 72      configure_pr
5360: 65 70 61 72 65 5f 74 6f 5f 72 65 63 65 69 76 65  epare_to_receive
5370: 28 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72  (0);.          r
5380: 65 63 76 43 6f 6e 66 69 67 20 3d 20 31 3b 0a 20  ecvConfig = 1;. 
5390: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
53a0: 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 22   db_multi_exec("
53b0: 25 73 22 2c 20 62 6c 6f 62 5f 73 74 72 28 26 63  %s", blob_str(&c
53c0: 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 20 20 20 20  ontent));.      
53d0: 7d 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73  }.      blob_res
53e0: 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20  et(&content);.  
53f0: 20 20 20 20 62 6c 6f 62 5f 73 65 65 6b 28 78 66      blob_seek(xf
5400: 65 72 2e 70 49 6e 2c 20 31 2c 20 42 4c 4f 42 5f  er.pIn, 1, BLOB_
5410: 53 45 45 4b 5f 43 55 52 29 3b 0a 20 20 20 20 7d  SEEK_CUR);.    }
5420: 65 6c 73 65 0a 0a 20 20 20 20 20 20 0a 0a 20 20  else..      ..  
5430: 20 20 2f 2a 20 20 20 20 63 6f 6f 6b 69 65 20 54    /*    cookie T
5440: 45 58 54 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  EXT.    **.    *
5450: 2a 20 41 20 63 6f 6f 6b 69 65 20 63 6f 6e 74 61  * A cookie conta
5460: 69 6e 73 20 61 20 61 72 62 69 74 72 61 72 79 2d  ins a arbitrary-
5470: 6c 65 6e 67 74 68 20 61 72 67 75 6d 65 6e 74 20  length argument 
5480: 74 68 61 74 20 69 73 20 73 65 72 76 65 72 2d 64  that is server-d
5490: 65 66 69 6e 65 64 2e 0a 20 20 20 20 2a 2a 20 54  efined..    ** T
54a0: 68 65 20 61 72 67 75 6d 65 6e 74 20 6d 75 73 74  he argument must
54b0: 20 62 65 20 65 6e 63 6f 64 65 64 20 73 6f 20 61   be encoded so a
54c0: 73 20 6e 6f 74 20 74 6f 20 63 6f 6e 74 61 69 6e  s not to contain
54d0: 20 61 6e 79 20 77 68 69 74 65 73 70 61 63 65 2e   any whitespace.
54e0: 0a 20 20 20 20 2a 2a 20 54 68 65 20 73 65 72 76  .    ** The serv
54f0: 65 72 20 63 61 6e 20 6f 70 74 69 6f 6e 61 6c 6c  er can optionall
5500: 79 20 73 65 6e 64 20 61 20 63 6f 6f 6b 69 65 20  y send a cookie 
5510: 74 6f 20 74 68 65 20 63 6c 69 65 6e 74 2e 20 20  to the client.  
5520: 54 68 65 20 63 6c 69 65 6e 74 0a 20 20 20 20 2a  The client.    *
5530: 2a 20 6d 69 67 68 74 20 74 68 65 6e 20 72 65 74  * might then ret
5540: 75 72 6e 20 74 68 65 20 73 61 6d 65 20 63 6f 6f  urn the same coo
5550: 6b 69 65 20 62 61 63 6b 20 74 6f 20 74 68 65 20  kie back to the 
5560: 73 65 72 76 65 72 20 6f 6e 20 69 74 73 20 6e 65  server on its ne
5570: 78 74 0a 20 20 20 20 2a 2a 20 63 6f 6d 6d 75 6e  xt.    ** commun
5580: 69 63 61 74 69 6f 6e 2e 20 20 54 68 65 20 63 6f  ication.  The co
5590: 6f 6b 69 65 20 6d 69 67 68 74 20 72 65 63 6f 72  okie might recor
55a0: 64 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 74 68  d information th
55b0: 61 74 20 68 65 6c 70 73 0a 20 20 20 20 2a 2a 20  at helps.    ** 
55c0: 74 68 65 20 73 65 72 76 65 72 20 6f 70 74 69 6d  the server optim
55d0: 69 7a 65 20 61 20 70 75 73 68 20 6f 72 20 70 75  ize a push or pu
55e0: 6c 6c 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  ll..    **.    *
55f0: 2a 20 54 68 65 20 63 6c 69 65 6e 74 20 69 73 20  * The client is 
5600: 6e 6f 74 20 72 65 71 75 69 72 65 64 20 74 6f 20  not required to 
5610: 72 65 74 75 72 6e 20 61 20 63 6f 6f 6b 69 65 2e  return a cookie.
5620: 20 20 53 6f 20 74 68 65 20 73 65 72 76 65 72 0a    So the server.
5630: 20 20 20 20 2a 2a 20 6d 75 73 74 20 6e 6f 74 20      ** must not 
5640: 64 65 70 65 6e 64 20 6f 6e 20 74 68 65 20 63 6f  depend on the co
5650: 6f 6b 69 65 2e 20 20 54 68 65 20 63 6f 6f 6b 69  okie.  The cooki
5660: 65 20 73 68 6f 75 6c 64 20 62 65 20 61 6e 20 6f  e should be an o
5670: 70 74 69 6d 69 7a 61 74 69 6f 6e 0a 20 20 20 20  ptimization.    
5680: 2a 2a 20 6f 6e 6c 79 2e 20 20 54 68 65 20 63 6c  ** only.  The cl
5690: 69 65 6e 74 20 6d 69 67 68 74 20 61 6c 73 6f 20  ient might also 
56a0: 73 65 6e 64 20 61 20 63 6f 6f 6b 69 65 20 74 68  send a cookie th
56b0: 61 74 20 63 61 6d 65 20 66 72 6f 6d 20 61 20 64  at came from a d
56c0: 69 66 66 65 72 65 6e 74 0a 20 20 20 20 2a 2a 20  ifferent.    ** 
56d0: 73 65 72 76 65 72 2e 20 20 53 6f 20 74 68 65 20  server.  So the 
56e0: 73 65 72 76 65 72 20 6d 75 73 74 20 62 65 20 70  server must be p
56f0: 72 65 70 61 72 65 64 20 74 6f 20 64 69 73 74 69  repared to disti
5700: 6e 67 75 69 73 68 20 69 74 73 20 6f 77 6e 20 63  nguish its own c
5710: 6f 6f 6b 69 65 0a 20 20 20 20 2a 2a 20 66 72 6f  ookie.    ** fro
5720: 6d 20 63 6f 6f 6b 69 65 73 20 6f 72 69 67 69 6e  m cookies origin
5730: 61 74 69 6e 67 20 66 72 6f 6d 20 6f 74 68 65 72  ating from other
5740: 20 73 65 72 76 65 72 73 2e 20 20 54 68 65 20 63   servers.  The c
5750: 6c 69 65 6e 74 20 6d 69 67 68 74 20 73 65 6e 64  lient might send
5760: 0a 20 20 20 20 2a 2a 20 62 61 63 6b 20 73 65 76  .    ** back sev
5770: 65 72 61 6c 20 64 69 66 66 65 72 65 6e 74 20 63  eral different c
5780: 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 73 65  ookies to the se
5790: 72 76 65 72 2e 20 20 54 68 65 20 73 65 72 76 65  rver.  The serve
57a0: 72 20 73 68 6f 75 6c 64 20 62 65 0a 20 20 20 20  r should be.    
57b0: 2a 2a 20 70 72 65 70 61 72 65 64 20 74 6f 20 73  ** prepared to s
57c0: 69 66 74 20 74 68 72 6f 75 67 68 20 74 68 65 20  ift through the 
57d0: 63 6f 6f 6b 69 65 73 20 61 6e 64 20 70 69 63 6b  cookies and pick
57e0: 20 74 68 65 20 6f 6e 65 20 74 68 61 74 20 69 74   the one that it
57f0: 20 77 61 6e 74 73 2e 0a 20 20 20 20 2a 2f 0a 20   wants..    */. 
5800: 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26     if( blob_eq(&
5810: 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 30 5d 2c 20  xfer.aToken[0], 
5820: 22 63 6f 6f 6b 69 65 22 29 20 26 26 20 78 66 65  "cookie") && xfe
5830: 72 2e 6e 54 6f 6b 65 6e 3d 3d 32 20 29 7b 0a 20  r.nToken==2 ){. 
5840: 20 20 20 20 20 2f 2a 20 50 72 6f 63 65 73 73 20       /* Process 
5850: 74 68 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20  the cookie */.  
5860: 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 2f 2a 20    }else..    /* 
5870: 55 6e 6b 6e 6f 77 6e 20 6d 65 73 73 61 67 65 0a  Unknown message.
5880: 20 20 20 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20      */.    {.   
5890: 20 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e     cgi_reset_con
58a0: 74 65 6e 74 28 29 3b 0a 20 20 20 20 20 20 40 20  tent();.      @ 
58b0: 65 72 72 6f 72 20 62 61 64 5c 73 63 6f 6d 6d 61  error bad\scomma
58c0: 6e 64 3a 5c 73 25 46 28 62 6c 6f 62 5f 73 74 72  nd:\s%F(blob_str
58d0: 28 26 78 66 65 72 2e 6c 69 6e 65 29 29 0a 20 20  (&xfer.line)).  
58e0: 20 20 7d 0a 20 20 20 20 62 6c 6f 62 61 72 72 61    }.    blobarra
58f0: 79 5f 72 65 73 65 74 28 78 66 65 72 2e 61 54 6f  y_reset(xfer.aTo
5900: 6b 65 6e 2c 20 78 66 65 72 2e 6e 54 6f 6b 65 6e  ken, xfer.nToken
5910: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 73 50  );.  }.  if( isP
5920: 75 73 68 20 29 7b 0a 20 20 20 20 72 65 71 75 65  ush ){.    reque
5930: 73 74 5f 70 68 61 6e 74 6f 6d 73 28 26 78 66 65  st_phantoms(&xfe
5940: 72 2c 20 35 30 30 29 3b 0a 20 20 7d 0a 20 20 69  r, 500);.  }.  i
5950: 66 28 20 69 73 43 6c 6f 6e 65 20 26 26 20 6e 47  f( isClone && nG
5960: 69 6d 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 2f  imme==0 ){.    /
5970: 2a 20 54 68 65 20 69 6e 69 74 69 61 6c 20 22 63  * The initial "c
5980: 6c 6f 6e 65 22 20 6d 65 73 73 61 67 65 20 66 72  lone" message fr
5990: 6f 6d 20 63 6c 69 65 6e 74 20 74 6f 20 73 65 72  om client to ser
59a0: 76 65 72 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 0a  ver contains no.
59b0: 20 20 20 20 2a 2a 20 22 67 69 6d 6d 65 22 20 63      ** "gimme" c
59c0: 61 72 64 73 2e 20 4f 6e 20 74 68 61 74 20 69 6e  ards. On that in
59d0: 69 74 69 61 6c 20 6d 65 73 73 61 67 65 2c 20 73  itial message, s
59e0: 65 6e 64 20 74 68 65 20 63 6c 69 65 6e 74 20 61  end the client a
59f0: 6e 20 22 69 67 6f 74 22 0a 20 20 20 20 2a 2a 20  n "igot".    ** 
5a00: 63 61 72 64 20 66 6f 72 20 65 76 65 72 79 20 61  card for every a
5a10: 72 74 69 66 61 63 74 20 63 75 72 72 65 6e 74 6c  rtifact currentl
5a20: 79 20 69 6e 20 74 68 65 20 72 65 73 70 6f 73 69  y in the resposi
5a30: 74 6f 72 79 2e 20 20 54 68 69 73 20 77 69 6c 6c  tory.  This will
5a40: 0a 20 20 20 20 2a 2a 20 63 61 75 73 65 20 74 68  .    ** cause th
5a50: 65 20 63 6c 69 65 6e 74 20 74 6f 20 63 72 65 61  e client to crea
5a60: 74 65 20 70 68 61 6e 74 6f 6d 73 20 66 6f 72 20  te phantoms for 
5a70: 61 6c 6c 20 61 72 74 69 66 61 63 74 73 2c 20 77  all artifacts, w
5a80: 68 69 63 68 20 77 69 6c 6c 0a 20 20 20 20 2a 2a  hich will.    **
5a90: 20 69 6e 20 74 75 72 6e 20 6d 61 6b 65 20 73 75   in turn make su
5aa0: 72 65 20 74 68 61 74 20 74 68 65 20 65 6e 74 69  re that the enti
5ab0: 72 65 20 72 65 70 6f 73 69 74 6f 72 79 20 69 73  re repository is
5ac0: 20 73 65 6e 74 20 65 66 66 69 63 69 65 6e 74 6c   sent efficientl
5ad0: 79 0a 20 20 20 20 2a 2a 20 61 6e 64 20 65 78 70  y.    ** and exp
5ae0: 65 64 69 74 69 6f 75 73 6c 79 2e 0a 20 20 20 20  editiously..    
5af0: 2a 2f 0a 20 20 20 20 73 65 6e 64 5f 61 6c 6c 28  */.    send_all(
5b00: 26 78 66 65 72 29 3b 0a 20 20 7d 65 6c 73 65 20  &xfer);.  }else 
5b10: 69 66 28 20 69 73 50 75 6c 6c 20 29 7b 0a 20 20  if( isPull ){.  
5b20: 20 20 63 72 65 61 74 65 5f 63 6c 75 73 74 65 72    create_cluster
5b30: 28 29 3b 0a 20 20 20 20 73 65 6e 64 5f 75 6e 63  ();.    send_unc
5b40: 6c 75 73 74 65 72 65 64 28 26 78 66 65 72 29 3b  lustered(&xfer);
5b50: 0a 20 20 7d 0a 20 20 69 66 28 20 72 65 63 76 43  .  }.  if( recvC
5b60: 6f 6e 66 69 67 20 29 7b 0a 20 20 20 20 63 6f 6e  onfig ){.    con
5b70: 66 69 67 75 72 65 5f 66 69 6e 61 6c 69 7a 65 5f  figure_finalize_
5b80: 72 65 63 65 69 76 65 28 29 3b 0a 20 20 7d 0a 20  receive();.  }. 
5b90: 20 64 62 5f 65 6e 64 5f 74 72 61 6e 73 61 63 74   db_end_transact
5ba0: 69 6f 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ion(0);.}../*.**
5bb0: 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 78   COMMAND: test-x
5bc0: 66 65 72 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63  fer.**.** This c
5bd0: 6f 6d 6d 61 6e 64 20 69 73 20 75 73 65 64 20 66  ommand is used f
5be0: 6f 72 20 64 65 62 75 67 67 69 6e 67 20 74 68 65  or debugging the
5bf0: 20 73 65 72 76 65 72 2e 20 20 54 68 65 72 65 20   server.  There 
5c00: 69 73 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 61  is a single.** a
5c10: 72 67 75 6d 65 6e 74 20 77 68 69 63 68 20 69 73  rgument which is
5c20: 20 74 68 65 20 75 6e 63 6f 6d 70 72 65 73 73 65   the uncompresse
5c30: 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61 6e 20  d content of an 
5c40: 22 78 66 65 72 22 20 6d 65 73 73 61 67 65 0a 2a  "xfer" message.*
5c50: 2a 20 66 72 6f 6d 20 63 6c 69 65 6e 74 20 74 6f  * from client to
5c60: 20 73 65 72 76 65 72 2e 20 20 54 68 69 73 20 63   server.  This c
5c70: 6f 6d 6d 61 6e 64 20 69 6e 74 65 72 70 72 65 74  ommand interpret
5c80: 73 20 74 68 61 74 20 6d 65 73 73 61 67 65 20 61  s that message a
5c90: 73 0a 2a 2a 20 69 66 20 68 61 64 20 62 65 65 6e  s.** if had been
5ca0: 20 72 65 63 65 69 76 65 64 20 62 79 20 74 68 65   received by the
5cb0: 20 73 65 72 76 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f   server..**.** O
5cc0: 6e 20 74 68 65 20 63 6c 69 65 6e 74 20 73 69 64  n the client sid
5cd0: 65 2c 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20  e, run:.**.**   
5ce0: 20 20 20 66 6f 73 73 69 6c 20 70 75 73 68 20 68     fossil push h
5cf0: 74 74 70 3a 2f 2f 62 6f 67 75 73 2f 20 2d 2d 68  ttp://bogus/ --h
5d00: 74 74 70 74 72 61 63 65 0a 2a 2a 0a 2a 2a 20 4f  ttptrace.**.** O
5d10: 72 20 61 20 73 69 6d 69 6c 61 72 20 63 6f 6d 6d  r a similar comm
5d20: 61 6e 64 20 74 6f 20 70 72 6f 76 69 64 65 20 74  and to provide t
5d30: 68 65 20 6f 75 74 70 75 74 2e 20 20 54 68 65 20  he output.  The 
5d40: 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 0a 2a  content of the.*
5d50: 2a 20 6d 65 73 73 61 67 65 20 77 69 6c 6c 20 61  * message will a
5d60: 70 70 65 61 72 20 6f 6e 20 73 74 61 6e 64 61 72  ppear on standar
5d70: 64 20 6f 75 74 70 75 74 2e 20 20 43 61 70 74 75  d output.  Captu
5d80: 72 65 20 74 68 69 73 20 6d 65 73 73 61 67 65 0a  re this message.
5d90: 2a 2a 20 69 6e 74 6f 20 61 20 66 69 6c 65 20 6e  ** into a file n
5da0: 61 6d 65 64 20 28 66 6f 72 20 65 78 61 6d 70 6c  amed (for exampl
5db0: 65 29 20 6f 75 74 2e 74 78 74 2e 20 20 54 68 65  e) out.txt.  The
5dc0: 6e 20 72 75 6e 20 74 68 65 0a 2a 2a 20 73 65 72  n run the.** ser
5dd0: 76 65 72 20 69 6e 20 67 64 62 3a 0a 2a 2a 0a 2a  ver in gdb:.**.*
5de0: 2a 20 20 20 20 20 67 64 62 20 66 6f 73 73 69 6c  *     gdb fossil
5df0: 0a 2a 2a 20 20 20 20 20 72 20 74 65 73 74 2d 78  .**     r test-x
5e00: 66 65 72 20 6f 75 74 2e 74 78 74 0a 2a 2f 0a 76  fer out.txt.*/.v
5e10: 6f 69 64 20 63 6d 64 5f 74 65 73 74 5f 78 66 65  oid cmd_test_xfe
5e20: 72 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 6e  r(void){.  int n
5e30: 6f 74 55 73 65 64 3b 0a 20 20 69 66 28 20 67 2e  otUsed;.  if( g.
5e40: 61 72 67 63 21 3d 32 20 26 26 20 67 2e 61 72 67  argc!=2 && g.arg
5e50: 63 21 3d 33 20 29 7b 0a 20 20 20 20 75 73 61 67  c!=3 ){.    usag
5e60: 65 28 22 3f 4d 45 53 53 41 47 45 46 49 4c 45 3f  e("?MESSAGEFILE?
5e70: 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d 75 73  ");.  }.  db_mus
5e80: 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65 65  t_be_within_tree
5e90: 28 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  ();.  blob_zero(
5ea0: 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 62 6c 6f  &g.cgiIn);.  blo
5eb0: 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65  b_read_from_file
5ec0: 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e 61 72 67  (&g.cgiIn, g.arg
5ed0: 63 3d 3d 32 20 3f 20 22 2d 22 20 3a 20 67 2e 61  c==2 ? "-" : g.a
5ee0: 72 67 76 5b 32 5d 29 3b 0a 20 20 64 69 73 61 62  rgv[2]);.  disab
5ef0: 6c 65 4c 6f 67 69 6e 20 3d 20 31 3b 0a 20 20 70  leLogin = 1;.  p
5f00: 61 67 65 5f 78 66 65 72 28 29 3b 0a 20 20 70 72  age_xfer();.  pr
5f10: 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 63 67 69  intf("%s\n", cgi
5f20: 5f 65 78 74 72 61 63 74 5f 63 6f 6e 74 65 6e 74  _extract_content
5f30: 28 26 6e 6f 74 55 73 65 64 29 29 3b 0a 7d 0a 0a  (&notUsed));.}..
5f40: 2f 2a 0a 2a 2a 20 46 6f 72 6d 61 74 20 73 74 72  /*.** Format str
5f50: 69 6e 67 73 20 66 6f 72 20 70 72 6f 67 72 65 73  ings for progres
5f60: 73 20 72 65 70 6f 72 74 69 6e 67 2e 0a 2a 2f 0a  s reporting..*/.
5f70: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61  static const cha
5f80: 72 20 7a 4c 61 62 65 6c 46 6f 72 6d 61 74 5b 5d  r zLabelFormat[]
5f90: 20 3d 20 22 25 2d 31 30 73 20 25 31 30 73 20 25   = "%-10s %10s %
5fa0: 31 30 73 20 25 31 30 73 20 25 31 30 73 5c 6e 22  10s %10s %10s\n"
5fb0: 3b 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63  ;.static const c
5fc0: 68 61 72 20 7a 56 61 6c 75 65 46 6f 72 6d 61 74  har zValueFormat
5fd0: 5b 5d 20 3d 20 22 5c 72 25 2d 31 30 73 20 25 31  [] = "\r%-10s %1
5fe0: 30 64 20 25 31 30 64 20 25 31 30 64 20 25 31 30  0d %10d %10d %10
5ff0: 64 5c 6e 22 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 53 79  d\n";.../*.** Sy
6000: 6e 63 20 74 6f 20 74 68 65 20 68 6f 73 74 20 69  nc to the host i
6010: 64 65 6e 74 69 66 69 65 64 20 69 6e 20 67 2e 75  dentified in g.u
6020: 72 6c 4e 61 6d 65 20 61 6e 64 20 67 2e 75 72 6c  rlName and g.url
6030: 50 61 74 68 2e 20 20 54 68 69 73 0a 2a 2a 20 72  Path.  This.** r
6040: 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64  outine is called
6050: 20 62 79 20 74 68 65 20 63 6c 69 65 6e 74 2e 0a   by the client..
6060: 2a 2a 0a 2a 2a 20 52 65 63 6f 72 64 73 20 61 72  **.** Records ar
6070: 65 20 70 75 73 68 65 64 20 74 6f 20 74 68 65 20  e pushed to the 
6080: 73 65 72 76 65 72 20 69 66 20 70 75 73 68 46 6c  server if pushFl
6090: 61 67 20 69 73 20 74 72 75 65 2e 20 20 52 65 63  ag is true.  Rec
60a0: 6f 72 64 73 0a 2a 2a 20 61 72 65 20 70 75 6c 6c  ords.** are pull
60b0: 65 64 20 69 66 20 70 75 6c 6c 46 6c 61 67 20 69  ed if pullFlag i
60c0: 73 20 74 72 75 65 2e 20 20 41 20 66 75 6c 6c 20  s true.  A full 
60d0: 73 79 6e 63 20 6f 63 63 75 72 73 20 69 66 20 62  sync occurs if b
60e0: 6f 74 68 20 61 72 65 0a 2a 2a 20 74 72 75 65 2e  oth are.** true.
60f0: 0a 2a 2f 0a 76 6f 69 64 20 63 6c 69 65 6e 74 5f  .*/.void client_
6100: 73 79 6e 63 28 0a 20 20 69 6e 74 20 70 75 73 68  sync(.  int push
6110: 46 6c 61 67 2c 20 20 20 20 20 20 20 20 20 20 2f  Flag,          /
6120: 2a 20 54 72 75 65 20 74 6f 20 64 6f 20 61 20 70  * True to do a p
6130: 75 73 68 20 28 6f 72 20 61 20 73 79 6e 63 29 20  ush (or a sync) 
6140: 2a 2f 0a 20 20 69 6e 74 20 70 75 6c 6c 46 6c 61  */.  int pullFla
6150: 67 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  g,          /* T
6160: 72 75 65 20 74 6f 20 64 6f 20 61 20 70 75 6c 6c  rue to do a pull
6170: 20 28 6f 72 20 61 20 73 79 6e 63 29 20 2a 2f 0a   (or a sync) */.
6180: 20 20 69 6e 74 20 63 6c 6f 6e 65 46 6c 61 67 2c    int cloneFlag,
6190: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
61a0: 20 69 66 20 74 68 69 73 20 69 73 20 61 20 63 6c   if this is a cl
61b0: 6f 6e 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6f 6e  one */.  int con
61c0: 66 69 67 52 63 76 4d 61 73 6b 2c 20 20 20 20 20  figRcvMask,     
61d0: 2f 2a 20 52 65 63 65 69 76 65 20 74 68 65 73 65  /* Receive these
61e0: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 69   configuration i
61f0: 74 65 6d 73 20 2a 2f 0a 20 20 69 6e 74 20 63 6f  tems */.  int co
6200: 6e 66 69 67 53 65 6e 64 4d 61 73 6b 20 20 20 20  nfigSendMask    
6210: 20 2f 2a 20 53 65 6e 64 20 74 68 65 73 65 20 63   /* Send these c
6220: 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 69 74 65  onfiguration ite
6230: 6d 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 67  ms */.){.  int g
6240: 6f 20 3d 20 31 3b 20 20 20 20 20 20 20 20 2f 2a  o = 1;        /*
6250: 20 4c 6f 6f 70 20 75 6e 74 69 6c 20 7a 65 72 6f   Loop until zero
6260: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
6270: 20 2a 7a 53 43 6f 64 65 20 3d 20 64 62 5f 67 65   *zSCode = db_ge
6280: 74 28 22 73 65 72 76 65 72 2d 63 6f 64 65 22 2c  t("server-code",
6290: 20 22 78 22 29 3b 0a 20 20 63 6f 6e 73 74 20 63   "x");.  const c
62a0: 68 61 72 20 2a 7a 50 43 6f 64 65 20 3d 20 64 62  har *zPCode = db
62b0: 5f 67 65 74 28 22 70 72 6f 6a 65 63 74 2d 63 6f  _get("project-co
62c0: 64 65 22 2c 20 30 29 3b 0a 20 20 69 6e 74 20 6e  de", 0);.  int n
62d0: 43 61 72 64 20 3d 20 30 3b 20 20 20 20 20 20 20  Card = 0;       
62e0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
62f0: 61 72 64 73 20 73 65 6e 74 20 6f 72 20 72 65 63  ards sent or rec
6300: 65 69 76 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e  eived */.  int n
6310: 43 79 63 6c 65 20 3d 20 30 3b 20 20 20 20 20 20  Cycle = 0;      
6320: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 72    /* Number of r
6330: 6f 75 6e 64 20 74 72 69 70 73 20 74 6f 20 74 68  ound trips to th
6340: 65 20 73 65 72 76 65 72 20 2a 2f 0a 20 20 69 6e  e server */.  in
6350: 74 20 73 69 7a 65 3b 20 20 20 20 20 20 20 20 20  t size;         
6360: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
6370: 20 61 20 63 6f 6e 66 69 67 20 76 61 6c 75 65 20   a config value 
6380: 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 6c 65 53 65  */.  int nFileSe
6390: 6e 64 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6f 72  nd = 0;.  int or
63a0: 69 67 43 6f 6e 66 69 67 52 63 76 4d 61 73 6b 3b  igConfigRcvMask;
63b0: 20 20 2f 2a 20 4f 72 69 67 69 6e 61 6c 20 76 61    /* Original va
63c0: 6c 75 65 20 6f 66 20 63 6f 6e 66 69 67 52 63 76  lue of configRcv
63d0: 4d 61 73 6b 20 2a 2f 0a 20 20 69 6e 74 20 6e 46  Mask */.  int nF
63e0: 69 6c 65 52 65 63 76 3b 20 20 20 20 20 20 20 20  ileRecv;        
63f0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 66    /* Number of f
6400: 69 6c 65 73 20 72 65 63 65 69 76 65 64 20 2a 2f  iles received */
6410: 0a 20 20 69 6e 74 20 6d 78 50 68 61 6e 74 6f 6d  .  int mxPhantom
6420: 52 65 71 20 3d 20 32 30 30 3b 20 2f 2a 20 4d 61  Req = 200; /* Ma
6430: 78 20 6e 75 6d 62 65 72 20 6f 66 20 70 68 61 6e  x number of phan
6440: 74 6f 6d 73 20 74 6f 20 72 65 71 75 65 73 74 20  toms to request 
6450: 70 65 72 20 63 6f 6d 6d 20 2a 2f 0a 20 20 63 6f  per comm */.  co
6460: 6e 73 74 20 63 68 61 72 20 2a 7a 43 6f 6f 6b 69  nst char *zCooki
6470: 65 3b 20 20 20 20 2f 2a 20 53 65 72 76 65 72 20  e;    /* Server 
6480: 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 42 6c 6f 62  cookie */.  Blob
6490: 20 73 65 6e 64 3b 20 20 20 20 20 20 20 20 2f 2a   send;        /*
64a0: 20 54 65 78 74 20 77 65 20 61 72 65 20 73 65 6e   Text we are sen
64b0: 64 69 6e 67 20 74 6f 20 74 68 65 20 73 65 72 76  ding to the serv
64c0: 65 72 20 2a 2f 0a 20 20 42 6c 6f 62 20 72 65 63  er */.  Blob rec
64d0: 76 3b 20 20 20 20 20 20 20 20 2f 2a 20 52 65 70  v;        /* Rep
64e0: 6c 79 20 77 65 20 67 6f 74 20 62 61 63 6b 20 66  ly we got back f
64f0: 72 6f 6d 20 74 68 65 20 73 65 72 76 65 72 20 2a  rom the server *
6500: 2f 0a 20 20 58 66 65 72 20 78 66 65 72 3b 20 20  /.  Xfer xfer;  
6510: 20 20 20 20 20 20 2f 2a 20 54 72 61 6e 73 66 65        /* Transfe
6520: 72 20 64 61 74 61 20 2a 2f 0a 0a 20 20 6d 65 6d  r data */..  mem
6530: 73 65 74 28 26 78 66 65 72 2c 20 30 2c 20 73 69  set(&xfer, 0, si
6540: 7a 65 6f 66 28 78 66 65 72 29 29 3b 0a 20 20 78  zeof(xfer));.  x
6550: 66 65 72 2e 70 49 6e 20 3d 20 26 72 65 63 76 3b  fer.pIn = &recv;
6560: 0a 20 20 78 66 65 72 2e 70 4f 75 74 20 3d 20 26  .  xfer.pOut = &
6570: 73 65 6e 64 3b 0a 20 20 78 66 65 72 2e 6d 78 53  send;.  xfer.mxS
6580: 65 6e 64 20 3d 20 64 62 5f 67 65 74 5f 69 6e 74  end = db_get_int
6590: 28 22 6d 61 78 2d 75 70 6c 6f 61 64 22 2c 20 32  ("max-upload", 2
65a0: 35 30 30 30 30 29 3b 0a 0a 20 20 61 73 73 65 72  50000);..  asser
65b0: 74 28 20 70 75 73 68 46 6c 61 67 20 7c 20 70 75  t( pushFlag | pu
65c0: 6c 6c 46 6c 61 67 20 7c 20 63 6c 6f 6e 65 46 6c  llFlag | cloneFl
65d0: 61 67 20 7c 20 63 6f 6e 66 69 67 52 63 76 4d 61  ag | configRcvMa
65e0: 73 6b 20 7c 20 63 6f 6e 66 69 67 53 65 6e 64 4d  sk | configSendM
65f0: 61 73 6b 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ask );.  assert(
6600: 20 21 67 2e 75 72 6c 49 73 46 69 6c 65 20 29 3b   !g.urlIsFile );
6610: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 69            /* Thi
6620: 73 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 66 6f 72  s only works for
6630: 20 6e 65 74 77 6f 72 6b 69 6e 67 20 2a 2f 0a 0a   networking */..
6640: 20 20 64 62 5f 62 65 67 69 6e 5f 74 72 61 6e 73    db_begin_trans
6650: 61 63 74 69 6f 6e 28 29 3b 0a 20 20 64 62 5f 72  action();.  db_r
6660: 65 63 6f 72 64 5f 72 65 70 6f 73 69 74 6f 72 79  ecord_repository
6670: 5f 66 69 6c 65 6e 61 6d 65 28 30 29 3b 0a 20 20  _filename(0);.  
6680: 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20  db_multi_exec(. 
6690: 20 20 20 22 43 52 45 41 54 45 20 54 45 4d 50 20     "CREATE TEMP 
66a0: 54 41 42 4c 45 20 6f 6e 72 65 6d 6f 74 65 28 72  TABLE onremote(r
66b0: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41  id INTEGER PRIMA
66c0: 52 59 20 4b 45 59 29 3b 22 0a 20 20 29 3b 0a 20  RY KEY);".  );. 
66d0: 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65 72 6f 28   blobarray_zero(
66e0: 78 66 65 72 2e 61 54 6f 6b 65 6e 2c 20 63 6f 75  xfer.aToken, cou
66f0: 6e 74 28 78 66 65 72 2e 61 54 6f 6b 65 6e 29 29  nt(xfer.aToken))
6700: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 73  ;.  blob_zero(&s
6710: 65 6e 64 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  end);.  blob_zer
6720: 6f 28 26 72 65 63 76 29 3b 0a 20 20 62 6c 6f 62  o(&recv);.  blob
6730: 5f 7a 65 72 6f 28 26 78 66 65 72 2e 65 72 72 29  _zero(&xfer.err)
6740: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 78  ;.  blob_zero(&x
6750: 66 65 72 2e 6c 69 6e 65 29 3b 0a 20 20 6f 72 69  fer.line);.  ori
6760: 67 43 6f 6e 66 69 67 52 63 76 4d 61 73 6b 20 3d  gConfigRcvMask =
6770: 20 63 6f 6e 66 69 67 52 63 76 4d 61 73 6b 3b 0a   configRcvMask;.
6780: 0a 20 20 2f 2a 0a 20 20 2a 2a 20 41 6c 77 61 79  .  /*.  ** Alway
6790: 73 20 62 65 67 69 6e 20 77 69 74 68 20 61 20 63  s begin with a c
67a0: 6c 6f 6e 65 2c 20 70 75 6c 6c 2c 20 6f 72 20 70  lone, pull, or p
67b0: 75 73 68 20 6d 65 73 73 61 67 65 0a 20 20 2a 2f  ush message.  */
67c0: 0a 20 20 69 66 28 20 63 6c 6f 6e 65 46 6c 61 67  .  if( cloneFlag
67d0: 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70   ){.    blob_app
67e0: 65 6e 64 66 28 26 73 65 6e 64 2c 20 22 63 6c 6f  endf(&send, "clo
67f0: 6e 65 5c 6e 22 29 3b 0a 20 20 20 20 70 75 73 68  ne\n");.    push
6800: 46 6c 61 67 20 3d 20 30 3b 0a 20 20 20 20 70 75  Flag = 0;.    pu
6810: 6c 6c 46 6c 61 67 20 3d 20 30 3b 0a 20 20 20 20  llFlag = 0;.    
6820: 6e 43 61 72 64 2b 2b 3b 0a 20 20 20 20 2f 2a 20  nCard++;.    /* 
6830: 54 42 44 3a 20 52 65 71 75 65 73 74 20 61 6c 6c  TBD: Request all
6840: 20 74 72 61 6e 73 66 65 72 61 62 6c 65 20 63 6f   transferable co
6850: 6e 66 69 67 75 72 61 74 69 6f 6e 20 76 61 6c 75  nfiguration valu
6860: 65 73 20 2a 2f 0a 20 20 7d 65 6c 73 65 20 69 66  es */.  }else if
6870: 28 20 70 75 6c 6c 46 6c 61 67 20 29 7b 0a 20 20  ( pullFlag ){.  
6880: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26    blob_appendf(&
6890: 73 65 6e 64 2c 20 22 70 75 6c 6c 20 25 73 20 25  send, "pull %s %
68a0: 73 5c 6e 22 2c 20 7a 53 43 6f 64 65 2c 20 7a 50  s\n", zSCode, zP
68b0: 43 6f 64 65 29 3b 0a 20 20 20 20 6e 43 61 72 64  Code);.    nCard
68c0: 2b 2b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 75  ++;.  }.  if( pu
68d0: 73 68 46 6c 61 67 20 29 7b 0a 20 20 20 20 62 6c  shFlag ){.    bl
68e0: 6f 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64  ob_appendf(&send
68f0: 2c 20 22 70 75 73 68 20 25 73 20 25 73 5c 6e 22  , "push %s %s\n"
6900: 2c 20 7a 53 43 6f 64 65 2c 20 7a 50 43 6f 64 65  , zSCode, zPCode
6910: 29 3b 0a 20 20 20 20 6e 43 61 72 64 2b 2b 3b 0a  );.    nCard++;.
6920: 20 20 7d 0a 20 20 70 72 69 6e 74 66 28 7a 4c 61    }.  printf(zLa
6930: 62 65 6c 46 6f 72 6d 61 74 2c 20 22 22 2c 20 22  belFormat, "", "
6940: 42 79 74 65 73 22 2c 20 22 43 61 72 64 73 22 2c  Bytes", "Cards",
6950: 20 22 41 72 74 69 66 61 63 74 73 22 2c 20 22 44   "Artifacts", "D
6960: 65 6c 74 61 73 22 29 3b 0a 0a 20 20 77 68 69 6c  eltas");..  whil
6970: 65 28 20 67 6f 20 29 7b 0a 20 20 20 20 69 6e 74  e( go ){.    int
6980: 20 6e 65 77 50 68 61 6e 74 6f 6d 20 3d 20 30 3b   newPhantom = 0;
6990: 0a 20 20 20 20 63 68 61 72 20 2a 7a 52 61 6e 64  .    char *zRand
69a0: 6f 6d 6e 65 73 73 3b 0a 0a 20 20 20 20 2f 2a 20  omness;..    /* 
69b0: 53 65 6e 64 20 6d 61 6b 65 20 74 68 65 20 6d 6f  Send make the mo
69c0: 73 74 20 72 65 63 65 6e 74 6c 79 20 72 65 63 65  st recently rece
69d0: 69 76 65 64 20 63 6f 6f 6b 69 65 2e 20 20 4c 65  ived cookie.  Le
69e0: 74 20 74 68 65 20 73 65 72 76 65 72 0a 20 20 20  t the server.   
69f0: 20 2a 2a 20 66 69 67 75 72 65 20 6f 75 74 20 69   ** figure out i
6a00: 66 20 74 68 69 73 20 69 73 20 61 20 63 6f 6f 6b  f this is a cook
6a10: 69 65 20 74 68 61 74 20 69 74 20 63 61 72 65 73  ie that it cares
6a20: 20 61 62 6f 75 74 2e 0a 20 20 20 20 2a 2f 0a 20   about..    */. 
6a30: 20 20 20 7a 43 6f 6f 6b 69 65 20 3d 20 64 62 5f     zCookie = db_
6a40: 67 65 74 28 22 63 6f 6f 6b 69 65 22 2c 20 30 29  get("cookie", 0)
6a50: 3b 0a 20 20 20 20 69 66 28 20 7a 43 6f 6f 6b 69  ;.    if( zCooki
6a60: 65 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f  e ){.      blob_
6a70: 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c 20 22  appendf(&send, "
6a80: 63 6f 6f 6b 69 65 20 25 73 5c 6e 22 2c 20 7a 43  cookie %s\n", zC
6a90: 6f 6f 6b 69 65 29 3b 0a 20 20 20 20 7d 0a 20 20  ookie);.    }.  
6aa0: 20 20 0a 20 20 20 20 2f 2a 20 47 65 6e 65 72 61    .    /* Genera
6ab0: 74 65 20 67 69 6d 6d 65 20 63 61 72 64 73 20 66  te gimme cards f
6ac0: 6f 72 20 70 68 61 6e 74 6f 6d 73 20 61 6e 64 20  or phantoms and 
6ad0: 6c 65 61 66 20 63 61 72 64 73 0a 20 20 20 20 2a  leaf cards.    *
6ae0: 2a 20 66 6f 72 20 61 6c 6c 20 6c 65 61 76 65 73  * for all leaves
6af0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
6b00: 20 70 75 6c 6c 46 6c 61 67 20 7c 7c 20 63 6c 6f   pullFlag || clo
6b10: 6e 65 46 6c 61 67 20 29 7b 0a 20 20 20 20 20 20  neFlag ){.      
6b20: 72 65 71 75 65 73 74 5f 70 68 61 6e 74 6f 6d 73  request_phantoms
6b30: 28 26 78 66 65 72 2c 20 6d 78 50 68 61 6e 74 6f  (&xfer, mxPhanto
6b40: 6d 52 65 71 29 3b 0a 20 20 20 20 7d 0a 20 20 20  mReq);.    }.   
6b50: 20 69 66 28 20 70 75 73 68 46 6c 61 67 20 29 7b   if( pushFlag ){
6b60: 0a 20 20 20 20 20 20 73 65 6e 64 5f 75 6e 73 65  .      send_unse
6b70: 6e 74 28 26 78 66 65 72 29 3b 0a 20 20 20 20 20  nt(&xfer);.     
6b80: 20 6e 43 61 72 64 20 2b 3d 20 73 65 6e 64 5f 75   nCard += send_u
6b90: 6e 63 6c 75 73 74 65 72 65 64 28 26 78 66 65 72  nclustered(&xfer
6ba0: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
6bb0: 20 53 65 6e 64 20 63 6f 6e 66 69 67 75 72 61 74   Send configurat
6bc0: 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 20 72 65  ion parameter re
6bd0: 71 75 65 73 74 73 20 2a 2f 0a 20 20 20 20 69 66  quests */.    if
6be0: 28 20 63 6f 6e 66 69 67 52 63 76 4d 61 73 6b 20  ( configRcvMask 
6bf0: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
6c00: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
6c10: 20 20 7a 4e 61 6d 65 20 3d 20 63 6f 6e 66 69 67    zName = config
6c20: 75 72 65 5f 66 69 72 73 74 5f 6e 61 6d 65 28 63  ure_first_name(c
6c30: 6f 6e 66 69 67 52 63 76 4d 61 73 6b 29 3b 0a 20  onfigRcvMask);. 
6c40: 20 20 20 20 20 77 68 69 6c 65 28 20 7a 4e 61 6d       while( zNam
6c50: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f  e ){.        blo
6c60: 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c  b_appendf(&send,
6c70: 20 22 72 65 71 63 6f 6e 66 69 67 20 25 73 5c 6e   "reqconfig %s\n
6c80: 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20  ", zName);.     
6c90: 20 20 20 7a 4e 61 6d 65 20 3d 20 63 6f 6e 66 69     zName = confi
6ca0: 67 75 72 65 5f 6e 65 78 74 5f 6e 61 6d 65 28 63  gure_next_name(c
6cb0: 6f 6e 66 69 67 52 63 76 4d 61 73 6b 29 3b 0a 20  onfigRcvMask);. 
6cc0: 20 20 20 20 20 20 20 6e 43 61 72 64 2b 2b 3b 0a         nCard++;.
6cd0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
6ce0: 28 20 63 6f 6e 66 69 67 52 63 76 4d 61 73 6b 20  ( configRcvMask 
6cf0: 26 20 28 43 4f 4e 46 49 47 53 45 54 5f 55 53 45  & (CONFIGSET_USE
6d00: 52 7c 43 4f 4e 46 49 47 53 45 54 5f 54 4b 54 29  R|CONFIGSET_TKT)
6d10: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 66   ){.        conf
6d20: 69 67 75 72 65 5f 70 72 65 70 61 72 65 5f 74 6f  igure_prepare_to
6d30: 5f 72 65 63 65 69 76 65 28 30 29 3b 0a 20 20 20  _receive(0);.   
6d40: 20 20 20 7d 0a 20 20 20 20 20 20 63 6f 6e 66 69     }.      confi
6d50: 67 52 63 76 4d 61 73 6b 20 3d 20 30 3b 0a 20 20  gRcvMask = 0;.  
6d60: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 65 6e 64    }..    /* Send
6d70: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70   configuration p
6d80: 61 72 61 6d 65 74 65 72 73 20 62 65 69 6e 67 20  arameters being 
6d90: 70 75 73 68 65 64 20 2a 2f 0a 20 20 20 20 69 66  pushed */.    if
6da0: 28 20 63 6f 6e 66 69 67 53 65 6e 64 4d 61 73 6b  ( configSendMask
6db0: 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20   ){.      const 
6dc0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
6dd0: 20 20 20 7a 4e 61 6d 65 20 3d 20 63 6f 6e 66 69     zName = confi
6de0: 67 75 72 65 5f 66 69 72 73 74 5f 6e 61 6d 65 28  gure_first_name(
6df0: 63 6f 6e 66 69 67 53 65 6e 64 4d 61 73 6b 29 3b  configSendMask);
6e00: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 7a 4e  .      while( zN
6e10: 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20 73  ame ){.        s
6e20: 65 6e 64 5f 63 6f 6e 66 69 67 5f 63 61 72 64 28  end_config_card(
6e30: 26 78 66 65 72 2c 20 7a 4e 61 6d 65 29 3b 0a 20  &xfer, zName);. 
6e40: 20 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 63         zName = c
6e50: 6f 6e 66 69 67 75 72 65 5f 6e 65 78 74 5f 6e 61  onfigure_next_na
6e60: 6d 65 28 63 6f 6e 66 69 67 53 65 6e 64 4d 61 73  me(configSendMas
6e70: 6b 29 3b 0a 20 20 20 20 20 20 20 20 6e 43 61 72  k);.        nCar
6e80: 64 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  d++;.      }.   
6e90: 20 20 20 63 6f 6e 66 69 67 53 65 6e 64 4d 61 73     configSendMas
6ea0: 6b 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 0a 20 20  k = 0;.    }..  
6eb0: 20 20 2f 2a 20 41 70 70 65 6e 64 20 72 61 6e 64    /* Append rand
6ec0: 6f 6d 6e 65 73 73 20 74 6f 20 74 68 65 20 65 6e  omness to the en
6ed0: 64 20 6f 66 20 74 68 65 20 6d 65 73 73 61 67 65  d of the message
6ee0: 20 2a 2f 0a 23 69 66 20 31 20 20 20 2f 2a 20 45   */.#if 1   /* E
6ef0: 6e 61 62 6c 65 20 74 68 69 73 20 61 66 74 65 72  nable this after
6f00: 20 61 6c 6c 20 73 65 72 76 65 72 73 20 68 61 76   all servers hav
6f10: 65 20 75 70 67 72 61 64 65 64 20 2a 2f 0a 20 20  e upgraded */.  
6f20: 20 20 7a 52 61 6e 64 6f 6d 6e 65 73 73 20 3d 20    zRandomness = 
6f30: 64 62 5f 74 65 78 74 28 30 2c 20 22 53 45 4c 45  db_text(0, "SELE
6f40: 43 54 20 68 65 78 28 72 61 6e 64 6f 6d 62 6c 6f  CT hex(randomblo
6f50: 62 28 32 30 29 29 22 29 3b 0a 20 20 20 20 62 6c  b(20))");.    bl
6f60: 6f 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64  ob_appendf(&send
6f70: 2c 20 22 23 20 25 73 5c 6e 22 2c 20 7a 52 61 6e  , "# %s\n", zRan
6f80: 64 6f 6d 6e 65 73 73 29 3b 0a 20 20 20 20 66 72  domness);.    fr
6f90: 65 65 28 7a 52 61 6e 64 6f 6d 6e 65 73 73 29 3b  ee(zRandomness);
6fa0: 0a 23 65 6e 64 69 66 0a 0a 20 20 20 20 2f 2a 20  .#endif..    /* 
6fb0: 45 78 63 68 61 6e 67 65 20 6d 65 73 73 61 67 65  Exchange message
6fc0: 73 20 77 69 74 68 20 74 68 65 20 73 65 72 76 65  s with the serve
6fd0: 72 20 2a 2f 0a 20 20 20 20 6e 46 69 6c 65 53 65  r */.    nFileSe
6fe0: 6e 64 20 3d 20 78 66 65 72 2e 6e 46 69 6c 65 53  nd = xfer.nFileS
6ff0: 65 6e 74 20 2b 20 78 66 65 72 2e 6e 44 65 6c 74  ent + xfer.nDelt
7000: 61 53 65 6e 74 3b 0a 20 20 20 20 70 72 69 6e 74  aSent;.    print
7010: 66 28 7a 56 61 6c 75 65 46 6f 72 6d 61 74 2c 20  f(zValueFormat, 
7020: 22 53 65 6e 64 3a 22 2c 0a 20 20 20 20 20 20 20  "Send:",.       
7030: 20 20 20 20 20 62 6c 6f 62 5f 73 69 7a 65 28 26       blob_size(&
7040: 73 65 6e 64 29 2c 20 6e 43 61 72 64 2b 78 66 65  send), nCard+xfe
7050: 72 2e 6e 47 69 6d 6d 65 53 65 6e 74 2b 78 66 65  r.nGimmeSent+xfe
7060: 72 2e 6e 49 47 6f 74 53 65 6e 74 2c 0a 20 20 20  r.nIGotSent,.   
7070: 20 20 20 20 20 20 20 20 20 78 66 65 72 2e 6e 46           xfer.nF
7080: 69 6c 65 53 65 6e 74 2c 20 78 66 65 72 2e 6e 44  ileSent, xfer.nD
7090: 65 6c 74 61 53 65 6e 74 29 3b 0a 20 20 20 20 6e  eltaSent);.    n
70a0: 43 61 72 64 20 3d 20 30 3b 0a 20 20 20 20 78 66  Card = 0;.    xf
70b0: 65 72 2e 6e 46 69 6c 65 53 65 6e 74 20 3d 20 30  er.nFileSent = 0
70c0: 3b 0a 20 20 20 20 78 66 65 72 2e 6e 44 65 6c 74  ;.    xfer.nDelt
70d0: 61 53 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 78  aSent = 0;.    x
70e0: 66 65 72 2e 6e 47 69 6d 6d 65 53 65 6e 74 20 3d  fer.nGimmeSent =
70f0: 20 30 3b 0a 20 20 20 20 66 66 6c 75 73 68 28 73   0;.    fflush(s
7100: 74 64 6f 75 74 29 3b 0a 20 20 20 20 68 74 74 70  tdout);.    http
7110: 5f 65 78 63 68 61 6e 67 65 28 26 73 65 6e 64 2c  _exchange(&send,
7120: 20 26 72 65 63 76 29 3b 0a 20 20 20 20 62 6c 6f   &recv);.    blo
7130: 62 5f 72 65 73 65 74 28 26 73 65 6e 64 29 3b 0a  b_reset(&send);.
7140: 0a 20 20 20 20 2f 2a 20 42 65 67 69 6e 20 63 6f  .    /* Begin co
7150: 6e 73 74 72 75 63 74 69 6e 67 20 74 68 65 20 6e  nstructing the n
7160: 65 78 74 20 6d 65 73 73 61 67 65 20 28 77 68 69  ext message (whi
7170: 63 68 20 6d 69 67 68 74 20 6e 65 76 65 72 20 62  ch might never b
7180: 65 0a 20 20 20 20 2a 2a 20 73 65 6e 74 29 20 62  e.    ** sent) b
7190: 79 20 62 65 67 69 6e 6e 69 6e 67 20 77 69 74 68  y beginning with
71a0: 20 74 68 65 20 70 75 6c 6c 20 6f 72 20 70 75 73   the pull or pus
71b0: 68 20 63 61 72 64 73 0a 20 20 20 20 2a 2f 0a 20  h cards.    */. 
71c0: 20 20 20 69 66 28 20 70 75 6c 6c 46 6c 61 67 20     if( pullFlag 
71d0: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70  ){.      blob_ap
71e0: 70 65 6e 64 66 28 26 73 65 6e 64 2c 20 22 70 75  pendf(&send, "pu
71f0: 6c 6c 20 25 73 20 25 73 5c 6e 22 2c 20 7a 53 43  ll %s %s\n", zSC
7200: 6f 64 65 2c 20 7a 50 43 6f 64 65 29 3b 0a 20 20  ode, zPCode);.  
7210: 20 20 20 20 6e 43 61 72 64 2b 2b 3b 0a 20 20 20      nCard++;.   
7220: 20 7d 0a 20 20 20 20 69 66 28 20 70 75 73 68 46   }.    if( pushF
7230: 6c 61 67 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f  lag ){.      blo
7240: 62 5f 61 70 70 65 6e 64 66 28 26 73 65 6e 64 2c  b_appendf(&send,
7250: 20 22 70 75 73 68 20 25 73 20 25 73 5c 6e 22 2c   "push %s %s\n",
7260: 20 7a 53 43 6f 64 65 2c 20 7a 50 43 6f 64 65 29   zSCode, zPCode)
7270: 3b 0a 20 20 20 20 20 20 6e 43 61 72 64 2b 2b 3b  ;.      nCard++;
7280: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 50  .    }..    /* P
7290: 72 6f 63 65 73 73 20 74 68 65 20 72 65 70 6c 79  rocess the reply
72a0: 20 74 68 61 74 20 63 61 6d 65 20 62 61 63 6b 20   that came back 
72b0: 66 72 6f 6d 20 74 68 65 20 73 65 72 76 65 72 20  from the server 
72c0: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 62 6c  */.    while( bl
72d0: 6f 62 5f 6c 69 6e 65 28 26 72 65 63 76 2c 20 26  ob_line(&recv, &
72e0: 78 66 65 72 2e 6c 69 6e 65 29 20 29 7b 0a 20 20  xfer.line) ){.  
72f0: 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 62 75 66      if( blob_buf
7300: 66 65 72 28 26 78 66 65 72 2e 6c 69 6e 65 29 5b  fer(&xfer.line)[
7310: 30 5d 3d 3d 27 23 27 20 29 7b 0a 20 20 20 20 20  0]=='#' ){.     
7320: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
7330: 20 20 20 7d 0a 20 20 20 20 20 20 78 66 65 72 2e     }.      xfer.
7340: 6e 54 6f 6b 65 6e 20 3d 20 62 6c 6f 62 5f 74 6f  nToken = blob_to
7350: 6b 65 6e 69 7a 65 28 26 78 66 65 72 2e 6c 69 6e  kenize(&xfer.lin
7360: 65 2c 20 78 66 65 72 2e 61 54 6f 6b 65 6e 2c 20  e, xfer.aToken, 
7370: 63 6f 75 6e 74 28 78 66 65 72 2e 61 54 6f 6b 65  count(xfer.aToke
7380: 6e 29 29 3b 0a 20 20 20 20 20 20 6e 43 61 72 64  n));.      nCard
7390: 2b 2b 3b 0a 20 20 20 20 20 20 70 72 69 6e 74 66  ++;.      printf
73a0: 28 22 5c 72 25 64 22 2c 20 6e 43 61 72 64 29 3b  ("\r%d", nCard);
73b0: 0a 20 20 20 20 20 20 66 66 6c 75 73 68 28 73 74  .      fflush(st
73c0: 64 6f 75 74 29 3b 0a 0a 20 20 20 20 20 20 2f 2a  dout);..      /*
73d0: 20 20 20 66 69 6c 65 20 55 55 49 44 20 53 49 5a     file UUID SIZ
73e0: 45 20 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20  E \n CONTENT.   
73f0: 20 20 20 2a 2a 20 20 20 66 69 6c 65 20 55 55 49     **   file UUI
7400: 44 20 44 45 4c 54 41 53 52 43 20 53 49 5a 45 20  D DELTASRC SIZE 
7410: 5c 6e 20 43 4f 4e 54 45 4e 54 0a 20 20 20 20 20  \n CONTENT.     
7420: 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 52 65 63   **.      ** Rec
7430: 65 69 76 65 20 61 20 66 69 6c 65 20 74 72 61 6e  eive a file tran
7440: 73 6d 69 74 74 65 64 20 66 72 6f 6d 20 74 68 65  smitted from the
7450: 20 73 65 72 76 65 72 2e 0a 20 20 20 20 20 20 2a   server..      *
7460: 2f 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62  /.      if( blob
7470: 5f 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e  _eq(&xfer.aToken
7480: 5b 30 5d 2c 22 66 69 6c 65 22 29 20 29 7b 0a 20  [0],"file") ){. 
7490: 20 20 20 20 20 20 20 78 66 65 72 5f 61 63 63 65         xfer_acce
74a0: 70 74 5f 66 69 6c 65 28 26 78 66 65 72 29 3b 0a  pt_file(&xfer);.
74b0: 20 20 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20        }else..   
74c0: 20 20 20 2f 2a 20 20 20 67 69 6d 6d 65 20 55 55     /*   gimme UU
74d0: 49 44 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20  ID.      **.    
74e0: 20 20 2a 2a 20 53 65 72 76 65 72 20 69 73 20 72    ** Server is r
74f0: 65 71 75 65 73 74 69 6e 67 20 61 20 66 69 6c 65  equesting a file
7500: 2e 20 20 49 66 20 74 68 65 20 66 69 6c 65 20 69  .  If the file i
7510: 73 20 61 20 6d 61 6e 69 66 65 73 74 2c 20 61 73  s a manifest, as
7520: 73 75 6d 65 0a 20 20 20 20 20 20 2a 2a 20 74 68  sume.      ** th
7530: 61 74 20 74 68 65 20 73 65 72 76 65 72 20 77 69  at the server wi
7540: 6c 6c 20 61 6c 73 6f 20 77 61 6e 74 20 74 6f 20  ll also want to 
7550: 6b 6e 6f 77 20 61 6c 6c 20 6f 66 20 74 68 65 20  know all of the 
7560: 63 6f 6e 74 65 6e 74 20 66 69 6c 65 73 0a 20 20  content files.  
7570: 20 20 20 20 2a 2a 20 61 73 73 6f 63 69 61 74 65      ** associate
7580: 64 20 77 69 74 68 20 74 68 65 20 6d 61 6e 69 66  d with the manif
7590: 65 73 74 20 61 6e 64 20 73 65 6e 64 20 74 68 6f  est and send tho
75a0: 73 65 20 74 6f 6f 2e 0a 20 20 20 20 20 20 2a 2f  se too..      */
75b0: 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f  .      if( blob_
75c0: 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  eq(&xfer.aToken[
75d0: 30 5d 2c 20 22 67 69 6d 6d 65 22 29 0a 20 20 20  0], "gimme").   
75e0: 20 20 20 20 26 26 20 78 66 65 72 2e 6e 54 6f 6b      && xfer.nTok
75f0: 65 6e 3d 3d 32 0a 20 20 20 20 20 20 20 26 26 20  en==2.       && 
7600: 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28 26 78 66  blob_is_uuid(&xf
7610: 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 29 0a 20 20  er.aToken[1]).  
7620: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 69      ){.        i
7630: 66 28 20 70 75 73 68 46 6c 61 67 20 29 7b 0a 20  f( pushFlag ){. 
7640: 20 20 20 20 20 20 20 20 20 69 6e 74 20 72 69 64           int rid
7650: 20 3d 20 72 69 64 5f 66 72 6f 6d 5f 75 75 69 64   = rid_from_uuid
7660: 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d  (&xfer.aToken[1]
7670: 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , 0);.          
7680: 69 66 28 20 72 69 64 20 29 20 73 65 6e 64 5f 66  if( rid ) send_f
7690: 69 6c 65 28 26 78 66 65 72 2c 20 72 69 64 2c 20  ile(&xfer, rid, 
76a0: 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 2c  &xfer.aToken[1],
76b0: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   0);.        }. 
76c0: 20 20 20 20 20 7d 65 6c 73 65 0a 20 20 0a 20 20       }else.  .  
76d0: 20 20 20 20 2f 2a 20 20 20 69 67 6f 74 20 55 55      /*   igot UU
76e0: 49 44 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20  ID.      **.    
76f0: 20 20 2a 2a 20 53 65 72 76 65 72 20 61 6e 6e 6f    ** Server anno
7700: 75 6e 63 65 73 20 74 68 61 74 20 69 74 20 68 61  unces that it ha
7710: 73 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 66  s a particular f
7720: 69 6c 65 2e 20 20 49 66 20 74 68 69 73 20 69 73  ile.  If this is
7730: 0a 20 20 20 20 20 20 2a 2a 20 6e 6f 74 20 61 20  .      ** not a 
7740: 66 69 6c 65 20 74 68 61 74 20 77 65 20 68 61 76  file that we hav
7750: 65 20 61 6e 64 20 77 65 20 61 72 65 20 70 75 6c  e and we are pul
7760: 6c 69 6e 67 2c 20 74 68 65 6e 20 63 72 65 61 74  ling, then creat
7770: 65 20 61 0a 20 20 20 20 20 20 2a 2a 20 70 68 61  e a.      ** pha
7780: 6e 74 6f 6d 20 74 6f 20 63 61 75 73 65 20 74 68  ntom to cause th
7790: 69 73 20 66 69 6c 65 20 74 6f 20 62 65 20 72 65  is file to be re
77a0: 71 75 65 73 74 65 64 20 6f 6e 20 74 68 65 20 6e  quested on the n
77b0: 65 78 74 20 63 79 63 6c 65 2e 0a 20 20 20 20 20  ext cycle..     
77c0: 20 2a 2a 20 41 6c 77 61 79 73 20 72 65 6d 65 6d   ** Always remem
77d0: 62 65 72 20 74 68 61 74 20 74 68 65 20 73 65 72  ber that the ser
77e0: 76 65 72 20 68 61 73 20 74 68 69 73 20 66 69 6c  ver has this fil
77f0: 65 20 73 6f 20 74 68 61 74 20 77 65 20 64 6f 0a  e so that we do.
7800: 20 20 20 20 20 20 2a 2a 20 6e 6f 74 20 74 72 61        ** not tra
7810: 6e 73 6d 69 74 20 69 74 20 62 79 20 61 63 63 69  nsmit it by acci
7820: 64 65 6e 74 2e 0a 20 20 20 20 20 20 2a 2f 0a 20  dent..      */. 
7830: 20 20 20 20 20 69 66 28 20 78 66 65 72 2e 6e 54       if( xfer.nT
7840: 6f 6b 65 6e 3d 3d 32 0a 20 20 20 20 20 20 20 26  oken==2.       &
7850: 26 20 62 6c 6f 62 5f 65 71 28 26 78 66 65 72 2e  & blob_eq(&xfer.
7860: 61 54 6f 6b 65 6e 5b 30 5d 2c 20 22 69 67 6f 74  aToken[0], "igot
7870: 22 29 0a 20 20 20 20 20 20 20 26 26 20 62 6c 6f  ").       && blo
7880: 62 5f 69 73 5f 75 75 69 64 28 26 78 66 65 72 2e  b_is_uuid(&xfer.
7890: 61 54 6f 6b 65 6e 5b 31 5d 29 0a 20 20 20 20 20  aToken[1]).     
78a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
78b0: 72 69 64 20 3d 20 72 69 64 5f 66 72 6f 6d 5f 75  rid = rid_from_u
78c0: 75 69 64 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e  uid(&xfer.aToken
78d0: 5b 31 5d 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  [1], 0);.       
78e0: 20 69 66 28 20 72 69 64 3d 3d 30 20 26 26 20 28   if( rid==0 && (
78f0: 70 75 6c 6c 46 6c 61 67 20 7c 7c 20 63 6c 6f 6e  pullFlag || clon
7900: 65 46 6c 61 67 29 20 29 7b 0a 20 20 20 20 20 20  eFlag) ){.      
7910: 20 20 20 20 72 69 64 20 3d 20 63 6f 6e 74 65 6e      rid = conten
7920: 74 5f 6e 65 77 28 62 6c 6f 62 5f 73 74 72 28 26  t_new(blob_str(&
7930: 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 29 29  xfer.aToken[1]))
7940: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
7950: 72 69 64 20 29 20 6e 65 77 50 68 61 6e 74 6f 6d  rid ) newPhantom
7960: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 1;.        }.
7970: 20 20 20 20 20 20 20 20 72 65 6d 6f 74 65 5f 68          remote_h
7980: 61 73 28 72 69 64 29 3b 0a 20 20 20 20 20 20 7d  as(rid);.      }
7990: 65 6c 73 65 0a 20 20 20 20 0a 20 20 20 20 20 20  else.    .      
79a0: 0a 20 20 20 20 20 20 2f 2a 20 20 20 70 75 73 68  .      /*   push
79b0: 20 20 53 45 52 56 45 52 43 4f 44 45 20 20 50 52    SERVERCODE  PR
79c0: 4f 44 55 43 54 43 4f 44 45 0a 20 20 20 20 20 20  ODUCTCODE.      
79d0: 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 53 68 6f 75  **.      ** Shou
79e0: 6c 64 20 6f 6e 6c 79 20 68 61 70 70 65 6e 20 69  ld only happen i
79f0: 6e 20 72 65 73 70 6f 6e 73 65 20 74 6f 20 61 20  n response to a 
7a00: 63 6c 6f 6e 65 2e 20 20 54 68 69 73 20 6d 65 73  clone.  This mes
7a10: 73 61 67 65 20 74 65 6c 6c 73 0a 20 20 20 20 20  sage tells.     
7a20: 20 2a 2a 20 74 68 65 20 63 6c 69 65 6e 74 20 77   ** the client w
7a30: 68 61 74 20 70 72 6f 64 75 63 74 20 74 6f 20 75  hat product to u
7a40: 73 65 20 66 6f 72 20 74 68 65 20 6e 65 77 20 64  se for the new d
7a50: 61 74 61 62 61 73 65 2e 0a 20 20 20 20 20 20 2a  atabase..      *
7a60: 2f 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62  /.      if( blob
7a70: 5f 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e  _eq(&xfer.aToken
7a80: 5b 30 5d 2c 22 70 75 73 68 22 29 0a 20 20 20 20  [0],"push").    
7a90: 20 20 20 26 26 20 78 66 65 72 2e 6e 54 6f 6b 65     && xfer.nToke
7aa0: 6e 3d 3d 33 0a 20 20 20 20 20 20 20 26 26 20 63  n==3.       && c
7ab0: 6c 6f 6e 65 46 6c 61 67 0a 20 20 20 20 20 20 20  loneFlag.       
7ac0: 26 26 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64 28  && blob_is_uuid(
7ad0: 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31 5d 29  &xfer.aToken[1])
7ae0: 0a 20 20 20 20 20 20 20 26 26 20 62 6c 6f 62 5f  .       && blob_
7af0: 69 73 5f 75 75 69 64 28 26 78 66 65 72 2e 61 54  is_uuid(&xfer.aT
7b00: 6f 6b 65 6e 5b 32 5d 29 0a 20 20 20 20 20 20 29  oken[2]).      )
7b10: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 6c  {.        if( bl
7b20: 6f 62 5f 65 71 5f 73 74 72 28 26 78 66 65 72 2e  ob_eq_str(&xfer.
7b30: 61 54 6f 6b 65 6e 5b 31 5d 2c 20 7a 53 43 6f 64  aToken[1], zSCod
7b40: 65 2c 20 2d 31 29 20 29 7b 0a 20 20 20 20 20 20  e, -1) ){.      
7b50: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c      fossil_fatal
7b60: 28 22 73 65 72 76 65 72 20 6c 6f 6f 70 22 29 3b  ("server loop");
7b70: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
7b80: 20 20 20 69 66 28 20 7a 50 43 6f 64 65 3d 3d 30     if( zPCode==0
7b90: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 50   ){.          zP
7ba0: 43 6f 64 65 20 3d 20 6d 70 72 69 6e 74 66 28 22  Code = mprintf("
7bb0: 25 62 22 2c 20 26 78 66 65 72 2e 61 54 6f 6b 65  %b", &xfer.aToke
7bc0: 6e 5b 32 5d 29 3b 0a 20 20 20 20 20 20 20 20 20  n[2]);.         
7bd0: 20 64 62 5f 73 65 74 28 22 70 72 6f 6a 65 63 74   db_set("project
7be0: 2d 63 6f 64 65 22 2c 20 7a 50 43 6f 64 65 2c 20  -code", zPCode, 
7bf0: 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  0);.        }.  
7c00: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
7c10: 64 66 28 26 73 65 6e 64 2c 20 22 63 6c 6f 6e 65  df(&send, "clone
7c20: 5c 6e 22 29 3b 0a 20 20 20 20 20 20 20 20 6e 43  \n");.        nC
7c30: 61 72 64 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c  ard++;.      }el
7c40: 73 65 0a 20 20 20 20 20 20 0a 20 20 20 20 20 20  se.      .      
7c50: 2f 2a 20 20 20 63 6f 6e 66 69 67 20 4e 41 4d 45  /*   config NAME
7c60: 20 53 49 5a 45 20 5c 6e 20 43 4f 4e 54 45 4e 54   SIZE \n CONTENT
7c70: 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20  .      **.      
7c80: 2a 2a 20 52 65 63 65 69 76 65 20 61 20 63 6f 6e  ** Receive a con
7c90: 66 69 67 75 72 61 74 69 6f 6e 20 76 61 6c 75 65  figuration value
7ca0: 20 66 72 6f 6d 20 74 68 65 20 73 65 72 76 65 72   from the server
7cb0: 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  ..      */.     
7cc0: 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26 78 66   if( blob_eq(&xf
7cd0: 65 72 2e 61 54 6f 6b 65 6e 5b 30 5d 2c 22 63 6f  er.aToken[0],"co
7ce0: 6e 66 69 67 22 29 20 26 26 20 78 66 65 72 2e 6e  nfig") && xfer.n
7cf0: 54 6f 6b 65 6e 3d 3d 33 0a 20 20 20 20 20 20 20  Token==3.       
7d00: 20 20 20 26 26 20 62 6c 6f 62 5f 69 73 5f 69 6e     && blob_is_in
7d10: 74 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 32  t(&xfer.aToken[2
7d20: 5d 2c 20 26 73 69 7a 65 29 20 29 7b 0a 20 20 20  ], &size) ){.   
7d30: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
7d40: 2a 7a 4e 61 6d 65 20 3d 20 62 6c 6f 62 5f 73 74  *zName = blob_st
7d50: 72 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 31  r(&xfer.aToken[1
7d60: 5d 29 3b 0a 20 20 20 20 20 20 20 20 42 6c 6f 62  ]);.        Blob
7d70: 20 63 6f 6e 74 65 6e 74 3b 0a 20 20 20 20 20 20   content;.      
7d80: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 63 6f 6e    blob_zero(&con
7d90: 74 65 6e 74 29 3b 0a 20 20 20 20 20 20 20 20 62  tent);.        b
7da0: 6c 6f 62 5f 65 78 74 72 61 63 74 28 78 66 65 72  lob_extract(xfer
7db0: 2e 70 49 6e 2c 20 73 69 7a 65 2c 20 26 63 6f 6e  .pIn, size, &con
7dc0: 74 65 6e 74 29 3b 0a 20 20 20 20 20 20 20 20 67  tent);.        g
7dd0: 2e 6f 6b 41 64 6d 69 6e 20 3d 20 67 2e 6f 6b 52  .okAdmin = g.okR
7de0: 64 41 64 64 72 20 3d 20 31 3b 0a 20 20 20 20 20  dAddr = 1;.     
7df0: 20 20 20 69 66 28 20 63 6f 6e 66 69 67 75 72 65     if( configure
7e00: 5f 69 73 5f 65 78 70 6f 72 74 61 62 6c 65 28 7a  _is_exportable(z
7e10: 4e 61 6d 65 29 20 26 20 6f 72 69 67 43 6f 6e 66  Name) & origConf
7e20: 69 67 52 63 76 4d 61 73 6b 20 29 7b 0a 20 20 20  igRcvMask ){.   
7e30: 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65         if( zName
7e40: 5b 30 5d 21 3d 27 40 27 20 29 7b 0a 20 20 20 20  [0]!='@' ){.    
7e50: 20 20 20 20 20 20 20 20 64 62 5f 6d 75 6c 74 69          db_multi
7e60: 5f 65 78 65 63 28 0a 20 20 20 20 20 20 20 20 20  _exec(.         
7e70: 20 20 20 20 20 20 20 22 52 45 50 4c 41 43 45 20         "REPLACE 
7e80: 49 4e 54 4f 20 63 6f 6e 66 69 67 28 6e 61 6d 65  INTO config(name
7e90: 2c 76 61 6c 75 65 29 20 56 41 4c 55 45 53 28 25  ,value) VALUES(%
7ea0: 51 2c 25 51 29 22 2c 0a 20 20 20 20 20 20 20 20  Q,%Q)",.        
7eb0: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 62          zName, b
7ec0: 6c 6f 62 5f 73 74 72 28 26 63 6f 6e 74 65 6e 74  lob_str(&content
7ed0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 29 3b  ).            );
7ee0: 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65  .          }else
7ef0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  {.            /*
7f00: 20 4e 6f 74 69 63 65 20 74 68 61 74 20 77 65 20   Notice that we 
7f10: 61 72 65 20 65 76 61 6c 75 61 74 69 6e 67 20 61  are evaluating a
7f20: 72 62 69 74 72 61 72 79 20 53 51 4c 20 72 65 63  rbitrary SQL rec
7f30: 65 69 76 65 64 20 66 72 6f 6d 20 74 68 65 0a 20  eived from the. 
7f40: 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 73 65             ** se
7f50: 72 76 65 72 2e 20 20 42 75 74 20 74 68 69 73 20  rver.  But this 
7f60: 63 61 6e 20 6f 6e 6c 79 20 68 61 70 70 65 6e 20  can only happen 
7f70: 69 66 20 77 65 20 68 61 76 65 20 73 70 65 63 69  if we have speci
7f80: 66 69 63 61 6c 6c 79 0a 20 20 20 20 20 20 20 20  fically.        
7f90: 20 20 20 20 2a 2a 20 72 65 71 75 65 73 74 65 64      ** requested
7fa0: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 69   configuration i
7fb0: 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 72 6f 6d 20  nformation from 
7fc0: 74 68 65 20 73 65 72 76 65 72 2c 20 73 6f 0a 20  the server, so. 
7fd0: 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 70 72             ** pr
7fe0: 65 73 75 6d 61 62 6c 79 20 74 68 65 20 6f 70 65  esumably the ope
7ff0: 72 61 74 6f 72 20 74 72 75 73 74 73 20 74 68 65  rator trusts the
8000: 20 73 65 72 76 65 72 2e 0a 20 20 20 20 20 20 20   server..       
8010: 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20       */.        
8020: 20 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65      db_multi_exe
8030: 63 28 22 25 73 22 2c 20 62 6c 6f 62 5f 73 74 72  c("%s", blob_str
8040: 28 26 63 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 20  (&content));.   
8050: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
8060: 20 7d 0a 20 20 20 20 20 20 20 20 6e 43 61 72 64   }.        nCard
8070: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62  ++;.        blob
8080: 5f 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29  _reset(&content)
8090: 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 73  ;.        blob_s
80a0: 65 65 6b 28 78 66 65 72 2e 70 49 6e 2c 20 31 2c  eek(xfer.pIn, 1,
80b0: 20 42 4c 4f 42 5f 53 45 45 4b 5f 43 55 52 29 3b   BLOB_SEEK_CUR);
80c0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20  .      }else..  
80d0: 20 20 20 20 0a 20 20 20 20 20 20 2f 2a 20 20 20      .      /*   
80e0: 20 63 6f 6f 6b 69 65 20 54 45 58 54 0a 20 20 20   cookie TEXT.   
80f0: 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 54     **.      ** T
8100: 68 65 20 73 65 72 76 65 72 20 6d 69 67 68 74 20  he server might 
8110: 69 6e 63 6c 75 64 65 20 61 20 63 6f 6f 6b 69 65  include a cookie
8120: 20 69 6e 20 69 74 73 20 72 65 70 6c 79 2e 20 20   in its reply.  
8130: 54 68 65 20 63 6c 69 65 6e 74 0a 20 20 20 20 20  The client.     
8140: 20 2a 2a 20 73 68 6f 75 6c 64 20 72 65 6d 65 6d   ** should remem
8150: 62 65 72 20 74 68 69 73 20 63 6f 6f 6b 69 65 20  ber this cookie 
8160: 61 6e 64 20 73 65 6e 64 20 69 74 20 62 61 63 6b  and send it back
8170: 20 74 6f 20 74 68 65 20 73 65 72 76 65 72 0a 20   to the server. 
8180: 20 20 20 20 20 2a 2a 20 69 6e 20 69 74 73 20 6e       ** in its n
8190: 65 78 74 20 71 75 65 72 79 2e 0a 20 20 20 20 20  ext query..     
81a0: 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 45 61 63   **.      ** Eac
81b0: 68 20 63 6f 6f 6b 69 65 20 72 65 63 65 69 76 65  h cookie receive
81c0: 64 20 6f 76 65 72 77 72 69 74 65 73 20 74 68 65  d overwrites the
81d0: 20 70 72 69 6f 72 20 63 6f 6f 6b 69 65 20 66 72   prior cookie fr
81e0: 6f 6d 20 74 68 65 0a 20 20 20 20 20 20 2a 2a 20  om the.      ** 
81f0: 73 61 6d 65 20 73 65 72 76 65 72 2e 0a 20 20 20  same server..   
8200: 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20     */.      if( 
8210: 62 6c 6f 62 5f 65 71 28 26 78 66 65 72 2e 61 54  blob_eq(&xfer.aT
8220: 6f 6b 65 6e 5b 30 5d 2c 20 22 63 6f 6f 6b 69 65  oken[0], "cookie
8230: 22 29 20 26 26 20 78 66 65 72 2e 6e 54 6f 6b 65  ") && xfer.nToke
8240: 6e 3d 3d 32 20 29 7b 0a 20 20 20 20 20 20 20 20  n==2 ){.        
8250: 64 62 5f 73 65 74 28 22 63 6f 6f 6b 69 65 22 2c  db_set("cookie",
8260: 20 62 6c 6f 62 5f 73 74 72 28 26 78 66 65 72 2e   blob_str(&xfer.
8270: 61 54 6f 6b 65 6e 5b 31 5d 29 2c 20 30 29 3b 0a  aToken[1]), 0);.
8280: 20 20 20 20 20 20 7d 65 6c 73 65 0a 0a 20 20 20        }else..   
8290: 20 20 20 2f 2a 20 20 20 6d 65 73 73 61 67 65 20     /*   message 
82a0: 4d 45 53 53 41 47 45 0a 20 20 20 20 20 20 2a 2a  MESSAGE.      **
82b0: 0a 20 20 20 20 20 20 2a 2a 20 50 72 69 6e 74 20  .      ** Print 
82c0: 61 20 6d 65 73 73 61 67 65 2e 20 20 53 69 6d 69  a message.  Simi
82d0: 6c 61 72 20 74 6f 20 22 65 72 72 6f 72 22 20 62  lar to "error" b
82e0: 75 74 20 64 6f 65 73 20 6e 6f 74 20 73 74 6f 70  ut does not stop
82f0: 20 70 72 6f 63 65 73 73 69 6e 67 0a 20 20 20 20   processing.    
8300: 20 20 2a 2f 20 20 20 20 20 20 20 20 0a 20 20 20    */        .   
8310: 20 20 20 69 66 28 20 62 6c 6f 62 5f 65 71 28 26     if( blob_eq(&
8320: 78 66 65 72 2e 61 54 6f 6b 65 6e 5b 30 5d 2c 22  xfer.aToken[0],"
8330: 6d 65 73 73 61 67 65 22 29 20 26 26 20 78 66 65  message") && xfe
8340: 72 2e 6e 54 6f 6b 65 6e 3d 3d 32 20 29 7b 0a 20  r.nToken==2 ){. 
8350: 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4d 73         char *zMs
8360: 67 20 3d 20 62 6c 6f 62 5f 74 65 72 6d 69 6e 61  g = blob_termina
8370: 74 65 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  te(&xfer.aToken[
8380: 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 64 65 66  1]);.        def
8390: 6f 73 73 69 6c 69 7a 65 28 7a 4d 73 67 29 3b 0a  ossilize(zMsg);.
83a0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 66 28 22          printf("
83b0: 53 65 72 76 65 72 20 73 61 79 73 3a 20 25 73 5c  Server says: %s\
83c0: 6e 22 2c 20 7a 4d 73 67 29 3b 0a 20 20 20 20 20  n", zMsg);.     
83d0: 20 7d 65 6c 73 65 0a 0a 20 20 20 20 20 20 2f 2a   }else..      /*
83e0: 20 20 20 65 72 72 6f 72 20 4d 45 53 53 41 47 45     error MESSAGE
83f0: 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20  .      **.      
8400: 2a 2a 20 52 65 70 6f 72 74 20 61 6e 20 65 72 72  ** Report an err
8410: 6f 72 20 61 6e 64 20 61 62 61 6e 64 6f 6e 20 74  or and abandon t
8420: 68 65 20 73 79 6e 63 20 73 65 73 73 69 6f 6e 0a  he sync session.
8430: 20 20 20 20 20 20 2a 2f 20 20 20 20 20 20 20 20        */        
8440: 0a 20 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f  .      if( blob_
8450: 65 71 28 26 78 66 65 72 2e 61 54 6f 6b 65 6e 5b  eq(&xfer.aToken[
8460: 30 5d 2c 22 65 72 72 6f 72 22 29 20 26 26 20 78  0],"error") && x
8470: 66 65 72 2e 6e 54 6f 6b 65 6e 3d 3d 32 20 29 7b  fer.nToken==2 ){
8480: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a  .        char *z
8490: 4d 73 67 20 3d 20 62 6c 6f 62 5f 74 65 72 6d 69  Msg = blob_termi
84a0: 6e 61 74 65 28 26 78 66 65 72 2e 61 54 6f 6b 65  nate(&xfer.aToke
84b0: 6e 5b 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 64  n[1]);.        d
84c0: 65 66 6f 73 73 69 6c 69 7a 65 28 7a 4d 73 67 29  efossilize(zMsg)
84d0: 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 61  ;.        blob_a
84e0: 70 70 65 6e 64 66 28 26 78 66 65 72 2e 65 72 72  ppendf(&xfer.err
84f0: 2c 20 22 73 65 72 76 65 72 20 73 61 79 73 3a 20  , "server says: 
8500: 25 73 22 2c 20 7a 4d 73 67 29 3b 0a 20 20 20 20  %s", zMsg);.    
8510: 20 20 7d 65 6c 73 65 0a 0a 20 20 20 20 20 20 2f    }else..      /
8520: 2a 20 55 6e 6b 6e 6f 77 6e 20 6d 65 73 73 61 67  * Unknown messag
8530: 65 20 2a 2f 0a 20 20 20 20 20 20 7b 0a 20 20 20  e */.      {.   
8540: 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64       blob_append
8550: 66 28 26 78 66 65 72 2e 65 72 72 2c 20 22 75 6e  f(&xfer.err, "un
8560: 6b 6e 6f 77 6e 20 63 6f 6d 6d 61 6e 64 3a 20 25  known command: %
8570: 62 22 2c 20 26 78 66 65 72 2e 61 54 6f 6b 65 6e  b", &xfer.aToken
8580: 5b 30 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  [0]);.      }.. 
8590: 20 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 73 69       if( blob_si
85a0: 7a 65 28 26 78 66 65 72 2e 65 72 72 29 20 29 7b  ze(&xfer.err) ){
85b0: 0a 20 20 20 20 20 20 20 20 66 6f 73 73 69 6c 5f  .        fossil_
85c0: 66 61 74 61 6c 28 22 25 62 22 2c 20 26 78 66 65  fatal("%b", &xfe
85d0: 72 2e 65 72 72 29 3b 0a 20 20 20 20 20 20 7d 0a  r.err);.      }.
85e0: 20 20 20 20 20 20 62 6c 6f 62 61 72 72 61 79 5f        blobarray_
85f0: 72 65 73 65 74 28 78 66 65 72 2e 61 54 6f 6b 65  reset(xfer.aToke
8600: 6e 2c 20 78 66 65 72 2e 6e 54 6f 6b 65 6e 29 3b  n, xfer.nToken);
8610: 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  .      blob_rese
8620: 74 28 26 78 66 65 72 2e 6c 69 6e 65 29 3b 0a 20  t(&xfer.line);. 
8630: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 6f 72 69     }.    if( ori
8640: 67 43 6f 6e 66 69 67 52 63 76 4d 61 73 6b 20 26  gConfigRcvMask &
8650: 20 28 43 4f 4e 46 49 47 53 45 54 5f 54 4b 54 7c   (CONFIGSET_TKT|
8660: 43 4f 4e 46 49 47 53 45 54 5f 55 53 45 52 29 20  CONFIGSET_USER) 
8670: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 66 69 67 75  ){.      configu
8680: 72 65 5f 66 69 6e 61 6c 69 7a 65 5f 72 65 63 65  re_finalize_rece
8690: 69 76 65 28 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ive();.    }.   
86a0: 20 6f 72 69 67 43 6f 6e 66 69 67 52 63 76 4d 61   origConfigRcvMa
86b0: 73 6b 20 3d 20 30 3b 0a 20 20 20 20 70 72 69 6e  sk = 0;.    prin
86c0: 74 66 28 7a 56 61 6c 75 65 46 6f 72 6d 61 74 2c  tf(zValueFormat,
86d0: 20 22 52 65 63 65 69 76 65 64 3a 22 2c 0a 20 20   "Received:",.  
86e0: 20 20 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 73            blob_s
86f0: 69 7a 65 28 26 72 65 63 76 29 2c 20 6e 43 61 72  ize(&recv), nCar
8700: 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 78  d,.            x
8710: 66 65 72 2e 6e 46 69 6c 65 52 63 76 64 2c 20 78  fer.nFileRcvd, x
8720: 66 65 72 2e 6e 44 65 6c 74 61 52 63 76 64 20 2b  fer.nDeltaRcvd +
8730: 20 78 66 65 72 2e 6e 44 61 6e 67 6c 69 6e 67 46   xfer.nDanglingF
8740: 69 6c 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  ile);.    blob_r
8750: 65 73 65 74 28 26 72 65 63 76 29 3b 0a 20 20 20  eset(&recv);.   
8760: 20 6e 43 79 63 6c 65 2b 2b 3b 0a 20 20 20 20 67   nCycle++;.    g
8770: 6f 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a 20 49  o = 0;..    /* I
8780: 66 20 77 65 20 72 65 63 65 69 76 65 64 20 6f 6e  f we received on
8790: 65 20 6f 72 20 6d 6f 72 65 20 66 69 6c 65 73 20  e or more files 
87a0: 6f 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73 20  on the previous 
87b0: 65 78 63 68 61 6e 67 65 20 62 75 74 0a 20 20 20  exchange but.   
87c0: 20 2a 2a 20 74 68 65 72 65 20 61 72 65 20 73 74   ** there are st
87d0: 69 6c 6c 20 70 68 61 6e 74 6f 6d 73 2c 20 74 68  ill phantoms, th
87e0: 65 6e 20 67 6f 20 61 6e 6f 74 68 65 72 20 72 6f  en go another ro
87f0: 75 6e 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  und..    */.    
8800: 6e 46 69 6c 65 52 65 63 76 20 3d 20 78 66 65 72  nFileRecv = xfer
8810: 2e 6e 46 69 6c 65 52 63 76 64 20 2b 20 78 66 65  .nFileRcvd + xfe
8820: 72 2e 6e 44 65 6c 74 61 52 63 76 64 20 2b 20 78  r.nDeltaRcvd + x
8830: 66 65 72 2e 6e 44 61 6e 67 6c 69 6e 67 46 69 6c  fer.nDanglingFil
8840: 65 3b 0a 20 20 20 20 69 66 28 20 28 6e 46 69 6c  e;.    if( (nFil
8850: 65 52 65 63 76 3e 30 20 7c 7c 20 6e 65 77 50 68  eRecv>0 || newPh
8860: 61 6e 74 6f 6d 29 20 26 26 20 64 62 5f 65 78 69  antom) && db_exi
8870: 73 74 73 28 22 53 45 4c 45 43 54 20 31 20 46 52  sts("SELECT 1 FR
8880: 4f 4d 20 70 68 61 6e 74 6f 6d 22 29 20 29 7b 0a  OM phantom") ){.
8890: 20 20 20 20 20 20 67 6f 20 3d 20 31 3b 0a 20 20        go = 1;.  
88a0: 20 20 20 20 6d 78 50 68 61 6e 74 6f 6d 52 65 71      mxPhantomReq
88b0: 20 3d 20 6e 46 69 6c 65 52 65 63 76 2a 32 3b 0a   = nFileRecv*2;.
88c0: 20 20 20 20 20 20 69 66 28 20 6d 78 50 68 61 6e        if( mxPhan
88d0: 74 6f 6d 52 65 71 3c 32 30 30 20 29 20 6d 78 50  tomReq<200 ) mxP
88e0: 68 61 6e 74 6f 6d 52 65 71 20 3d 20 32 30 30 3b  hantomReq = 200;
88f0: 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43 61 72 64  .    }.    nCard
8900: 20 3d 20 30 3b 0a 20 20 20 20 78 66 65 72 2e 6e   = 0;.    xfer.n
8910: 46 69 6c 65 52 63 76 64 20 3d 20 30 3b 0a 20 20  FileRcvd = 0;.  
8920: 20 20 78 66 65 72 2e 6e 44 65 6c 74 61 52 63 76    xfer.nDeltaRcv
8930: 64 20 3d 20 30 3b 0a 20 20 20 20 78 66 65 72 2e  d = 0;.    xfer.
8940: 6e 44 61 6e 67 6c 69 6e 67 46 69 6c 65 20 3d 20  nDanglingFile = 
8950: 30 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 77 65  0;..    /* If we
8960: 20 68 61 76 65 20 6f 6e 65 20 6f 72 20 6d 6f 72   have one or mor
8970: 65 20 66 69 6c 65 73 20 71 75 65 75 65 64 20 74  e files queued t
8980: 6f 20 73 65 6e 64 2c 20 74 68 65 6e 20 67 6f 0a  o send, then go.
8990: 20 20 20 20 2a 2a 20 61 6e 6f 74 68 65 72 20 72      ** another r
89a0: 6f 75 6e 64 20 0a 20 20 20 20 2a 2f 0a 20 20 20  ound .    */.   
89b0: 20 69 66 28 20 78 66 65 72 2e 6e 46 69 6c 65 53   if( xfer.nFileS
89c0: 65 6e 74 2b 78 66 65 72 2e 6e 44 65 6c 74 61 53  ent+xfer.nDeltaS
89d0: 65 6e 74 3e 30 20 29 7b 0a 20 20 20 20 20 20 67  ent>0 ){.      g
89e0: 6f 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  o = 1;.    }.  }
89f0: 3b 0a 20 20 68 74 74 70 5f 63 6c 6f 73 65 28 29  ;.  http_close()
8a00: 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65  ;.  db_multi_exe
8a10: 63 28 22 44 52 4f 50 20 54 41 42 4c 45 20 6f 6e  c("DROP TABLE on
8a20: 72 65 6d 6f 74 65 22 29 3b 0a 20 20 64 62 5f 65  remote");.  db_e
8a30: 6e 64 5f 74 72 61 6e 73 61 63 74 69 6f 6e 28 30  nd_transaction(0
8a40: 29 3b 0a 7d 0a                                   );.}.