Hex Artifact Content

Artifact 3805f48036457abcf7babb93adfe39b6f9505d5f:


0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45  #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e  _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 74 79 70 65 73  clude <sys/types
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 71  .h>.#include <sq
0040: 6c 69 74 65 33 2e 68 3e 0a 23 69 6e 63 6c 75 64  lite3.h>.#includ
0050: 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a 23 69  e <pthread.h>.#i
0060: 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68  nclude <string.h
0070: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 61  >.#include <stda
0080: 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  rg.h>.#include <
0090: 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75  stdlib.h>.#inclu
00a0: 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69  de <unistd.h>.#i
00b0: 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e  nclude <errno.h>
00c0: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c  .#include <fcntl
00d0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
00e0: 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  dio.h>.#include 
00f0: 3c 66 75 73 65 2e 68 3e 0a 23 69 6e 63 6c 75 64  <fuse.h>.#includ
0100: 65 20 3c 74 63 6c 2e 68 3e 0a 0a 23 64 65 66 69  e <tcl.h>..#defi
0110: 6e 65 20 41 50 50 46 53 5f 43 41 43 48 45 44 49  ne APPFS_CACHEDI
0120: 52 20 22 2f 74 6d 70 2f 61 70 70 66 73 2d 63 61  R "/tmp/appfs-ca
0130: 63 68 65 22 0a 0a 23 64 65 66 69 6e 65 20 41 50  che"..#define AP
0140: 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20  PFS_DEBUG(x...) 
0150: 7b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  { fprintf(stderr
0160: 2c 20 22 5b 64 65 62 75 67 5d 20 25 73 3a 25 69  , "[debug] %s:%i
0170: 3a 25 73 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f  :%s: ", __FILE__
0180: 2c 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75  , __LINE__, __fu
0190: 6e 63 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73  nc__); fprintf(s
01a0: 74 64 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e  tderr, x); fprin
01b0: 74 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29  tf(stderr, "\n")
01c0: 3b 20 7d 0a 0a 73 74 61 74 69 63 20 70 74 68 72  ; }..static pthr
01d0: 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74 65 72 70  ead_key_t interp
01e0: 4b 65 79 3b 0a 0a 73 74 72 75 63 74 20 61 70 70  Key;..struct app
01f0: 66 73 5f 74 68 72 65 61 64 5f 64 61 74 61 20 7b  fs_thread_data {
0200: 0a 09 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 09  ..sqlite3 *db;..
0210: 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 61 63 68  const char *cach
0220: 65 64 69 72 3b 0a 09 74 69 6d 65 5f 74 20 62 6f  edir;..time_t bo
0230: 6f 74 74 69 6d 65 3b 0a 7d 3b 0a 0a 73 74 72 75  ottime;.};..stru
0240: 63 74 20 61 70 70 66 73 5f 74 68 72 65 61 64 5f  ct appfs_thread_
0250: 64 61 74 61 20 67 6c 6f 62 61 6c 54 68 72 65 61  data globalThrea
0260: 64 3b 0a 0a 74 79 70 65 64 65 66 20 65 6e 75 6d  d;..typedef enum
0270: 20 7b 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59   {..APPFS_PATHTY
0280: 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09 41 50 50  PE_INVALID,..APP
0290: 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45  FS_PATHTYPE_FILE
02a0: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
02b0: 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a 09 41 50  E_DIRECTORY,..AP
02c0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d  PFS_PATHTYPE_SYM
02d0: 4c 49 4e 4b 0a 7d 20 61 70 70 66 73 5f 70 61 74  LINK.} appfs_pat
02e0: 68 74 79 70 65 5f 74 3b 0a 0a 73 74 72 75 63 74  htype_t;..struct
02f0: 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65 6e 20   appfs_children 
0300: 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  {..struct appfs_
0310: 63 68 69 6c 64 72 65 6e 20 2a 5f 6e 65 78 74 3b  children *_next;
0320: 0a 09 69 6e 74 20 63 6f 75 6e 74 65 72 3b 0a 0a  ..int counter;..
0330: 09 63 68 61 72 20 6e 61 6d 65 5b 32 35 36 5d 3b  .char name[256];
0340: 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 61 70 70 66  .};..struct appf
0350: 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61 70  s_pathinfo {..ap
0360: 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 20 74  pfs_pathtype_t t
0370: 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69 6d  ype;..time_t tim
0380: 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e 61 6d  e;..char hostnam
0390: 65 5b 32 35 36 5d 3b 0a 09 75 6e 69 6f 6e 20 7b  e[256];..union {
03a0: 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69  ...struct {....i
03b0: 6e 74 20 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09  nt childcount;..
03c0: 09 7d 20 64 69 72 3b 0a 09 09 73 74 72 75 63 74  .} dir;...struct
03d0: 20 7b 0a 09 09 09 69 6e 74 20 65 78 65 63 75 74   {....int execut
03e0: 61 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73  able;....off_t s
03f0: 69 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 68 61  ize;....char sha
0400: 31 5b 34 31 5d 3b 0a 09 09 7d 20 66 69 6c 65 3b  1[41];...} file;
0410: 0a 09 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 7d 3b  ..} typeinfo;.};
0420: 0a 0a 73 74 72 75 63 74 20 61 70 70 66 73 5f 73  ..struct appfs_s
0430: 71 6c 69 74 65 33 5f 71 75 65 72 79 5f 63 62 5f  qlite3_query_cb_
0440: 68 61 6e 64 6c 65 20 7b 0a 09 73 74 72 75 63 74  handle {..struct
0450: 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65 6e 20   appfs_children 
0460: 2a 68 65 61 64 3b 0a 09 69 6e 74 20 61 72 67 63  *head;..int argc
0470: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 66  ;..const char *f
0480: 6d 74 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 54  mt;.};..static T
0490: 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73  cl_Interp *appfs
04a0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
04b0: 70 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 61  p(const char *ca
04c0: 63 68 65 64 69 72 29 20 7b 0a 09 54 63 6c 5f 49  chedir) {..Tcl_I
04d0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
04e0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
04f0: 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65 61  nterp = Tcl_Crea
0500: 74 65 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  teInterp();..if 
0510: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
0520: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
0530: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
0540: 63 72 65 61 74 65 20 54 63 6c 20 49 6e 74 65 72  create Tcl Inter
0550: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e  preter.  Abortin
0560: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72  g.\n");....retur
0570: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
0580: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 49 6e 69 74  l_ret = Tcl_Init
0590: 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 74  (interp);..if (t
05a0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
05b0: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
05c0: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
05d0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 2e   initialize Tcl.
05e0: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
05f0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
0600: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
0610: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
0620: 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 61  , "".#include "a
0630: 70 70 66 73 64 2e 74 63 6c 2e 68 22 0a 09 22 22  ppfsd.tcl.h"..""
0640: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
0650: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66  != TCL_OK) {...f
0660: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
0670: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61  Unable to initia
0680: 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73  lize Tcl AppFS s
0690: 63 72 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67  cript.  Aborting
06a0: 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  .\n");...fprintf
06b0: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
06c0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
06d0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
06e0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
06f0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
0700: 0a 0a 09 69 66 20 28 54 63 6c 5f 53 65 74 56 61  ...if (Tcl_SetVa
0710: 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70  r(interp, "::app
0720: 66 73 3a 3a 63 61 63 68 65 64 69 72 22 2c 20 63  fs::cachedir", c
0730: 61 63 68 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f  achedir, TCL_GLO
0740: 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e 55 4c  BAL_ONLY) == NUL
0750: 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  L) {...fprintf(s
0760: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
0770: 6f 20 73 65 74 20 63 61 63 68 65 20 64 69 72 65  o set cache dire
0780: 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f  ctory.  This sho
0790: 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c  uld never fail.\
07a0: 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  n");....return(N
07b0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  ULL);..}...tcl_r
07c0: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
07d0: 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  terp, "::appfs::
07e0: 69 6e 69 74 22 29 3b 0a 09 69 66 20 28 74 63 6c  init");..if (tcl
07f0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
0800: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
0810: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
0820: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70  nitialize Tcl Ap
0830: 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61 70  pFS script (::ap
0840: 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62 6f  pfs::init).  Abo
0850: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70  rting.\n");...fp
0860: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
0870: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
0880: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
0890: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
08a0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
08b0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 69  );..}...return(i
08c0: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 73 74 61 74 69  nterp);.}..stati
08d0: 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c 5f  c int appfs_Tcl_
08e0: 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70 20  Eval(Tcl_Interp 
08f0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
0900: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
0910: 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f  md, ...) {..Tcl_
0920: 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e  Obj **objv;..con
0930: 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09 76  st char *arg;..v
0940: 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69 6e  a_list argp;..in
0950: 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 69  t retval;..int i
0960: 3b 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64  ;...objv = (void
0970: 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65   *) ckalloc(size
0980: 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63  of(*objv) * objc
0990: 29 3b 0a 09 6f 62 6a 76 5b 30 5d 20 3d 20 54 63  );..objv[0] = Tc
09a0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 63  l_NewStringObj(c
09b0: 6d 64 2c 20 2d 31 29 3b 0a 09 54 63 6c 5f 49 6e  md, -1);..Tcl_In
09c0: 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b  crRefCount(objv[
09d0: 30 5d 29 3b 0a 0a 09 76 61 5f 73 74 61 72 74 28  0]);...va_start(
09e0: 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 66 6f 72  argp, cmd);..for
09f0: 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f 62 6a   (i = 1; i < obj
0a00: 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 67 20  c; i++) {...arg 
0a10: 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c 20 63  = va_arg(argp, c
0a20: 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a 09 09  onst char *);...
0a30: 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65  objv[i] = Tcl_Ne
0a40: 77 53 74 72 69 6e 67 4f 62 6a 28 61 72 67 2c 20  wStringObj(arg, 
0a50: 2d 31 29 3b 0a 09 09 54 63 6c 5f 49 6e 63 72 52  -1);...Tcl_IncrR
0a60: 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29  efCount(objv[i])
0a70: 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64 28 61 72 67  ;..}..va_end(arg
0a80: 70 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 54  p);...retval = T
0a90: 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74 65  cl_EvalObjv(inte
0aa0: 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20  rp, objc, objv, 
0ab0: 30 29 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20 30  0);...for (i = 0
0ac0: 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29  ; i < objc; i++)
0ad0: 20 7b 0a 09 09 54 63 6c 5f 44 65 63 72 52 65 66   {...Tcl_DecrRef
0ae0: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a  Count(objv[i]);.
0af0: 09 7d 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f 69  .}...ckfree((voi
0b00: 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69 66  d *) objv);...if
0b10: 20 28 72 65 74 76 61 6c 20 21 3d 20 54 43 4c 5f   (retval != TCL_
0b20: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
0b30: 42 55 47 28 22 54 63 6c 20 63 6f 6d 6d 61 6e 64  BUG("Tcl command
0b40: 20 66 61 69 6c 65 64 2c 20 3a 3a 65 72 72 6f 72   failed, ::error
0b50: 49 6e 66 6f 20 63 6f 6e 74 61 69 6e 73 3a 20 25  Info contains: %
0b60: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72  s\n", Tcl_GetVar
0b70: 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65 72 72 6f  (interp, "::erro
0b80: 72 49 6e 66 6f 22 2c 20 30 29 29 3b 0a 09 7d 0a  rInfo", 0));..}.
0b90: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
0ba0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
0bb0: 20 61 70 70 66 73 5f 75 70 64 61 74 65 5f 69 6e   appfs_update_in
0bc0: 64 65 78 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  dex(const char *
0bd0: 68 6f 73 74 6e 61 6d 65 29 20 7b 0a 09 54 63 6c  hostname) {..Tcl
0be0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
0bf0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
0c00: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
0c10: 74 65 72 3a 20 68 6f 73 74 6e 61 6d 65 20 3d 20  ter: hostname = 
0c20: 25 73 22 2c 20 68 6f 73 74 6e 61 6d 65 29 3b 0a  %s", hostname);.
0c30: 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65  ..interp = pthre
0c40: 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 69  ad_getspecific(i
0c50: 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28  nterpKey);..if (
0c60: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
0c70: 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70 70  {...interp = app
0c80: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
0c90: 65 72 70 28 67 6c 6f 62 61 6c 54 68 72 65 61 64  erp(globalThread
0ca0: 2e 63 61 63 68 65 64 69 72 29 3b 0a 0a 09 09 70  .cachedir);....p
0cb0: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66  thread_setspecif
0cc0: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e  ic(interpKey, in
0cd0: 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  terp);..}...tcl_
0ce0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
0cf0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
0d00: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 69 6e 64  "::appfs::getind
0d10: 65 78 22 2c 20 68 6f 73 74 6e 61 6d 65 29 3b 0a  ex", hostname);.
0d20: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
0d30: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
0d40: 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f  S_DEBUG("Call to
0d50: 20 3a 3a 61 70 70 66 73 3a 3a 67 65 74 69 6e 64   ::appfs::getind
0d60: 65 78 20 66 61 69 6c 65 64 3a 20 25 73 22 2c 20  ex failed: %s", 
0d70: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0d80: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
0d90: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
0da0: 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  turn;.}..static 
0db0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
0dc0: 73 5f 67 65 74 66 69 6c 65 28 63 6f 6e 73 74 20  s_getfile(const 
0dd0: 63 68 61 72 20 2a 68 6f 73 74 6e 61 6d 65 2c 20  char *hostname, 
0de0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 68 61 31  const char *sha1
0df0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
0e00: 2a 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a  *interp;..char *
0e10: 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 74 63 6c  retval;..int tcl
0e20: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
0e30: 20 70 74 68 72 65 61 64 5f 67 65 74 73 70 65 63   pthread_getspec
0e40: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 29 3b  ific(interpKey);
0e50: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
0e60: 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72 70  NULL) {...interp
0e70: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
0e80: 54 63 6c 49 6e 74 65 72 70 28 67 6c 6f 62 61 6c  TclInterp(global
0e90: 54 68 72 65 61 64 2e 63 61 63 68 65 64 69 72 29  Thread.cachedir)
0ea0: 3b 0a 0a 09 09 70 74 68 72 65 61 64 5f 73 65 74  ;....pthread_set
0eb0: 73 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b  specific(interpK
0ec0: 65 79 2c 20 69 6e 74 65 72 70 29 3b 0a 09 7d 0a  ey, interp);..}.
0ed0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
0ee0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
0ef0: 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 3, "::appfs::
0f00: 64 6f 77 6e 6c 6f 61 64 22 2c 20 68 6f 73 74 6e  download", hostn
0f10: 61 6d 65 2c 20 73 68 61 31 29 3b 0a 09 69 66 20  ame, sha1);..if 
0f20: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
0f30: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
0f40: 42 55 47 28 22 43 61 6c 6c 20 74 6f 20 3a 3a 61  BUG("Call to ::a
0f50: 70 70 66 73 3a 3a 64 6f 77 6e 6c 6f 61 64 20 66  ppfs::download f
0f60: 61 69 6c 65 64 3a 20 25 73 22 2c 20 54 63 6c 5f  ailed: %s", Tcl_
0f70: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
0f80: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74  interp));....ret
0f90: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
0fa0: 72 65 74 76 61 6c 20 3d 20 73 74 72 64 75 70 28  retval = strdup(
0fb0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0fc0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
0fd0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
0fe0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  }..static void a
0ff0: 70 70 66 73 5f 75 70 64 61 74 65 5f 6d 61 6e 69  ppfs_update_mani
1000: 66 65 73 74 28 63 6f 6e 73 74 20 63 68 61 72 20  fest(const char 
1010: 2a 68 6f 73 74 6e 61 6d 65 2c 20 63 6f 6e 73 74  *hostname, const
1020: 20 63 68 61 72 20 2a 73 68 61 31 29 20 7b 0a 09   char *sha1) {..
1030: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1040: 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  rp;..int tcl_ret
1050: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68  ;...interp = pth
1060: 72 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63  read_getspecific
1070: 28 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66  (interpKey);..if
1080: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
1090: 29 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61  ) {...interp = a
10a0: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
10b0: 6e 74 65 72 70 28 67 6c 6f 62 61 6c 54 68 72 65  nterp(globalThre
10c0: 61 64 2e 63 61 63 68 65 64 69 72 29 3b 0a 0a 09  ad.cachedir);...
10d0: 09 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63  .pthread_setspec
10e0: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20  ific(interpKey, 
10f0: 69 6e 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 74 63  interp);..}...tc
1100: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
1110: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33  l_Eval(interp, 3
1120: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 70  , "::appfs::getp
1130: 6b 67 6d 61 6e 69 66 65 73 74 22 2c 20 68 6f 73  kgmanifest", hos
1140: 74 6e 61 6d 65 2c 20 73 68 61 31 29 3b 0a 09 69  tname, sha1);..i
1150: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
1160: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
1170: 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f 20 3a  DEBUG("Call to :
1180: 3a 61 70 70 66 73 3a 3a 67 65 74 70 6b 67 6d 61  :appfs::getpkgma
1190: 6e 69 66 65 73 74 20 66 61 69 6c 65 64 3a 20 25  nifest failed: %
11a0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
11b0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
11c0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
11d0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 0a 23 64  ..return;.}...#d
11e0: 65 66 69 6e 65 20 61 70 70 66 73 5f 66 72 65 65  efine appfs_free
11f0: 5f 6c 69 73 74 5f 74 79 70 65 28 69 64 2c 20 74  _list_type(id, t
1200: 79 70 65 29 20 73 74 61 74 69 63 20 76 6f 69 64  ype) static void
1210: 20 61 70 70 66 73 5f 66 72 65 65 5f 6c 69 73 74   appfs_free_list
1220: 5f 20 23 23 20 69 64 28 74 79 70 65 20 2a 68 65  _ ## id(type *he
1230: 61 64 29 20 7b 20 5c 0a 09 74 79 70 65 20 2a 6f  ad) { \..type *o
1240: 62 6a 2c 20 2a 6e 65 78 74 3b 20 5c 0a 09 66 6f  bj, *next; \..fo
1250: 72 20 28 6f 62 6a 20 3d 20 68 65 61 64 3b 20 6f  r (obj = head; o
1260: 62 6a 3b 20 6f 62 6a 20 3d 20 6e 65 78 74 29 20  bj; obj = next) 
1270: 7b 20 5c 0a 09 09 6e 65 78 74 20 3d 20 6f 62 6a  { \...next = obj
1280: 2d 3e 5f 6e 65 78 74 3b 20 5c 0a 09 09 63 6b 66  ->_next; \...ckf
1290: 72 65 65 28 28 76 6f 69 64 20 2a 29 20 6f 62 6a  ree((void *) obj
12a0: 29 3b 20 5c 0a 09 7d 20 5c 0a 7d 0a 0a 61 70 70  ); \..} \.}..app
12b0: 66 73 5f 66 72 65 65 5f 6c 69 73 74 5f 74 79 70  fs_free_list_typ
12c0: 65 28 63 68 69 6c 64 72 65 6e 2c 20 73 74 72 75  e(children, stru
12d0: 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65  ct appfs_childre
12e0: 6e 29 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  n)..static int a
12f0: 70 70 66 73 5f 67 65 74 63 68 69 6c 64 72 65 6e  ppfs_getchildren
1300: 5f 63 62 28 76 6f 69 64 20 2a 5f 68 65 61 64 2c  _cb(void *_head,
1310: 20 69 6e 74 20 63 6f 6c 75 6d 6e 73 2c 20 63 68   int columns, ch
1320: 61 72 20 2a 2a 76 61 6c 75 65 73 2c 20 63 68 61  ar **values, cha
1330: 72 20 2a 2a 6e 61 6d 65 73 29 20 7b 0a 09 73 74  r **names) {..st
1340: 72 75 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64  ruct appfs_child
1350: 72 65 6e 20 2a 2a 68 65 61 64 5f 70 2c 20 2a 6f  ren **head_p, *o
1360: 62 6a 3b 0a 0a 09 68 65 61 64 5f 70 20 3d 20 5f  bj;...head_p = _
1370: 68 65 61 64 3b 0a 0a 09 6f 62 6a 20 3d 20 28 76  head;...obj = (v
1380: 6f 69 64 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73  oid *) ckalloc(s
1390: 69 7a 65 6f 66 28 2a 6f 62 6a 29 29 3b 0a 0a 09  izeof(*obj));...
13a0: 73 6e 70 72 69 6e 74 66 28 6f 62 6a 2d 3e 6e 61  snprintf(obj->na
13b0: 6d 65 2c 20 73 69 7a 65 6f 66 28 6f 62 6a 2d 3e  me, sizeof(obj->
13c0: 6e 61 6d 65 29 2c 20 22 25 73 22 2c 20 76 61 6c  name), "%s", val
13d0: 75 65 73 5b 30 5d 29 3b 0a 0a 09 69 66 20 28 2a  ues[0]);...if (*
13e0: 68 65 61 64 5f 70 20 3d 3d 20 4e 55 4c 4c 29 20  head_p == NULL) 
13f0: 7b 0a 09 09 6f 62 6a 2d 3e 63 6f 75 6e 74 65 72  {...obj->counter
1400: 20 3d 20 30 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a   = 0;..} else {.
1410: 09 09 6f 62 6a 2d 3e 63 6f 75 6e 74 65 72 20 3d  ..obj->counter =
1420: 20 28 2a 68 65 61 64 5f 70 29 2d 3e 63 6f 75 6e   (*head_p)->coun
1430: 74 65 72 20 2b 20 31 3b 0a 09 7d 0a 0a 09 6f 62  ter + 1;..}...ob
1440: 6a 2d 3e 5f 6e 65 78 74 20 3d 20 2a 68 65 61 64  j->_next = *head
1450: 5f 70 3b 0a 09 2a 68 65 61 64 5f 70 20 3d 20 6f  _p;..*head_p = o
1460: 62 6a 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  bj;...return(0);
1470: 0a 09 0a 7d 0a 0a 73 74 61 74 69 63 20 73 74 72  ...}..static str
1480: 75 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64 72  uct appfs_childr
1490: 65 6e 20 2a 61 70 70 66 73 5f 67 65 74 63 68 69  en *appfs_getchi
14a0: 6c 64 72 65 6e 28 63 6f 6e 73 74 20 63 68 61 72  ldren(const char
14b0: 20 2a 68 6f 73 74 6e 61 6d 65 2c 20 63 6f 6e 73   *hostname, cons
14c0: 74 20 63 68 61 72 20 2a 70 61 63 6b 61 67 65 5f  t char *package_
14d0: 68 61 73 68 2c 20 63 6f 6e 73 74 20 63 68 61 72  hash, const char
14e0: 20 2a 70 61 74 68 2c 20 69 6e 74 20 2a 63 68 69   *path, int *chi
14f0: 6c 64 72 65 6e 5f 63 6f 75 6e 74 5f 70 29 20 7b  ldren_count_p) {
1500: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 63  ..struct appfs_c
1510: 68 69 6c 64 72 65 6e 20 2a 68 65 61 64 20 3d 20  hildren *head = 
1520: 4e 55 4c 4c 3b 0a 09 63 68 61 72 20 2a 73 71 6c  NULL;..char *sql
1530: 3b 0a 09 69 6e 74 20 73 71 6c 69 74 65 5f 72 65  ;..int sqlite_re
1540: 74 3b 0a 0a 09 69 66 20 28 63 68 69 6c 64 72 65  t;...if (childre
1550: 6e 5f 63 6f 75 6e 74 5f 70 20 3d 3d 20 4e 55 4c  n_count_p == NUL
1560: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
1570: 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  LL);..}...appfs_
1580: 75 70 64 61 74 65 5f 69 6e 64 65 78 28 68 6f 73  update_index(hos
1590: 74 6e 61 6d 65 29 3b 0a 09 61 70 70 66 73 5f 75  tname);..appfs_u
15a0: 70 64 61 74 65 5f 6d 61 6e 69 66 65 73 74 28 68  pdate_manifest(h
15b0: 6f 73 74 6e 61 6d 65 2c 20 70 61 63 6b 61 67 65  ostname, package
15c0: 5f 68 61 73 68 29 3b 0a 0a 09 73 71 6c 20 3d 20  _hash);...sql = 
15d0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
15e0: 22 53 45 4c 45 43 54 20 66 69 6c 65 5f 6e 61 6d  "SELECT file_nam
15f0: 65 20 46 52 4f 4d 20 66 69 6c 65 73 20 57 48 45  e FROM files WHE
1600: 52 45 20 70 61 63 6b 61 67 65 5f 73 68 61 31 20  RE package_sha1 
1610: 3d 20 25 51 20 41 4e 44 20 66 69 6c 65 5f 64 69  = %Q AND file_di
1620: 72 65 63 74 6f 72 79 20 3d 20 25 51 3b 22 2c 20  rectory = %Q;", 
1630: 70 61 63 6b 61 67 65 5f 68 61 73 68 2c 20 70 61  package_hash, pa
1640: 74 68 29 3b 0a 09 69 66 20 28 73 71 6c 20 3d 3d  th);..if (sql ==
1650: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
1660: 5f 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f 20  _DEBUG("Call to 
1670: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 20  sqlite3_mprintf 
1680: 66 61 69 6c 65 64 2e 22 29 3b 0a 0a 09 09 72 65  failed.");....re
1690: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
16a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 53 51  .APPFS_DEBUG("SQ
16b0: 4c 3a 20 25 73 22 2c 20 73 71 6c 29 3b 0a 09 73  L: %s", sql);..s
16c0: 71 6c 69 74 65 5f 72 65 74 20 3d 20 73 71 6c 69  qlite_ret = sqli
16d0: 74 65 33 5f 65 78 65 63 28 67 6c 6f 62 61 6c 54  te3_exec(globalT
16e0: 68 72 65 61 64 2e 64 62 2c 20 73 71 6c 2c 20 61  hread.db, sql, a
16f0: 70 70 66 73 5f 67 65 74 63 68 69 6c 64 72 65 6e  ppfs_getchildren
1700: 5f 63 62 2c 20 26 68 65 61 64 2c 20 4e 55 4c 4c  _cb, &head, NULL
1710: 29 3b 0a 09 73 71 6c 69 74 65 33 5f 66 72 65 65  );..sqlite3_free
1720: 28 73 71 6c 29 3b 0a 0a 09 69 66 20 28 73 71 6c  (sql);...if (sql
1730: 69 74 65 5f 72 65 74 20 21 3d 20 53 51 4c 49 54  ite_ret != SQLIT
1740: 45 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  E_OK) {...APPFS_
1750: 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f 20 73  DEBUG("Call to s
1760: 71 6c 69 74 65 33 5f 65 78 65 63 20 66 61 69 6c  qlite3_exec fail
1770: 65 64 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ed.");....return
1780: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
1790: 28 68 65 61 64 20 21 3d 20 4e 55 4c 4c 29 20 7b  (head != NULL) {
17a0: 0a 09 09 2a 63 68 69 6c 64 72 65 6e 5f 63 6f 75  ...*children_cou
17b0: 6e 74 5f 70 20 3d 20 68 65 61 64 2d 3e 63 6f 75  nt_p = head->cou
17c0: 6e 74 65 72 20 2b 20 31 3b 0a 09 7d 0a 0a 09 72  nter + 1;..}...r
17d0: 65 74 75 72 6e 28 68 65 61 64 29 3b 0a 7d 0a 0a  eturn(head);.}..
17e0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
17f0: 5f 73 71 6c 69 74 65 33 5f 71 75 65 72 79 5f 63  _sqlite3_query_c
1800: 62 28 76 6f 69 64 20 2a 5f 63 62 5f 68 61 6e 64  b(void *_cb_hand
1810: 6c 65 2c 20 69 6e 74 20 63 6f 6c 75 6d 6e 73 2c  le, int columns,
1820: 20 63 68 61 72 20 2a 2a 76 61 6c 75 65 73 2c 20   char **values, 
1830: 63 68 61 72 20 2a 2a 6e 61 6d 65 73 29 20 7b 0a  char **names) {.
1840: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 73 71  .struct appfs_sq
1850: 6c 69 74 65 33 5f 71 75 65 72 79 5f 63 62 5f 68  lite3_query_cb_h
1860: 61 6e 64 6c 65 20 2a 63 62 5f 68 61 6e 64 6c 65  andle *cb_handle
1870: 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  ;..struct appfs_
1880: 63 68 69 6c 64 72 65 6e 20 2a 6f 62 6a 3b 0a 0a  children *obj;..
1890: 09 63 62 5f 68 61 6e 64 6c 65 20 3d 20 5f 63 62  .cb_handle = _cb
18a0: 5f 68 61 6e 64 6c 65 3b 0a 0a 09 6f 62 6a 20 3d  _handle;...obj =
18b0: 20 28 76 6f 69 64 20 2a 29 20 63 6b 61 6c 6c 6f   (void *) ckallo
18c0: 63 28 73 69 7a 65 6f 66 28 2a 6f 62 6a 29 29 3b  c(sizeof(*obj));
18d0: 0a 0a 09 73 77 69 74 63 68 20 28 63 62 5f 68 61  ...switch (cb_ha
18e0: 6e 64 6c 65 2d 3e 61 72 67 63 29 20 7b 0a 09 09  ndle->argc) {...
18f0: 63 61 73 65 20 31 3a 0a 09 09 09 73 6e 70 72 69  case 1:....snpri
1900: 6e 74 66 28 6f 62 6a 2d 3e 6e 61 6d 65 2c 20 73  ntf(obj->name, s
1910: 69 7a 65 6f 66 28 6f 62 6a 2d 3e 6e 61 6d 65 29  izeof(obj->name)
1920: 2c 20 63 62 5f 68 61 6e 64 6c 65 2d 3e 66 6d 74  , cb_handle->fmt
1930: 2c 20 76 61 6c 75 65 73 5b 30 5d 29 3b 0a 09 09  , values[0]);...
1940: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 32  .break;...case 2
1950: 3a 0a 09 09 09 73 6e 70 72 69 6e 74 66 28 6f 62  :....snprintf(ob
1960: 6a 2d 3e 6e 61 6d 65 2c 20 73 69 7a 65 6f 66 28  j->name, sizeof(
1970: 6f 62 6a 2d 3e 6e 61 6d 65 29 2c 20 63 62 5f 68  obj->name), cb_h
1980: 61 6e 64 6c 65 2d 3e 66 6d 74 2c 20 76 61 6c 75  andle->fmt, valu
1990: 65 73 5b 30 5d 2c 20 76 61 6c 75 65 73 5b 31 5d  es[0], values[1]
19a0: 29 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  );....break;...c
19b0: 61 73 65 20 33 3a 0a 09 09 09 73 6e 70 72 69 6e  ase 3:....snprin
19c0: 74 66 28 6f 62 6a 2d 3e 6e 61 6d 65 2c 20 73 69  tf(obj->name, si
19d0: 7a 65 6f 66 28 6f 62 6a 2d 3e 6e 61 6d 65 29 2c  zeof(obj->name),
19e0: 20 63 62 5f 68 61 6e 64 6c 65 2d 3e 66 6d 74 2c   cb_handle->fmt,
19f0: 20 76 61 6c 75 65 73 5b 30 5d 2c 20 76 61 6c 75   values[0], valu
1a00: 65 73 5b 31 5d 2c 20 76 61 6c 75 65 73 5b 32 5d  es[1], values[2]
1a10: 29 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  );....break;...c
1a20: 61 73 65 20 34 3a 0a 09 09 09 73 6e 70 72 69 6e  ase 4:....snprin
1a30: 74 66 28 6f 62 6a 2d 3e 6e 61 6d 65 2c 20 73 69  tf(obj->name, si
1a40: 7a 65 6f 66 28 6f 62 6a 2d 3e 6e 61 6d 65 29 2c  zeof(obj->name),
1a50: 20 63 62 5f 68 61 6e 64 6c 65 2d 3e 66 6d 74 2c   cb_handle->fmt,
1a60: 20 76 61 6c 75 65 73 5b 30 5d 2c 20 76 61 6c 75   values[0], valu
1a70: 65 73 5b 31 5d 2c 20 76 61 6c 75 65 73 5b 32 5d  es[1], values[2]
1a80: 2c 20 76 61 6c 75 65 73 5b 33 5d 29 3b 0a 09 09  , values[3]);...
1a90: 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20  .break;..}...if 
1aa0: 28 63 62 5f 68 61 6e 64 6c 65 2d 3e 68 65 61 64  (cb_handle->head
1ab0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 6f 62   == NULL) {...ob
1ac0: 6a 2d 3e 63 6f 75 6e 74 65 72 20 3d 20 30 3b 0a  j->counter = 0;.
1ad0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 6f 62 6a 2d  .} else {...obj-
1ae0: 3e 63 6f 75 6e 74 65 72 20 3d 20 63 62 5f 68 61  >counter = cb_ha
1af0: 6e 64 6c 65 2d 3e 68 65 61 64 2d 3e 63 6f 75 6e  ndle->head->coun
1b00: 74 65 72 20 2b 20 31 3b 0a 09 7d 0a 0a 09 6f 62  ter + 1;..}...ob
1b10: 6a 2d 3e 5f 6e 65 78 74 20 3d 20 63 62 5f 68 61  j->_next = cb_ha
1b20: 6e 64 6c 65 2d 3e 68 65 61 64 3b 0a 09 63 62 5f  ndle->head;..cb_
1b30: 68 61 6e 64 6c 65 2d 3e 68 65 61 64 20 3d 20 6f  handle->head = o
1b40: 62 6a 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  bj;...return(0);
1b50: 0a 7d 0a 0a 73 74 61 74 69 63 20 73 74 72 75 63  .}..static struc
1b60: 74 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65 6e  t appfs_children
1b70: 20 2a 61 70 70 66 73 5f 73 71 6c 69 74 65 33 5f   *appfs_sqlite3_
1b80: 71 75 65 72 79 28 63 68 61 72 20 2a 73 71 6c 2c  query(char *sql,
1b90: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
1ba0: 20 63 68 61 72 20 2a 66 6d 74 2c 20 69 6e 74 20   char *fmt, int 
1bb0: 2a 72 65 73 75 6c 74 73 5f 63 6f 75 6e 74 5f 70  *results_count_p
1bc0: 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66  ) {..struct appf
1bd0: 73 5f 73 71 6c 69 74 65 33 5f 71 75 65 72 79 5f  s_sqlite3_query_
1be0: 63 62 5f 68 61 6e 64 6c 65 20 63 62 5f 68 61 6e  cb_handle cb_han
1bf0: 64 6c 65 3b 0a 09 69 6e 74 20 73 71 6c 69 74 65  dle;..int sqlite
1c00: 5f 72 65 74 3b 0a 0a 09 69 66 20 28 72 65 73 75  _ret;...if (resu
1c10: 6c 74 73 5f 63 6f 75 6e 74 5f 70 20 3d 3d 20 4e  lts_count_p == N
1c20: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
1c30: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
1c40: 73 71 6c 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  sql == NULL) {..
1c50: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
1c60: 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 5f 6d 70  ll to sqlite3_mp
1c70: 72 69 6e 74 66 20 70 72 6f 62 61 62 6c 79 20 66  rintf probably f
1c80: 61 69 6c 65 64 2e 22 29 3b 0a 0a 09 09 72 65 74  ailed.");....ret
1c90: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
1ca0: 69 66 20 28 66 6d 74 20 3d 3d 20 4e 55 4c 4c 29  if (fmt == NULL)
1cb0: 20 7b 0a 09 09 66 6d 74 20 3d 20 22 25 73 22 3b   {...fmt = "%s";
1cc0: 0a 09 7d 0a 0a 09 63 62 5f 68 61 6e 64 6c 65 2e  ..}...cb_handle.
1cd0: 68 65 61 64 20 3d 20 4e 55 4c 4c 3b 0a 09 63 62  head = NULL;..cb
1ce0: 5f 68 61 6e 64 6c 65 2e 61 72 67 63 20 3d 20 61  _handle.argc = a
1cf0: 72 67 63 3b 0a 09 63 62 5f 68 61 6e 64 6c 65 2e  rgc;..cb_handle.
1d00: 66 6d 74 20 20 3d 20 66 6d 74 3b 0a 0a 09 41 50  fmt  = fmt;...AP
1d10: 50 46 53 5f 44 45 42 55 47 28 22 53 51 4c 3a 20  PFS_DEBUG("SQL: 
1d20: 25 73 22 2c 20 73 71 6c 29 3b 0a 09 73 71 6c 69  %s", sql);..sqli
1d30: 74 65 5f 72 65 74 20 3d 20 73 71 6c 69 74 65 33  te_ret = sqlite3
1d40: 5f 65 78 65 63 28 67 6c 6f 62 61 6c 54 68 72 65  _exec(globalThre
1d50: 61 64 2e 64 62 2c 20 73 71 6c 2c 20 61 70 70 66  ad.db, sql, appf
1d60: 73 5f 73 71 6c 69 74 65 33 5f 71 75 65 72 79 5f  s_sqlite3_query_
1d70: 63 62 2c 20 26 63 62 5f 68 61 6e 64 6c 65 2c 20  cb, &cb_handle, 
1d80: 4e 55 4c 4c 29 3b 0a 09 73 71 6c 69 74 65 33 5f  NULL);..sqlite3_
1d90: 66 72 65 65 28 73 71 6c 29 3b 0a 0a 09 69 66 20  free(sql);...if 
1da0: 28 73 71 6c 69 74 65 5f 72 65 74 20 21 3d 20 53  (sqlite_ret != S
1db0: 51 4c 49 54 45 5f 4f 4b 29 20 7b 0a 09 09 41 50  QLITE_OK) {...AP
1dc0: 50 46 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 20  PFS_DEBUG("Call 
1dd0: 74 6f 20 73 71 6c 69 74 65 33 5f 65 78 65 63 20  to sqlite3_exec 
1de0: 66 61 69 6c 65 64 2e 22 29 3b 0a 0a 09 09 72 65  failed.");....re
1df0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1e00: 09 69 66 20 28 63 62 5f 68 61 6e 64 6c 65 2e 68  .if (cb_handle.h
1e10: 65 61 64 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ead != NULL) {..
1e20: 09 2a 72 65 73 75 6c 74 73 5f 63 6f 75 6e 74 5f  .*results_count_
1e30: 70 20 3d 20 63 62 5f 68 61 6e 64 6c 65 2e 68 65  p = cb_handle.he
1e40: 61 64 2d 3e 63 6f 75 6e 74 65 72 20 2b 20 31 3b  ad->counter + 1;
1e50: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63 62 5f  ..}...return(cb_
1e60: 68 61 6e 64 6c 65 2e 68 65 61 64 29 3b 0a 7d 0a  handle.head);.}.
1e70: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
1e80: 73 5f 6c 6f 6f 6b 75 70 5f 70 61 63 6b 61 67 65  s_lookup_package
1e90: 5f 68 61 73 68 5f 63 62 28 76 6f 69 64 20 2a 5f  _hash_cb(void *_
1ea0: 72 65 74 76 61 6c 2c 20 69 6e 74 20 63 6f 6c 75  retval, int colu
1eb0: 6d 6e 73 2c 20 63 68 61 72 20 2a 2a 76 61 6c 75  mns, char **valu
1ec0: 65 73 2c 20 63 68 61 72 20 2a 2a 6e 61 6d 65 73  es, char **names
1ed0: 29 20 7b 0a 09 63 68 61 72 20 2a 2a 72 65 74 76  ) {..char **retv
1ee0: 61 6c 20 3d 20 5f 72 65 74 76 61 6c 3b 0a 0a 09  al = _retval;...
1ef0: 2a 72 65 74 76 61 6c 20 3d 20 73 74 72 64 75 70  *retval = strdup
1f00: 28 76 61 6c 75 65 73 5b 30 5d 29 3b 0a 0a 09 72  (values[0]);...r
1f10: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
1f20: 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f  tic char *appfs_
1f30: 6c 6f 6f 6b 75 70 5f 70 61 63 6b 61 67 65 5f 68  lookup_package_h
1f40: 61 73 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ash(const char *
1f50: 68 6f 73 74 6e 61 6d 65 2c 20 63 6f 6e 73 74 20  hostname, const 
1f60: 63 68 61 72 20 2a 70 61 63 6b 61 67 65 2c 20 63  char *package, c
1f70: 6f 6e 73 74 20 63 68 61 72 20 2a 6f 73 2c 20 63  onst char *os, c
1f80: 6f 6e 73 74 20 63 68 61 72 20 2a 63 70 75 41 72  onst char *cpuAr
1f90: 63 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ch, const char *
1fa0: 76 65 72 73 69 6f 6e 29 20 7b 0a 09 63 68 61 72  version) {..char
1fb0: 20 2a 73 71 6c 3b 0a 09 63 68 61 72 20 2a 72 65   *sql;..char *re
1fc0: 74 76 61 6c 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e  tval = NULL;..in
1fd0: 74 20 73 71 6c 69 74 65 5f 72 65 74 3b 0a 0a 09  t sqlite_ret;...
1fe0: 61 70 70 66 73 5f 75 70 64 61 74 65 5f 69 6e 64  appfs_update_ind
1ff0: 65 78 28 68 6f 73 74 6e 61 6d 65 29 3b 0a 0a 09  ex(hostname);...
2000: 73 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  sql = sqlite3_mp
2010: 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 73 68  rintf("SELECT sh
2020: 61 31 20 46 52 4f 4d 20 70 61 63 6b 61 67 65 73  a1 FROM packages
2030: 20 57 48 45 52 45 20 68 6f 73 74 6e 61 6d 65 20   WHERE hostname 
2040: 3d 20 25 51 20 41 4e 44 20 70 61 63 6b 61 67 65  = %Q AND package
2050: 20 3d 20 25 51 20 41 4e 44 20 6f 73 20 3d 20 25   = %Q AND os = %
2060: 51 20 41 4e 44 20 63 70 75 41 72 63 68 20 3d 20  Q AND cpuArch = 
2070: 25 51 20 41 4e 44 20 76 65 72 73 69 6f 6e 20 3d  %Q AND version =
2080: 20 25 51 3b 22 2c 0a 09 09 68 6f 73 74 6e 61 6d   %Q;",...hostnam
2090: 65 2c 0a 09 09 70 61 63 6b 61 67 65 2c 0a 09 09  e,...package,...
20a0: 6f 73 2c 0a 09 09 63 70 75 41 72 63 68 2c 0a 09  os,...cpuArch,..
20b0: 09 76 65 72 73 69 6f 6e 0a 09 29 3b 0a 09 69 66  .version..);..if
20c0: 20 28 73 71 6c 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (sql == NULL) {
20d0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
20e0: 43 61 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 5f  Call to sqlite3_
20f0: 6d 70 72 69 6e 74 66 20 66 61 69 6c 65 64 2e 22  mprintf failed."
2100: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
2110: 4c 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44  L);..}...APPFS_D
2120: 45 42 55 47 28 22 53 51 4c 3a 20 25 73 22 2c 20  EBUG("SQL: %s", 
2130: 73 71 6c 29 3b 0a 09 73 71 6c 69 74 65 5f 72 65  sql);..sqlite_re
2140: 74 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  t = sqlite3_exec
2150: 28 67 6c 6f 62 61 6c 54 68 72 65 61 64 2e 64 62  (globalThread.db
2160: 2c 20 73 71 6c 2c 20 61 70 70 66 73 5f 6c 6f 6f  , sql, appfs_loo
2170: 6b 75 70 5f 70 61 63 6b 61 67 65 5f 68 61 73 68  kup_package_hash
2180: 5f 63 62 2c 20 26 72 65 74 76 61 6c 2c 20 4e 55  _cb, &retval, NU
2190: 4c 4c 29 3b 0a 09 73 71 6c 69 74 65 33 5f 66 72  LL);..sqlite3_fr
21a0: 65 65 28 73 71 6c 29 3b 0a 0a 09 69 66 20 28 73  ee(sql);...if (s
21b0: 71 6c 69 74 65 5f 72 65 74 20 21 3d 20 53 51 4c  qlite_ret != SQL
21c0: 49 54 45 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  ITE_OK) {...APPF
21d0: 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f  S_DEBUG("Call to
21e0: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 20 66 61   sqlite3_exec fa
21f0: 69 6c 65 64 2e 22 29 3b 0a 0a 09 09 72 65 74 75  iled.");....retu
2200: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72  rn(NULL);..}...r
2210: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
2220: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
2230: 66 73 5f 67 65 74 66 69 6c 65 69 6e 66 6f 5f 63  fs_getfileinfo_c
2240: 62 28 76 6f 69 64 20 2a 5f 70 61 74 68 69 6e 66  b(void *_pathinf
2250: 6f 2c 20 69 6e 74 20 63 6f 6c 75 6d 6e 73 2c 20  o, int columns, 
2260: 63 68 61 72 20 2a 2a 76 61 6c 75 65 73 2c 20 63  char **values, c
2270: 68 61 72 20 2a 2a 6e 61 6d 65 73 29 20 7b 0a 09  har **names) {..
2280: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
2290: 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 20  hinfo *pathinfo 
22a0: 3d 20 5f 70 61 74 68 69 6e 66 6f 3b 0a 09 63 6f  = _pathinfo;..co
22b0: 6e 73 74 20 63 68 61 72 20 2a 74 79 70 65 2c 20  nst char *type, 
22c0: 2a 74 69 6d 65 2c 20 2a 73 6f 75 72 63 65 2c 20  *time, *source, 
22d0: 2a 73 69 7a 65 2c 20 2a 70 65 72 6d 73 2c 20 2a  *size, *perms, *
22e0: 73 68 61 31 3b 0a 0a 09 74 79 70 65 20 3d 20 76  sha1;...type = v
22f0: 61 6c 75 65 73 5b 30 5d 3b 0a 09 74 69 6d 65 20  alues[0];..time 
2300: 3d 20 76 61 6c 75 65 73 5b 31 5d 3b 0a 09 73 6f  = values[1];..so
2310: 75 72 63 65 20 3d 20 76 61 6c 75 65 73 5b 32 5d  urce = values[2]
2320: 3b 0a 09 73 69 7a 65 20 3d 20 76 61 6c 75 65 73  ;..size = values
2330: 5b 33 5d 3b 0a 09 70 65 72 6d 73 20 3d 20 76 61  [3];..perms = va
2340: 6c 75 65 73 5b 34 5d 3b 0a 09 73 68 61 31 20 3d  lues[4];..sha1 =
2350: 20 76 61 6c 75 65 73 5b 35 5d 3b 0a 0a 09 70 61   values[5];...pa
2360: 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 73  thinfo->time = s
2370: 74 72 74 6f 75 6c 6c 28 74 69 6d 65 2c 20 4e 55  trtoull(time, NU
2380: 4c 4c 2c 20 31 30 29 3b 0a 0a 09 69 66 20 28 73  LL, 10);...if (s
2390: 74 72 63 6d 70 28 74 79 70 65 2c 20 22 66 69 6c  trcmp(type, "fil
23a0: 65 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 70 61  e") == 0) {...pa
23b0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
23c0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
23d0: 4c 45 3b 0a 0a 09 09 69 66 20 28 21 73 69 7a 65  LE;....if (!size
23e0: 29 20 7b 0a 09 09 09 73 69 7a 65 20 3d 20 22 30  ) {....size = "0
23f0: 22 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 21 70  ";...}....if (!p
2400: 65 72 6d 73 29 20 7b 0a 09 09 09 70 65 72 6d 73  erms) {....perms
2410: 20 3d 20 22 22 3b 0a 09 09 7d 0a 0a 09 09 69 66   = "";...}....if
2420: 20 28 21 73 68 61 31 29 20 7b 0a 09 09 09 73 68   (!sha1) {....sh
2430: 61 31 20 3d 20 22 22 3b 0a 09 09 7d 0a 0a 09 09  a1 = "";...}....
2440: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
2450: 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 73  fo.file.size = s
2460: 74 72 74 6f 75 6c 6c 28 73 69 7a 65 2c 20 4e 55  trtoull(size, NU
2470: 4c 4c 2c 20 31 30 29 3b 0a 09 09 73 6e 70 72 69  LL, 10);...snpri
2480: 6e 74 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ntf(pathinfo->ty
2490: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 68 61 31  peinfo.file.sha1
24a0: 2c 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66  , sizeof(pathinf
24b0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
24c0: 2e 73 68 61 31 29 2c 20 22 25 73 22 2c 20 73 68  .sha1), "%s", sh
24d0: 61 31 29 3b 0a 0a 09 09 69 66 20 28 73 74 72 63  a1);....if (strc
24e0: 6d 70 28 70 65 72 6d 73 2c 20 22 78 22 29 20 3d  mp(perms, "x") =
24f0: 3d 20 30 29 20 7b 0a 09 09 09 70 61 74 68 69 6e  = 0) {....pathin
2500: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
2510: 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31  e.executable = 1
2520: 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ;...} else {....
2530: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
2540: 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62  fo.file.executab
2550: 6c 65 20 3d 20 30 3b 0a 09 09 7d 0a 0a 09 09 72  le = 0;...}....r
2560: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69  eturn(0);..}...i
2570: 66 20 28 73 74 72 63 6d 70 28 74 79 70 65 2c 20  f (strcmp(type, 
2580: 22 64 69 72 65 63 74 6f 72 79 22 29 20 3d 3d 20  "directory") == 
2590: 30 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d  0) {...pathinfo-
25a0: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
25b0: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
25c0: 3b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ;...pathinfo->ty
25d0: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
25e0: 63 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 72 65  count = 0;....re
25f0: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 72 65  turn(0);..}...re
2600: 74 75 72 6e 28 30 29 3b 0a 0a 09 2f 2a 20 55 6e  turn(0);.../* Un
2610: 74 69 6c 20 74 68 69 73 20 69 73 20 75 73 65 64  til this is used
2620: 2c 20 70 72 65 76 65 6e 74 20 74 68 65 20 63 6f  , prevent the co
2630: 6d 70 69 6c 65 72 20 66 72 6f 6d 20 63 6f 6d 70  mpiler from comp
2640: 6c 61 69 6e 69 6e 67 20 2a 2f 0a 09 73 6f 75 72  laining */..sour
2650: 63 65 20 3d 20 73 6f 75 72 63 65 3b 0a 7d 0a 0a  ce = source;.}..
2660: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
2670: 5f 67 65 74 66 69 6c 65 69 6e 66 6f 28 63 6f 6e  _getfileinfo(con
2680: 73 74 20 63 68 61 72 20 2a 68 6f 73 74 6e 61 6d  st char *hostnam
2690: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  e, const char *p
26a0: 61 63 6b 61 67 65 5f 68 61 73 68 2c 20 63 6f 6e  ackage_hash, con
26b0: 73 74 20 63 68 61 72 20 2a 5f 70 61 74 68 2c 20  st char *_path, 
26c0: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
26d0: 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29  hinfo *pathinfo)
26e0: 20 7b 0a 09 63 68 61 72 20 2a 64 69 72 65 63 74   {..char *direct
26f0: 6f 72 79 2c 20 2a 66 69 6c 65 2c 20 2a 70 61 74  ory, *file, *pat
2700: 68 3b 0a 09 63 68 61 72 20 2a 73 71 6c 3b 0a 09  h;..char *sql;..
2710: 69 6e 74 20 73 71 6c 69 74 65 5f 72 65 74 3b 0a  int sqlite_ret;.
2720: 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 20 3d  ..if (pathinfo =
2730: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
2740: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
2750: 70 70 66 73 5f 75 70 64 61 74 65 5f 69 6e 64 65  ppfs_update_inde
2760: 78 28 68 6f 73 74 6e 61 6d 65 29 3b 0a 09 61 70  x(hostname);..ap
2770: 70 66 73 5f 75 70 64 61 74 65 5f 6d 61 6e 69 66  pfs_update_manif
2780: 65 73 74 28 68 6f 73 74 6e 61 6d 65 2c 20 70 61  est(hostname, pa
2790: 63 6b 61 67 65 5f 68 61 73 68 29 3b 0a 0a 09 70  ckage_hash);...p
27a0: 61 74 68 20 3d 20 73 74 72 64 75 70 28 5f 70 61  ath = strdup(_pa
27b0: 74 68 29 3b 0a 09 64 69 72 65 63 74 6f 72 79 20  th);..directory 
27c0: 3d 20 70 61 74 68 3b 0a 09 66 69 6c 65 20 3d 20  = path;..file = 
27d0: 73 74 72 72 63 68 72 28 70 61 74 68 2c 20 27 2f  strrchr(path, '/
27e0: 27 29 3b 0a 09 69 66 20 28 66 69 6c 65 20 3d 3d  ');..if (file ==
27f0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 69 6c 65 20   NULL) {...file 
2800: 3d 20 70 61 74 68 3b 0a 09 09 64 69 72 65 63 74  = path;...direct
2810: 6f 72 79 20 3d 20 22 22 3b 0a 09 7d 20 65 6c 73  ory = "";..} els
2820: 65 20 7b 0a 09 09 2a 66 69 6c 65 20 3d 20 27 5c  e {...*file = '\
2830: 30 27 3b 0a 09 09 66 69 6c 65 2b 2b 3b 0a 09 7d  0';...file++;..}
2840: 0a 0a 09 73 71 6c 20 3d 20 73 71 6c 69 74 65 33  ...sql = sqlite3
2850: 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54  _mprintf("SELECT
2860: 20 74 79 70 65 2c 20 74 69 6d 65 2c 20 73 6f 75   type, time, sou
2870: 72 63 65 2c 20 73 69 7a 65 2c 20 70 65 72 6d 73  rce, size, perms
2880: 2c 20 66 69 6c 65 5f 73 68 61 31 20 46 52 4f 4d  , file_sha1 FROM
2890: 20 66 69 6c 65 73 20 57 48 45 52 45 20 70 61 63   files WHERE pac
28a0: 6b 61 67 65 5f 73 68 61 31 20 3d 20 25 51 20 41  kage_sha1 = %Q A
28b0: 4e 44 20 66 69 6c 65 5f 64 69 72 65 63 74 6f 72  ND file_director
28c0: 79 20 3d 20 25 51 20 41 4e 44 20 66 69 6c 65 5f  y = %Q AND file_
28d0: 6e 61 6d 65 20 3d 20 25 51 3b 22 2c 20 70 61 63  name = %Q;", pac
28e0: 6b 61 67 65 5f 68 61 73 68 2c 20 64 69 72 65 63  kage_hash, direc
28f0: 74 6f 72 79 2c 20 66 69 6c 65 29 3b 0a 09 69 66  tory, file);..if
2900: 20 28 73 71 6c 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (sql == NULL) {
2910: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2920: 43 61 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 5f  Call to sqlite3_
2930: 6d 70 72 69 6e 74 66 20 66 61 69 6c 65 64 2e 22  mprintf failed."
2940: 29 3b 0a 0a 09 09 66 72 65 65 28 70 61 74 68 29  );....free(path)
2950: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  ;....return(-EIO
2960: 29 3b 0a 09 7d 0a 0a 09 66 72 65 65 28 70 61 74  );..}...free(pat
2970: 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e  h);...pathinfo->
2980: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
2990: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
29a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 53 51  .APPFS_DEBUG("SQ
29b0: 4c 3a 20 25 73 22 2c 20 73 71 6c 29 3b 0a 09 73  L: %s", sql);..s
29c0: 71 6c 69 74 65 5f 72 65 74 20 3d 20 73 71 6c 69  qlite_ret = sqli
29d0: 74 65 33 5f 65 78 65 63 28 67 6c 6f 62 61 6c 54  te3_exec(globalT
29e0: 68 72 65 61 64 2e 64 62 2c 20 73 71 6c 2c 20 61  hread.db, sql, a
29f0: 70 70 66 73 5f 67 65 74 66 69 6c 65 69 6e 66 6f  ppfs_getfileinfo
2a00: 5f 63 62 2c 20 70 61 74 68 69 6e 66 6f 2c 20 4e  _cb, pathinfo, N
2a10: 55 4c 4c 29 3b 0a 09 73 71 6c 69 74 65 33 5f 66  ULL);..sqlite3_f
2a20: 72 65 65 28 73 71 6c 29 3b 0a 0a 09 69 66 20 28  ree(sql);...if (
2a30: 73 71 6c 69 74 65 5f 72 65 74 20 21 3d 20 53 51  sqlite_ret != SQ
2a40: 4c 49 54 45 5f 4f 4b 29 20 7b 0a 09 09 41 50 50  LITE_OK) {...APP
2a50: 46 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 20 74  FS_DEBUG("Call t
2a60: 6f 20 73 71 6c 69 74 65 33 5f 65 78 65 63 20 66  o sqlite3_exec f
2a70: 61 69 6c 65 64 2e 22 29 3b 0a 0a 09 09 72 65 74  ailed.");....ret
2a80: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
2a90: 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79  if (pathinfo->ty
2aa0: 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48  pe == APPFS_PATH
2ab0: 54 59 50 45 5f 49 4e 56 41 4c 49 44 29 20 7b 0a  TYPE_INVALID) {.
2ac0: 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54  ..return(-ENOENT
2ad0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
2ae0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
2af0: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
2b00: 69 6e 66 6f 5f 73 71 6c 28 63 68 61 72 20 2a 73  info_sql(char *s
2b10: 71 6c 2c 20 69 6e 74 20 61 72 67 63 2c 20 63 6f  ql, int argc, co
2b20: 6e 73 74 20 63 68 61 72 20 2a 66 6d 74 2c 20 73  nst char *fmt, s
2b30: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
2b40: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 2c 20  info *pathinfo, 
2b50: 73 74 72 75 63 74 20 61 70 70 66 73 5f 63 68 69  struct appfs_chi
2b60: 6c 64 72 65 6e 20 2a 2a 63 68 69 6c 64 72 65 6e  ldren **children
2b70: 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66  ) {..struct appf
2b80: 73 5f 63 68 69 6c 64 72 65 6e 20 2a 6e 6f 64 65  s_children *node
2b90: 2c 20 2a 64 69 72 5f 63 68 69 6c 64 72 65 6e 2c  , *dir_children,
2ba0: 20 2a 64 69 72 5f 63 68 69 6c 64 3b 0a 09 69 6e   *dir_child;..in
2bb0: 74 20 64 69 72 5f 63 68 69 6c 64 72 65 6e 5f 63  t dir_children_c
2bc0: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 64 69 72 5f  ount = 0;...dir_
2bd0: 63 68 69 6c 64 72 65 6e 20 3d 20 61 70 70 66 73  children = appfs
2be0: 5f 73 71 6c 69 74 65 33 5f 71 75 65 72 79 28 73  _sqlite3_query(s
2bf0: 71 6c 2c 20 61 72 67 63 2c 20 66 6d 74 2c 20 26  ql, argc, fmt, &
2c00: 64 69 72 5f 63 68 69 6c 64 72 65 6e 5f 63 6f 75  dir_children_cou
2c10: 6e 74 29 3b 0a 0a 09 69 66 20 28 64 69 72 5f 63  nt);...if (dir_c
2c20: 68 69 6c 64 72 65 6e 20 3d 3d 20 4e 55 4c 4c 20  hildren == NULL 
2c30: 7c 7c 20 64 69 72 5f 63 68 69 6c 64 72 65 6e 5f  || dir_children_
2c40: 63 6f 75 6e 74 20 3d 3d 20 30 29 20 7b 0a 09 09  count == 0) {...
2c50: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b  return(-ENOENT);
2c60: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74  ..}.../* Request
2c70: 20 66 6f 72 20 61 20 73 69 6e 67 6c 65 20 68 6f   for a single ho
2c80: 73 74 6e 61 6d 65 20 2a 2f 0a 09 70 61 74 68 69  stname */..pathi
2c90: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
2ca0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
2cb0: 54 4f 52 59 3b 0a 09 70 61 74 68 69 6e 66 6f 2d  TORY;..pathinfo-
2cc0: 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  >typeinfo.dir.ch
2cd0: 69 6c 64 63 6f 75 6e 74 20 3d 20 64 69 72 5f 63  ildcount = dir_c
2ce0: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 0a 09  hildren_count;..
2cf0: 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d  pathinfo->time =
2d00: 20 67 6c 6f 62 61 6c 54 68 72 65 61 64 2e 62 6f   globalThread.bo
2d10: 6f 74 74 69 6d 65 3b 0a 0a 09 69 66 20 28 63 68  ottime;...if (ch
2d20: 69 6c 64 72 65 6e 29 20 7b 0a 09 09 66 6f 72 20  ildren) {...for 
2d30: 28 64 69 72 5f 63 68 69 6c 64 20 3d 20 64 69 72  (dir_child = dir
2d40: 5f 63 68 69 6c 64 72 65 6e 3b 20 64 69 72 5f 63  _children; dir_c
2d50: 68 69 6c 64 3b 20 64 69 72 5f 63 68 69 6c 64 20  hild; dir_child 
2d60: 3d 20 64 69 72 5f 63 68 69 6c 64 2d 3e 5f 6e 65  = dir_child->_ne
2d70: 78 74 29 20 7b 0a 09 09 09 6e 6f 64 65 20 3d 20  xt) {....node = 
2d80: 28 76 6f 69 64 20 2a 29 20 63 6b 61 6c 6c 6f 63  (void *) ckalloc
2d90: 28 73 69 7a 65 6f 66 28 2a 6e 6f 64 65 29 29 3b  (sizeof(*node));
2da0: 0a 09 09 09 6e 6f 64 65 2d 3e 5f 6e 65 78 74 20  ....node->_next 
2db0: 3d 20 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 09 09  = *children;....
2dc0: 73 74 72 63 70 79 28 6e 6f 64 65 2d 3e 6e 61 6d  strcpy(node->nam
2dd0: 65 2c 20 64 69 72 5f 63 68 69 6c 64 2d 3e 6e 61  e, dir_child->na
2de0: 6d 65 29 3b 0a 09 09 09 2a 63 68 69 6c 64 72 65  me);....*childre
2df0: 6e 20 3d 20 6e 6f 64 65 3b 0a 09 09 7d 0a 09 7d  n = node;...}..}
2e00: 0a 0a 09 61 70 70 66 73 5f 66 72 65 65 5f 6c 69  ...appfs_free_li
2e10: 73 74 5f 63 68 69 6c 64 72 65 6e 28 64 69 72 5f  st_children(dir_
2e20: 63 68 69 6c 64 72 65 6e 29 3b 0a 0a 09 72 65 74  children);...ret
2e30: 75 72 6e 28 30 29 3b 0a 7d 0a 2f 2a 20 47 65 74  urn(0);.}./* Get
2e40: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   information abo
2e50: 75 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f  ut a path, and o
2e60: 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63  ptionally list c
2e70: 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69  hildren */.stati
2e80: 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f  c int appfs_get_
2e90: 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20  path_info(const 
2ea0: 63 68 61 72 20 2a 5f 70 61 74 68 2c 20 73 74 72  char *_path, str
2eb0: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
2ec0: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 2c 20 73 74  fo *pathinfo, st
2ed0: 72 75 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64  ruct appfs_child
2ee0: 72 65 6e 20 2a 2a 63 68 69 6c 64 72 65 6e 29 20  ren **children) 
2ef0: 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  {..struct appfs_
2f00: 63 68 69 6c 64 72 65 6e 20 2a 64 69 72 5f 63 68  children *dir_ch
2f10: 69 6c 64 72 65 6e 3b 0a 09 63 68 61 72 20 2a 68  ildren;..char *h
2f20: 6f 73 74 6e 61 6d 65 2c 20 2a 70 61 63 6b 61 67  ostname, *packag
2f30: 65 6e 61 6d 65 2c 20 2a 6f 73 5f 63 70 75 41 72  ename, *os_cpuAr
2f40: 63 68 2c 20 2a 6f 73 2c 20 2a 63 70 75 41 72 63  ch, *os, *cpuArc
2f50: 68 2c 20 2a 76 65 72 73 69 6f 6e 3b 0a 09 63 68  h, *version;..ch
2f60: 61 72 20 2a 70 61 74 68 2c 20 2a 70 61 74 68 5f  ar *path, *path_
2f70: 73 3b 0a 09 63 68 61 72 20 2a 70 61 63 6b 61 67  s;..char *packag
2f80: 65 5f 68 61 73 68 3b 0a 09 63 68 61 72 20 2a 73  e_hash;..char *s
2f90: 71 6c 3b 0a 09 69 6e 74 20 66 69 6c 65 73 5f 63  ql;..int files_c
2fa0: 6f 75 6e 74 3b 0a 09 69 6e 74 20 66 69 6c 65 69  ount;..int filei
2fb0: 6e 66 6f 5f 72 65 74 2c 20 72 65 74 76 61 6c 3b  nfo_ret, retval;
2fc0: 0a 0a 09 69 66 20 28 63 68 69 6c 64 72 65 6e 29  ...if (children)
2fd0: 20 7b 0a 09 09 2a 63 68 69 6c 64 72 65 6e 20 3d   {...*children =
2fe0: 20 4e 55 4c 4c 3b 0a 09 7d 0a 0a 09 69 66 20 28   NULL;..}...if (
2ff0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
3000: 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e  ...return(-ENOEN
3010: 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 5f 70 61  T);..}...if (_pa
3020: 74 68 5b 30 5d 20 21 3d 20 27 2f 27 29 20 7b 0a  th[0] != '/') {.
3030: 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54  ..return(-ENOENT
3040: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 5f 70 61 74  );..}...if (_pat
3050: 68 5b 31 5d 20 3d 3d 20 27 5c 30 27 29 20 7b 0a  h[1] == '\0') {.
3060: 09 09 2f 2a 20 52 65 71 75 65 73 74 20 66 6f 72  ../* Request for
3070: 20 74 68 65 20 72 6f 6f 74 20 64 69 72 65 63 74   the root direct
3080: 6f 72 79 20 2a 2f 0a 09 09 70 61 74 68 69 6e 66  ory */...pathinf
3090: 6f 2d 3e 68 6f 73 74 6e 61 6d 65 5b 30 5d 20 3d  o->hostname[0] =
30a0: 20 27 5c 30 27 3b 0a 0a 09 09 73 71 6c 20 3d 20   '\0';....sql = 
30b0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
30c0: 22 53 45 4c 45 43 54 20 44 49 53 54 49 4e 43 54  "SELECT DISTINCT
30d0: 20 68 6f 73 74 6e 61 6d 65 20 46 52 4f 4d 20 70   hostname FROM p
30e0: 61 63 6b 61 67 65 73 3b 22 29 3b 0a 0a 09 09 72  ackages;");....r
30f0: 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65  etval = appfs_ge
3100: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 73 71 6c 28  t_path_info_sql(
3110: 73 71 6c 2c 20 31 2c 20 4e 55 4c 4c 2c 20 70 61  sql, 1, NULL, pa
3120: 74 68 69 6e 66 6f 2c 20 63 68 69 6c 64 72 65 6e  thinfo, children
3130: 29 3b 0a 0a 09 09 2f 2a 20 54 68 65 20 72 6f 6f  );..../* The roo
3140: 74 20 64 69 72 65 63 74 6f 72 79 20 61 6c 77 61  t directory alwa
3150: 79 73 20 65 78 69 73 74 73 2c 20 65 76 65 6e 20  ys exists, even 
3160: 69 66 20 69 74 20 68 61 73 20 6e 6f 20 73 75 62  if it has no sub
3170: 6f 72 64 69 6e 61 74 65 73 20 2a 2f 0a 09 09 69  ordinates */...i
3180: 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20  f (retval != 0) 
3190: 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  {....pathinfo->t
31a0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
31b0: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a  TYPE_DIRECTORY;.
31c0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
31d0: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63  einfo.dir.childc
31e0: 6f 75 6e 74 20 3d 20 30 3b 0a 09 09 09 70 61 74  ount = 0;....pat
31f0: 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 67 6c  hinfo->time = gl
3200: 6f 62 61 6c 54 68 72 65 61 64 2e 62 6f 6f 74 74  obalThread.boott
3210: 69 6d 65 3b 0a 0a 09 09 09 72 65 74 76 61 6c 20  ime;.....retval 
3220: 3d 20 30 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  = 0;...}....retu
3230: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a  rn(retval);..}..
3240: 09 70 61 74 68 20 3d 20 73 74 72 64 75 70 28 5f  .path = strdup(_
3250: 70 61 74 68 29 3b 0a 09 70 61 74 68 5f 73 20 3d  path);..path_s =
3260: 20 70 61 74 68 3b 0a 0a 09 68 6f 73 74 6e 61 6d   path;...hostnam
3270: 65 20 3d 20 70 61 74 68 20 2b 20 31 3b 0a 09 70  e = path + 1;..p
3280: 61 63 6b 61 67 65 6e 61 6d 65 20 3d 20 73 74 72  ackagename = str
3290: 63 68 72 28 68 6f 73 74 6e 61 6d 65 2c 20 27 2f  chr(hostname, '/
32a0: 27 29 3b 0a 0a 09 69 66 20 28 70 61 63 6b 61 67  ');...if (packag
32b0: 65 6e 61 6d 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  ename != NULL) {
32c0: 0a 09 09 2a 70 61 63 6b 61 67 65 6e 61 6d 65 20  ...*packagename 
32d0: 3d 20 27 5c 30 27 3b 0a 09 09 70 61 63 6b 61 67  = '\0';...packag
32e0: 65 6e 61 6d 65 2b 2b 3b 0a 09 7d 0a 0a 09 73 6e  ename++;..}...sn
32f0: 70 72 69 6e 74 66 28 70 61 74 68 69 6e 66 6f 2d  printf(pathinfo-
3300: 3e 68 6f 73 74 6e 61 6d 65 2c 20 73 69 7a 65 6f  >hostname, sizeo
3310: 66 28 70 61 74 68 69 6e 66 6f 2d 3e 68 6f 73 74  f(pathinfo->host
3320: 6e 61 6d 65 29 2c 20 22 25 73 22 2c 20 68 6f 73  name), "%s", hos
3330: 74 6e 61 6d 65 29 3b 0a 0a 09 69 66 20 28 70 61  tname);...if (pa
3340: 63 6b 61 67 65 6e 61 6d 65 20 3d 3d 20 4e 55 4c  ckagename == NUL
3350: 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f 75 70 64  L) {...appfs_upd
3360: 61 74 65 5f 69 6e 64 65 78 28 68 6f 73 74 6e 61  ate_index(hostna
3370: 6d 65 29 3b 0a 0a 09 09 73 71 6c 20 3d 20 73 71  me);....sql = sq
3380: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53  lite3_mprintf("S
3390: 45 4c 45 43 54 20 44 49 53 54 49 4e 43 54 20 70  ELECT DISTINCT p
33a0: 61 63 6b 61 67 65 20 46 52 4f 4d 20 70 61 63 6b  ackage FROM pack
33b0: 61 67 65 73 20 57 48 45 52 45 20 68 6f 73 74 6e  ages WHERE hostn
33c0: 61 6d 65 20 3d 20 25 51 3b 22 2c 20 68 6f 73 74  ame = %Q;", host
33d0: 6e 61 6d 65 29 3b 0a 0a 09 09 66 72 65 65 28 70  name);....free(p
33e0: 61 74 68 5f 73 29 3b 0a 0a 09 09 72 65 74 75 72  ath_s);....retur
33f0: 6e 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  n(appfs_get_path
3400: 5f 69 6e 66 6f 5f 73 71 6c 28 73 71 6c 2c 20 31  _info_sql(sql, 1
3410: 2c 20 4e 55 4c 4c 2c 20 70 61 74 68 69 6e 66 6f  , NULL, pathinfo
3420: 2c 20 63 68 69 6c 64 72 65 6e 29 29 3b 0a 09 7d  , children));..}
3430: 0a 0a 09 6f 73 5f 63 70 75 41 72 63 68 20 3d 20  ...os_cpuArch = 
3440: 73 74 72 63 68 72 28 70 61 63 6b 61 67 65 6e 61  strchr(packagena
3450: 6d 65 2c 20 27 2f 27 29 3b 0a 0a 09 69 66 20 28  me, '/');...if (
3460: 6f 73 5f 63 70 75 41 72 63 68 20 21 3d 20 4e 55  os_cpuArch != NU
3470: 4c 4c 29 20 7b 0a 09 09 2a 6f 73 5f 63 70 75 41  LL) {...*os_cpuA
3480: 72 63 68 20 3d 20 27 5c 30 27 3b 0a 09 09 6f 73  rch = '\0';...os
3490: 5f 63 70 75 41 72 63 68 2b 2b 3b 0a 09 7d 0a 0a  _cpuArch++;..}..
34a0: 09 69 66 20 28 6f 73 5f 63 70 75 41 72 63 68 20  .if (os_cpuArch 
34b0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70  == NULL) {...app
34c0: 66 73 5f 75 70 64 61 74 65 5f 69 6e 64 65 78 28  fs_update_index(
34d0: 68 6f 73 74 6e 61 6d 65 29 3b 0a 0a 09 09 73 71  hostname);....sq
34e0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
34f0: 6e 74 66 28 22 53 45 4c 45 43 54 20 44 49 53 54  ntf("SELECT DIST
3500: 49 4e 43 54 20 6f 73 2c 20 63 70 75 41 72 63 68  INCT os, cpuArch
3510: 20 46 52 4f 4d 20 70 61 63 6b 61 67 65 73 20 57   FROM packages W
3520: 48 45 52 45 20 68 6f 73 74 6e 61 6d 65 20 3d 20  HERE hostname = 
3530: 25 51 20 41 4e 44 20 70 61 63 6b 61 67 65 20 3d  %Q AND package =
3540: 20 25 51 3b 22 2c 20 68 6f 73 74 6e 61 6d 65 2c   %Q;", hostname,
3550: 20 70 61 63 6b 61 67 65 6e 61 6d 65 29 3b 0a 0a   packagename);..
3560: 09 09 66 72 65 65 28 70 61 74 68 5f 73 29 3b 0a  ..free(path_s);.
3570: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
3580: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 73 71  get_path_info_sq
3590: 6c 28 73 71 6c 2c 20 32 2c 20 22 25 73 2d 25 73  l(sql, 2, "%s-%s
35a0: 22 2c 20 70 61 74 68 69 6e 66 6f 2c 20 63 68 69  ", pathinfo, chi
35b0: 6c 64 72 65 6e 29 29 3b 0a 09 7d 0a 0a 09 76 65  ldren));..}...ve
35c0: 72 73 69 6f 6e 20 3d 20 73 74 72 63 68 72 28 6f  rsion = strchr(o
35d0: 73 5f 63 70 75 41 72 63 68 2c 20 27 2f 27 29 3b  s_cpuArch, '/');
35e0: 0a 0a 09 69 66 20 28 76 65 72 73 69 6f 6e 20 21  ...if (version !
35f0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2a 76 65 72  = NULL) {...*ver
3600: 73 69 6f 6e 20 3d 20 27 5c 30 27 3b 0a 09 09 76  sion = '\0';...v
3610: 65 72 73 69 6f 6e 2b 2b 3b 0a 09 7d 0a 0a 09 6f  ersion++;..}...o
3620: 73 20 3d 20 6f 73 5f 63 70 75 41 72 63 68 3b 0a  s = os_cpuArch;.
3630: 09 63 70 75 41 72 63 68 20 3d 20 73 74 72 63 68  .cpuArch = strch
3640: 72 28 6f 73 5f 63 70 75 41 72 63 68 2c 20 27 2d  r(os_cpuArch, '-
3650: 27 29 3b 0a 09 69 66 20 28 63 70 75 41 72 63 68  ');..if (cpuArch
3660: 29 20 7b 0a 09 09 2a 63 70 75 41 72 63 68 20 3d  ) {...*cpuArch =
3670: 20 27 5c 30 27 3b 0a 09 09 63 70 75 41 72 63 68   '\0';...cpuArch
3680: 2b 2b 3b 0a 09 7d 0a 0a 09 69 66 20 28 76 65 72  ++;..}...if (ver
3690: 73 69 6f 6e 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  sion == NULL) {.
36a0: 09 09 2f 2a 20 52 65 71 75 65 73 74 20 66 6f 72  ../* Request for
36b0: 20 76 65 72 73 69 6f 6e 20 6c 69 73 74 20 66 6f   version list fo
36c0: 72 20 61 20 70 61 63 6b 61 67 65 20 6f 6e 20 61  r a package on a
36d0: 6e 20 4f 53 2f 43 50 55 20 2a 2f 0a 09 09 61 70  n OS/CPU */...ap
36e0: 70 66 73 5f 75 70 64 61 74 65 5f 69 6e 64 65 78  pfs_update_index
36f0: 28 68 6f 73 74 6e 61 6d 65 29 3b 0a 0a 09 09 73  (hostname);....s
3700: 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ql = sqlite3_mpr
3710: 69 6e 74 66 28 22 53 45 4c 45 43 54 20 44 49 53  intf("SELECT DIS
3720: 54 49 4e 43 54 20 76 65 72 73 69 6f 6e 20 46 52  TINCT version FR
3730: 4f 4d 20 70 61 63 6b 61 67 65 73 20 57 48 45 52  OM packages WHER
3740: 45 20 68 6f 73 74 6e 61 6d 65 20 3d 20 25 51 20  E hostname = %Q 
3750: 41 4e 44 20 70 61 63 6b 61 67 65 20 3d 20 25 51  AND package = %Q
3760: 20 41 4e 44 20 6f 73 20 3d 20 25 51 20 61 6e 64   AND os = %Q and
3770: 20 63 70 75 41 72 63 68 20 3d 20 25 51 3b 22 2c   cpuArch = %Q;",
3780: 20 68 6f 73 74 6e 61 6d 65 2c 20 70 61 63 6b 61   hostname, packa
3790: 67 65 6e 61 6d 65 2c 20 6f 73 2c 20 63 70 75 41  gename, os, cpuA
37a0: 72 63 68 29 3b 0a 0a 09 09 66 72 65 65 28 70 61  rch);....free(pa
37b0: 74 68 5f 73 29 3b 0a 0a 09 09 72 65 74 75 72 6e  th_s);....return
37c0: 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  (appfs_get_path_
37d0: 69 6e 66 6f 5f 73 71 6c 28 73 71 6c 2c 20 31 2c  info_sql(sql, 1,
37e0: 20 4e 55 4c 4c 2c 20 70 61 74 68 69 6e 66 6f 2c   NULL, pathinfo,
37f0: 20 63 68 69 6c 64 72 65 6e 29 29 3b 0a 09 7d 0a   children));..}.
3800: 0a 09 70 61 74 68 20 3d 20 73 74 72 63 68 72 28  ..path = strchr(
3810: 76 65 72 73 69 6f 6e 2c 20 27 2f 27 29 3b 0a 09  version, '/');..
3820: 69 66 20 28 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  if (path == NULL
3830: 29 20 7b 0a 09 09 70 61 74 68 20 3d 20 22 22 3b  ) {...path = "";
3840: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2a 70 61  ..} else {...*pa
3850: 74 68 20 3d 20 27 5c 30 27 3b 0a 09 09 70 61 74  th = '\0';...pat
3860: 68 2b 2b 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71  h++;..}.../* Req
3870: 75 65 73 74 20 66 6f 72 20 61 20 66 69 6c 65 20  uest for a file 
3880: 69 6e 20 61 20 73 70 65 63 69 66 69 63 20 70 61  in a specific pa
3890: 63 6b 61 67 65 20 2a 2f 0a 09 41 50 50 46 53 5f  ckage */..APPFS_
38a0: 44 45 42 55 47 28 22 52 65 71 75 65 73 74 69 6e  DEBUG("Requestin
38b0: 67 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 6f  g information fo
38c0: 72 20 68 6f 73 74 6e 61 6d 65 20 3d 20 25 73 2c  r hostname = %s,
38d0: 20 70 61 63 6b 61 67 65 20 3d 20 25 73 2c 20 6f   package = %s, o
38e0: 73 20 3d 20 25 73 2c 20 63 70 75 41 72 63 68 20  s = %s, cpuArch 
38f0: 3d 20 25 73 2c 20 76 65 72 73 69 6f 6e 20 3d 20  = %s, version = 
3900: 25 73 2c 20 70 61 74 68 20 3d 20 25 73 22 2c 20  %s, path = %s", 
3910: 0a 09 09 68 6f 73 74 6e 61 6d 65 2c 20 70 61 63  ...hostname, pac
3920: 6b 61 67 65 6e 61 6d 65 2c 20 6f 73 2c 20 63 70  kagename, os, cp
3930: 75 41 72 63 68 2c 20 76 65 72 73 69 6f 6e 2c 20  uArch, version, 
3940: 70 61 74 68 0a 09 29 3b 0a 0a 09 70 61 63 6b 61  path..);...packa
3950: 67 65 5f 68 61 73 68 20 3d 20 61 70 70 66 73 5f  ge_hash = appfs_
3960: 6c 6f 6f 6b 75 70 5f 70 61 63 6b 61 67 65 5f 68  lookup_package_h
3970: 61 73 68 28 68 6f 73 74 6e 61 6d 65 2c 20 70 61  ash(hostname, pa
3980: 63 6b 61 67 65 6e 61 6d 65 2c 20 6f 73 2c 20 63  ckagename, os, c
3990: 70 75 41 72 63 68 2c 20 76 65 72 73 69 6f 6e 29  puArch, version)
39a0: 3b 0a 09 69 66 20 28 70 61 63 6b 61 67 65 5f 68  ;..if (package_h
39b0: 61 73 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ash == NULL) {..
39c0: 09 66 72 65 65 28 70 61 74 68 5f 73 29 3b 0a 0a  .free(path_s);..
39d0: 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54  ..return(-ENOENT
39e0: 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45  );..}...APPFS_DE
39f0: 42 55 47 28 22 20 20 2e 2e 2e 20 77 68 69 63 68  BUG("  ... which
3a00: 20 68 61 73 68 20 61 20 68 61 73 68 20 6f 66 20   hash a hash of 
3a10: 25 73 22 2c 20 70 61 63 6b 61 67 65 5f 68 61 73  %s", package_has
3a20: 68 29 3b 0a 0a 09 61 70 70 66 73 5f 75 70 64 61  h);...appfs_upda
3a30: 74 65 5f 6d 61 6e 69 66 65 73 74 28 68 6f 73 74  te_manifest(host
3a40: 6e 61 6d 65 2c 20 70 61 63 6b 61 67 65 5f 68 61  name, package_ha
3a50: 73 68 29 3b 0a 0a 09 69 66 20 28 73 74 72 63 6d  sh);...if (strcm
3a60: 70 28 70 61 74 68 2c 20 22 22 29 20 3d 3d 20 30  p(path, "") == 0
3a70: 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ) {...pathinfo->
3a80: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
3a90: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b  HTYPE_DIRECTORY;
3aa0: 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d  ...pathinfo->tim
3ab0: 65 20 3d 20 67 6c 6f 62 61 6c 54 68 72 65 61 64  e = globalThread
3ac0: 2e 62 6f 6f 74 74 69 6d 65 3b 0a 09 7d 20 65 6c  .boottime;..} el
3ad0: 73 65 20 7b 0a 09 09 66 69 6c 65 69 6e 66 6f 5f  se {...fileinfo_
3ae0: 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65 74 66  ret = appfs_getf
3af0: 69 6c 65 69 6e 66 6f 28 68 6f 73 74 6e 61 6d 65  ileinfo(hostname
3b00: 2c 20 70 61 63 6b 61 67 65 5f 68 61 73 68 2c 20  , package_hash, 
3b10: 70 61 74 68 2c 20 70 61 74 68 69 6e 66 6f 29 3b  path, pathinfo);
3b20: 0a 09 09 69 66 20 28 66 69 6c 65 69 6e 66 6f 5f  ...if (fileinfo_
3b30: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 66  ret != 0) {....f
3b40: 72 65 65 28 70 61 74 68 5f 73 29 3b 0a 0a 09 09  ree(path_s);....
3b50: 09 72 65 74 75 72 6e 28 66 69 6c 65 69 6e 66 6f  .return(fileinfo
3b60: 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  _ret);...}..}...
3b70: 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79  if (pathinfo->ty
3b80: 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48  pe == APPFS_PATH
3b90: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 29 20  TYPE_DIRECTORY) 
3ba0: 7b 0a 09 09 64 69 72 5f 63 68 69 6c 64 72 65 6e  {...dir_children
3bb0: 20 3d 20 61 70 70 66 73 5f 67 65 74 63 68 69 6c   = appfs_getchil
3bc0: 64 72 65 6e 28 68 6f 73 74 6e 61 6d 65 2c 20 70  dren(hostname, p
3bd0: 61 63 6b 61 67 65 5f 68 61 73 68 2c 20 70 61 74  ackage_hash, pat
3be0: 68 2c 20 26 66 69 6c 65 73 5f 63 6f 75 6e 74 29  h, &files_count)
3bf0: 3b 0a 0a 09 09 69 66 20 28 64 69 72 5f 63 68 69  ;....if (dir_chi
3c00: 6c 64 72 65 6e 20 21 3d 20 4e 55 4c 4c 29 20 7b  ldren != NULL) {
3c10: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
3c20: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
3c30: 63 6f 75 6e 74 20 3d 20 66 69 6c 65 73 5f 63 6f  count = files_co
3c40: 75 6e 74 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28  unt;...}....if (
3c50: 63 68 69 6c 64 72 65 6e 29 20 7b 0a 09 09 09 2a  children) {....*
3c60: 63 68 69 6c 64 72 65 6e 20 3d 20 64 69 72 5f 63  children = dir_c
3c70: 68 69 6c 64 72 65 6e 3b 0a 09 09 7d 0a 09 7d 0a  hildren;...}..}.
3c80: 0a 09 66 72 65 65 28 70 61 74 68 5f 73 29 3b 0a  ..free(path_s);.
3c90: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
3ca0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
3cb0: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28 63 6f  _fuse_getattr(co
3cc0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
3cd0: 73 74 72 75 63 74 20 73 74 61 74 20 2a 73 74 62  struct stat *stb
3ce0: 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  uf) {..struct ap
3cf0: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
3d00: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 73 20  hinfo;..int res 
3d10: 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  = 0;...APPFS_DEB
3d20: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
3d30: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
3d40: 68 29 3b 0a 0a 09 72 65 73 20 3d 20 61 70 70 66  h);...res = appf
3d50: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
3d60: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 2c  path, &pathinfo,
3d70: 20 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 72 65 73   NULL);..if (res
3d80: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
3d90: 6e 28 72 65 73 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  n(res);..}...mem
3da0: 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69  set(stbuf, 0, si
3db0: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74  zeof(struct stat
3dc0: 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ));...stbuf->st_
3dd0: 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f  mtime = pathinfo
3de0: 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73  .time;..stbuf->s
3df0: 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e  t_ctime = pathin
3e00: 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d  fo.time;..stbuf-
3e10: 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68  >st_atime = path
3e20: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 0a 09 69 66 20  info.time;...if 
3e30: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d  (pathinfo.type =
3e40: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
3e50: 5f 44 49 52 45 43 54 4f 52 59 29 20 7b 0a 09 09  _DIRECTORY) {...
3e60: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d  stbuf->st_mode =
3e70: 20 53 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b   S_IFDIR | 0555;
3e80: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
3e90: 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66  nk = 2 + pathinf
3ea0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63  o.typeinfo.dir.c
3eb0: 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 7d 20 65 6c  hildcount;..} el
3ec0: 73 65 20 7b 0a 09 09 69 66 20 28 70 61 74 68 69  se {...if (pathi
3ed0: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
3ee0: 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a  e.executable) {.
3ef0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
3f00: 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 35  e = S_IFREG | 05
3f10: 35 35 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09  55;...} else {..
3f20: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
3f30: 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34   = S_IFREG | 044
3f40: 34 3b 0a 09 09 7d 0a 0a 09 09 73 74 62 75 66 2d  4;...}....stbuf-
3f50: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
3f60: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
3f70: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  = pathinfo.typei
3f80: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 09  nfo.file.size;..
3f90: 7d 0a 0a 09 72 65 74 75 72 6e 20 72 65 73 3b 0a  }...return res;.
3fa0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
3fb0: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72  pfs_fuse_readdir
3fc0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
3fd0: 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66 75  h, void *buf, fu
3fe0: 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66 69  se_fill_dir_t fi
3ff0: 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66 73  ller, off_t offs
4000: 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  et, struct fuse_
4010: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
4020: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
4030: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
4040: 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  ;..struct appfs_
4050: 63 68 69 6c 64 72 65 6e 20 2a 63 68 69 6c 64 72  children *childr
4060: 65 6e 2c 20 2a 63 68 69 6c 64 3b 0a 09 69 6e 74  en, *child;..int
4070: 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53   retval;...APPFS
4080: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
4090: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
40a0: 20 70 61 74 68 29 3b 0a 0a 09 72 65 74 76 61 6c   path);...retval
40b0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74   = appfs_get_pat
40c0: 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61  h_info(path, &pa
40d0: 74 68 69 6e 66 6f 2c 20 26 63 68 69 6c 64 72 65  thinfo, &childre
40e0: 6e 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20  n);..if (retval 
40f0: 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  != 0) {...return
4100: 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 66  (retval);..}...f
4110: 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20  iller(buf, ".", 
4120: 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65  NULL, 0);..fille
4130: 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c  r(buf, "..", NUL
4140: 4c 2c 20 30 29 3b 0a 0a 09 66 6f 72 20 28 63 68  L, 0);...for (ch
4150: 69 6c 64 20 3d 20 63 68 69 6c 64 72 65 6e 3b 20  ild = children; 
4160: 63 68 69 6c 64 3b 20 63 68 69 6c 64 20 3d 20 63  child; child = c
4170: 68 69 6c 64 2d 3e 5f 6e 65 78 74 29 20 7b 0a 09  hild->_next) {..
4180: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 63 68 69  .filler(buf, chi
4190: 6c 64 2d 3e 6e 61 6d 65 2c 20 4e 55 4c 4c 2c 20  ld->name, NULL, 
41a0: 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 66  0);..}...appfs_f
41b0: 72 65 65 5f 6c 69 73 74 5f 63 68 69 6c 64 72 65  ree_list_childre
41c0: 6e 28 63 68 69 6c 64 72 65 6e 29 3b 0a 0a 09 72  n(children);...r
41d0: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
41e0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
41f0: 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68  se_open(const ch
4200: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
4210: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
4220: 2a 66 69 29 20 7b 0a 09 73 74 72 75 63 74 20 61  *fi) {..struct a
4230: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61  ppfs_pathinfo pa
4240: 74 68 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63  thinfo;..const c
4250: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
4260: 09 69 6e 74 20 66 68 3b 0a 09 69 6e 74 20 67 70  .int fh;..int gp
4270: 69 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  i_ret;...APPFS_D
4280: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
4290: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
42a0: 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d  ath);...if ((fi-
42b0: 3e 66 6c 61 67 73 20 26 20 33 29 20 21 3d 20 4f  >flags & 3) != O
42c0: 5f 52 44 4f 4e 4c 59 29 20 7b 0a 20 20 20 20 20  _RDONLY) {.     
42d0: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
42e0: 6e 28 2d 45 41 43 43 45 53 29 3b 0a 09 7d 0a 0a  n(-EACCES);..}..
42f0: 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73  .gpi_ret = appfs
4300: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
4310: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 2c 20  ath, &pathinfo, 
4320: 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 67 70 69 5f  NULL);..if (gpi_
4330: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  ret != 0) {...re
4340: 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09  turn(gpi_ret);..
4350: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
4360: 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  .type == APPFS_P
4370: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
4380: 59 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  Y) {...return(-E
4390: 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 72 65 61  ISDIR);..}...rea
43a0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 67  l_path = appfs_g
43b0: 65 74 66 69 6c 65 28 70 61 74 68 69 6e 66 6f 2e  etfile(pathinfo.
43c0: 68 6f 73 74 6e 61 6d 65 2c 20 70 61 74 68 69 6e  hostname, pathin
43d0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
43e0: 2e 73 68 61 31 29 3b 0a 09 69 66 20 28 72 65 61  .sha1);..if (rea
43f0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
4400: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
4410: 3b 0a 09 7d 0a 0a 09 66 68 20 3d 20 6f 70 65 6e  ;..}...fh = open
4420: 28 72 65 61 6c 5f 70 61 74 68 2c 20 4f 5f 52 44  (real_path, O_RD
4430: 4f 4e 4c 59 29 3b 0a 09 66 72 65 65 28 28 76 6f  ONLY);..free((vo
4440: 69 64 20 2a 29 20 72 65 61 6c 5f 70 61 74 68 29  id *) real_path)
4450: 3b 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20 7b  ;..if (fh < 0) {
4460: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
4470: 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66  ..}...fi->fh = f
4480: 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  h;...return(0);.
4490: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
44a0: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f  pfs_fuse_read(co
44b0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
44c0: 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f  char *buf, size_
44d0: 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66  t size, off_t of
44e0: 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73  fset, struct fus
44f0: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
4500: 20 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f   {..off_t lseek_
4510: 72 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 72 65  ret;..ssize_t re
4520: 61 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  ad_ret;...APPFS_
4530: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
4540: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
4550: 70 61 74 68 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72  path);...lseek_r
4560: 65 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66  et = lseek(fi->f
4570: 68 2c 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f  h, offset, SEEK_
4580: 53 45 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b  SET);..if (lseek
4590: 5f 72 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20  _ret != offset) 
45a0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
45b0: 3b 0a 09 7d 0a 0a 09 72 65 61 64 5f 72 65 74 20  ;..}...read_ret 
45c0: 3d 20 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62  = read(fi->fh, b
45d0: 75 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74  uf, size);...ret
45e0: 75 72 6e 28 72 65 61 64 5f 72 65 74 29 3b 0a 7d  urn(read_ret);.}
45f0: 0a 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20  ..static struct 
4600: 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20  fuse_operations 
4610: 61 70 70 66 73 5f 6f 70 65 72 20 3d 20 7b 0a 09  appfs_oper = {..
4620: 2e 67 65 74 61 74 74 72 09 3d 20 61 70 70 66 73  .getattr.= appfs
4630: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 2c 0a 09  _fuse_getattr,..
4640: 2e 72 65 61 64 64 69 72 09 3d 20 61 70 70 66 73  .readdir.= appfs
4650: 5f 66 75 73 65 5f 72 65 61 64 64 69 72 2c 0a 09  _fuse_readdir,..
4660: 2e 6f 70 65 6e 09 09 3d 20 61 70 70 66 73 5f 66  .open..= appfs_f
4670: 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 61 64  use_open,...read
4680: 09 09 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72  ..= appfs_fuse_r
4690: 65 61 64 0a 7d 3b 0a 0a 69 6e 74 20 6d 61 69 6e  ead.};..int main
46a0: 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20  (int argc, char 
46b0: 2a 2a 61 72 67 76 29 20 7b 0a 09 63 6f 6e 73 74  **argv) {..const
46c0: 20 63 68 61 72 20 2a 63 61 63 68 65 64 69 72 20   char *cachedir 
46d0: 3d 20 41 50 50 46 53 5f 43 41 43 48 45 44 49 52  = APPFS_CACHEDIR
46e0: 3b 0a 09 63 68 61 72 20 64 62 66 69 6c 65 6e 61  ;..char dbfilena
46f0: 6d 65 5b 31 30 32 34 5d 3b 0a 09 69 6e 74 20 70  me[1024];..int p
4700: 74 68 72 65 61 64 5f 72 65 74 2c 20 73 6e 70 72  thread_ret, snpr
4710: 69 6e 74 66 5f 72 65 74 2c 20 73 71 6c 69 74 65  intf_ret, sqlite
4720: 5f 72 65 74 3b 0a 0a 09 67 6c 6f 62 61 6c 54 68  _ret;...globalTh
4730: 72 65 61 64 2e 63 61 63 68 65 64 69 72 20 3d 20  read.cachedir = 
4740: 63 61 63 68 65 64 69 72 3b 0a 09 67 6c 6f 62 61  cachedir;..globa
4750: 6c 54 68 72 65 61 64 2e 62 6f 6f 74 74 69 6d 65  lThread.boottime
4760: 20 3d 20 74 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a   = time(NULL);..
4770: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4780: 74 68 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74  thread_key_creat
4790: 65 28 26 69 6e 74 65 72 70 4b 65 79 2c 20 4e 55  e(&interpKey, NU
47a0: 4c 4c 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  LL);..if (pthrea
47b0: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
47c0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
47d0: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
47e0: 65 20 54 53 44 20 6b 65 79 20 66 6f 72 20 54 63  e TSD key for Tc
47f0: 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  l.  Aborting.\n"
4800: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
4810: 0a 09 7d 0a 0a 09 73 6e 70 72 69 6e 74 66 5f 72  ..}...snprintf_r
4820: 65 74 20 3d 20 73 6e 70 72 69 6e 74 66 28 64 62  et = snprintf(db
4830: 66 69 6c 65 6e 61 6d 65 2c 20 73 69 7a 65 6f 66  filename, sizeof
4840: 28 64 62 66 69 6c 65 6e 61 6d 65 29 2c 20 22 25  (dbfilename), "%
4850: 73 2f 25 73 22 2c 20 63 61 63 68 65 64 69 72 2c  s/%s", cachedir,
4860: 20 22 63 61 63 68 65 2e 64 62 22 29 3b 0a 09 69   "cache.db");..i
4870: 66 20 28 73 6e 70 72 69 6e 74 66 5f 72 65 74 20  f (snprintf_ret 
4880: 3e 3d 20 73 69 7a 65 6f 66 28 64 62 66 69 6c 65  >= sizeof(dbfile
4890: 6e 61 6d 65 29 29 20 7b 0a 09 09 66 70 72 69 6e  name)) {...fprin
48a0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
48b0: 6c 65 20 74 6f 20 73 65 74 20 64 61 74 61 62 61  le to set databa
48c0: 73 65 20 66 69 6c 65 6e 61 6d 65 2e 20 20 41 62  se filename.  Ab
48d0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
48e0: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
48f0: 73 71 6c 69 74 65 5f 72 65 74 20 3d 20 73 71 6c  sqlite_ret = sql
4900: 69 74 65 33 5f 6f 70 65 6e 28 64 62 66 69 6c 65  ite3_open(dbfile
4910: 6e 61 6d 65 2c 20 26 67 6c 6f 62 61 6c 54 68 72  name, &globalThr
4920: 65 61 64 2e 64 62 29 3b 0a 09 69 66 20 28 73 71  ead.db);..if (sq
4930: 6c 69 74 65 5f 72 65 74 20 21 3d 20 53 51 4c 49  lite_ret != SQLI
4940: 54 45 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  TE_OK) {...fprin
4950: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
4960: 6c 65 20 74 6f 20 6f 70 65 6e 20 64 61 74 61 62  le to open datab
4970: 61 73 65 3a 20 25 73 5c 6e 22 2c 20 64 62 66 69  ase: %s\n", dbfi
4980: 6c 65 6e 61 6d 65 29 3b 0a 0a 09 09 72 65 74 75  lename);....retu
4990: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  rn(1);..}...retu
49a0: 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67  rn(fuse_main(arg
49b0: 63 2c 20 61 72 67 76 2c 20 26 61 70 70 66 73 5f  c, argv, &appfs_
49c0: 6f 70 65 72 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a  oper, NULL));.}.
49d0: 20 0a                                             .