Hex Artifact Content

Artifact 7148f823cb333610c78d89beb5d1b4d1ae8bb31b:


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 66 73 75 69 64  clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a  ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67  #include <string
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0080: 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  darg.h>.#include
0090: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
00a0: 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a  lude <unistd.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e  #include <errno.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e  h>.#include <fcn
00d0: 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  tl.h>.#include <
00e0: 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64  stdio.h>.#includ
00f0: 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69 6e 63 6c  e <fuse.h>.#incl
0100: 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23 69 6e 63  ude <pwd.h>.#inc
0110: 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a  lude <tcl.h>../*
0120: 0a 20 2a 20 44 65 66 61 75 6c 74 20 63 61 63 68  . * Default cach
0130: 65 20 64 69 72 65 63 74 6f 72 79 0a 20 2a 2f 0a  e directory. */.
0140: 23 69 66 6e 64 65 66 20 41 50 50 46 53 5f 43 41  #ifndef APPFS_CA
0150: 43 48 45 44 49 52 0a 23 64 65 66 69 6e 65 20 41  CHEDIR.#define A
0160: 50 50 46 53 5f 43 41 43 48 45 44 49 52 20 22 2f  PPFS_CACHEDIR "/
0170: 76 61 72 2f 63 61 63 68 65 2f 61 70 70 66 73 22  var/cache/appfs"
0180: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44 65 62 75  .#endif../* Debu
0190: 67 67 69 6e 67 20 6d 61 63 72 6f 73 20 2a 2f 0a  gging macros */.
01a0: 23 69 66 64 65 66 20 44 45 42 55 47 0a 23 64 65  #ifdef DEBUG.#de
01b0: 66 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47  fine APPFS_DEBUG
01c0: 28 78 2e 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66  (x...) { fprintf
01d0: 28 73 74 64 65 72 72 2c 20 22 5b 64 65 62 75 67  (stderr, "[debug
01e0: 5d 20 25 73 3a 25 69 3a 25 73 3a 20 22 2c 20 5f  ] %s:%i:%s: ", _
01f0: 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f  _FILE__, __LINE_
0200: 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 66 70  _, __func__); fp
0210: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 29  rintf(stderr, x)
0220: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ; fprintf(stderr
0230: 2c 20 22 5c 6e 22 29 3b 20 7d 0a 23 65 6c 73 65  , "\n"); }.#else
0240: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
0250: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a  EBUG(x...) /**/.
0260: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48  #endif../*. * SH
0270: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69  A1 Tcl Package i
0280: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d  nitializer, from
0290: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20   sha1.o. */.int 
02a0: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  Sha1_Init(Tcl_In
02b0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a  terp *interp);..
02c0: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65  /*. * Thread Spe
02d0: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29  cific Data (TSD)
02e0: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72   for Tcl Interpr
02f0: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72  eter for the cur
0300: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a  rent thread. */.
0310: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b  static pthread_k
0320: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a  ey_t interpKey;.
0330: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61  ./*. * Global va
0340: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20  riables, needed 
0350: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20  for all threads 
0360: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c  but only initial
0370: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a  ized before any.
0380: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20   * FUSE threads 
0390: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a  are created. */.
03a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
03b0: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65  s_cachedir;.time
03c0: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d  _t appfs_boottim
03d0: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73  e;.int appfs_fus
03e0: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 0a  e_started = 0;..
03f0: 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68  /*. * AppFS Path
0400: 20 54 79 70 65 3a 20 20 44 65 73 63 72 69 62 65   Type:  Describe
0410: 73 20 74 68 65 20 74 79 70 65 20 6f 66 20 70 61  s the type of pa
0420: 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c 65 20  th a given file 
0430: 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20 65  is. */.typedef e
0440: 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f 50 41 54  num {..APPFS_PAT
0450: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09  HTYPE_INVALID,..
0460: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
0470: 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  ILE,..APPFS_PATH
0480: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a  TYPE_DIRECTORY,.
0490: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f  .APPFS_PATHTYPE_
04a0: 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46 53 5f  SYMLINK,..APPFS_
04b0: 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 2c  PATHTYPE_SOCKET,
04c0: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
04d0: 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 73 5f 70  _FIFO,.} appfs_p
04e0: 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a 0a 20  athtype_t;../*. 
04f0: 2a 20 41 70 70 46 53 20 50 61 74 68 20 49 6e 66  * AppFS Path Inf
0500: 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20 20 20  ormation:. *    
0510: 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 6c 79 20       Completely 
0520: 64 65 73 63 72 69 62 65 73 20 61 20 73 70 65 63  describes a spec
0530: 69 66 69 63 20 70 61 74 68 2c 20 68 6f 77 20 69  ific path, how i
0540: 74 20 73 68 6f 75 6c 64 20 62 65 20 72 65 74 75  t should be retu
0550: 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 20 20 20  rned to. *      
0560: 20 20 20 74 6f 20 74 68 65 20 6b 65 72 6e 65 6c     to the kernel
0570: 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70 70 66  . */.struct appf
0580: 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61 70  s_pathinfo {..ap
0590: 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 20 74  pfs_pathtype_t t
05a0: 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69 6d  ype;..time_t tim
05b0: 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e 61 6d  e;..char hostnam
05c0: 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70 61 63  e[256];..int pac
05d0: 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e 65 64  kaged;..unsigned
05e0: 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f 64 65   long long inode
05f0: 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73 74 72  ;..union {...str
0600: 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63 68 69  uct {....int chi
0610: 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64 69 72  ldcount;...} dir
0620: 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  ;...struct {....
0630: 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65 3b 0a  int executable;.
0640: 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09  ...off_t size;..
0650: 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74 72 75 63  .} file;...struc
0660: 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a  t {....off_t siz
0670: 65 3b 0a 09 09 09 63 68 61 72 20 73 6f 75 72 63  e;....char sourc
0680: 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 79 6d 6c  e[256];...} syml
0690: 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 6e 66 6f  ink;..} typeinfo
06a0: 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61  ;.};../*. * Crea
06b0: 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74  te a new Tcl int
06c0: 65 72 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d  erpreter and com
06d0: 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69  pletely initiali
06e0: 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63  ze it. */.static
06f0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70   Tcl_Interp *app
0700: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
0710: 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72  erp(char **error
0720: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f  _string) {..Tcl_
0730: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
0740: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
0750: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65  APPFS_DEBUG("Cre
0760: 61 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e  ating new Tcl in
0770: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49  terpreter for TI
0780: 44 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e  D = 0x%llx", (un
0790: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
07a0: 29 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29  ) pthread_self()
07b0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 54 63  );...interp = Tc
07c0: 6c 5f 43 72 65 61 74 65 49 6e 74 65 72 70 28 29  l_CreateInterp()
07d0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
07e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
07f0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0800: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c  le to create Tcl
0810: 20 49 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   Interpreter.  A
0820: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
0830: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
0840: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
0850: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22  tring = strdup("
0860: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
0870: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
0880: 2e 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  .");...}....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 49 6e 69  cl_ret = Tcl_Ini
08b0: 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28  t(interp);..if (
08c0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
08d0: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
08e0: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
08f0: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
0900: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
0910: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
0920: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
0930: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
0940: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0950: 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65  terp));....if (e
0960: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
0970: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
0980: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(Tcl_Get
0990: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
09a0: 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63  erp));...}....Tc
09b0: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
09c0: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
09d0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
09e0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
09f0: 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67  (interp, "packag
0a00: 65 20 69 66 6e 65 65 64 65 64 20 73 68 61 31 20  e ifneeded sha1 
0a10: 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b  1.0 [list load {
0a20: 7d 20 73 68 61 31 5d 22 29 3b 0a 09 69 66 20 28  } sha1]");..if (
0a30: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
0a40: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
0a50: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
0a60: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
0a70: 20 53 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67   SHA1.  Aborting
0a80: 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  .\n");...fprintf
0a90: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
0aa0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
0ab0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
0ac0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
0ad0: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
0ae0: 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74  ) {....*error_st
0af0: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
0b00: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
0b10: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a  t(interp));...}.
0b20: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
0b30: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  erp(interp);....
0b40: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
0b50: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
0b60: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70  _Eval(interp, "p
0b70: 61 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20  ackage ifneeded 
0b80: 61 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74  appfsd 1.0 [list
0b90: 20 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d   load {} appfsd]
0ba0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0bb0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0bc0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0bd0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0be0: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
0bf0: 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72 74 69  Package.  Aborti
0c00: 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  ng.\n");...fprin
0c10: 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20  tf(stderr, "Tcl 
0c20: 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c  Error is: %s\n",
0c30: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
0c40: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
0c50: 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69  ..if (error_stri
0c60: 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f  ng) {....*error_
0c70: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
0c80: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0c90: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
0ca0: 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  }....Tcl_DeleteI
0cb0: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
0cc0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
0cd0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64  .}.../*.. * Load
0ce0: 20 22 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68   "pki.tcl" in th
0cf0: 65 20 73 61 6d 65 20 77 61 79 20 61 73 20 61 70  e same way as ap
0d00: 70 66 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65  pfsd.tcl (see be
0d10: 6c 6f 77 29 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72  low).. */..tcl_r
0d20: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
0d30: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
0d40: 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 22  e "pki.tcl.h".."
0d50: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0d60: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0d70: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0d80: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0d90: 61 6c 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20  alize Tcl PKI.  
0da0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
0db0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0dc0: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
0dd0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
0de0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0df0: 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  p));....if (erro
0e00: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
0e10: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
0e20: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
0e30: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0e40: 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44  ));...}....Tcl_D
0e50: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
0e60: 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  rp);....return(N
0e70: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
0e80: 2a 20 4c 6f 61 64 20 74 68 65 20 22 61 70 70 66  * Load the "appf
0e90: 73 64 2e 74 63 6c 22 20 73 63 72 69 70 74 2c 20  sd.tcl" script, 
0ea0: 77 68 69 63 68 20 69 73 20 22 63 6f 6d 70 69 6c  which is "compil
0eb0: 65 64 22 20 69 6e 74 6f 20 61 20 43 20 68 65 61  ed" into a C hea
0ec0: 64 65 72 0a 09 20 2a 20 73 6f 20 74 68 61 74 20  der.. * so that 
0ed0: 69 74 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64  it does not need
0ee0: 20 74 6f 20 65 78 69 73 74 20 6f 6e 20 74 68 65   to exist on the
0ef0: 20 66 69 6c 65 73 79 73 74 65 6d 20 61 6e 64 20   filesystem and 
0f00: 63 61 6e 20 62 65 0a 09 20 2a 20 64 69 72 65 63  can be.. * direc
0f10: 74 6c 79 20 65 76 61 6c 75 61 74 65 64 2e 0a 09  tly evaluated...
0f20: 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54   */..tcl_ret = T
0f30: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
0f40: 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 61 70 70  "".#include "app
0f50: 66 73 64 2e 74 63 6c 2e 68 22 0a 09 22 22 29 3b  fsd.tcl.h".."");
0f60: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
0f70: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
0f80: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
0f90: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
0fa0: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72  ze Tcl AppFS scr
0fb0: 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ipt.  Aborting.\
0fc0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
0fd0: 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f  tderr, "Tcl Erro
0fe0: 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  r is: %s\n", Tcl
0ff0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1000: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66  (interp));....if
1010: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1020: 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  {....*error_stri
1030: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
1040: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1050: 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09  interp));...}...
1060: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
1070: 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  p(interp);....re
1080: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1090: 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62  ./*.. * Set glob
10a0: 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66 72 6f  al variables fro
10b0: 6d 20 43 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a  m C to Tcl.. */.
10c0: 09 69 66 20 28 54 63 6c 5f 53 65 74 56 61 72 28  .if (Tcl_SetVar(
10d0: 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73  interp, "::appfs
10e0: 3a 3a 63 61 63 68 65 64 69 72 22 2c 20 61 70 70  ::cachedir", app
10f0: 66 73 5f 63 61 63 68 65 64 69 72 2c 20 54 43 4c  fs_cachedir, TCL
1100: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d  _GLOBAL_ONLY) ==
1110: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
1120: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1130: 6c 65 20 74 6f 20 73 65 74 20 63 61 63 68 65 20  le to set cache 
1140: 64 69 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73  directory.  This
1150: 20 73 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61   should never fa
1160: 69 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28  il.\n");....if (
1170: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
1180: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
1190: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
11a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
11b0: 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54  terp));...}....T
11c0: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
11d0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
11e0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
11f0: 2a 0a 09 20 2a 20 49 6e 69 74 69 61 6c 69 7a 65  *.. * Initialize
1200: 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63 6c   the "appfsd.tcl
1210: 22 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20 77  " environment, w
1220: 68 69 63 68 20 6d 75 73 74 20 62 65 20 64 6f 6e  hich must be don
1230: 65 20 61 66 74 65 72 0a 09 20 2a 20 67 6c 6f 62  e after.. * glob
1240: 61 6c 20 76 61 72 69 61 62 6c 65 73 20 61 72 65  al variables are
1250: 20 73 65 74 2e 0a 09 20 2a 2f 0a 09 74 63 6c 5f   set... */..tcl_
1260: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1270: 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a  nterp, "::appfs:
1280: 3a 69 6e 69 74 22 29 3b 0a 09 69 66 20 28 74 63  :init");..if (tc
1290: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
12a0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
12b0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
12c0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
12d0: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61  ppFS script (::a
12e0: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62  ppfs::init).  Ab
12f0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
1300: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1310: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1320: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
1330: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1340: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
1350: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
1360: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1370: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1380: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1390: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c  ;...}....Tcl_Del
13a0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
13b0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
13c0: 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  L);..}.../*.. * 
13d0: 48 69 64 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f  Hide some Tcl co
13e0: 6d 6d 61 6e 64 73 20 74 68 61 74 20 77 65 20 64  mmands that we d
13f0: 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f 20 75 73  o not care to us
1400: 65 20 61 6e 64 20 77 68 69 63 68 20 6d 61 79 0a  e and which may.
1410: 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75  . * slow down ru
1420: 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e  n-time operation
1430: 73 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 48 69 64  s... */..Tcl_Hid
1440: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
1450: 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65   "auto_load_inde
1460: 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69  x", "auto_load_i
1470: 6e 64 65 78 22 29 3b 0a 09 54 63 6c 5f 48 69 64  ndex");..Tcl_Hid
1480: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
1490: 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b   "unknown", "unk
14a0: 6e 6f 77 6e 22 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nown");.../*.. *
14b0: 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d 70   Return the comp
14c0: 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a  letely initializ
14d0: 65 64 20 69 6e 74 65 72 70 72 65 74 65 72 0a 09  ed interpreter..
14e0: 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e 74 65   */..return(inte
14f0: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65  rp);.}../*. * Re
1500: 74 75 72 6e 20 74 68 65 20 74 68 72 65 61 64 2d  turn the thread-
1510: 73 70 65 63 69 66 69 63 20 54 63 6c 20 69 6e 74  specific Tcl int
1520: 65 72 70 72 65 74 65 72 2c 20 63 72 65 61 74 69  erpreter, creati
1530: 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65 64 0a  ng it if needed.
1540: 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49   */.static Tcl_I
1550: 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54 63 6c  nterp *appfs_Tcl
1560: 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b 0a 09  Interp(void) {..
1570: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1580: 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  rp;..int pthread
1590: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
15a0: 20 70 74 68 72 65 61 64 5f 67 65 74 73 70 65 63   pthread_getspec
15b0: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 29 3b  ific(interpKey);
15c0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
15d0: 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72 70  NULL) {...interp
15e0: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
15f0: 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b  TclInterp(NULL);
1600: 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ....if (interp =
1610: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74  = NULL) {....ret
1620: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a  urn(NULL);...}..
1630: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
1640: 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69  pthread_setspeci
1650: 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69  fic(interpKey, i
1660: 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70 74  nterp);...if (pt
1670: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
1680: 7b 0a 09 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  {....Tcl_DeleteI
1690: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
16a0: 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
16b0: 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  ...}..}...return
16c0: 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a  (interp);.}../*.
16d0: 20 2a 20 45 76 61 6c 75 61 74 65 20 61 20 54 63   * Evaluate a Tc
16e0: 6c 20 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75  l script constru
16f0: 63 74 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e  cted by concaten
1700: 61 74 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66  ating a bunch of
1710: 20 43 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f   C strings. * to
1720: 67 65 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74  gether.. */.stat
1730: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c  ic int appfs_Tcl
1740: 5f 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70  _Eval(Tcl_Interp
1750: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
1760: 6a 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  jc, const char *
1770: 63 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c  cmd, ...) {..Tcl
1780: 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f  _Obj **objv;..co
1790: 6e 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09  nst char *arg;..
17a0: 76 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69  va_list argp;..i
17b0: 6e 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20  nt retval;..int 
17c0: 69 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20  i;...if (interp 
17d0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
17e0: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
17f0: 09 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69  .}...objv = (voi
1800: 64 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a  d *) ckalloc(siz
1810: 65 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a  eof(*objv) * obj
1820: 63 29 3b 0a 09 6f 62 6a 76 5b 30 5d 20 3d 20 54  c);..objv[0] = T
1830: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
1840: 63 6d 64 2c 20 2d 31 29 3b 0a 09 54 63 6c 5f 49  cmd, -1);..Tcl_I
1850: 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76  ncrRefCount(objv
1860: 5b 30 5d 29 3b 0a 0a 09 76 61 5f 73 74 61 72 74  [0]);...va_start
1870: 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 66 6f  (argp, cmd);..fo
1880: 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f 62  r (i = 1; i < ob
1890: 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 67  jc; i++) {...arg
18a0: 20 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c 20   = va_arg(argp, 
18b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a 09  const char *);..
18c0: 09 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e  .objv[i] = Tcl_N
18d0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 72 67 2c  ewStringObj(arg,
18e0: 20 2d 31 29 3b 0a 09 09 54 63 6c 5f 49 6e 63 72   -1);...Tcl_Incr
18f0: 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d  RefCount(objv[i]
1900: 29 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64 28 61 72  );..}..va_end(ar
1910: 67 70 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  gp);...retval = 
1920: 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74  Tcl_EvalObjv(int
1930: 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c  erp, objc, objv,
1940: 20 30 29 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20   0);...for (i = 
1950: 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  0; i < objc; i++
1960: 29 20 7b 0a 09 09 54 63 6c 5f 44 65 63 72 52 65  ) {...Tcl_DecrRe
1970: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b  fCount(objv[i]);
1980: 0a 09 7d 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f  ..}...ckfree((vo
1990: 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69  id *) objv);...i
19a0: 66 20 28 72 65 74 76 61 6c 20 21 3d 20 54 43 4c  f (retval != TCL
19b0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
19c0: 45 42 55 47 28 22 54 63 6c 20 63 6f 6d 6d 61 6e  EBUG("Tcl comman
19d0: 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65 72 72 6f  d failed, ::erro
19e0: 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e 73 3a 20  rInfo contains: 
19f0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61  %s\n", Tcl_GetVa
1a00: 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65 72 72  r(interp, "::err
1a10: 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b 0a 09 7d  orInfo", 0));..}
1a20: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
1a30: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65  );.}../*. * Dete
1a40: 72 6d 69 6e 65 20 74 68 65 20 55 49 44 20 66 6f  rmine the UID fo
1a50: 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e  r the user makin
1a60: 67 20 74 68 65 20 63 75 72 72 65 6e 74 20 46 55  g the current FU
1a70: 53 45 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65  SE filesystem re
1a80: 71 75 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77  quest.. * This w
1a90: 69 6c 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c  ill be used to l
1aa0: 6f 6f 6b 75 70 20 74 68 65 20 75 73 65 72 27 73  ookup the user's
1ab0: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20   home directory 
1ac0: 73 6f 20 77 65 20 63 61 6e 20 73 65 61 72 63 68  so we can search
1ad0: 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20   for. * locally 
1ae0: 6d 6f 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a  modified files..
1af0: 20 2a 2f 0a 73 74 61 74 69 63 20 75 69 64 5f 74   */.static uid_t
1b00: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
1b10: 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74  (void) {..struct
1b20: 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63   fuse_context *c
1b30: 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73  tx;...if (!appfs
1b40: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b  _fuse_started) {
1b50: 0a 09 09 72 65 74 75 72 6e 28 67 65 74 75 69 64  ...return(getuid
1b60: 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20  ());..}...ctx = 
1b70: 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74  fuse_get_context
1b80: 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20  ();..if (ctx == 
1b90: 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61  NULL) {.../* Una
1ba0: 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73  ble to lookup us
1bb0: 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73  er for some reas
1bc0: 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72  on */.../* Retur
1bd0: 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65  n an unprivilege
1be0: 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 72  d user ID */...r
1bf0: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72  eturn(1);..}...r
1c00: 65 74 75 72 6e 28 63 74 78 2d 3e 75 69 64 29 3b  eturn(ctx->uid);
1c10: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d  .}../*. * Determ
1c20: 69 6e 65 20 74 68 65 20 47 49 44 20 66 6f 72 20  ine the GID for 
1c30: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
1c40: 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53 45  the current FUSE
1c50: 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71 75   filesystem requ
1c60: 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c  est.. * This wil
1c70: 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  l be used to loo
1c80: 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20 68  kup the user's h
1c90: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73 6f  ome directory so
1ca0: 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20 66   we can search f
1cb0: 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f  or. * locally mo
1cc0: 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a  dified files.. *
1cd0: 2f 0a 73 74 61 74 69 63 20 67 69 64 5f 74 20 61  /.static gid_t a
1ce0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 76  ppfs_get_fsgid(v
1cf0: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66  oid) {..struct f
1d00: 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  use_context *ctx
1d10: 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66  ;...if (!appfs_f
1d20: 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09  use_started) {..
1d30: 09 72 65 74 75 72 6e 28 67 65 74 67 69 64 28 29  .return(getgid()
1d40: 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75  );..}...ctx = fu
1d50: 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29  se_get_context()
1d60: 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e 55  ;..if (ctx == NU
1d70: 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c  LL) {.../* Unabl
1d80: 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72  e to lookup user
1d90: 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e   for some reason
1da0: 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20   */.../* Return 
1db0: 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64 20  an unprivileged 
1dc0: 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 72 65 74  user ID */...ret
1dd0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74  urn(1);..}...ret
1de0: 75 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d  urn(ctx->gid);.}
1df0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
1e00: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
1e10: 72 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29  r_fs_enter(void)
1e20: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70   {..setfsuid(app
1e30: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
1e40: 0a 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73  ..setfsgid(appfs
1e50: 5f 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d  _get_fsgid());.}
1e60: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
1e70: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
1e80: 72 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29  r_fs_leave(void)
1e90: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b   {..setfsuid(0);
1ea0: 0a 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d  ..setfsgid(0);.}
1eb0: 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20  ../*. * Look up 
1ec0: 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  the home directo
1ed0: 72 79 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55  ry for a given U
1ee0: 49 44 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74  ID. *        Ret
1ef0: 75 72 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20  urns a C string 
1f00: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75  containing the u
1f10: 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63  ser's home direc
1f20: 74 6f 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a  tory or NULL if.
1f30: 20 2a 20 20 20 20 20 20 20 20 74 68 65 20 75 73   *        the us
1f40: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74  er's home direct
1f50: 6f 72 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69  ory does not exi
1f60: 73 74 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72  st or is not cor
1f70: 72 65 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20  rectly. *       
1f80: 20 63 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a   configured. */.
1f90: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70  static char *app
1fa0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75  fs_get_homedir(u
1fb0: 69 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73  id_t fsuid) {..s
1fc0: 74 72 75 63 74 20 70 61 73 73 77 64 20 65 6e 74  truct passwd ent
1fd0: 72 79 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74  ry, *result;..st
1fe0: 72 75 63 74 20 73 74 61 74 20 73 74 62 75 66 3b  ruct stat stbuf;
1ff0: 0a 09 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d  ..char buf[1024]
2000: 2c 20 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20  , *retval;..int 
2010: 67 70 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65  gpu_ret, stat_re
2020: 74 3b 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67  t;...gpu_ret = g
2030: 65 74 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c  etpwuid_r(fsuid,
2040: 20 26 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69   &entry, buf, si
2050: 7a 65 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75  zeof(buf), &resu
2060: 6c 74 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65  lt);..if (gpu_re
2070: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
2080: 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69  S_DEBUG("getpwui
2090: 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72  d_r(%llu, ...) r
20a0: 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75  eturned in failu
20b0: 72 65 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c  re", (unsigned l
20c0: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29  ong long) fsuid)
20d0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
20e0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75  );..}...if (resu
20f0: 6c 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  lt == NULL) {...
2100: 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74  APPFS_DEBUG("get
2110: 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e  pwuid_r(%llu, ..
2120: 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c  .) returned NULL
2130: 20 72 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67   result", (unsig
2140: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
2150: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
2160: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
2170: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20  (result->pw_dir 
2180: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
2190: 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75  FS_DEBUG("getpwu
21a0: 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20  id_r(%llu, ...) 
21b0: 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f  returned NULL ho
21c0: 6d 65 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28  me directory", (
21d0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
21e0: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
21f0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2200: 0a 09 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61  ..stat_ret = sta
2210: 74 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72  t(result->pw_dir
2220: 2c 20 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28  , &stbuf);..if (
2230: 73 74 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b  stat_ret != 0) {
2240: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2250: 73 74 61 74 28 25 73 29 20 72 65 74 75 72 6e 65  stat(%s) returne
2260: 64 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72  d in failure", r
2270: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a  esult->pw_dir);.
2280: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2290: 0a 09 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e  ..}...if (stbuf.
22a0: 73 74 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29  st_uid != fsuid)
22b0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
22c0: 28 22 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20  ("UID mis-match 
22d0: 6f 6e 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68  on user %llu's h
22e0: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 28 25  ome directory (%
22f0: 73 29 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20  s).  It's owned 
2300: 62 79 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20  by %llu.",...   
2310: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
2320: 6c 6f 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20  long) fsuid,... 
2330: 20 20 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69     result->pw_di
2340: 72 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e  r,...    (unsign
2350: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74  ed long long) st
2360: 62 75 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a  buf.st_uid...);.
2370: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2380: 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73  ..}...retval = s
2390: 74 72 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77  trdup(result->pw
23a0: 5f 64 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28  _dir);...return(
23b0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20  retval);.}../*. 
23c0: 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20  * Tcl interface 
23d0: 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20  to get the home 
23e0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68  directory for th
23f0: 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68  e user making th
2400: 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46  e "current". * F
2410: 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a  USE I/O request.
2420: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74   */.static int t
2430: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
2440: 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20  edir(ClientData 
2450: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
2460: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
2470: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
2480: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72   objv[]) {..char
2490: 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f   *homedir;..Tcl_
24a0: 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a  Obj *homedir_obj
24b0: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  ;..uid_t fsuid;.
24c0: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
24d0: 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68   Tcl_Obj *last_h
24e0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c  omedir_obj = NUL
24f0: 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  L;..static __thr
2500: 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66  ead uid_t last_f
2510: 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20  suid = -1;..    
2520: 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20      if (objc != 
2530: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1) {.           
2540: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
2550: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
2560: 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20   objv, NULL);.  
2570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
2580: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
2590: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75  .        }...fsu
25a0: 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66  id = appfs_get_f
25b0: 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73  suid();...if (fs
25c0: 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69  uid == last_fsui
25d0: 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69  d && last_homedi
25e0: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b  r_obj != NULL) {
25f0: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d  ...homedir_obj =
2600: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
2610: 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 69  j;..} else {...i
2620: 66 20 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  f (last_homedir_
2630: 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  obj != NULL) {..
2640: 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75  ..Tcl_DecrRefCou
2650: 6e 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  nt(last_homedir_
2660: 6f 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d  obj);...}....hom
2670: 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74  edir = appfs_get
2680: 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67  _homedir(appfs_g
2690: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09  et_fsuid());....
26a0: 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e  if (homedir == N
26b0: 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  ULL) {....return
26c0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d  (TCL_ERROR);...}
26d0: 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ....homedir_obj 
26e0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
26f0: 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b  bj(homedir, -1);
2700: 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72  ....free(homedir
2710: 29 3b 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  );....last_homed
2720: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
2730: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
2740: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
2750: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
2760: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
2770: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
2780: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
2790: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
27a0: 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72  obj);..        r
27b0: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
27c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
27d0: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
27e0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c  user_fs_enter(Cl
27f0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
2800: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
2810: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
2820: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
2830: 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  ) {..appfs_simul
2840: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
2850: 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  r();...return(TC
2860: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  L_OK);.}..static
2870: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73   int tcl_appfs_s
2880: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
2890: 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61  leave(ClientData
28a0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
28b0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
28c0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
28d0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70  T objv[]) {..app
28e0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
28f0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72  _fs_leave();...r
2900: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
2910: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
2920: 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  _appfs_get_fsuid
2930: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
2940: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
2950: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
2960: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
2970: 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73  v[]) {..uid_t fs
2980: 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61  uid;...fsuid = a
2990: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
29a0: 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53  ;..       .Tcl_S
29b0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
29c0: 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49  rp, Tcl_NewWideI
29d0: 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a  ntObj(fsuid));..
29e0: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
29f0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
2a00: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67  cl_appfs_get_fsg
2a10: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
2a20: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
2a30: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
2a40: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
2a50: 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20  bjv[]) {..gid_t 
2a60: 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d  fsgid;...fsgid =
2a70: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64   appfs_get_fsgid
2a80: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
2a90: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
2aa0: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
2ab0: 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b  eIntObj(fsgid));
2ac0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
2ad0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65  );.}../*. * Gene
2ae0: 72 61 74 65 20 61 6e 20 69 6e 6f 64 65 20 66 6f  rate an inode fo
2af0: 72 20 61 20 67 69 76 65 6e 20 70 61 74 68 2e 20  r a given path. 
2b00: 20 54 68 65 20 69 6e 6f 64 65 20 73 68 6f 75 6c   The inode shoul
2b10: 64 20 62 65 20 63 6f 6d 70 75 74 65 64 20 69 6e  d be computed in
2b20: 20 73 75 63 68 0a 20 2a 20 61 20 77 61 79 20 74   such. * a way t
2b30: 68 61 74 20 69 74 20 69 73 20 75 6e 6c 69 6b 65  hat it is unlike
2b40: 6c 79 20 74 6f 20 62 65 20 64 75 70 6c 69 63 61  ly to be duplica
2b50: 74 65 64 20 61 6e 64 20 72 65 6d 61 69 6e 73 20  ted and remains 
2b60: 74 68 65 20 73 61 6d 65 20 66 6f 72 20 61 20 67  the same for a g
2b70: 69 76 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a 2f  iven. * file. */
2b80: 0a 73 74 61 74 69 63 20 6c 6f 6e 67 20 6c 6f 6e  .static long lon
2b90: 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  g appfs_get_path
2ba0: 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68 61  _inode(const cha
2bb0: 72 20 2a 70 61 74 68 29 20 7b 0a 09 6c 6f 6e 67  r *path) {..long
2bc0: 20 6c 6f 6e 67 20 72 65 74 76 61 6c 3b 0a 09 63   long retval;..c
2bd0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a 09  onst char *p;...
2be0: 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09 66  retval = 10;...f
2bf0: 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a 70  or (p = path; *p
2c00: 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76 61  ; p++) {...retva
2c10: 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30 55  l %= 4290960290U
2c20: 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20  LL;...retval += 
2c30: 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c 3d  *p;...retval <<=
2c40: 20 37 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20   7;..}...retval 
2c50: 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20 25  += 10;..retval %
2c60: 3d 20 34 32 39 34 39 36 37 32 39 36 55 4c 4c 3b  = 4294967296ULL;
2c70: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
2c80: 29 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e 66  );.}../* Get inf
2c90: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61  ormation about a
2ca0: 20 70 61 74 68 2c 20 61 6e 64 20 6f 70 74 69 6f   path, and optio
2cb0: 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68 69 6c 64  nally list child
2cc0: 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ren */.static in
2cd0: 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  t appfs_get_path
2ce0: 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63 68 61 72  _info(const char
2cf0: 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 61   *path, struct a
2d00: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70  ppfs_pathinfo *p
2d10: 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f  athinfo) {..Tcl_
2d20: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
2d30: 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 73 5f  .Tcl_Obj *attrs_
2d40: 64 69 63 74 2c 20 2a 61 74 74 72 5f 76 61 6c 75  dict, *attr_valu
2d50: 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  e;..const char *
2d60: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 3b 0a  attr_value_str;.
2d70: 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74 74  .Tcl_WideInt att
2d80: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69  r_value_wide;..i
2d90: 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e  nt attr_value_in
2da0: 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  t;..static __thr
2db0: 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74  ead Tcl_Obj *att
2dc0: 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c  r_key_type = NUL
2dd0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72  L, *attr_key_per
2de0: 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72  ms = NULL, *attr
2df0: 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c  _key_size = NULL
2e00: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65  , *attr_key_time
2e10: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
2e20: 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c  ey_source = NULL
2e30: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c  , *attr_key_chil
2e40: 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a  dcount = NULL, *
2e50: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
2e60: 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 74  d = NULL;..int t
2e70: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
2e80: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
2e90: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
2ea0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
2eb0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
2ec0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
2ed0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
2ee0: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
2ef0: 67 65 74 61 74 74 72 22 2c 20 70 61 74 68 29 3b  getattr", path);
2f00: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
2f10: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
2f20: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
2f30: 73 3a 3a 67 65 74 61 74 74 72 28 25 73 29 20 66  s::getattr(%s) f
2f40: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
2f50: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
2f60: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
2f70: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
2f80: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
2f90: 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e  ...return(-ENOEN
2fa0: 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74  T);..}...if (att
2fb0: 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55  r_key_type == NU
2fc0: 4c 4c 29 20 7b 0a 09 09 61 74 74 72 5f 6b 65 79  LL) {...attr_key
2fd0: 5f 74 79 70 65 20 20 20 20 20 20 20 3d 20 54 63  _type       = Tc
2fe0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
2ff0: 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  type", -1);...at
3000: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20 20  tr_key_perms    
3010: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
3020: 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31  gObj("perms", -1
3030: 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 73 69  );...attr_key_si
3040: 7a 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  ze       = Tcl_N
3050: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a  ewStringObj("siz
3060: 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f  e", -1);...attr_
3070: 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 20 20 3d  key_time       =
3080: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3090: 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 3b 0a 09  j("time", -1);..
30a0: 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65  .attr_key_source
30b0: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
30c0: 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72 63 65 22  ringObj("source"
30d0: 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65  , -1);...attr_ke
30e0: 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 54  y_childcount = T
30f0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
3100: 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c 20 2d 31  "childcount", -1
3110: 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 70 61  );...attr_key_pa
3120: 63 6b 61 67 65 64 20 20 20 3d 20 54 63 6c 5f 4e  ckaged   = Tcl_N
3130: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 70 61 63  ewStringObj("pac
3140: 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a 09 7d 0a  kaged", -1);..}.
3150: 0a 09 61 74 74 72 73 5f 64 69 63 74 20 3d 20 54  ..attrs_dict = T
3160: 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_GetObjResult(
3170: 69 6e 74 65 72 70 29 3b 0a 09 74 63 6c 5f 72 65  interp);..tcl_re
3180: 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47  t = Tcl_DictObjG
3190: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
31a0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
31b0: 74 79 70 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  type, &attr_valu
31c0: 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  e);..if (tcl_ret
31d0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
31e0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69  APPFS_DEBUG("[di
31f0: 63 74 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d  ct get \"type\"]
3200: 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 41 50 50   failed");...APP
3210: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
3220: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
3230: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
3240: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65  (interp));....re
3250: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
3260: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
3270: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
3280: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
3290: 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67  pathinfo->packag
32a0: 65 64 20 3d 20 30 3b 0a 09 70 61 74 68 69 6e 66  ed = 0;..pathinf
32b0: 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73  o->inode = appfs
32c0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
32d0: 70 61 74 68 29 3b 0a 0a 09 61 74 74 72 5f 76 61  path);...attr_va
32e0: 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65  lue_str = Tcl_Ge
32f0: 74 53 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c  tString(attr_val
3300: 75 65 29 3b 0a 09 73 77 69 74 63 68 20 28 61 74  ue);..switch (at
3310: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29  tr_value_str[0])
3320: 20 7b 0a 09 09 63 61 73 65 20 27 64 27 3a 20 2f   {...case 'd': /
3330: 2a 20 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09  * directory */..
3340: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
3350: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
3360: 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09  E_DIRECTORY;....
3370: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
3380: 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e  fo.dir.childcoun
3390: 74 20 3d 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44  t = 0;.....Tcl_D
33a0: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
33b0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
33c0: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
33d0: 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  t, &attr_value);
33e0: 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
33f0: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
3400: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
3410: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
3420: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
3430: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
3440: 77 69 64 65 29 3b 0a 09 09 09 09 69 66 20 28 74  wide);.....if (t
3450: 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b  cl_ret == TCL_OK
3460: 29 20 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66  ) {......pathinf
3470: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e  o->typeinfo.dir.
3480: 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74  childcount = att
3490: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09  r_value_wide;...
34a0: 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 62 72 65  ..}....}.....bre
34b0: 61 6b 3b 0a 09 09 63 61 73 65 20 27 66 27 3a 20  ak;...case 'f': 
34c0: 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09 09 70 61  /* file */....pa
34d0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
34e0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
34f0: 4c 45 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d  LE;....pathinfo-
3500: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  >typeinfo.file.s
3510: 69 7a 65 20 3d 20 30 3b 0a 09 09 09 70 61 74 68  ize = 0;....path
3520: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
3530: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d  ile.executable =
3540: 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74   0;.....Tcl_Dict
3550: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
3560: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
3570: 6b 65 79 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f  key_size, &attr_
3580: 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 20 28 61  value);....if (a
3590: 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c  ttr_value != NUL
35a0: 4c 29 20 7b 0a 09 09 09 09 74 63 6c 5f 72 65 74  L) {.....tcl_ret
35b0: 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e   = Tcl_GetWideIn
35c0: 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61  tFromObj(NULL, a
35d0: 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72  ttr_value, &attr
35e0: 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09  _value_wide);...
35f0: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d  ..if (tcl_ret ==
3600: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09   TCL_OK) {......
3610: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
3620: 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 61  fo.file.size = a
3630: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a  ttr_value_wide;.
3640: 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 54  ....}....}.....T
3650: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
3660: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
3670: 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73  , attr_key_perms
3680: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
3690: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
36a0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
36b0: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
36c0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
36d0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
36e0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 5f  .if (attr_value_
36f0: 73 74 72 5b 30 5d 20 3d 3d 20 27 78 27 29 20 7b  str[0] == 'x') {
3700: 0a 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ......pathinfo->
3710: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78  typeinfo.file.ex
3720: 65 63 75 74 61 62 6c 65 20 3d 20 31 3b 0a 09 09  ecutable = 1;...
3730: 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 72 65 61  ..}....}....brea
3740: 6b 3b 0a 09 09 63 61 73 65 20 27 73 27 3a 20 2f  k;...case 's': /
3750: 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09  * symlink */....
3760: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
3770: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
3780: 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09 70 61 74 68  SYMLINK;....path
3790: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
37a0: 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b  ymlink.size = 0;
37b0: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
37c0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
37d0: 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b  ource[0] = '\0';
37e0: 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a  .....Tcl_DictObj
37f0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
3800: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
3810: 5f 73 6f 75 72 63 65 2c 20 26 61 74 74 72 5f 76  _source, &attr_v
3820: 61 6c 75 65 29 3b 0a 09 09 09 69 66 20 28 61 74  alue);....if (at
3830: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
3840: 29 20 7b 0a 09 09 09 09 61 74 74 72 5f 76 61 6c  ) {.....attr_val
3850: 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74  ue_str = Tcl_Get
3860: 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74  StringFromObj(at
3870: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
3880: 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09  value_int); ....
3890: 09 09 69 66 20 28 28 61 74 74 72 5f 76 61 6c 75  ..if ((attr_valu
38a0: 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69  e_int + 1) <= si
38b0: 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74  zeof(pathinfo->t
38c0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
38d0: 73 6f 75 72 63 65 29 29 20 7b 0a 09 09 09 09 09  source)) {......
38e0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
38f0: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20  fo.symlink.size 
3900: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  = attr_value_int
3910: 3b 0a 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  ;......pathinfo-
3920: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  >typeinfo.symlin
3930: 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61  k.source[attr_va
3940: 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b  lue_int] = '\0';
3950: 0a 0a 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61  .......memcpy(pa
3960: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
3970: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
3980: 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c   attr_value_str,
3990: 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29   attr_value_int)
39a0: 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09  ;.....}....}....
39b0: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 46  break;...case 'F
39c0: 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66 6f 20  ': /* pipe/fifo 
39d0: 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  */....pathinfo->
39e0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
39f0: 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09 09 09 62  HTYPE_FIFO;....b
3a00: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 53 27  reak;...case 'S'
3a10: 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e  : /* UNIX domain
3a20: 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 70 61   socket */....pa
3a30: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
3a40: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f  PPFS_PATHTYPE_SO
3a50: 43 4b 45 54 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  CKET;....break;.
3a60: 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 72 65  ..default:....re
3a70: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
3a80: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
3a90: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
3aa0: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 61 63  ct, attr_key_pac
3ab0: 6b 61 67 65 64 2c 20 26 61 74 74 72 5f 76 61 6c  kaged, &attr_val
3ac0: 75 65 29 3b 0a 09 69 66 20 28 61 74 74 72 5f 76  ue);..if (attr_v
3ad0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
3ae0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b  ..pathinfo->pack
3af0: 61 67 65 64 20 3d 20 31 3b 0a 09 7d 0a 0a 09 54  aged = 1;..}...T
3b00: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
3b10: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
3b20: 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 2c  , attr_key_time,
3b30: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
3b40: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
3b50: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 74 63 6c 5f  = NULL) {...tcl_
3b60: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64  ret = Tcl_GetWid
3b70: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c  eIntFromObj(NULL
3b80: 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61  , attr_value, &a
3b90: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b  ttr_value_wide);
3ba0: 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d  ...if (tcl_ret =
3bb0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 70  = TCL_OK) {....p
3bc0: 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20  athinfo->time = 
3bd0: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
3be0: 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  ...}..} else {..
3bf0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20  .pathinfo->time 
3c00: 3d 20 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  = 0;..}...return
3c10: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  (0);.}..static c
3c20: 68 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70 61  har *appfs_prepa
3c30: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e  re_to_create(con
3c40: 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b  st char *path) {
3c50: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
3c60: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
3c70: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
3c80: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
3c90: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
3ca0: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
3cb0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
3cc0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3cd0: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
3ce0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
3cf0: 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70  nterp, 2, "::app
3d00: 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63  fs::prepare_to_c
3d10: 72 65 61 74 65 22 2c 20 70 61 74 68 29 3b 0a 09  reate", path);..
3d20: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
3d30: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
3d40: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
3d50: 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  :prepare_to_crea
3d60: 74 65 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  te(%s) failed.",
3d70: 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f   path);...APPFS_
3d80: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
3d90: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
3da0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
3db0: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72  terp));....retur
3dc0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
3dd0: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
3de0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
3df0: 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 6c  terp);..if (real
3e00: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
3e10: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3e20: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 72  ..}...return(str
3e30: 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29 3b  dup(real_path));
3e40: 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20  .}..static char 
3e50: 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68  *appfs_localpath
3e60: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
3e70: 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  h) {..Tcl_Interp
3e80: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
3e90: 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68   char *real_path
3ea0: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
3eb0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
3ec0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
3ed0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
3ee0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
3ef0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  LL);..}...tcl_re
3f00: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
3f10: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
3f20: 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74  :appfs::localpat
3f30: 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  h", path);..if (
3f40: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
3f50: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
3f60: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63  UG("::appfs::loc
3f70: 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c 65  alpath(%s) faile
3f80: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
3f90: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
3fa0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
3fb0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
3fc0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72  t(interp));....r
3fd0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
3fe0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
3ff0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
4000: 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28  t(interp);..if (
4010: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
4020: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
4030: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  LL);..}...return
4040: 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74  (strdup(real_pat
4050: 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  h));.}..static i
4060: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
4070: 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61  adlink(const cha
4080: 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62  r *path, char *b
4090: 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 29  uf, size_t size)
40a0: 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73   {..struct appfs
40b0: 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e  _pathinfo pathin
40c0: 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 20  fo;..int retval 
40d0: 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  = 0;...APPFS_DEB
40e0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
40f0: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
4100: 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74  h);...pathinfo.t
4110: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
4120: 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09  TYPE_INVALID;...
4130: 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67  retval = appfs_g
4140: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74  et_path_info(pat
4150: 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09  h, &pathinfo);..
4160: 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29  if (retval != 0)
4170: 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 74 76   {...return(retv
4180: 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61  al);..}...if (pa
4190: 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41  thinfo.type != A
41a0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
41b0: 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72  MLINK) {...retur
41c0: 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a  n(-EINVAL);..}..
41d0: 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70 61 74  .if ((strlen(pat
41e0: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73  hinfo.typeinfo.s
41f0: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b  ymlink.source) +
4200: 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09   1) > size) {...
4210: 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f  return(-ENAMETOO
4220: 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63  LONG);..}...memc
4230: 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e 66 6f  py(buf, pathinfo
4240: 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  .typeinfo.symlin
4250: 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e  k.source, strlen
4260: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e  (pathinfo.typein
4270: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
4280: 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72  e) + 1);...retur
4290: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
42a0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 67  int appfs_fuse_g
42b0: 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63 68 61  etattr(const cha
42c0: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
42d0: 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b 0a 09  stat *stbuf) {..
42e0: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
42f0: 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a  hinfo pathinfo;.
4300: 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72  .int retval;...r
4310: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50  etval = 0;...APP
4320: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
4330: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
4340: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74 68  ", path);...path
4350: 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46  info.type = APPF
4360: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
4370: 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61  ID;...retval = a
4380: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4390: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e  fo(path, &pathin
43a0: 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c  fo);..if (retval
43b0: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
43c0: 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09  n(retval);..}...
43d0: 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20 30 2c  memset(stbuf, 0,
43e0: 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73   sizeof(struct s
43f0: 74 61 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e  tat));...stbuf->
4400: 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68 69  st_mtime = pathi
4410: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
4420: 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 70 61 74  ->st_ctime = pat
4430: 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62  hinfo.time;..stb
4440: 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70  uf->st_atime = p
4450: 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73  athinfo.time;..s
4460: 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d  tbuf->st_ino   =
4470: 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b   pathinfo.inode;
4480: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
4490: 20 20 3d 20 30 3b 0a 0a 09 73 77 69 74 63 68 20    = 0;...switch 
44a0: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 20  (pathinfo.type) 
44b0: 7b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  {...case APPFS_P
44c0: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
44d0: 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  Y:....stbuf->st_
44e0: 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49 52 20 7c  mode = S_IFDIR |
44f0: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
4500: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20  >st_nlink = 2 + 
4510: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
4520: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74  o.dir.childcount
4530: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
4540: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
4550: 45 5f 46 49 4c 45 3a 0a 09 09 09 69 66 20 28 70  E_FILE:....if (p
4560: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
4570: 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65  .file.executable
4580: 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73  ) {.....stbuf->s
4590: 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47  t_mode = S_IFREG
45a0: 20 7c 20 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c   | 0555;....} el
45b0: 73 65 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e  se {.....stbuf->
45c0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45  st_mode = S_IFRE
45d0: 47 20 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a  G | 0444;....}..
45e0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
45f0: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
4600: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68  ->st_size = path
4610: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69  info.typeinfo.fi
4620: 6c 65 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61  le.size;....brea
4630: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
4640: 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b  PATHTYPE_SYMLINK
4650: 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  :....stbuf->st_m
4660: 6f 64 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20  ode = S_IFLNK | 
4670: 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e  0555;....stbuf->
4680: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
4690: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
46a0: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  = pathinfo.typei
46b0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65  nfo.symlink.size
46c0: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
46d0: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
46e0: 45 5f 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62  E_SOCKET:....stb
46f0: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
4700: 49 46 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09  IFSOCK | 0555;..
4710: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
4720: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
4730: 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09  >st_size = 0;...
4740: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
4750: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
4760: 46 4f 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  FO:....stbuf->st
4770: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f 20  _mode = S_IFIFO 
4780: 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66  | 0555;....stbuf
4790: 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a  ->st_nlink = 1;.
47a0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a  ...stbuf->st_siz
47b0: 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b  e = 0;....break;
47c0: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
47d0: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a  THTYPE_INVALID:.
47e0: 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e 4f  ...retval = -ENO
47f0: 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ENT;.....break;.
4800: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
4810: 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09  o.packaged) {...
4820: 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20  stbuf->st_uid   
4830: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
4840: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
4850: 5f 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67  _gid   = appfs_g
4860: 65 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74  et_fsgid();...st
4870: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20  buf->st_mode |= 
4880: 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  0200;..}...retur
4890: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
48a0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
48b0: 75 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73  use_readdir(cons
48c0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f  t char *path, vo
48d0: 69 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69  id *buf, fuse_fi
48e0: 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c  ll_dir_t filler,
48f0: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
4900: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
4910: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
4920: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
4930: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c  ..Tcl_Obj **chil
4940: 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64  dren;..int child
4950: 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a  ren_count, idx;.
4960: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
4970: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
4980: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
4990: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
49a0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
49b0: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
49c0: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
49d0: 7b 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  {...return(0);..
49e0: 7d 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20  }...filler(buf, 
49f0: 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09  ".", NULL, 0);..
4a00: 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22  filler(buf, ".."
4a10: 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63  , NULL, 0);...tc
4a20: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
4a30: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
4a40: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63  , "::appfs::getc
4a50: 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b  hildren", path);
4a60: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
4a70: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
4a80: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
4a90: 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25  s::getchildren(%
4aa0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
4ab0: 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  h);...APPFS_DEBU
4ac0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
4ad0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
4ae0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
4af0: 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  ));....return(0)
4b00: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
4b10: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45   Tcl_ListObjGetE
4b20: 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20  lements(interp, 
4b30: 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_GetObjResult
4b40: 28 69 6e 74 65 72 70 29 2c 20 26 63 68 69 6c 64  (interp), &child
4b50: 72 65 6e 5f 63 6f 75 6e 74 2c 20 26 63 68 69 6c  ren_count, &chil
4b60: 64 72 65 6e 29 3b 0a 09 69 66 20 28 74 63 6c 5f  dren);..if (tcl_
4b70: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
4b80: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4b90: 50 61 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20  Parsing list of 
4ba0: 63 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68  children on path
4bb0: 20 25 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61   %s failed.", pa
4bc0: 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42  th);...APPFS_DEB
4bd0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
4be0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
4bf0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
4c00: 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30  p));....return(0
4c10: 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78  );..}...for (idx
4c20: 20 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c   = 0; idx < chil
4c30: 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b  dren_count; idx+
4c40: 2b 29 20 7b 0a 09 09 66 69 6c 6c 65 72 28 62 75  +) {...filler(bu
4c50: 66 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  f, Tcl_GetString
4c60: 28 63 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c  (children[idx]),
4c70: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a 09   NULL, 0);..}...
4c80: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
4c90: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
4ca0: 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63  use_open(const c
4cb0: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
4cc0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
4cd0: 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74   *fi) {..Tcl_Int
4ce0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73 74  erp *interp;..st
4cf0: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
4d00: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 63  nfo pathinfo;..c
4d10: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
4d20: 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69 6e  path, *mode;..in
4d30: 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f 72  t gpi_ret, tcl_r
4d40: 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09 41  et;..int fh;...A
4d50: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
4d60: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
4d70: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67 70  .)", path);...gp
4d80: 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65  i_ret = appfs_ge
4d90: 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68  t_path_info(path
4da0: 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  , &pathinfo);...
4db0: 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26  if ((fi->flags &
4dc0: 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45   (O_WRONLY|O_CRE
4dd0: 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54  AT)) == (O_CREAT
4de0: 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09  |O_WRONLY)) {...
4df0: 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c 6c  /* The file will
4e00: 20 62 65 20 63 72 65 61 74 65 64 20 69 66 20 69   be created if i
4e10: 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  t does not exist
4e20: 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65   */...if (gpi_re
4e30: 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72 65  t != 0 && gpi_re
4e40: 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a  t != -ENOENT) {.
4e50: 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65  ...return(gpi_re
4e60: 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20  t);...}....mode 
4e70: 3d 20 22 63 72 65 61 74 65 22 3b 0a 09 7d 20 65  = "create";..} e
4e80: 6c 73 65 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66  lse {.../* The f
4e90: 69 6c 65 20 6d 75 73 74 20 61 6c 72 65 61 64 79  ile must already
4ea0: 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28   exist */...if (
4eb0: 67 70 69 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  gpi_ret != 0) {.
4ec0: 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65  ...return(gpi_re
4ed0: 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20  t);...}....mode 
4ee0: 3d 20 22 22 3b 0a 0a 09 09 69 66 20 28 28 66 69  = "";....if ((fi
4ef0: 2d 3e 66 6c 61 67 73 20 26 20 4f 5f 57 52 4f 4e  ->flags & O_WRON
4f00: 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f 4e 4c 59 29  LY) == O_WRONLY)
4f10: 20 7b 0a 09 09 09 6d 6f 64 65 20 3d 20 22 77 72   {....mode = "wr
4f20: 69 74 65 22 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69  ite";...}..}...i
4f30: 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  f (pathinfo.type
4f40: 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59   == APPFS_PATHTY
4f50: 50 45 5f 44 49 52 45 43 54 4f 52 59 29 20 7b 0a  PE_DIRECTORY) {.
4f60: 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44 49 52  ..return(-EISDIR
4f70: 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d  );..}...interp =
4f80: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
4f90: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
4fa0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
4fb0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
4fc0: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
4fd0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
4fe0: 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70   3, "::appfs::op
4ff0: 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d  enpath", path, m
5000: 6f 64 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  ode);..if (tcl_r
5010: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
5020: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
5030: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
5040: 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e  (%s, %s) failed.
5050: 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a  ", path, mode);.
5060: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
5070: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
5080: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
5090: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
50a0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
50b0: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
50c0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
50d0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
50e0: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
50f0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
5100: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41 50  n(-EIO);..}...AP
5110: 50 46 53 5f 44 45 42 55 47 28 22 54 72 61 6e 73  PFS_DEBUG("Trans
5120: 6c 61 74 65 64 20 72 65 71 75 65 73 74 20 74 6f  lated request to
5130: 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70 65 6e   open %s to open
5140: 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d 20 5c  ing %s (mode = \
5150: 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c 20 72  "%s\")", path, r
5160: 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b  eal_path, mode);
5170: 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72 65 61  ...fh = open(rea
5180: 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c 61 67  l_path, fi->flag
5190: 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66 20 28  s, 0600);...if (
51a0: 66 68 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75  fh < 0) {...retu
51b0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 66  rn(-EIO);..}...f
51c0: 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 72 65  i->fh = fh;...re
51d0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
51e0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
51f0: 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 20 63 68  e_close(const ch
5200: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
5210: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
5220: 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63 6c 6f 73  *fi) {..int clos
5230: 65 5f 72 65 74 3b 0a 0a 09 63 6c 6f 73 65 5f 72  e_ret;...close_r
5240: 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66  et = close(fi->f
5250: 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72  h);..if (close_r
5260: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
5270: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
5280: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
5290: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
52a0: 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63  use_read(const c
52b0: 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20  har *path, char 
52c0: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
52d0: 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c  e, off_t offset,
52e0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
52f0: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 6f  e_info *fi) {..o
5300: 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b 0a  ff_t lseek_ret;.
5310: 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 65  .ssize_t read_re
5320: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
5330: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
5340: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
5350: 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d 20  ;...lseek_ret = 
5360: 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f 66  lseek(fi->fh, of
5370: 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b  fset, SEEK_SET);
5380: 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 20  ..if (lseek_ret 
5390: 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 72  != offset) {...r
53a0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
53b0: 0a 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65 61  ..read_ret = rea
53c0: 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73  d(fi->fh, buf, s
53d0: 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72  ize);...return(r
53e0: 65 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61  ead_ret);.}..sta
53f0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
5400: 73 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63  se_write(const c
5410: 68 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74  har *path, const
5420: 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65   char *buf, size
5430: 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f  _t size, off_t o
5440: 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75  ffset, struct fu
5450: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
5460: 29 20 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b  ) {..off_t lseek
5470: 5f 72 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 77  _ret;..ssize_t w
5480: 72 69 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46  rite_ret;...APPF
5490: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
54a0: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
54b0: 2c 20 70 61 74 68 29 3b 0a 0a 09 6c 73 65 65 6b  , path);...lseek
54c0: 5f 72 65 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d  _ret = lseek(fi-
54d0: 3e 66 68 2c 20 6f 66 66 73 65 74 2c 20 53 45 45  >fh, offset, SEE
54e0: 4b 5f 53 45 54 29 3b 0a 09 69 66 20 28 6c 73 65  K_SET);..if (lse
54f0: 65 6b 5f 72 65 74 20 21 3d 20 6f 66 66 73 65 74  ek_ret != offset
5500: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
5510: 4f 29 3b 0a 09 7d 0a 0a 09 77 72 69 74 65 5f 72  O);..}...write_r
5520: 65 74 20 3d 20 77 72 69 74 65 28 66 69 2d 3e 66  et = write(fi->f
5530: 68 2c 20 62 75 66 2c 20 73 69 7a 65 29 3b 0a 0a  h, buf, size);..
5540: 09 72 65 74 75 72 6e 28 77 72 69 74 65 5f 72 65  .return(write_re
5550: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
5560: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e  t appfs_fuse_mkn
5570: 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  od(const char *p
5580: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
5590: 2c 20 64 65 76 5f 74 20 64 65 76 69 63 65 29 20  , dev_t device) 
55a0: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
55b0: 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72  th;..int mknod_r
55c0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
55d0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
55e0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
55f0: 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  );...if ((mode &
5600: 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49   S_IFCHR) == S_I
5610: 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e  FCHR) {...return
5620: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69  (-EPERM);..}...i
5630: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42  f ((mode & S_IFB
5640: 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20  LK) == S_IFBLK) 
5650: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
5660: 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  M);..}...real_pa
5670: 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61  th = appfs_prepa
5680: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74  re_to_create(pat
5690: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
56a0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
56b0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
56c0: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
56d0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
56e0: 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d  );...mknod_ret =
56f0: 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f 70 61 74 68   mknod(real_path
5700: 2c 20 6d 6f 64 65 2c 20 64 65 76 69 63 65 29 3b  , mode, device);
5710: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
5720: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
5730: 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70  );...free(real_p
5740: 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f  ath);...if (mkno
5750: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
5760: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
5770: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
5780: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
5790: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72 65  t appfs_fuse_cre
57a0: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ate(const char *
57b0: 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64  path, mode_t mod
57c0: 65 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  e, struct fuse_f
57d0: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
57e0: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
57f0: 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50  ;..int fd;...APP
5800: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
5810: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
5820: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  ", path);...if (
5830: 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29  (mode & S_IFCHR)
5840: 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09   == S_IFCHR) {..
5850: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
5860: 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20  ..}...if ((mode 
5870: 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f  & S_IFBLK) == S_
5880: 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72  IFBLK) {...retur
5890: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09  n(-EPERM);..}...
58a0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
58b0: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
58c0: 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ate(path);..if (
58d0: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
58e0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
58f0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
5900: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
5910: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 66 64 20 3d  _enter();...fd =
5920: 20 63 72 65 61 74 28 72 65 61 6c 5f 70 61 74 68   creat(real_path
5930: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73  , mode);...appfs
5940: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
5950: 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65  s_leave();...fre
5960: 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09  e(real_path);...
5970: 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09  if (fd < 0) {...
5980: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
5990: 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20  1);..}...fi->fh 
59a0: 3d 20 66 64 3b 0a 0a 09 72 65 74 75 72 6e 28 30  = fd;...return(0
59b0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
59c0: 20 61 70 70 66 73 5f 66 75 73 65 5f 74 72 75 6e   appfs_fuse_trun
59d0: 63 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20  cate(const char 
59e0: 2a 70 61 74 68 2c 20 6f 66 66 5f 74 20 73 69 7a  *path, off_t siz
59f0: 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  e) {..char *real
5a00: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 72 75 6e  _path;..int trun
5a10: 63 61 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46  cate_ret;...APPF
5a20: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
5a30: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
5a40: 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f  , path);...real_
5a50: 70 61 74 68 20 3d 20 61 70 70 66 73 5f 6c 6f 63  path = appfs_loc
5a60: 61 6c 70 61 74 68 28 70 61 74 68 29 3b 0a 09 69  alpath(path);..i
5a70: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
5a80: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
5a90: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
5aa0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
5ab0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74  _fs_enter();...t
5ac0: 72 75 6e 63 61 74 65 5f 72 65 74 20 3d 20 74 72  runcate_ret = tr
5ad0: 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 61 74 68  uncate(real_path
5ae0: 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73  , size);...appfs
5af0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
5b00: 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65  s_leave();...fre
5b10: 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09  e(real_path);...
5b20: 69 66 20 28 74 72 75 6e 63 61 74 65 5f 72 65 74  if (truncate_ret
5b30: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
5b40: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
5b50: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
5b60: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
5b70: 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72  fs_fuse_unlink_r
5b80: 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  mdir(const char 
5b90: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
5ba0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69  terp *interp;..i
5bb0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50  nt tcl_ret;...AP
5bc0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
5bd0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
5be0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e 74  )", path);...int
5bf0: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
5c00: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
5c10: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
5c20: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
5c30: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  .}...tcl_ret = a
5c40: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
5c50: 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66  terp, 2, "::appf
5c60: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20  s::unlinkpath", 
5c70: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
5c80: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
5c90: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5ca0: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
5cb0: 61 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ath(%s) failed."
5cc0: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
5cd0: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
5ce0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
5cf0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
5d00: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75  nterp));....retu
5d10: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72  rn(-EIO);..}...r
5d20: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
5d30: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
5d40: 73 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63  se_mkdir(const c
5d50: 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f  har *path, mode_
5d60: 74 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72 20  t mode) {..char 
5d70: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
5d80: 20 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50   mkdir_ret;...AP
5d90: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
5da0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
5db0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 0a 09 72 65  )", path);....re
5dc0: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
5dd0: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
5de0: 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  e(path);..if (re
5df0: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
5e00: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
5e10: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
5e20: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
5e30: 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f  nter();...mkdir_
5e40: 72 65 74 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c  ret = mkdir(real
5e50: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
5e60: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
5e70: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
5e80: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
5e90: 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72  );...if (mkdir_r
5ea0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20  et != 0) {...if 
5eb0: 28 65 72 72 6e 6f 20 21 3d 20 45 45 58 49 53 54  (errno != EEXIST
5ec0: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 65 72  ) {....return(er
5ed0: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09  rno * -1);...}..
5ee0: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
5ef0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
5f00: 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f  fs_fuse_chmod(co
5f10: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
5f20: 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09  mode_t mode) {..
5f30: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
5f40: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
5f50: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
5f60: 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f   tcl_ret, chmod_
5f70: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
5f80: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
5f90: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
5fa0: 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  h);...interp = a
5fb0: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
5fc0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
5fd0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
5fe0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63  n(-EIO);..}...tc
5ff0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
6000: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33  l_Eval(interp, 3
6010: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e  , "::appfs::open
6020: 70 61 74 68 22 2c 20 70 61 74 68 2c 20 22 77 72  path", path, "wr
6030: 69 74 65 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f  ite");..if (tcl_
6040: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
6050: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6060: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
6070: 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64  h(%s, %s) failed
6080: 2e 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65  .", path, "write
6090: 22 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ");...APPFS_DEBU
60a0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
60b0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
60c0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
60d0: 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  ));....return(-E
60e0: 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70  IO);..}...real_p
60f0: 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ath = Tcl_GetStr
6100: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
6110: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
6120: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
6130: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
6140: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
6150: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
6160: 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20  ;...chmod_ret = 
6170: 63 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c  chmod(real_path,
6180: 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f   mode);...appfs_
6190: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
61a0: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75  _leave();...retu
61b0: 72 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d  rn(chmod_ret);.}
61c0: 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20  ../*. * SQLite3 
61d0: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61  mode: Execute ra
61e0: 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e  w SQL and return
61f0: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c   success or fail
6200: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ure. */.static i
6210: 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33  nt appfs_sqlite3
6220: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c  (const char *sql
6230: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
6240: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
6250: 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09  char *sql_ret;..
6260: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
6270: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
6280: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e  eate_TclInterp(N
6290: 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  ULL);..if (inter
62a0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  p == NULL) {...f
62b0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
62c0: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
62d0: 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74   a Tcl interpret
62e0: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
62f0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
6300: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
6310: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
6320: 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70  interp, 5, "::ap
6330: 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22  pfs::db", "eval"
6340: 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75  , sql, "row", "u
6350: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
6360: 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20   row(*); parray 
6370: 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d  row; puts \"----
6380: 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d  \"");..sql_ret =
6390: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
63a0: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
63b0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
63c0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
63d0: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72  tf(stderr, "[err
63e0: 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72  or] %s\n", sql_r
63f0: 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  et);....return(1
6400: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f  );..}...if (sql_
6410: 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30  ret && sql_ret[0
6420: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
6430: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71  rintf("%s\n", sq
6440: 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74  l_ret);..}...ret
6450: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  urn(0);.}../*. *
6460: 20 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75   Tcl mode: Execu
6470: 74 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72  te raw Tcl and r
6480: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72  eturn success or
6490: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61   failure. */.sta
64a0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63  tic int appfs_tc
64b0: 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63  l(const char *tc
64c0: 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  l) {..Tcl_Interp
64d0: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
64e0: 20 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c   char *tcl_resul
64f0: 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  t;..int tcl_ret;
6500: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
6510: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
6520: 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69  rp(NULL);..if (i
6530: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
6540: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
6550: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  r, "Unable to cr
6560: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
6570: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e  preter.  Abortin
6580: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72  g.\n");....retur
6590: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  n(1);..}...tcl_r
65a0: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
65b0: 74 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c  terp, tcl);..tcl
65c0: 5f 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65  _result = Tcl_Ge
65d0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
65e0: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c  terp);...if (tcl
65f0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
6600: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
6610: 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c  rr, "[error] %s\
6620: 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b  n", tcl_result);
6630: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
6640: 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75  }...if (tcl_resu
6650: 6c 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74  lt && tcl_result
6660: 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09  [0] != '\0') {..
6670: 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20  .printf("%s\n", 
6680: 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a  tcl_result);..}.
6690: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
66a0: 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63  /*. * AppFSd Pac
66b0: 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a  kage for Tcl:. *
66c0: 20 20 20 20 20 20 20 20 20 42 72 69 64 67 65 20           Bridge 
66d0: 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f  for I/O operatio
66e0: 6e 73 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e  ns to request in
66f0: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
6700: 74 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20  the current. *  
6710: 20 20 20 20 20 20 20 74 72 61 6e 73 61 63 74 69         transacti
6720: 6f 6e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  on. */.static in
6730: 74 20 41 70 70 66 73 64 5f 49 6e 69 74 28 54 63  t Appfsd_Init(Tc
6740: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6750: 29 20 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54  ) {.#ifdef USE_T
6760: 43 4c 5f 53 54 55 42 53 0a 09 69 66 20 28 54 63  CL_STUBS..if (Tc
6770: 6c 5f 49 6e 69 74 53 74 75 62 73 28 69 6e 74 65  l_InitStubs(inte
6780: 72 70 2c 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c  rp, TCL_VERSION,
6790: 20 30 29 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72   0) == 0L) {...r
67a0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
67b0: 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63  ;..}.#endif...Tc
67c0: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
67d0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
67e0: 73 64 3a 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22  sd::get_homedir"
67f0: 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f  , tcl_appfs_get_
6800: 68 6f 6d 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e  homedir, NULL, N
6810: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
6820: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
6830: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74  rp, "appfsd::get
6840: 5f 66 73 75 69 64 22 2c 20 74 63 6c 5f 61 70 70  _fsuid", tcl_app
6850: 66 73 5f 67 65 74 5f 66 73 75 69 64 2c 20 4e 55  fs_get_fsuid, NU
6860: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
6870: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
6880: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
6890: 3a 3a 67 65 74 5f 66 73 67 69 64 22 2c 20 74 63  ::get_fsgid", tc
68a0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  l_appfs_get_fsgi
68b0: 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  d, NULL, NULL);.
68c0: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
68d0: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
68e0: 70 70 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f  ppfsd::simulate_
68f0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20  user_fs_enter", 
6900: 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61  tcl_appfs_simula
6910: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
6920: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
6930: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
6940: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70  mand(interp, "ap
6950: 70 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75  pfsd::simulate_u
6960: 73 65 72 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74  ser_fs_leave", t
6970: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
6980: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c  e_user_fs_leave,
6990: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09   NULL, NULL);...
69a0: 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69  Tcl_PkgProvide(i
69b0: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c  nterp, "appfsd",
69c0: 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72   "1.0");...retur
69d0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a  n(TCL_OK);.}../*
69e0: 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69  . * FUSE operati
69f0: 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a  ons structure. *
6a00: 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20  /.static struct 
6a10: 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20  fuse_operations 
6a20: 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73  appfs_operations
6a30: 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20   = {...getattr  
6a40: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65   = appfs_fuse_ge
6a50: 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72  tattr,...readdir
6a60: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
6a70: 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c  readdir,...readl
6a80: 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ink  = appfs_fus
6a90: 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70  e_readlink,...op
6aa0: 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  en      = appfs_
6ab0: 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c  fuse_open,...rel
6ac0: 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66  ease   = appfs_f
6ad0: 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61  use_close,...rea
6ae0: 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  d      = appfs_f
6af0: 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74  use_read,...writ
6b00: 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  e     = appfs_fu
6b10: 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f  se_write,...mkno
6b20: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
6b30: 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61  se_mknod,...crea
6b40: 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  te    = appfs_fu
6b50: 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75  se_create,...tru
6b60: 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66  ncate  = appfs_f
6b70: 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e  use_truncate,...
6b80: 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66  unlink    = appf
6b90: 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d  s_fuse_unlink_rm
6ba0: 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20  dir,...rmdir    
6bb0: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e   = appfs_fuse_un
6bc0: 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b  link_rmdir,...mk
6bd0: 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f  dir     = appfs_
6be0: 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68  fuse_mkdir,...ch
6bf0: 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f  mod     = appfs_
6c00: 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a  fuse_chmod,.};..
6c10: 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70 74 69 6f  /*. * FUSE optio
6c20: 6e 20 70 61 72 73 69 6e 67 20 63 61 6c 6c 62 61  n parsing callba
6c30: 63 6b 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ck. */.static in
6c40: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 74  t appfs_fuse_opt
6c50: 5f 63 62 28 76 6f 69 64 20 2a 64 61 74 61 2c 20  _cb(void *data, 
6c60: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67 2c  const char *arg,
6c70: 20 69 6e 74 20 6b 65 79 2c 20 73 74 72 75 63 74   int key, struct
6c80: 20 66 75 73 65 5f 61 72 67 73 20 2a 6f 75 74 61   fuse_args *outa
6c90: 72 67 73 29 20 7b 0a 09 73 74 61 74 69 63 20 69  rgs) {..static i
6ca0: 6e 74 20 73 65 65 6e 5f 63 61 63 68 65 64 69 72  nt seen_cachedir
6cb0: 20 3d 20 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20   = 0;...if (key 
6cc0: 3d 3d 20 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f  == FUSE_OPT_KEY_
6cd0: 4e 4f 4e 4f 50 54 20 26 26 20 73 65 65 6e 5f 63  NONOPT && seen_c
6ce0: 61 63 68 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a  achedir == 0) {.
6cf0: 09 09 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20  ..seen_cachedir 
6d00: 3d 20 31 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  = 1;....appfs_ca
6d10: 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70 28  chedir = strdup(
6d20: 61 72 67 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  arg);....return(
6d30: 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  0);..}...return(
6d40: 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74  1);.}../*. * Ent
6d50: 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68  ry point into th
6d60: 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a  is program.. */.
6d70: 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67  int main(int arg
6d80: 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29 20  c, char **argv) 
6d90: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74  {..Tcl_Interp *t
6da0: 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61  est_interp;..cha
6db0: 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  r *test_interp_e
6dc0: 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66 75  rror;..struct fu
6dd0: 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20 46  se_args args = F
6de0: 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 61 72  USE_ARGS_INIT(ar
6df0: 67 63 2c 20 61 72 67 76 29 3b 0a 09 69 6e 74 20  gc, argv);..int 
6e00: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 2f  pthread_ret;.../
6e10: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
6e20: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
6e30: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
6e40: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
6e50: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
6e60: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
6e70: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
6e80: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
6e90: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
6ea0: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
6eb0: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
6ec0: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
6ed0: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
6ee0: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
6ef0: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
6f00: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
6f10: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
6f20: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
6f30: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
6f40: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
6f50: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
6f60: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
6f70: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
6f80: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
6f90: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
6fa0: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
6fb0: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
6fc0: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
6fd0: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
6fe0: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
6ff0: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
7000: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
7010: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
7020: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
7030: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
7040: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
7050: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
7060: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
7070: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
7080: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
7090: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
70a0: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
70b0: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
70c0: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
70d0: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
70e0: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
70f0: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
7100: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
7110: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
7120: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
7130: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
7140: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
7150: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
7160: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
7170: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
7180: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
7190: 65 72 70 4b 65 79 2c 20 4e 55 4c 4c 29 3b 0a 09  erpKey, NULL);..
71a0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
71b0: 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74  != 0) {...fprint
71c0: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
71d0: 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20  e to create TSD 
71e0: 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62  key for Tcl.  Ab
71f0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
7200: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
7210: 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20  /*.. * Manually 
7220: 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69  specify cache di
7230: 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74  rectory, without
7240: 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09   FUSE callback..
7250: 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f   * This option o
7260: 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e  nly works when n
7270: 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73  ot using FUSE, s
7280: 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e  ince we.. * do n
7290: 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69  ot process it wi
72a0: 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20  th FUSEs option 
72b0: 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f  processing... */
72c0: 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29  ..if (argc >= 2)
72d0: 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28   {...if (strcmp(
72e0: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68  argv[0], "--cach
72f0: 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  edir") == 0) {..
7300: 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
7310: 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31   = strdup(argv[1
7320: 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20  ]);.....argc -= 
7330: 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b  2;....argv += 2;
7340: 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ...}..}.../*.. *
7350: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66   SQLite3 mode, f
7360: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53  or running raw S
7370: 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63  QL against the c
7380: 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20  ache database.. 
7390: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
73a0: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
73b0: 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22  [0], "--sqlite3"
73c0: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
73d0: 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33  rn(appfs_sqlite3
73e0: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
73f0: 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65  ./*.. * Tcl mode
7400: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
7410: 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d  w Tcl in the sam
7420: 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70  e environment Ap
7430: 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72  pFSd would.. * r
7440: 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69  un code... */..i
7450: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
7460: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
7470: 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b  "--tcl") == 0) {
7480: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
7490: 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  tcl(argv[1]));..
74a0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74  }.../*.. * Creat
74b0: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
74c0: 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69  ter just to veri
74d0: 66 79 20 74 68 61 74 20 74 68 69 6e 67 73 20 61  fy that things a
74e0: 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09  re in working ..
74f0: 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20   * order before 
7500: 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d  we become a daem
7510: 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69  on... */..test_i
7520: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
7530: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26  eate_TclInterp(&
7540: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
7550: 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e  r);..if (test_in
7560: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
7570: 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72  ..if (test_inter
7580: 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29  p_error == NULL)
7590: 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72   {....test_inter
75a0: 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f  p_error = "Unkno
75b0: 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a  wn error";...}..
75c0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
75d0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
75e0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65  tialize Tcl inte
75f0: 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70 46  rpreter for AppF
7600: 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  Sd:\n");...fprin
7610: 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c 6e  tf(stderr, "%s\n
7620: 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  ", test_interp_e
7630: 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  rror);....return
7640: 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 65 6c  (1);..}..Tcl_Del
7650: 65 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f 69  eteInterp(test_i
7660: 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nterp);.../*.. *
7670: 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d 65   Add FUSE argume
7680: 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c 77  nts which we alw
7690: 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f 0a  ays supply.. */.
76a0: 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28  .fuse_opt_parse(
76b0: 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  &args, NULL, NUL
76c0: 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70  L, appfs_fuse_op
76d0: 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70 74  t_cb);..fuse_opt
76e0: 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c 20  _add_arg(&args, 
76f0: 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69  "-odefault_permi
7700: 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70  ssions,fsname=ap
7710: 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66  pfs,subtype=appf
7720: 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65  sd,use_ino,kerne
7730: 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69  l_cache,entry_ti
7740: 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d  meout=0,attr_tim
7750: 65 6f 75 74 3d 30 2c 69 6e 74 72 2c 62 69 67 5f  eout=0,intr,big_
7760: 77 72 69 74 65 73 2c 68 61 72 64 5f 72 65 6d 6f  writes,hard_remo
7770: 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75  ve");...if (getu
7780: 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66  id() == 0) {...f
7790: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 26 61  use_opt_parse(&a
77a0: 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  rgs, NULL, NULL,
77b0: 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f   NULL);...fuse_o
77c0: 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73  pt_add_arg(&args
77d0: 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72  , "-oallow_other
77e0: 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  ");..}.../*.. * 
77f0: 45 6e 74 65 72 20 74 68 65 20 46 55 53 45 20 6d  Enter the FUSE m
7800: 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73  ain loop -- this
7810: 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e   will process an
7820: 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20  y arguments.. * 
7830: 61 6e 64 20 73 74 61 72 74 20 73 65 72 76 69 63  and start servic
7840: 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a 09 20  ing requests... 
7850: 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65 5f 73  */..appfs_fuse_s
7860: 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72 65 74  tarted = 1;..ret
7870: 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61 72  urn(fuse_main(ar
7880: 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e 61 72  gs.argc, args.ar
7890: 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65 72 61  gv, &appfs_opera
78a0: 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d  tions, NULL));.}
78b0: 0a 20 0a                                         . .