Hex Artifact Content

Artifact e20407f29fceb02185fa94ee1c80c62b07fa18e4:


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 70 74  .h>.#include <pt
0040: 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  hread.h>.#includ
0050: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
0060: 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e  clude <stdarg.h>
0070: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
0080: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75  b.h>.#include <u
0090: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  nistd.h>.#includ
00a0: 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63  e <errno.h>.#inc
00b0: 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23  lude <fcntl.h>.#
00c0: 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68  include <stdio.h
00d0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65  >.#include <fuse
00e0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77  .h>.#include <pw
00f0: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74  d.h>.#include <t
0100: 63 6c 2e 68 3e 0a 0a 2f 2a 20 46 72 6f 6d 20 73  cl.h>../* From s
0110: 68 61 31 2e 63 20 2a 2f 0a 69 6e 74 20 53 68 61  ha1.c */.int Sha
0120: 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72  1_Init(Tcl_Inter
0130: 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a 23 69 66  p *interp);..#if
0140: 6e 64 65 66 20 41 50 50 46 53 5f 43 41 43 48 45  ndef APPFS_CACHE
0150: 44 49 52 0a 23 64 65 66 69 6e 65 20 41 50 50 46  DIR.#define APPF
0160: 53 5f 43 41 43 48 45 44 49 52 20 22 2f 76 61 72  S_CACHEDIR "/var
0170: 2f 63 61 63 68 65 2f 61 70 70 66 73 22 0a 23 65  /cache/appfs".#e
0180: 6e 64 69 66 0a 0a 23 69 66 64 65 66 20 44 45 42  ndif..#ifdef DEB
0190: 55 47 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53  UG.#define APPFS
01a0: 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b 20 66  _DEBUG(x...) { f
01b0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
01c0: 5b 64 65 62 75 67 5d 20 25 73 3a 25 69 3a 25 73  [debug] %s:%i:%s
01d0: 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f 2c 20 5f  : ", __FILE__, _
01e0: 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e 63 5f  _LINE__, __func_
01f0: 5f 29 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65  _); fprintf(stde
0200: 72 72 2c 20 78 29 3b 20 66 70 72 69 6e 74 66 28  rr, x); fprintf(
0210: 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b 20 7d  stderr, "\n"); }
0220: 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 41  .#else.#define A
0230: 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29  PPFS_DEBUG(x...)
0240: 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a 73 74   /**/.#endif..st
0250: 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b 65 79  atic pthread_key
0260: 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a 0a 73  _t interpKey;..s
0270: 74 72 75 63 74 20 61 70 70 66 73 5f 74 68 72 65  truct appfs_thre
0280: 61 64 5f 64 61 74 61 20 7b 0a 09 63 6f 6e 73 74  ad_data {..const
0290: 20 63 68 61 72 20 2a 63 61 63 68 65 64 69 72 3b   char *cachedir;
02a0: 0a 09 74 69 6d 65 5f 74 20 62 6f 6f 74 74 69 6d  ..time_t boottim
02b0: 65 3b 0a 09 73 74 72 75 63 74 20 7b 0a 09 09 69  e;..struct {...i
02c0: 6e 74 20 77 72 69 74 61 62 6c 65 3b 0a 09 7d 20  nt writable;..} 
02d0: 6f 70 74 69 6f 6e 73 3b 0a 7d 3b 0a 0a 73 74 72  options;.};..str
02e0: 75 63 74 20 61 70 70 66 73 5f 74 68 72 65 61 64  uct appfs_thread
02f0: 5f 64 61 74 61 20 67 6c 6f 62 61 6c 54 68 72 65  _data globalThre
0300: 61 64 3b 0a 0a 74 79 70 65 64 65 66 20 65 6e 75  ad;..typedef enu
0310: 6d 20 7b 0a 09 41 50 50 46 53 5f 50 41 54 48 54  m {..APPFS_PATHT
0320: 59 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09 41 50  YPE_INVALID,..AP
0330: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c  PFS_PATHTYPE_FIL
0340: 45 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  E,..APPFS_PATHTY
0350: 50 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a 09 41  PE_DIRECTORY,..A
0360: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
0370: 4d 4c 49 4e 4b 0a 7d 20 61 70 70 66 73 5f 70 61  MLINK.} appfs_pa
0380: 74 68 74 79 70 65 5f 74 3b 0a 0a 73 74 72 75 63  thtype_t;..struc
0390: 74 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65 6e  t appfs_children
03a0: 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73   {..struct appfs
03b0: 5f 63 68 69 6c 64 72 65 6e 20 2a 5f 6e 65 78 74  _children *_next
03c0: 3b 0a 09 69 6e 74 20 63 6f 75 6e 74 65 72 3b 0a  ;..int counter;.
03d0: 0a 09 63 68 61 72 20 6e 61 6d 65 5b 32 35 36 5d  ..char name[256]
03e0: 3b 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 61 70 70  ;.};..struct app
03f0: 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61  fs_pathinfo {..a
0400: 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 20  ppfs_pathtype_t 
0410: 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69  type;..time_t ti
0420: 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e 61  me;..char hostna
0430: 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70 61  me[256];..int pa
0440: 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e 65  ckaged;..unsigne
0450: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f 64  d long long inod
0460: 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73 74  e;..union {...st
0470: 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63 68  ruct {....int ch
0480: 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64 69  ildcount;...} di
0490: 72 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09  r;...struct {...
04a0: 09 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65 3b  .int executable;
04b0: 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a  ....off_t size;.
04c0: 09 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74 72 75  ..} file;...stru
04d0: 63 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20 73 69  ct {....off_t si
04e0: 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 6f 75 72  ze;....char sour
04f0: 63 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 79 6d  ce[256];...} sym
0500: 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 6e 66  link;..} typeinf
0510: 6f 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 54 63  o;.};..static Tc
0520: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f  l_Interp *appfs_
0530: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
0540: 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f 49 6e  (void) {..Tcl_In
0550: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
0560: 6f 6e 73 74 20 63 68 61 72 20 2a 63 61 63 68 65  onst char *cache
0570: 64 69 72 20 3d 20 67 6c 6f 62 61 6c 54 68 72 65  dir = globalThre
0580: 61 64 2e 63 61 63 68 65 64 69 72 3b 0a 09 69 6e  ad.cachedir;..in
0590: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50  t tcl_ret;...APP
05a0: 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74 69  FS_DEBUG("Creati
05b0: 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72  ng new Tcl inter
05c0: 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 20 3d  preter for TID =
05d0: 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67   0x%llx", (unsig
05e0: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70  ned long long) p
05f0: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a  thread_self());.
0600: 0a 09 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43  ..interp = Tcl_C
0610: 72 65 61 74 65 49 6e 74 65 72 70 28 29 3b 0a 09  reateInterp();..
0620: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
0630: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  LL) {...fprintf(
0640: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
0650: 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 49 6e  to create Tcl In
0660: 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72  terpreter.  Abor
0670: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65  ting.\n");....re
0680: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
0690: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 49  .tcl_ret = Tcl_I
06a0: 6e 69 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66  nit(interp);..if
06b0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
06c0: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
06d0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
06e0: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
06f0: 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  cl.  Aborting.\n
0700: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ");...fprintf(st
0710: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72  derr, "Tcl Error
0720: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f   is: %s\n", Tcl_
0730: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
0740: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c  interp));....Tcl
0750: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
0760: 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e  terp);....return
0770: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c  (NULL);..}...tcl
0780: 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28  _ret = Tcl_Eval(
0790: 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65  interp, "package
07a0: 20 69 66 6e 65 65 64 65 64 20 73 68 61 31 20 31   ifneeded sha1 1
07b0: 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d  .0 [list load {}
07c0: 20 73 68 61 31 5d 22 29 3b 0a 09 69 66 20 28 74   sha1]");..if (t
07d0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
07e0: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
07f0: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
0800: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
0810: 53 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67 2e  SHA1.  Aborting.
0820: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28  \n");...fprintf(
0830: 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72  stderr, "Tcl Err
0840: 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63  or is: %s\n", Tc
0850: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
0860: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54  t(interp));....T
0870: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
0880: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
0890: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74  rn(NULL);..}...t
08a0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61  cl_ret = Tcl_Eva
08b0: 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61  l(interp, "packa
08c0: 67 65 20 69 66 6e 65 65 64 65 64 20 61 70 70 66  ge ifneeded appf
08d0: 73 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61  sd 1.0 [list loa
08e0: 64 20 7b 7d 20 61 70 70 66 73 64 5d 22 29 3b 0a  d {} appfsd]");.
08f0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
0900: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
0910: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
0920: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
0930: 65 20 54 63 6c 20 41 70 70 46 53 20 50 61 63 6b  e Tcl AppFS Pack
0940: 61 67 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  age.  Aborting.\
0950: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
0960: 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f  tderr, "Tcl Erro
0970: 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  r is: %s\n", Tcl
0980: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
0990: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63  (interp));....Tc
09a0: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
09b0: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
09c0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
09d0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
09e0: 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63  (interp, "".#inc
09f0: 6c 75 64 65 20 22 61 70 70 66 73 64 2e 74 63 6c  lude "appfsd.tcl
0a00: 2e 68 22 0a 09 22 22 29 3b 0a 09 69 66 20 28 74  .h".."");..if (t
0a10: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
0a20: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
0a30: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
0a40: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
0a50: 41 70 70 46 53 20 73 63 72 69 70 74 2e 20 20 41  AppFS script.  A
0a60: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09  borting.\n");...
0a70: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0a80: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
0a90: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  s\n", Tcl_GetStr
0aa0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0ab0: 29 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74  ));....Tcl_Delet
0ac0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
0ad0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
0ae0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 54 63 6c 5f 53  ;..}...if (Tcl_S
0af0: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a  etVar(interp, ":
0b00: 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72  :appfs::cachedir
0b10: 22 2c 20 63 61 63 68 65 64 69 72 2c 20 54 43 4c  ", cachedir, TCL
0b20: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d  _GLOBAL_ONLY) ==
0b30: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
0b40: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0b50: 6c 65 20 74 6f 20 73 65 74 20 63 61 63 68 65 20  le to set cache 
0b60: 64 69 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73  directory.  This
0b70: 20 73 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61   should never fa
0b80: 69 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 54 63 6c 5f  il.\n");....Tcl_
0b90: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
0ba0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
0bb0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  NULL);..}...tcl_
0bc0: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
0bd0: 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a  nterp, "::appfs:
0be0: 3a 69 6e 69 74 22 29 3b 0a 09 69 66 20 28 74 63  :init");..if (tc
0bf0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
0c00: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
0c10: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
0c20: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
0c30: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61  ppFS script (::a
0c40: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62  ppfs::init).  Ab
0c50: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
0c60: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
0c70: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
0c80: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
0c90: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
0ca0: 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65  );....Tcl_Delete
0cb0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a  Interp(interp);.
0cc0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
0cd0: 0a 09 7d 0a 0a 09 54 63 6c 5f 48 69 64 65 43 6f  ..}...Tcl_HideCo
0ce0: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
0cf0: 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 2c  uto_load_index",
0d00: 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65   "auto_load_inde
0d10: 78 22 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43 6f  x");..Tcl_HideCo
0d20: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 75  mmand(interp, "u
0d30: 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77  nknown", "unknow
0d40: 6e 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 69 6e  n");...return(in
0d50: 74 65 72 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  terp);.}..static
0d60: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70   Tcl_Interp *app
0d70: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 76 6f 69  fs_TclInterp(voi
0d80: 64 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  d) {..Tcl_Interp
0d90: 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 69 6e 74 65   *interp;...inte
0da0: 72 70 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74  rp = pthread_get
0db0: 73 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b  specific(interpK
0dc0: 65 79 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  ey);..if (interp
0dd0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e   == NULL) {...in
0de0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
0df0: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  ate_TclInterp();
0e00: 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ....if (interp =
0e10: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74  = NULL) {....ret
0e20: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a  urn(NULL);...}..
0e30: 09 09 70 74 68 72 65 61 64 5f 73 65 74 73 70 65  ..pthread_setspe
0e40: 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c  cific(interpKey,
0e50: 20 69 6e 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 72   interp);..}...r
0e60: 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d  eturn(interp);.}
0e70: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
0e80: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f  fs_Tcl_Eval(Tcl_
0e90: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
0ea0: 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20  int objc, const 
0eb0: 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20  char *cmd, ...) 
0ec0: 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a  {..Tcl_Obj **obj
0ed0: 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  v;..const char *
0ee0: 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72  arg;..va_list ar
0ef0: 67 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  gp;..int retval;
0f00: 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69  ..int i;...if (i
0f10: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
0f20: 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52  ...return(TCL_ER
0f30: 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62 6a 76 20  ROR);..}...objv 
0f40: 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b 61 6c 6c  = (void *) ckall
0f50: 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62 6a 76 29  oc(sizeof(*objv)
0f60: 20 2a 20 6f 62 6a 63 29 3b 0a 09 6f 62 6a 76 5b   * objc);..objv[
0f70: 30 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  0] = Tcl_NewStri
0f80: 6e 67 4f 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a  ngObj(cmd, -1);.
0f90: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
0fa0: 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 76 61  t(objv[0]);...va
0fb0: 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64  _start(argp, cmd
0fc0: 29 3b 0a 09 66 6f 72 20 28 69 20 3d 20 31 3b 20  );..for (i = 1; 
0fd0: 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b  i < objc; i++) {
0fe0: 0a 09 09 61 72 67 20 3d 20 76 61 5f 61 72 67 28  ...arg = va_arg(
0ff0: 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  argp, const char
1000: 20 2a 29 3b 0a 09 09 6f 62 6a 76 5b 69 5d 20 3d   *);...objv[i] =
1010: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
1020: 6a 28 61 72 67 2c 20 2d 31 29 3b 0a 09 09 54 63  j(arg, -1);...Tc
1030: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f  l_IncrRefCount(o
1040: 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 09 76 61 5f  bjv[i]);..}..va_
1050: 65 6e 64 28 61 72 67 70 29 3b 0a 0a 09 72 65 74  end(argp);...ret
1060: 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62  val = Tcl_EvalOb
1070: 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c  jv(interp, objc,
1080: 20 6f 62 6a 76 2c 20 30 29 3b 0a 0a 09 66 6f 72   objv, 0);...for
1090: 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 6f 62 6a   (i = 0; i < obj
10a0: 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 54 63 6c 5f  c; i++) {...Tcl_
10b0: 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a  DecrRefCount(obj
10c0: 76 5b 69 5d 29 3b 0a 09 7d 0a 0a 09 63 6b 66 72  v[i]);..}...ckfr
10d0: 65 65 28 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76  ee((void *) objv
10e0: 29 3b 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20  );...if (retval 
10f0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
1100: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
1110: 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65 64 2c 20  command failed, 
1120: 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63 6f 6e 74  ::errorInfo cont
1130: 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  ains: %s\n", Tcl
1140: 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20  _GetVar(interp, 
1150: 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22 2c 20 30  "::errorInfo", 0
1160: 29 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ));..}...return(
1170: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
1180: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 75 70  ic void appfs_up
1190: 64 61 74 65 5f 69 6e 64 65 78 28 63 6f 6e 73 74  date_index(const
11a0: 20 63 68 61 72 20 2a 68 6f 73 74 6e 61 6d 65 29   char *hostname)
11b0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
11c0: 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c  interp;..int tcl
11d0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
11e0: 42 55 47 28 22 45 6e 74 65 72 3a 20 68 6f 73 74  BUG("Enter: host
11f0: 6e 61 6d 65 20 3d 20 25 73 22 2c 20 68 6f 73 74  name = %s", host
1200: 6e 61 6d 65 29 3b 0a 0a 09 69 6e 74 65 72 70 20  name);...interp 
1210: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
1220: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
1230: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
1240: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  turn;..}...tcl_r
1250: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
1260: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
1270: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 69 6e 64 65  ::appfs::getinde
1280: 78 22 2c 20 68 6f 73 74 6e 61 6d 65 29 3b 0a 09  x", hostname);..
1290: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
12a0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
12b0: 5f 44 45 42 55 47 28 22 43 61 6c 6c 20 74 6f 20  _DEBUG("Call to 
12c0: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 69 6e 64 65  ::appfs::getinde
12d0: 78 20 66 61 69 6c 65 64 3a 20 25 73 22 2c 20 54  x failed: %s", T
12e0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
12f0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
1300: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74  return;..}...ret
1310: 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  urn;.}..static c
1320: 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66 73  onst char *appfs
1330: 5f 67 65 74 66 69 6c 65 28 63 6f 6e 73 74 20 63  _getfile(const c
1340: 68 61 72 20 2a 68 6f 73 74 6e 61 6d 65 2c 20 63  har *hostname, c
1350: 6f 6e 73 74 20 63 68 61 72 20 2a 73 68 61 31 29  onst char *sha1)
1360: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
1370: 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a 72  interp;..char *r
1380: 65 74 76 61 6c 3b 0a 09 69 6e 74 20 74 63 6c 5f  etval;..int tcl_
1390: 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ret;...interp = 
13a0: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
13b0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
13c0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
13d0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74  rn(NULL);..}...t
13e0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
13f0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
1400: 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64 6f 77  3, "::appfs::dow
1410: 6e 6c 6f 61 64 22 2c 20 68 6f 73 74 6e 61 6d 65  nload", hostname
1420: 2c 20 73 68 61 31 29 3b 0a 09 69 66 20 28 74 63  , sha1);..if (tc
1430: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
1440: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
1450: 28 22 43 61 6c 6c 20 74 6f 20 3a 3a 61 70 70 66  ("Call to ::appf
1460: 73 3a 3a 64 6f 77 6e 6c 6f 61 64 20 66 61 69 6c  s::download fail
1470: 65 64 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  ed: %s", Tcl_Get
1480: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1490: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
14a0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74  (NULL);..}...ret
14b0: 76 61 6c 20 3d 20 73 74 72 64 75 70 28 54 63 6c  val = strdup(Tcl
14c0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
14d0: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 72 65 74  (interp));...ret
14e0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
14f0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
1500: 73 5f 75 70 64 61 74 65 5f 6d 61 6e 69 66 65 73  s_update_manifes
1510: 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 68 6f  t(const char *ho
1520: 73 74 6e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  stname, const ch
1530: 61 72 20 2a 73 68 61 31 29 20 7b 0a 09 54 63 6c  ar *sha1) {..Tcl
1540: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
1550: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
1560: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
1570: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
1580: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
1590: 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  ) {...return;..}
15a0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
15b0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
15c0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
15d0: 3a 67 65 74 70 6b 67 6d 61 6e 69 66 65 73 74 22  :getpkgmanifest"
15e0: 2c 20 68 6f 73 74 6e 61 6d 65 2c 20 73 68 61 31  , hostname, sha1
15f0: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
1600: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
1610: 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 6c 6c  PPFS_DEBUG("Call
1620: 20 74 6f 20 3a 3a 61 70 70 66 73 3a 3a 67 65 74   to ::appfs::get
1630: 70 6b 67 6d 61 6e 69 66 65 73 74 20 66 61 69 6c  pkgmanifest fail
1640: 65 64 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  ed: %s", Tcl_Get
1650: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1660: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
1670: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..}...return;.}
1680: 0a 0a 73 74 61 74 69 63 20 75 69 64 5f 74 20 61  ..static uid_t a
1690: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 76  ppfs_get_fsuid(v
16a0: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66  oid) {..struct f
16b0: 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  use_context *ctx
16c0: 3b 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67  ;...ctx = fuse_g
16d0: 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69  et_context();..i
16e0: 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20  f (ctx == NULL) 
16f0: 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f  {.../* Unable to
1700: 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72   lookup user for
1710: 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a   some reason */.
1720: 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75  ../* Return an u
1730: 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72  nprivileged user
1740: 20 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e 28   ID */...return(
1750: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
1760: 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 73 74  ctx->uid);.}..st
1770: 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73  atic char *appfs
1780: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69 64  _get_homedir(uid
1790: 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74 72  _t fsuid) {..str
17a0: 75 63 74 20 70 61 73 73 77 64 20 65 6e 74 72 79  uct passwd entry
17b0: 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72 75  , *result;..stru
17c0: 63 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a 09  ct stat stbuf;..
17d0: 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c 20  char buf[1024], 
17e0: 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70  *retval;..int gp
17f0: 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74 3b  u_ret, stat_ret;
1800: 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65 74  ...gpu_ret = get
1810: 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20 26  pwuid_r(fsuid, &
1820: 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a 65  entry, buf, size
1830: 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c 74  of(buf), &result
1840: 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74 20  );..if (gpu_ret 
1850: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
1860: 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f  DEBUG("getpwuid_
1870: 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74  r(%llu, ...) ret
1880: 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65  urned in failure
1890: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
18a0: 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a  g long) fsuid);.
18b0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
18c0: 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74  ..}...if (result
18d0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
18e0: 50 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77  PFS_DEBUG("getpw
18f0: 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29  uid_r(%llu, ...)
1900: 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72   returned NULL r
1910: 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65  esult", (unsigne
1920: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75  d long long) fsu
1930: 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  id);....return(N
1940: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72  ULL);..}...if (r
1950: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d  esult->pw_dir ==
1960: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
1970: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64  _DEBUG("getpwuid
1980: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65  _r(%llu, ...) re
1990: 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65  turned NULL home
19a0: 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75 6e   directory", (un
19b0: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
19c0: 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74  ) fsuid);....ret
19d0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
19e0: 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74 28  stat_ret = stat(
19f0: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20  result->pw_dir, 
1a00: 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73 74  &stbuf);..if (st
1a10: 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  at_ret != 0) {..
1a20: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 73 74  .APPFS_DEBUG("st
1a30: 61 74 28 25 73 29 20 72 65 74 75 72 6e 65 64 20  at(%s) returned 
1a40: 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65 73  in failure", res
1a50: 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09  ult->pw_dir);...
1a60: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1a70: 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73 74  }...if (stbuf.st
1a80: 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29 20 7b  _uid != fsuid) {
1a90: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
1aa0: 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e  UID mis-match on
1ab0: 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d   user %llu's hom
1ac0: 65 20 64 69 72 65 63 74 6f 72 79 20 28 25 73 29  e directory (%s)
1ad0: 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62 79  .  It's owned by
1ae0: 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28   %llu.",...    (
1af0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
1b00: 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20 20  ng) fsuid,...   
1b10: 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c   result->pw_dir,
1b20: 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64  ...    (unsigned
1b30: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75   long long) stbu
1b40: 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09  f.st_uid...);...
1b50: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1b60: 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74 72  }...retval = str
1b70: 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64  dup(result->pw_d
1b80: 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65  ir);...return(re
1b90: 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  tval);.}..static
1ba0: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67   int tcl_appfs_g
1bb0: 65 74 5f 68 6f 6d 65 64 69 72 28 43 6c 69 65 6e  et_homedir(Clien
1bc0: 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e  tData cd, Tcl_In
1bd0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
1be0: 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20  t objc, Tcl_Obj 
1bf0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b  *CONST objv[]) {
1c00: 0a 09 63 68 61 72 20 2a 68 6f 6d 65 64 69 72 3b  ..char *homedir;
1c10: 0a 0a 20 20 20 20 20 20 20 20 69 66 20 28 6f 62  ..        if (ob
1c20: 6a 63 20 21 3d 20 31 29 20 7b 0a 20 20 20 20 20  jc != 1) {.     
1c30: 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57             Tcl_W
1c40: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
1c50: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 4e 55 4c  rp, 1, objv, NUL
1c60: 4c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  L);.            
1c70: 20 20 20 20 72 65 74 75 72 6e 28 54 43 4c 5f 45      return(TCL_E
1c80: 52 52 4f 52 29 3b 0a 20 20 20 20 20 20 20 20 7d  RROR);.        }
1c90: 0a 0a 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70  ...homedir = app
1ca0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61  fs_get_homedir(a
1cb0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
1cc0: 29 3b 0a 0a 09 69 66 20 28 68 6f 6d 65 64 69 72  );...if (homedir
1cd0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
1ce0: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
1cf0: 0a 09 7d 0a 0a 20 20 20 20 20 20 20 20 54 63 6c  ..}..        Tcl
1d00: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
1d10: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 53 74 72  terp, Tcl_NewStr
1d20: 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20  ingObj(homedir, 
1d30: 2d 31 29 29 3b 0a 0a 09 66 72 65 65 28 68 6f 6d  -1));...free(hom
1d40: 65 64 69 72 29 3b 0a 0a 20 20 20 20 20 20 20 20  edir);..        
1d50: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
1d60: 7d 0a 0a 2f 2a 20 47 65 6e 65 72 61 74 65 20 61  }../* Generate a
1d70: 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67 69  n inode for a gi
1d80: 76 65 6e 20 70 61 74 68 20 2a 2f 0a 73 74 61 74  ven path */.stat
1d90: 69 63 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70  ic long long app
1da0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
1db0: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
1dc0: 74 68 29 20 7b 0a 09 6c 6f 6e 67 20 6c 6f 6e 67  th) {..long long
1dd0: 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74 20   retval;..const 
1de0: 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74 76 61  char *p;...retva
1df0: 6c 20 3d 20 31 30 3b 0a 0a 09 66 6f 72 20 28 70  l = 10;...for (p
1e00: 20 3d 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b   = path; *p; p++
1e10: 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 25 3d 20  ) {...retval %= 
1e20: 34 32 39 30 39 36 30 32 39 30 55 4c 4c 3b 0a 09  4290960290ULL;..
1e30: 09 72 65 74 76 61 6c 20 2b 3d 20 2a 70 3b 0a 09  .retval += *p;..
1e40: 09 72 65 74 76 61 6c 20 3c 3c 3d 20 37 3b 0a 09  .retval <<= 7;..
1e50: 7d 0a 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31 30  }...retval += 10
1e60: 3b 0a 09 72 65 74 76 61 6c 20 25 3d 20 34 32 39  ;..retval %= 429
1e70: 34 39 36 37 32 39 36 55 4c 4c 3b 0a 0a 09 72 65  4967296ULL;...re
1e80: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
1e90: 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61 74  ./* Get informat
1ea0: 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74 68  ion about a path
1eb0: 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79  , and optionally
1ec0: 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20 2a   list children *
1ed0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
1ee0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
1ef0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 5f 70 61  (const char *_pa
1f00: 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  th, struct appfs
1f10: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
1f20: 6e 66 6f 2c 20 73 74 72 75 63 74 20 61 70 70 66  nfo, struct appf
1f30: 73 5f 63 68 69 6c 64 72 65 6e 20 2a 2a 63 68 69  s_children **chi
1f40: 6c 64 72 65 6e 29 20 7b 0a 7d 0a 0a 73 74 61 74  ldren) {.}..stat
1f50: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
1f60: 65 5f 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74  e_readlink(const
1f70: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61   char *path, cha
1f80: 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73  r *buf, size_t s
1f90: 69 7a 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61  ize) {..struct a
1fa0: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61  ppfs_pathinfo pa
1fb0: 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 73  thinfo;..int res
1fc0: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45   = 0;...APPFS_DE
1fd0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
1fe0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
1ff0: 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e  th);...pathinfo.
2000: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
2010: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
2020: 09 72 65 73 20 3d 20 61 70 70 66 73 5f 67 65 74  .res = appfs_get
2030: 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c  _path_info(path,
2040: 20 26 70 61 74 68 69 6e 66 6f 2c 20 4e 55 4c 4c   &pathinfo, NULL
2050: 29 3b 0a 09 69 66 20 28 72 65 73 20 21 3d 20 30  );..if (res != 0
2060: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 73  ) {...return(res
2070: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  );..}...if (path
2080: 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50  info.type != APP
2090: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
20a0: 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  INK) {...return(
20b0: 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69  -EINVAL);..}...i
20c0: 66 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69  f ((strlen(pathi
20d0: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
20e0: 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31  link.source) + 1
20f0: 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65  ) > size) {...re
2100: 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f  turn(-ENAMETOOLO
2110: 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  NG);..}...memcpy
2120: 28 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74  (buf, pathinfo.t
2130: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
2140: 73 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70  source, strlen(p
2150: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
2160: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29  .symlink.source)
2170: 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28   + 1);...return(
2180: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
2190: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74  t appfs_fuse_get
21a0: 61 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20  attr(const char 
21b0: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74  *path, struct st
21c0: 61 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74  at *stbuf) {..st
21d0: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
21e0: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69  nfo pathinfo;..i
21f0: 6e 74 20 72 65 73 20 3d 20 30 3b 0a 0a 09 41 50  nt res = 0;...AP
2200: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
2210: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
2220: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74  )", path);...pat
2230: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
2240: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
2250: 4c 49 44 3b 0a 0a 09 72 65 73 20 3d 20 61 70 70  LID;...res = app
2260: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
2270: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
2280: 2c 20 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 72 65  , NULL);..if (re
2290: 73 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  s != 0) {...retu
22a0: 72 6e 28 72 65 73 29 3b 0a 09 7d 0a 0a 09 6d 65  rn(res);..}...me
22b0: 6d 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73  mset(stbuf, 0, s
22c0: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61  izeof(struct sta
22d0: 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74  t));...stbuf->st
22e0: 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66  _mtime = pathinf
22f0: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e  o.time;..stbuf->
2300: 73 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69  st_ctime = pathi
2310: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
2320: 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74  ->st_atime = pat
2330: 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62  hinfo.time;..stb
2340: 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70  uf->st_ino   = p
2350: 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09  athinfo.inode;..
2360: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20  stbuf->st_mode  
2370: 3d 20 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70  = 0;...switch (p
2380: 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a  athinfo.type) {.
2390: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
23a0: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a  HTYPE_DIRECTORY:
23b0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
23c0: 64 65 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30  de = S_IFDIR | 0
23d0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
23e0: 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61  t_nlink = 2 + pa
23f0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
2400: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a  dir.childcount;.
2410: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
2420: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
2430: 46 49 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74  FILE:....if (pat
2440: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
2450: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20  ile.executable) 
2460: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
2470: 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c  mode = S_IFREG |
2480: 20 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65   0555;....} else
2490: 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74   {.....stbuf->st
24a0: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20  _mode = S_IFREG 
24b0: 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09  | 0444;....}....
24c0: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
24d0: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
24e0: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
24f0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
2500: 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b  .size;....break;
2510: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
2520: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a  THTYPE_SYMLINK:.
2530: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
2540: 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35  e = S_IFLNK | 05
2550: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
2560: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
2570: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
2580: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
2590: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a  o.symlink.size;.
25a0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
25b0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
25c0: 49 4e 56 41 4c 49 44 3a 0a 09 09 09 72 65 73 20  INVALID:....res 
25d0: 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61  = -EIO;.....brea
25e0: 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  k;..}...if (path
25f0: 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b  info.packaged) {
2600: 0a 09 09 69 66 20 28 67 6c 6f 62 61 6c 54 68 72  ...if (globalThr
2610: 65 61 64 2e 6f 70 74 69 6f 6e 73 2e 77 72 69 74  ead.options.writ
2620: 61 62 6c 65 29 20 7b 0a 09 09 09 73 74 62 75 66  able) {....stbuf
2630: 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 32  ->st_mode |= 022
2640: 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75  2;...}..}...retu
2650: 72 6e 20 72 65 73 3b 0a 7d 0a 0a 73 74 61 74 69  rn res;.}..stati
2660: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
2670: 5f 72 65 61 64 64 69 72 28 63 6f 6e 73 74 20 63  _readdir(const c
2680: 68 61 72 20 2a 70 61 74 68 2c 20 76 6f 69 64 20  har *path, void 
2690: 2a 62 75 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f  *buf, fuse_fill_
26a0: 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66  dir_t filler, of
26b0: 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75  f_t offset, stru
26c0: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
26d0: 6f 20 2a 66 69 29 20 7b 0a 09 73 74 72 75 63 74  o *fi) {..struct
26e0: 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20   appfs_pathinfo 
26f0: 70 61 74 68 69 6e 66 6f 3b 0a 09 73 74 72 75 63  pathinfo;..struc
2700: 74 20 61 70 70 66 73 5f 63 68 69 6c 64 72 65 6e  t appfs_children
2710: 20 2a 63 68 69 6c 64 72 65 6e 2c 20 2a 63 68 69   *children, *chi
2720: 6c 64 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  ld;..int retval;
2730: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2740: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
2750: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
2760: 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73  ..retval = appfs
2770: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
2780: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 2c 20  ath, &pathinfo, 
2790: 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69 66 20  &children);..if 
27a0: 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a  (retval != 0) {.
27b0: 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
27c0: 3b 0a 09 7d 0a 0a 09 66 69 6c 6c 65 72 28 62 75  ;..}...filler(bu
27d0: 66 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29  f, ".", NULL, 0)
27e0: 3b 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22  ;..filler(buf, "
27f0: 2e 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a  ..", NULL, 0);..
2800: 09 66 6f 72 20 28 63 68 69 6c 64 20 3d 20 63 68  .for (child = ch
2810: 69 6c 64 72 65 6e 3b 20 63 68 69 6c 64 3b 20 63  ildren; child; c
2820: 68 69 6c 64 20 3d 20 63 68 69 6c 64 2d 3e 5f 6e  hild = child->_n
2830: 65 78 74 29 20 7b 0a 09 09 66 69 6c 6c 65 72 28  ext) {...filler(
2840: 62 75 66 2c 20 63 68 69 6c 64 2d 3e 6e 61 6d 65  buf, child->name
2850: 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a  , NULL, 0);..}..
2860: 2f 2f 09 61 70 70 66 73 5f 66 72 65 65 5f 6c 69  //.appfs_free_li
2870: 73 74 5f 63 68 69 6c 64 72 65 6e 28 63 68 69 6c  st_children(chil
2880: 64 72 65 6e 29 3b 0a 0a 09 72 65 74 75 72 6e 28  dren);...return(
2890: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
28a0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65  t appfs_fuse_ope
28b0: 6e 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  n(const char *pa
28c0: 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  th, struct fuse_
28d0: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
28e0: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
28f0: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
2900: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
2910: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66  eal_path;..int f
2920: 68 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 3b  h;..int gpi_ret;
2930: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2940: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
2950: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
2960: 0a 23 69 66 20 30 0a 0a 09 69 66 20 28 28 66 69  .#if 0...if ((fi
2970: 2d 3e 66 6c 61 67 73 20 26 20 33 29 20 21 3d 20  ->flags & 3) != 
2980: 4f 5f 52 44 4f 4e 4c 59 29 20 7b 0a 20 20 20 20  O_RDONLY) {.    
2990: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
29a0: 72 6e 28 2d 45 41 43 43 45 53 29 3b 0a 09 7d 0a  rn(-EACCES);..}.
29b0: 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66  ..gpi_ret = appf
29c0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
29d0: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 2c  path, &pathinfo,
29e0: 20 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 67 70 69   NULL);..if (gpi
29f0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72  _ret != 0) {...r
2a00: 65 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a  eturn(gpi_ret);.
2a10: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
2a20: 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f  o.type == APPFS_
2a30: 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f  PATHTYPE_DIRECTO
2a40: 52 59 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  RY) {...return(-
2a50: 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 72 65  EISDIR);..}...re
2a60: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
2a70: 67 65 74 66 69 6c 65 28 70 61 74 68 69 6e 66 6f  getfile(pathinfo
2a80: 2e 68 6f 73 74 6e 61 6d 65 2c 20 70 61 74 68 69  .hostname, pathi
2a90: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
2aa0: 65 2e 73 68 61 31 29 3b 0a 09 69 66 20 28 72 65  e.sha1);..if (re
2ab0: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
2ac0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
2ad0: 29 3b 0a 09 7d 0a 0a 09 66 68 20 3d 20 6f 70 65  );..}...fh = ope
2ae0: 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 4f 5f 52  n(real_path, O_R
2af0: 44 4f 4e 4c 59 29 3b 0a 09 66 72 65 65 28 28 76  DONLY);..free((v
2b00: 6f 69 64 20 2a 29 20 72 65 61 6c 5f 70 61 74 68  oid *) real_path
2b10: 29 3b 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20  );..if (fh < 0) 
2b20: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
2b30: 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20  ;..}...fi->fh = 
2b40: 66 68 3b 0a 23 65 6e 64 69 66 0a 0a 09 72 65 74  fh;.#endif...ret
2b50: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
2b60: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
2b70: 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 20 63 68 61  _close(const cha
2b80: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
2b90: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
2ba0: 66 69 29 20 7b 0a 09 69 6e 74 20 63 6c 6f 73 65  fi) {..int close
2bb0: 5f 72 65 74 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65  _ret;...close_re
2bc0: 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68  t = close(fi->fh
2bd0: 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72 65  );..if (close_re
2be0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
2bf0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72  rn(-EIO);..}...r
2c00: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
2c10: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
2c20: 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63 68  se_read(const ch
2c30: 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a  ar *path, char *
2c40: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
2c50: 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20  , off_t offset, 
2c60: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
2c70: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 6f 66  _info *fi) {..of
2c80: 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b 0a 09  f_t lseek_ret;..
2c90: 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 65 74  ssize_t read_ret
2ca0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
2cb0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
2cc0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
2cd0: 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d 20 6c  ...lseek_ret = l
2ce0: 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f 66 66  seek(fi->fh, off
2cf0: 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a  set, SEEK_SET);.
2d00: 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 20 21  .if (lseek_ret !
2d10: 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 72 65  = offset) {...re
2d20: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
2d30: 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65 61 64  .read_ret = read
2d40: 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69  (fi->fh, buf, si
2d50: 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65  ze);...return(re
2d60: 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74  ad_ret);.}..stat
2d70: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73 71 6c  ic int appfs_sql
2d80: 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61 72 20  ite3(const char 
2d90: 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  *sql) {..Tcl_Int
2da0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
2db0: 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f 72 65  nst char *sql_re
2dc0: 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  t;..int tcl_ret;
2dd0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
2de0: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
2df0: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
2e00: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  p == NULL) {...f
2e10: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
2e20: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
2e30: 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74   a Tcl interpret
2e40: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
2e50: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
2e60: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
2e70: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
2e80: 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70  interp, 5, "::ap
2e90: 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22  pfs::db", "eval"
2ea0: 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75  , sql, "row", "u
2eb0: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
2ec0: 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20   row(*); parray 
2ed0: 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d  row; puts \"----
2ee0: 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d  \"");..sql_ret =
2ef0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
2f00: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
2f10: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
2f20: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
2f30: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72  tf(stderr, "[err
2f40: 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72  or] %s\n", sql_r
2f50: 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  et);....return(1
2f60: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f  );..}...if (sql_
2f70: 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30  ret && sql_ret[0
2f80: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
2f90: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71  rintf("%s\n", sq
2fa0: 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74  l_ret);..}...ret
2fb0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
2fc0: 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63 6c 28  c int appfs_tcl(
2fd0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 29  const char *tcl)
2fe0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
2ff0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
3000: 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b  har *tcl_result;
3010: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
3020: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
3030: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
3040: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
3050: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72  == NULL) {...fpr
3060: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
3070: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61  able to create a
3080: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
3090: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
30a0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
30b0: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54  .}...tcl_ret = T
30c0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
30d0: 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c  tcl);..tcl_resul
30e0: 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  t = Tcl_GetStrin
30f0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
3100: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ...if (tcl_ret !
3110: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
3120: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b  rintf(stderr, "[
3130: 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 74 63  error] %s\n", tc
3140: 6c 5f 72 65 73 75 6c 74 29 3b 0a 0a 09 09 72 65  l_result);....re
3150: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66  turn(1);..}...if
3160: 20 28 74 63 6c 5f 72 65 73 75 6c 74 20 26 26 20   (tcl_result && 
3170: 74 63 6c 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d  tcl_result[0] !=
3180: 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74   '\0') {...print
3190: 66 28 22 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65  f("%s\n", tcl_re
31a0: 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  sult);..}...retu
31b0: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
31c0: 20 69 6e 74 20 41 70 70 66 73 64 5f 49 6e 69 74   int Appfsd_Init
31d0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
31e0: 65 72 70 29 20 7b 0a 23 69 66 64 65 66 20 55 53  erp) {.#ifdef US
31f0: 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09 69 66 20  E_TCL_STUBS..if 
3200: 28 54 63 6c 5f 49 6e 69 74 53 74 75 62 73 28 69  (Tcl_InitStubs(i
3210: 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45 52 53 49  nterp, TCL_VERSI
3220: 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29 20 7b 0a  ON, 0) == 0L) {.
3230: 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52  ..return(TCL_ERR
3240: 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  OR);..}.#endif..
3250: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
3260: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
3270: 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f 6d 65 64  ppfsd::get_homed
3280: 69 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67  ir", tcl_appfs_g
3290: 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e 55 4c 4c  et_homedir, NULL
32a0: 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50  , NULL);...Tcl_P
32b0: 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70  kgProvide(interp
32c0: 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30  , "appfsd", "1.0
32d0: 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c  ");...return(TCL
32e0: 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  _OK);.}..static 
32f0: 73 74 72 75 63 74 20 66 75 73 65 5f 6f 70 65 72  struct fuse_oper
3300: 61 74 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70 65  ations appfs_ope
3310: 72 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20  r = {...getattr 
3320: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67    = appfs_fuse_g
3330: 65 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69  etattr,...readdi
3340: 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  r   = appfs_fuse
3350: 5f 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64  _readdir,...read
3360: 6c 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75  link  = appfs_fu
3370: 73 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f  se_readlink,...o
3380: 70 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73  pen      = appfs
3390: 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65  _fuse_open,...re
33a0: 6c 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f  lease   = appfs_
33b0: 66 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65  fuse_close,...re
33c0: 61 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  ad      = appfs_
33d0: 66 75 73 65 5f 72 65 61 64 0a 7d 3b 0a 0a 69 6e  fuse_read.};..in
33e0: 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c  t main(int argc,
33f0: 20 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a   char **argv) {.
3400: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 61 63  .const char *cac
3410: 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41  hedir = APPFS_CA
3420: 43 48 45 44 49 52 3b 0a 09 69 6e 74 20 70 74 68  CHEDIR;..int pth
3430: 72 65 61 64 5f 72 65 74 3b 0a 0a 09 67 6c 6f 62  read_ret;...glob
3440: 61 6c 54 68 72 65 61 64 2e 63 61 63 68 65 64 69  alThread.cachedi
3450: 72 20 3d 20 63 61 63 68 65 64 69 72 3b 0a 09 67  r = cachedir;..g
3460: 6c 6f 62 61 6c 54 68 72 65 61 64 2e 62 6f 6f 74  lobalThread.boot
3470: 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c 4c  time = time(NULL
3480: 29 3b 0a 09 67 6c 6f 62 61 6c 54 68 72 65 61 64  );..globalThread
3490: 2e 6f 70 74 69 6f 6e 73 2e 77 72 69 74 61 62 6c  .options.writabl
34a0: 65 20 3d 20 31 3b 0a 0a 09 54 63 6c 5f 53 74 61  e = 1;...Tcl_Sta
34b0: 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c  ticPackage(NULL,
34c0: 20 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49 6e   "sha1", Sha1_In
34d0: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  it, NULL);..Tcl_
34e0: 53 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55  StaticPackage(NU
34f0: 4c 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41 70  LL, "appfsd", Ap
3500: 70 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29  pfsd_Init, NULL)
3510: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
3520: 3d 20 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72  = pthread_key_cr
3530: 65 61 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c  eate(&interpKey,
3540: 20 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 70 74 68   NULL);..if (pth
3550: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3560: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
3570: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  r, "Unable to cr
3580: 65 61 74 65 20 54 53 44 20 6b 65 79 20 66 6f 72  eate TSD key for
3590: 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e   Tcl.  Aborting.
35a0: 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  \n");....return(
35b0: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 72 67  1);..}...if (arg
35c0: 63 20 3d 3d 20 33 20 26 26 20 73 74 72 63 6d 70  c == 3 && strcmp
35d0: 28 61 72 67 76 5b 31 5d 2c 20 22 2d 73 71 6c 69  (argv[1], "-sqli
35e0: 74 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  te3") == 0) {...
35f0: 72 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c  return(appfs_sql
3600: 69 74 65 33 28 61 72 67 76 5b 32 5d 29 29 3b 0a  ite3(argv[2]));.
3610: 09 7d 0a 0a 09 69 66 20 28 61 72 67 63 20 3d 3d  .}...if (argc ==
3620: 20 33 20 26 26 20 73 74 72 63 6d 70 28 61 72 67   3 && strcmp(arg
3630: 76 5b 31 5d 2c 20 22 2d 74 63 6c 22 29 20 3d 3d  v[1], "-tcl") ==
3640: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61   0) {...return(a
3650: 70 70 66 73 5f 74 63 6c 28 61 72 67 76 5b 32 5d  ppfs_tcl(argv[2]
3660: 29 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ));..}...return(
3670: 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 63 2c 20  fuse_main(argc, 
3680: 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65  argv, &appfs_ope
3690: 72 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a     r, NULL));.}. .