Hex Artifact Content

Artifact cbe8db4a9d76f2a058dfffda7c0d17a20e3a8122:


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 69 67 6e 61 6c  #include <signal
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6c 69  .h>.#include <li
0080: 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  mits.h>.#include
0090: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
00a0: 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e 0a  lude <stdarg.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
00c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75 6e  .h>.#include <un
00d0: 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  istd.h>.#include
00e0: 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63 6c   <errno.h>.#incl
00f0: 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69  ude <fcntl.h>.#i
0100: 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e  nclude <stdio.h>
0110: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65 2e  .#include <fuse.
0120: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77 64  h>.#include <pwd
0130: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63  .h>.#include <tc
0140: 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44 65 66 61  l.h>../*. * Defa
0150: 75 6c 74 20 63 61 63 68 65 20 64 69 72 65 63 74  ult cache direct
0160: 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64 65 66 20  ory. */.#ifndef 
0170: 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 0a 23  APPFS_CACHEDIR.#
0180: 64 65 66 69 6e 65 20 41 50 50 46 53 5f 43 41 43  define APPFS_CAC
0190: 48 45 44 49 52 20 22 2f 76 61 72 2f 63 61 63 68  HEDIR "/var/cach
01a0: 65 2f 61 70 70 66 73 22 0a 23 65 6e 64 69 66 0a  e/appfs".#endif.
01b0: 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67 20 6d 61  ./* Debugging ma
01c0: 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65 66 20 44  cros */.#ifdef D
01d0: 45 42 55 47 0a 69 6e 74 20 61 70 70 66 73 5f 64  EBUG.int appfs_d
01e0: 65 62 75 67 5f 66 64 20 3d 20 53 54 44 45 52 52  ebug_fd = STDERR
01f0: 5f 46 49 4c 45 4e 4f 3b 0a 23 64 65 66 69 6e 65  _FILENO;.#define
0200: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e   APPFS_DEBUG(x..
0210: 2e 29 20 7b 20 5c 0a 09 63 68 61 72 20 62 75 66  .) { \..char buf
0220: 5b 38 31 39 32 5d 3b 20 5c 0a 09 69 6e 74 20 62  [8192]; \..int b
0230: 75 66 6f 66 66 20 3d 20 30 3b 20 5c 0a 09 69 66  ufoff = 0; \..if
0240: 20 28 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64   (appfs_debug_fd
0250: 20 3d 3d 20 2d 31 29 20 7b 20 5c 0a 09 09 61 70   == -1) { \...ap
0260: 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 20 6f  pfs_debug_fd = o
0270: 70 65 6e 28 22 2f 74 6d 70 2f 61 70 70 66 73 64  pen("/tmp/appfsd
0280: 2e 6c 6f 67 22 2c 20 4f 5f 57 52 4f 4e 4c 59 20  .log", O_WRONLY 
0290: 7c 20 4f 5f 41 50 50 45 4e 44 20 7c 20 4f 5f 43  | O_APPEND | O_C
02a0: 52 45 41 54 2c 20 30 36 30 30 29 3b 20 5c 0a 09  REAT, 0600); \..
02b0: 7d 3b 20 5c 0a 09 62 75 66 6f 66 66 20 3d 20 73  }; \..bufoff = s
02c0: 6e 70 72 69 6e 74 66 28 62 75 66 2c 20 73 69 7a  nprintf(buf, siz
02d0: 65 6f 66 28 62 75 66 29 2c 20 22 5b 64 65 62 75  eof(buf), "[debu
02e0: 67 5d 20 5b 74 3d 25 6c 6c 78 5d 20 25 73 3a 25  g] [t=%llx] %s:%
02f0: 69 3a 25 73 3a 20 22 2c 20 28 75 6e 73 69 67 6e  i:%s: ", (unsign
0300: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74  ed long long) pt
0310: 68 72 65 61 64 5f 73 65 6c 66 28 29 2c 20 5f 5f  hread_self(), __
0320: 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f  FILE__, __LINE__
0330: 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 5c 0a 09  , __func__); \..
0340: 69 66 20 28 62 75 66 6f 66 66 20 3c 20 73 69 7a  if (bufoff < siz
0350: 65 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a 09 09  eof(buf)) { \...
0360: 62 75 66 6f 66 66 20 2b 3d 20 73 6e 70 72 69 6e  bufoff += snprin
0370: 74 66 28 62 75 66 20 2b 20 62 75 66 6f 66 66 2c  tf(buf + bufoff,
0380: 20 73 69 7a 65 6f 66 28 62 75 66 29 20 2d 20 62   sizeof(buf) - b
0390: 75 66 6f 66 66 2c 20 78 29 3b 20 5c 0a 09 7d 3b  ufoff, x); \..};
03a0: 20 5c 0a 09 69 66 20 28 62 75 66 6f 66 66 20 3c   \..if (bufoff <
03b0: 20 73 69 7a 65 6f 66 28 62 75 66 29 29 20 7b 20   sizeof(buf)) { 
03c0: 5c 0a 09 09 62 75 66 6f 66 66 20 2b 3d 20 73 6e  \...bufoff += sn
03d0: 70 72 69 6e 74 66 28 62 75 66 20 2b 20 62 75 66  printf(buf + buf
03e0: 6f 66 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29  off, sizeof(buf)
03f0: 20 2d 20 62 75 66 6f 66 66 2c 20 22 5c 6e 22 29   - bufoff, "\n")
0400: 3b 5c 0a 09 7d 20 5c 0a 09 69 66 20 28 62 75 66  ;\..} \..if (buf
0410: 6f 66 66 20 3e 20 73 69 7a 65 6f 66 28 62 75 66  off > sizeof(buf
0420: 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66 66 20  )) { \...bufoff 
0430: 3d 20 73 69 7a 65 6f 66 28 62 75 66 29 3b 20 5c  = sizeof(buf); \
0440: 0a 09 7d 3b 20 5c 0a 09 77 72 69 74 65 28 61 70  ..}; \..write(ap
0450: 70 66 73 5f 64 65 62 75 67 5f 66 64 2c 20 62 75  pfs_debug_fd, bu
0460: 66 2c 20 62 75 66 6f 66 66 29 3b 20 5c 0a 7d 0a  f, bufoff); \.}.
0470: 23 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 41 50  #else.#define AP
0480: 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20  PFS_DEBUG(x...) 
0490: 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a  /**/.#endif../*.
04a0: 20 2a 20 53 48 41 31 20 54 63 6c 20 50 61 63 6b   * SHA1 Tcl Pack
04b0: 61 67 65 20 69 6e 69 74 69 61 6c 69 7a 65 72 2c  age initializer,
04c0: 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a 20 2a 2f   from sha1.o. */
04d0: 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69 74 28 54  .int Sha1_Init(T
04e0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
04f0: 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68 72 65 61  p);../*. * Threa
0500: 64 20 53 70 65 63 69 66 69 63 20 44 61 74 61 20  d Specific Data 
0510: 28 54 53 44 29 20 66 6f 72 20 54 63 6c 20 49 6e  (TSD) for Tcl In
0520: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 74 68  terpreter for th
0530: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
0540: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70 74 68 72  . */.static pthr
0550: 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74 65 72 70  ead_key_t interp
0560: 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62  Key;../*. * Glob
0570: 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 6e 65  al variables, ne
0580: 65 64 65 64 20 66 6f 72 20 61 6c 6c 20 74 68 72  eded for all thr
0590: 65 61 64 73 20 62 75 74 20 6f 6e 6c 79 20 69 6e  eads but only in
05a0: 69 74 69 61 6c 69 7a 65 64 20 62 65 66 6f 72 65  itialized before
05b0: 20 61 6e 79 0a 20 2a 20 46 55 53 45 20 74 68 72   any. * FUSE thr
05c0: 65 61 64 73 20 61 72 65 20 63 72 65 61 74 65 64  eads are created
05d0: 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20  . */.const char 
05e0: 2a 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 3b  *appfs_cachedir;
05f0: 0a 74 69 6d 65 5f 74 20 61 70 70 66 73 5f 62 6f  .time_t appfs_bo
0600: 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61 70 70 66  ottime;.int appf
0610: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d  s_fuse_started =
0620: 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61   0;../*. * Globa
0630: 6c 20 76 61 72 69 61 62 6c 65 73 20 66 6f 72 20  l variables for 
0640: 41 70 70 46 53 20 63 61 63 68 69 6e 67 0a 20 2a  AppFS caching. *
0650: 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  /.pthread_mutex_
0660: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
0670: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 20 3d 20  o_cache_mutex = 
0680: 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e  PTHREAD_MUTEX_IN
0690: 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e 74 20 61  ITIALIZER;.int a
06a0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
06b0: 61 63 68 65 5f 73 69 7a 65 20 3d 20 38 32 30 39  ache_size = 8209
06c0: 3b 0a 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ;.struct appfs_p
06d0: 61 74 68 69 6e 66 6f 20 2a 61 70 70 66 73 5f 70  athinfo *appfs_p
06e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d  ath_info_cache =
06f0: 20 4e 55 4c 4c 3b 0a 0a 23 69 66 6e 64 65 66 20   NULL;..#ifndef 
0700: 54 43 4c 5f 54 48 52 45 41 44 53 0a 2f 2a 0a 20  TCL_THREADS./*. 
0710: 2a 20 48 61 6e 64 6c 65 20 75 6e 74 68 72 65 61  * Handle unthrea
0720: 64 65 64 20 54 63 6c 0a 20 2a 2f 0a 70 74 68 72  ded Tcl. */.pthr
0730: 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 70 70 66  ead_mutex_t appf
0740: 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c  s_tcl_big_global
0750: 5f 6c 6f 63 6b 20 3d 20 50 54 48 52 45 41 44 5f  _lock = PTHREAD_
0760: 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c 49 5a 45  MUTEX_INITIALIZE
0770: 52 3b 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73  R;.#define appfs
0780: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74  _call_libtcl_ent
0790: 65 72 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  er pthread_mutex
07a0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 74 63 6c  _lock(&appfs_tcl
07b0: 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b  _big_global_lock
07c0: 29 3b 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73  );.#define appfs
07d0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69  _call_libtcl_exi
07e0: 74 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  t pthread_mutex_
07f0: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 74 63  unlock(&appfs_tc
0800: 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63  l_big_global_loc
0810: 6b 29 3b 0a 23 65 6c 73 65 0a 23 77 61 72 6e 69  k);.#else.#warni
0820: 6e 67 20 55 73 69 6e 67 20 61 20 54 68 72 65 61  ng Using a Threa
0830: 64 65 64 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ded Tcl interpre
0840: 74 65 72 20 6d 61 79 20 63 61 75 73 65 20 6d 65  ter may cause me
0850: 6d 6f 72 79 20 6c 65 61 6b 73 0a 23 64 65 66 69  mory leaks.#defi
0860: 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ne appfs_call_li
0870: 62 74 63 6c 5f 65 6e 74 65 72 20 2f 2a 2a 2f 0a  btcl_enter /**/.
0880: 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f 63 61  #define appfs_ca
0890: 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 20 2f  ll_libtcl_exit /
08a0: 2a 2a 2f 0a 23 65 6e 64 69 66 0a 23 64 65 66 69  **/.#endif.#defi
08b0: 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ne appfs_call_li
08c0: 62 74 63 6c 28 78 2e 2e 2e 29 20 61 70 70 66 73  btcl(x...) appfs
08d0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74  _call_libtcl_ent
08e0: 65 72 20 78 20 61 70 70 66 73 5f 63 61 6c 6c 5f  er x appfs_call_
08f0: 6c 69 62 74 63 6c 5f 65 78 69 74 0a 0a 2f 2a 0a  libtcl_exit../*.
0900: 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62   * Global variab
0910: 6c 65 73 20 66 6f 72 20 41 70 70 46 53 20 54 63  les for AppFS Tc
0920: 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20 72 65  l Interpreter re
0930: 73 74 61 72 74 69 6e 67 0a 20 2a 2f 0a 69 6e 74  starting. */.int
0940: 20 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65   interp_reset_ke
0950: 79 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 41 70  y = 0;../*. * Ap
0960: 70 46 53 20 50 61 74 68 20 54 79 70 65 3a 20 20  pFS Path Type:  
0970: 44 65 73 63 72 69 62 65 73 20 74 68 65 20 74 79  Describes the ty
0980: 70 65 20 6f 66 20 70 61 74 68 20 61 20 67 69 76  pe of path a giv
0990: 65 6e 20 66 69 6c 65 20 69 73 0a 20 2a 2f 0a 74  en file is. */.t
09a0: 79 70 65 64 65 66 20 65 6e 75 6d 20 7b 0a 09 41  ypedef enum {..A
09b0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
09c0: 56 41 4c 49 44 2c 0a 09 41 50 50 46 53 5f 50 41  VALID,..APPFS_PA
09d0: 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f  THTYPE_DOES_NOT_
09e0: 45 58 49 53 54 2c 0a 09 41 50 50 46 53 5f 50 41  EXIST,..APPFS_PA
09f0: 54 48 54 59 50 45 5f 46 49 4c 45 2c 0a 09 41 50  THTYPE_FILE,..AP
0a00: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
0a10: 45 43 54 4f 52 59 2c 0a 09 41 50 50 46 53 5f 50  ECTORY,..APPFS_P
0a20: 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 2c  ATHTYPE_SYMLINK,
0a30: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
0a40: 5f 53 4f 43 4b 45 54 2c 0a 09 41 50 50 46 53 5f  _SOCKET,..APPFS_
0a50: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 2c 0a 7d  PATHTYPE_FIFO,.}
0a60: 20 61 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f   appfs_pathtype_
0a70: 74 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20  t;../*. * AppFS 
0a80: 50 61 74 68 20 49 6e 66 6f 72 6d 61 74 69 6f 6e  Path Information
0a90: 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 43 6f 6d  :. *         Com
0aa0: 70 6c 65 74 65 6c 79 20 64 65 73 63 72 69 62 65  pletely describe
0ab0: 73 20 61 20 73 70 65 63 69 66 69 63 20 70 61 74  s a specific pat
0ac0: 68 2c 20 68 6f 77 20 69 74 20 73 68 6f 75 6c 64  h, how it should
0ad0: 20 62 65 20 72 65 74 75 72 6e 65 64 20 74 6f 0a   be returned to.
0ae0: 20 2a 20 20 20 20 20 20 20 20 20 74 6f 20 74 68   *         to th
0af0: 65 20 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73 74 72  e kernel. */.str
0b00: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
0b10: 66 6f 20 7b 0a 09 61 70 70 66 73 5f 70 61 74 68  fo {..appfs_path
0b20: 74 79 70 65 5f 74 20 74 79 70 65 3b 0a 09 74 69  type_t type;..ti
0b30: 6d 65 5f 74 20 74 69 6d 65 3b 0a 09 63 68 61 72  me_t time;..char
0b40: 20 68 6f 73 74 6e 61 6d 65 5b 32 35 36 5d 3b 0a   hostname[256];.
0b50: 09 69 6e 74 20 70 61 63 6b 61 67 65 64 3b 0a 09  .int packaged;..
0b60: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
0b70: 6e 67 20 69 6e 6f 64 65 3b 0a 09 75 6e 69 6f 6e  ng inode;..union
0b80: 20 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09   {...struct {...
0b90: 09 69 6e 74 20 63 68 69 6c 64 63 6f 75 6e 74 3b  .int childcount;
0ba0: 0a 09 09 7d 20 64 69 72 3b 0a 09 09 73 74 72 75  ...} dir;...stru
0bb0: 63 74 20 7b 0a 09 09 09 69 6e 74 20 65 78 65 63  ct {....int exec
0bc0: 75 74 61 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74  utable;....off_t
0bd0: 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65 3b   size;...} file;
0be0: 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 6f  ...struct {....o
0bf0: 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63 68  ff_t size;....ch
0c00: 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b 0a  ar source[256];.
0c10: 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d 20  ..} symlink;..} 
0c20: 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a 20 41  typeinfo;.../* A
0c30: 74 74 72 69 62 75 74 65 73 20 75 73 65 64 20 6f  ttributes used o
0c40: 6e 6c 79 20 66 6f 72 20 63 61 63 68 69 6e 67 20  nly for caching 
0c50: 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68 61 72  entries */..char
0c60: 20 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b 0a 09   *_cache_path;..
0c70: 75 69 64 5f 74 20 5f 63 61 63 68 65 5f 75 69 64  uid_t _cache_uid
0c80: 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61  ;.};../*. * Crea
0c90: 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74  te a new Tcl int
0ca0: 65 72 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d  erpreter and com
0cb0: 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69  pletely initiali
0cc0: 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63  ze it. */.static
0cd0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70   Tcl_Interp *app
0ce0: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
0cf0: 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72  erp(char **error
0d00: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f  _string) {..Tcl_
0d10: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
0d20: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09 63  .int tcl_ret;..c
0d30: 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f 73  onst char *tcl_s
0d40: 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41 50 50  etvar_ret;...APP
0d50: 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74 69  FS_DEBUG("Creati
0d60: 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72  ng new Tcl inter
0d70: 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 20 3d  preter for TID =
0d80: 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67   0x%llx", (unsig
0d90: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70  ned long long) p
0da0: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a  thread_self());.
0db0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
0dc0: 74 63 6c 28 0a 09 09 69 6e 74 65 72 70 20 3d 20  tcl(...interp = 
0dd0: 54 63 6c 5f 43 72 65 61 74 65 49 6e 74 65 72 70  Tcl_CreateInterp
0de0: 28 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e 74 65  ();..)..if (inte
0df0: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
0e00: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0e10: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
0e20: 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65 74 65  e Tcl Interprete
0e30: 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  r.  Aborting.\n"
0e40: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
0e50: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
0e60: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
0e70: 64 75 70 28 22 55 6e 61 62 6c 65 20 74 6f 20 63  dup("Unable to c
0e80: 72 65 61 74 65 20 54 63 6c 20 69 6e 74 65 72 70  reate Tcl interp
0e90: 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a 0a 09  reter.");...}...
0ea0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
0eb0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
0ec0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
0ed0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61  ve(interp);)...a
0ee0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
0ef0: 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  (...tcl_ret = Tc
0f00: 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b 0a  l_Init(interp);.
0f10: 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  .)..if (tcl_ret 
0f20: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66  != TCL_OK) {...f
0f30: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
0f40: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61  Unable to initia
0f50: 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f 72 74  lize Tcl.  Abort
0f60: 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66  ing.\n");...appf
0f70: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
0f80: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0f90: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
0fa0: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
0fb0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
0fc0: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20  rp));...)....if 
0fd0: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b  (error_string) {
0fe0: 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
0ff0: 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f  ibtcl(.....*erro
1000: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
1010: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
1020: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1030: 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66  ...)...}....appf
1040: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
1050: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
1060: 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42  );)....APPFS_DEB
1070: 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20  UG("Terminating 
1080: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
1090: 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ");....appfs_cal
10a0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c  l_libtcl(Tcl_Del
10b0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
10c0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  );)....return(NU
10d0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  LL);..}...appfs_
10e0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
10f0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61  cl_ret = Tcl_Eva
1100: 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61  l(interp, "packa
1110: 67 65 20 69 66 6e 65 65 64 65 64 20 73 68 61 31  ge ifneeded sha1
1120: 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20   1.0 [list load 
1130: 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09 29 0a 09  {} sha1]");..)..
1140: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
1150: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
1160: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1170: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
1180: 20 54 63 6c 20 53 48 41 31 2e 20 20 41 62 6f 72   Tcl SHA1.  Abor
1190: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70  ting.\n");...app
11a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
11b0: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
11c0: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
11d0: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
11e0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
11f0: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66  erp));...)....if
1200: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1210: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  {....appfs_call_
1220: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72  libtcl(.....*err
1230: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
1240: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
1250: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1260: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70  ....)...}....app
1270: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
1280: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1290: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45  p);)....APPFS_DE
12a0: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
12b0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
12c0: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
12d0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
12e0: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
12f0: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e  p);)....return(N
1300: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ULL);..}...appfs
1310: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1320: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
1330: 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b  al(interp, "pack
1340: 61 67 65 20 69 66 6e 65 65 64 65 64 20 61 70 70  age ifneeded app
1350: 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f  fsd 1.0 [list lo
1360: 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22 29 3b  ad {} appfsd]");
1370: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
1380: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
1390: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
13a0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
13b0: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
13c0: 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72 74 69  Package.  Aborti
13d0: 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73  ng.\n");...appfs
13e0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
13f0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1400: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
1410: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
1420: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
1430: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28  p));...)....if (
1440: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
1450: 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1460: 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72  btcl(.....*error
1470: 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70  _string = strdup
1480: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65  (Tcl_GetStringRe
1490: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
14a0: 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73  ..)...}....appfs
14b0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
14c0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
14d0: 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ;)....APPFS_DEBU
14e0: 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54  G("Terminating T
14f0: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
1500: 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  );....appfs_call
1510: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65  _libtcl(Tcl_Dele
1520: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
1530: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ;)....return(NUL
1540: 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  L);..}.../*.. * 
1550: 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c 22 20 69  Load "pki.tcl" i
1560: 6e 20 74 68 65 20 73 61 6d 65 20 77 61 79 20 61  n the same way a
1570: 73 20 61 70 70 66 73 64 2e 74 63 6c 20 28 73 65  s appfsd.tcl (se
1580: 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f 0a 09 61  e below).. */..a
1590: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
15a0: 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72 65 74  _enter...tcl_ret
15b0: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
15c0: 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20  rp, "".#include 
15d0: 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 09 22 22  "pki.tcl.h"...""
15e0: 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  );..appfs_call_l
15f0: 69 62 74 63 6c 5f 65 78 69 74 0a 09 69 66 20 28  ibtcl_exit..if (
1600: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
1610: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
1620: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
1630: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
1640: 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e 67 2e   PKI.  Aborting.
1650: 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  \n");...appfs_ca
1660: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70  ll_libtcl(....fp
1670: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
1680: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
1690: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
16a0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
16b0: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
16c0: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
16d0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
16e0: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
16f0: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
1700: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1710: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
1720: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
1730: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
1740: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
1750: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
1760: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
1770: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
1780: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1790: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
17a0: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
17b0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
17c0: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61  ..}.../*.. * Loa
17d0: 64 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63  d the "appfsd.tc
17e0: 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 63 68  l" script, which
17f0: 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20 69   is "compiled" i
1800: 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a 09  nto a C header..
1810: 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64 6f   * so that it do
1820: 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 65  es not need to e
1830: 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c 65  xist on the file
1840: 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20 62  system and can b
1850: 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20 65  e.. * directly e
1860: 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a 09  valuated... */..
1870: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1880: 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72 65  l_enter...tcl_re
1890: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
18a0: 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65  erp, "".#include
18b0: 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 22 0a   "appfsd.tcl.h".
18c0: 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61  .."");..appfs_ca
18d0: 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09  ll_libtcl_exit..
18e0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
18f0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
1900: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1910: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
1920: 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69 70   Tcl AppFS scrip
1930: 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  t.  Aborting.\n"
1940: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
1950: 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72 69 6e  libtcl(....fprin
1960: 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20  tf(stderr, "Tcl 
1970: 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c  Error is: %s\n",
1980: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
1990: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
19a0: 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  .)....if (error_
19b0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70  string) {....app
19c0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
19d0: 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e  ....*error_strin
19e0: 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47  g = strdup(Tcl_G
19f0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1a00: 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09  nterp));....)...
1a10: 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  }....appfs_call_
1a20: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
1a30: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
1a40: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72  APPFS_DEBUG("Ter
1a50: 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74  minating Tcl int
1a60: 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09  erpreter.");....
1a70: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1a80: 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65  l(Tcl_DeleteInte
1a90: 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  rp(interp);)....
1aa0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1ab0: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c  .../*.. * Set gl
1ac0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
1ad0: 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09 20 2a  rom C to Tcl.. *
1ae0: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  /..appfs_call_li
1af0: 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73 65 74 76  btcl(...tcl_setv
1b00: 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f 53 65 74  ar_ret = Tcl_Set
1b10: 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61  Var(interp, "::a
1b20: 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72 22 2c  ppfs::cachedir",
1b30: 20 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 2c   appfs_cachedir,
1b40: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
1b50: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 73  );..)..if (tcl_s
1b60: 65 74 76 61 72 5f 72 65 74 20 3d 3d 20 4e 55 4c  etvar_ret == NUL
1b70: 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  L) {...fprintf(s
1b80: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
1b90: 6f 20 73 65 74 20 63 61 63 68 65 20 64 69 72 65  o set cache dire
1ba0: 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f  ctory.  This sho
1bb0: 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c  uld never fail.\
1bc0: 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  n");....if (erro
1bd0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61  r_string) {....a
1be0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1bf0: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72  (.....*error_str
1c00: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
1c10: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1c20: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a  (interp));....).
1c30: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..}....appfs_cal
1c40: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
1c50: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
1c60: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
1c70: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69  erminating Tcl i
1c80: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a  nterpreter.");..
1c90: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1ca0: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e  tcl(Tcl_DeleteIn
1cb0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a  terp(interp);)..
1cc0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1cd0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74  .}.../*.. * Init
1ce0: 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 70 66  ialize the "appf
1cf0: 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d  sd.tcl" environm
1d00: 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 74 20  ent, which must 
1d10: 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a 09 20  be done after.. 
1d20: 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  * global variabl
1d30: 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f  es are set... */
1d40: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1d50: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d  tcl(...tcl_ret =
1d60: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
1d70: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74  , "::appfs::init
1d80: 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f  ");..)..if (tcl_
1d90: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
1da0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1db0: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  r, "Unable to in
1dc0: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70  itialize Tcl App
1dd0: 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61 70 70  FS script (::app
1de0: 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62 6f 72  fs::init).  Abor
1df0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70  ting.\n");...app
1e00: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1e10: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1e20: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
1e30: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
1e40: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1e50: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66  erp));...)....if
1e60: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1e70: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  {....appfs_call_
1e80: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72  libtcl(.....*err
1e90: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
1ea0: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
1eb0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1ec0: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70  ....)...}....app
1ed0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
1ee0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1ef0: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45  p);)....APPFS_DE
1f00: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
1f10: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
1f20: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
1f30: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
1f40: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
1f50: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e  p);)....return(N
1f60: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
1f70: 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 6c 20  * Hide some Tcl 
1f80: 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 77 65  commands that we
1f90: 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f 20   do not care to 
1fa0: 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 6d 61  use and which ma
1fb0: 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e 20  y.. * slow down 
1fc0: 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74 69  run-time operati
1fd0: 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ons... */..appfs
1fe0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1ff0: 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e 64 28  Tcl_HideCommand(
2000: 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f 6c 6f  interp, "auto_lo
2010: 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75 74 6f  ad_index", "auto
2020: 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b 0a 09  _load_index");..
2030: 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e 64  .Tcl_HideCommand
2040: 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f 77  (interp, "unknow
2050: 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29 3b 0a  n", "unknown");.
2060: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e  ..Tcl_HideComman
2070: 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69 74 22  d(interp, "exit"
2080: 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a 0a 09  , "exit");..)...
2090: 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65 20 74  /*.. * Release t
20a0: 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76 65 20  he hold we have 
20b0: 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72 65 74  on the interpret
20c0: 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 6d 61  er so that it ma
20d0: 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74 65 64  y be.. * deleted
20e0: 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a 2f 0a   if needed.. */.
20f0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2100: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
2110: 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a 09 20  nterp);).../*.. 
2120: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d  * Return the com
2130: 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69  pletely initiali
2140: 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65 72 0a  zed interpreter.
2150: 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e 74  . */..return(int
2160: 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52  erp);.}../*. * R
2170: 65 74 75 72 6e 20 74 68 65 20 74 68 72 65 61 64  eturn the thread
2180: 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20 69 6e  -specific Tcl in
2190: 74 65 72 70 72 65 74 65 72 2c 20 63 72 65 61 74  terpreter, creat
21a0: 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65 64  ing it if needed
21b0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f  . */.static Tcl_
21c0: 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54 63  Interp *appfs_Tc
21d0: 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b 0a  lInterp(void) {.
21e0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
21f0: 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65 61  erp;..int pthrea
2200: 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 20 5f  d_ret;..static _
2210: 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68 72 65  _thread int thre
2220: 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  ad_interp_reset_
2230: 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 67 6c  key = 0;..int gl
2240: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
2250: 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f  t_key;...global_
2260: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2270: 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f   = __sync_fetch_
2280: 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f  and_add(&interp_
2290: 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 0a  reset_key, 0);..
22a0: 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65 61  .interp = pthrea
22b0: 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 69 6e  d_getspecific(in
22c0: 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28 69  terpKey);..if (i
22d0: 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 26 26  nterp != NULL &&
22e0: 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72   thread_interp_r
22f0: 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c 6f 62  eset_key != glob
2300: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
2310: 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  key) {...APPFS_D
2320: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
2330: 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 74 65  g old interprete
2340: 72 20 61 6e 64 20 72 65 73 74 61 72 74 69 6e 67  r and restarting
2350: 20 64 75 65 20 74 6f 20 72 65 73 65 74 20 72 65   due to reset re
2360: 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61 70 70  quest.");....app
2370: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
2380: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
2390: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69 6e 74  interp);)....int
23a0: 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 70  erp = NULL;....p
23b0: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
23c0: 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 69 63  read_setspecific
23d0: 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65  (interpKey, inte
23e0: 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 67 6c  rp);..}...if (gl
23f0: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
2400: 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b 0a 09  t_key == -1) {..
2410: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65  .APPFS_DEBUG("Re
2420: 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20 73 69 6e  turning NULL sin
2430: 63 65 20 77 65 20 61 72 65 20 69 6e 20 74 68 65  ce we are in the
2440: 20 70 72 6f 63 65 73 73 20 6f 66 20 74 65 72 6d   process of term
2450: 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74 68 72 65  inating all thre
2460: 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72  ads.");....retur
2470: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 68  n(NULL);..}...th
2480: 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65  read_interp_rese
2490: 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61 6c 5f 69  t_key = global_i
24a0: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b  nterp_reset_key;
24b0: 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ...if (interp ==
24c0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72   NULL) {...inter
24d0: 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65  p = appfs_create
24e0: 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29  _TclInterp(NULL)
24f0: 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20  ;....if (interp 
2500: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 41 50  == NULL) {....AP
2510: 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74  PFS_DEBUG("Creat
2520: 65 20 69 6e 74 65 72 70 20 66 61 69 6c 65 64 2c  e interp failed,
2530: 20 72 65 74 75 72 6e 69 6e 67 69 6e 20 66 61 69   returningin fai
2540: 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09 72 65 74  lure.");.....ret
2550: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a  urn(NULL);...}..
2560: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
2570: 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69  pthread_setspeci
2580: 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69  fic(interpKey, i
2590: 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70 74  nterp);...if (pt
25a0: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
25b0: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
25c0: 28 22 70 74 68 72 65 61 64 5f 73 65 74 73 70 65  ("pthread_setspe
25d0: 63 69 66 69 63 28 29 20 66 61 69 6c 65 64 2e 20  cific() failed. 
25e0: 20 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c   Terminating Tcl
25f0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
2600: 0a 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .....appfs_call_
2610: 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74  libtcl(Tcl_Delet
2620: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
2630: 29 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c  ).....return(NUL
2640: 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  L);...}..}...ret
2650: 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  urn(interp);.}..
2660: 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65 20 61  /*. * Evaluate a
2670: 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f 6e 73   Tcl script cons
2680: 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e 63 61  tructed by conca
2690: 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e 63 68  tenating a bunch
26a0: 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a 20 2a   of C strings. *
26b0: 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f 0a 73   together.. */.s
26c0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
26d0: 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49 6e 74  Tcl_Eval(Tcl_Int
26e0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
26f0: 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63 68 61   objc, const cha
2700: 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09  r *cmd, ...) {..
2710: 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a  Tcl_Obj **objv;.
2720: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67  .const char *arg
2730: 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67 70 3b  ;..va_list argp;
2740: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09 69  ..int retval;..i
2750: 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e 74 65  nt i;...if (inte
2760: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
2770: 41 50 50 46 53 5f 44 45 42 55 47 28 22 49 6e 76  APPFS_DEBUG("Inv
2780: 61 6c 69 64 20 69 6e 74 65 72 70 72 65 74 65 72  alid interpreter
2790: 20 70 61 73 73 65 64 20 69 6e 2c 20 72 65 74 75   passed in, retu
27a0: 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75 72 65  rning in failure
27b0: 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 54  .");....return(T
27c0: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
27d0: 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20  objv = (void *) 
27e0: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a  ckalloc(sizeof(*
27f0: 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 0a  objv) * objc);..
2800: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2810: 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d 20 3d 20  cl(...objv[0] = 
2820: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
2830: 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 09 54 63  (cmd, -1);....Tc
2840: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f  l_IncrRefCount(o
2850: 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76 61 5f 73  bjv[0]);....va_s
2860: 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64 29 3b  tart(argp, cmd);
2870: 0a 09 09 66 6f 72 20 28 69 20 3d 20 31 3b 20 69  ...for (i = 1; i
2880: 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a   < objc; i++) {.
2890: 09 09 09 61 72 67 20 3d 20 76 61 5f 61 72 67 28  ...arg = va_arg(
28a0: 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  argp, const char
28b0: 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76 5b 69 5d   *);.....objv[i]
28c0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
28d0: 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a 0a 09  Obj(arg, -1);...
28e0: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
28f0: 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d  nt(objv[i]);...}
2900: 0a 09 09 76 61 5f 65 6e 64 28 61 72 67 70 29 3b  ...va_end(argp);
2910: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
2920: 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 74 76 61  _libtcl(...retva
2930: 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 76  l = Tcl_EvalObjv
2940: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c 20 6f  (interp, objc, o
2950: 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a 09 61 70  bjv, 0);..)...ap
2960: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2970: 0a 09 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69  ...for (i = 0; i
2980: 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a   < objc; i++) {.
2990: 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  ...Tcl_DecrRefCo
29a0: 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09  unt(objv[i]);...
29b0: 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65 28 28 76  }..)...ckfree((v
29c0: 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09  oid *) objv);...
29d0: 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 54 43  if (retval != TC
29e0: 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70 66 73 5f  L_OK) {...appfs_
29f0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
2a00: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
2a10: 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65 64 2c   command failed,
2a20: 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63 6f 6e   ::errorInfo con
2a30: 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20 54 63  tains: %s\n", Tc
2a40: 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_GetVar(interp,
2a50: 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22 2c 20   "::errorInfo", 
2a60: 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 72 65  0));...)..}...re
2a70: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
2a80: 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74 20 61  ./*. * Request a
2a90: 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ll Tcl interpret
2aa0: 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a  ers restart. */.
2ab0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
2ac0: 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72  s_tcl_ResetInter
2ad0: 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46  ps(void) {..APPF
2ae0: 53 5f 44 45 42 55 47 28 22 52 65 71 75 65 73 74  S_DEBUG("Request
2af0: 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61 6c 6c  ing reset of all
2b00: 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e 22 29   interpreters.")
2b10: 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 5f 61  ;...__sync_add_a
2b20: 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70  nd_fetch(&interp
2b30: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 3b 0a  _reset_key, 1);.
2b40: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
2b50: 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65   * Determine the
2b60: 20 55 49 44 20 66 6f 72 20 74 68 65 20 75 73 65   UID for the use
2b70: 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72  r making the cur
2b80: 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79  rent FUSE filesy
2b90: 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a  stem request.. *
2ba0: 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73   This will be us
2bb0: 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65  ed to lookup the
2bc0: 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72   user's home dir
2bd0: 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e  ectory so we can
2be0: 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c   search for. * l
2bf0: 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20  ocally modified 
2c00: 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69  files.. */.stati
2c10: 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f 67 65  c uid_t appfs_ge
2c20: 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20 7b 0a  t_fsuid(void) {.
2c30: 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e  .struct fuse_con
2c40: 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20  text *ctx;...if 
2c50: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
2c60: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
2c70: 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d 0a 0a  (getuid());..}..
2c80: 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f  .ctx = fuse_get_
2c90: 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28  context();..if (
2ca0: 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ctx == NULL) {..
2cb0: 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  ./* Unable to lo
2cc0: 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f  okup user for so
2cd0: 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f  me reason */.../
2ce0: 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72  * Return an unpr
2cf0: 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 49 44  ivileged user ID
2d00: 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45 42 55   */...APPFS_DEBU
2d10: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f  G("Unable to loo
2d20: 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f 6d  kup user for som
2d30: 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75 72 6e  e reason, return
2d40: 69 6e 6e 67 20 75 73 65 72 20 49 44 20 6f 66 20  inng user ID of 
2d50: 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  1");....return(1
2d60: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63  );..}...return(c
2d70: 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a  tx->uid);.}../*.
2d80: 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65   * Determine the
2d90: 20 47 49 44 20 66 6f 72 20 74 68 65 20 75 73 65   GID for the use
2da0: 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72  r making the cur
2db0: 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79  rent FUSE filesy
2dc0: 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a  stem request.. *
2dd0: 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73   This will be us
2de0: 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65  ed to lookup the
2df0: 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72   user's home dir
2e00: 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e  ectory so we can
2e10: 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c   search for. * l
2e20: 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20  ocally modified 
2e30: 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69  files.. */.stati
2e40: 63 20 67 69 64 5f 74 20 61 70 70 66 73 5f 67 65  c gid_t appfs_ge
2e50: 74 5f 66 73 67 69 64 28 76 6f 69 64 29 20 7b 0a  t_fsgid(void) {.
2e60: 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e  .struct fuse_con
2e70: 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20  text *ctx;...if 
2e80: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
2e90: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
2ea0: 28 67 65 74 67 69 64 28 29 29 3b 0a 09 7d 0a 0a  (getgid());..}..
2eb0: 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f  .ctx = fuse_get_
2ec0: 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28  context();..if (
2ed0: 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ctx == NULL) {..
2ee0: 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  ./* Unable to lo
2ef0: 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f  okup user for so
2f00: 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f  me reason */.../
2f10: 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72  * Return an unpr
2f20: 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 49 44  ivileged user ID
2f30: 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45 42 55   */...APPFS_DEBU
2f40: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f  G("Unable to loo
2f50: 6b 75 70 20 67 72 6f 75 70 20 66 6f 72 20 73 6f  kup group for so
2f60: 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75 72  me reason, retur
2f70: 6e 69 6e 6e 67 20 67 72 6f 75 70 20 49 44 20 6f  ninng group ID o
2f80: 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  f 1");....return
2f90: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (1);..}...return
2fa0: 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a 0a 73  (ctx->gid);.}..s
2fb0: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
2fc0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
2fd0: 73 5f 65 6e 74 65 72 28 76 6f 69 64 29 20 7b 0a  s_enter(void) {.
2fe0: 09 73 65 74 66 73 75 69 64 28 61 70 70 66 73 5f  .setfsuid(appfs_
2ff0: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 09 73  get_fsuid());..s
3000: 65 74 66 73 67 69 64 28 61 70 70 66 73 5f 67 65  etfsgid(appfs_ge
3010: 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d 0a 0a 73  t_fsgid());.}..s
3020: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
3030: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
3040: 73 5f 6c 65 61 76 65 28 76 6f 69 64 29 20 7b 0a  s_leave(void) {.
3050: 09 73 65 74 66 73 75 69 64 28 30 29 3b 0a 09 73  .setfsuid(0);..s
3060: 65 74 66 73 67 69 64 28 30 29 3b 0a 7d 0a 0a 2f  etfsgid(0);.}../
3070: 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 68 65  *. * Look up the
3080: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20   home directory 
3090: 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49 44 0a  for a given UID.
30a0: 20 2a 20 20 20 20 20 20 20 20 52 65 74 75 72 6e   *        Return
30b0: 73 20 61 20 43 20 73 74 72 69 6e 67 20 63 6f 6e  s a C string con
30c0: 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73 65 72  taining the user
30d0: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
30e0: 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 2a 20  y or NULL if. * 
30f0: 20 20 20 20 20 20 20 74 68 65 20 75 73 65 72 27         the user'
3100: 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  s home directory
3110: 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20   does not exist 
3120: 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72 65 63  or is not correc
3130: 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20 63 6f  tly. *        co
3140: 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73 74 61  nfigured. */.sta
3150: 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f  tic char *appfs_
3160: 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69 64 5f  get_homedir(uid_
3170: 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74 72 75  t fsuid) {..stru
3180: 63 74 20 70 61 73 73 77 64 20 65 6e 74 72 79 2c  ct passwd entry,
3190: 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72 75 63   *result;..struc
31a0: 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a 09 63  t stat stbuf;..c
31b0: 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c 20 2a  har buf[1024], *
31c0: 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70 75  retval;..int gpu
31d0: 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74 3b 0a  _ret, stat_ret;.
31e0: 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65 74 70  ..gpu_ret = getp
31f0: 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20 26 65  wuid_r(fsuid, &e
3200: 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a 65 6f  ntry, buf, sizeo
3210: 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c 74 29  f(buf), &result)
3220: 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74 20 21  ;..if (gpu_ret !
3230: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
3240: 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72  EBUG("getpwuid_r
3250: 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75  (%llu, ...) retu
3260: 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65 22  rned in failure"
3270: 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  , (unsigned long
3280: 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a   long) fsuid);..
3290: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
32a0: 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 20  .}...if (result 
32b0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
32c0: 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75  FS_DEBUG("getpwu
32d0: 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20  id_r(%llu, ...) 
32e0: 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72 65  returned NULL re
32f0: 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65 64  sult", (unsigned
3300: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69   long long) fsui
3310: 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  d);....return(NU
3320: 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65  LL);..}...if (re
3330: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d 20  sult->pw_dir == 
3340: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
3350: 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f  DEBUG("getpwuid_
3360: 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74  r(%llu, ...) ret
3370: 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65 20  urned NULL home 
3380: 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75 6e 73  directory", (uns
3390: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
33a0: 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75   fsuid);....retu
33b0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 73  rn(NULL);..}...s
33c0: 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74 28 72  tat_ret = stat(r
33d0: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20 26  esult->pw_dir, &
33e0: 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73 74 61  stbuf);..if (sta
33f0: 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  t_ret != 0) {...
3400: 41 50 50 46 53 5f 44 45 42 55 47 28 22 73 74 61  APPFS_DEBUG("sta
3410: 74 28 25 73 29 20 72 65 74 75 72 6e 65 64 20 69  t(%s) returned i
3420: 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65 73 75  n failure", resu
3430: 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 09  lt->pw_dir);....
3440: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
3450: 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73 74 5f  ...if (stbuf.st_
3460: 75 69 64 20 21 3d 20 66 73 75 69 64 29 20 7b 0a  uid != fsuid) {.
3470: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
3480: 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e 20  ID mis-match on 
3490: 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d 65  user %llu's home
34a0: 20 64 69 72 65 63 74 6f 72 79 20 28 25 73 29 2e   directory (%s).
34b0: 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62 79 20    It's owned by 
34c0: 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28 75  %llu.",...    (u
34d0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
34e0: 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20 20 20  g) fsuid,...    
34f0: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 0a  result->pw_dir,.
3500: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
3510: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75 66  long long) stbuf
3520: 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09 09  .st_uid...);....
3530: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
3540: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74 72 64  ...retval = strd
3550: 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69  up(result->pw_di
3560: 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  r);...return(ret
3570: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47  val);.}../*. * G
3580: 65 6e 65 72 61 74 65 20 61 6e 20 69 6e 6f 64 65  enerate an inode
3590: 20 66 6f 72 20 61 20 67 69 76 65 6e 20 70 61 74   for a given pat
35a0: 68 2e 20 20 54 68 65 20 69 6e 6f 64 65 20 73 68  h.  The inode sh
35b0: 6f 75 6c 64 20 62 65 20 63 6f 6d 70 75 74 65 64  ould be computed
35c0: 20 69 6e 20 73 75 63 68 0a 20 2a 20 61 20 77 61   in such. * a wa
35d0: 79 20 74 68 61 74 20 69 74 20 69 73 20 75 6e 6c  y that it is unl
35e0: 69 6b 65 6c 79 20 74 6f 20 62 65 20 64 75 70 6c  ikely to be dupl
35f0: 69 63 61 74 65 64 20 61 6e 64 20 72 65 6d 61 69  icated and remai
3600: 6e 73 20 74 68 65 20 73 61 6d 65 20 66 6f 72 20  ns the same for 
3610: 61 20 67 69 76 65 6e 0a 20 2a 20 66 69 6c 65 0a  a given. * file.
3620: 20 2a 0a 20 2a 20 43 75 72 72 65 6e 74 20 69 6d   *. * Current im
3630: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20  plementation is 
3640: 61 6e 20 46 4e 56 2d 31 61 20 33 32 2d 62 69 74  an FNV-1a 32-bit
3650: 0a 20 2a 2f 0a 23 69 66 20 55 49 4e 54 5f 4d 41  . */.#if UINT_MA
3660: 58 20 3c 20 34 32 39 34 39 36 37 32 39 35 0a 23  X < 4294967295.#
3670: 65 72 72 6f 72 20 49 6e 74 65 67 65 72 20 73 69  error Integer si
3680: 7a 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c 6c 20  ze is too small 
3690: 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 20 75  .#endif.static u
36a0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
36b0: 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  g appfs_get_path
36c0: 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68 61  _inode(const cha
36d0: 72 20 2a 70 61 74 68 29 20 7b 0a 09 75 6e 73 69  r *path) {..unsi
36e0: 67 6e 65 64 20 69 6e 74 20 72 65 74 76 61 6c 3b  gned int retval;
36f0: 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64  ..const unsigned
3700: 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74 76   char *p;...retv
3710: 61 6c 20 3d 20 32 31 36 36 31 33 36 32 36 31 3b  al = 2166136261;
3720: 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d 62 69   /* FNV-1a 32-bi
3730: 74 20 6f 66 66 73 65 74 5f 62 61 73 69 73 20 2a  t offset_basis *
3740: 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20 28 75 6e  /...for (p = (un
3750: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 20 70  signed char *) p
3760: 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29 20 7b 0a  ath; *p; p++) {.
3770: 09 09 72 65 74 76 61 6c 20 5e 3d 20 28 69 6e 74  ..retval ^= (int
3780: 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09 09 72 65  ) *p;.#if 0...re
3790: 74 76 61 6c 20 2a 3d 20 31 36 37 37 37 36 31 39  tval *= 16777619
37a0: 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d 62  ; /* FNV-1a 32-b
37b0: 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23 65 6c 73  it prime */.#els
37c0: 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70 74 69 6d  e.../* GCC Optim
37d0: 69 7a 65 64 20 72 65 70 6c 61 63 65 6d 65 6e 74  ized replacement
37e0: 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20   */...retval += 
37f0: 28 72 65 74 76 61 6c 20 3c 3c 20 31 29 20 2b 20  (retval << 1) + 
3800: 28 72 65 74 76 61 6c 20 3c 3c 20 34 29 20 2b 20  (retval << 4) + 
3810: 28 72 65 74 76 61 6c 20 3c 3c 20 37 29 20 2b 20  (retval << 7) + 
3820: 28 72 65 74 76 61 6c 20 3c 3c 20 38 29 20 2b 20  (retval << 8) + 
3830: 28 72 65 74 76 61 6c 20 3c 3c 20 32 34 29 3b 0a  (retval << 24);.
3840: 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 72 65 74 75  #endif..}...retu
3850: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f  rn(retval);.}../
3860: 2a 0a 20 2a 20 43 61 63 68 65 20 47 65 74 20 50  *. * Cache Get P
3870: 61 74 68 20 49 6e 66 6f 20 6c 6f 6f 6b 75 70 73  ath Info lookups
3880: 20 66 6f 72 20 73 70 65 65 64 0a 20 2a 2f 0a 73   for speed. */.s
3890: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
38a0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
38b0: 63 68 65 5f 67 65 74 28 63 6f 6e 73 74 20 63 68  che_get(const ch
38c0: 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20  ar *path, uid_t 
38d0: 75 69 64 2c 20 73 74 72 75 63 74 20 61 70 70 66  uid, struct appf
38e0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68  s_pathinfo *path
38f0: 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65  info) {..unsigne
3900: 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a  d int hash_idx;.
3910: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
3920: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a  ;..int retval;..
3930: 09 72 65 74 76 61 6c 20 3d 20 31 3b 0a 0a 09 70  .retval = 1;...p
3940: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
3950: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
3960: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
3970: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
3980: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
3990: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
39a0: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
39b0: 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20   lock path_info 
39c0: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
39d0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a  ....return(-1);.
39e0: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
39f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
3a00: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68  = NULL) {...hash
3a10: 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65  _idx = (appfs_ge
3a20: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
3a30: 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 70 66  h) + uid) % appf
3a40: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3a50: 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61  e_size;....if (a
3a60: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3a70: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
3a80: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
3a90: 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 74 72  LL) {....if (str
3aa0: 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68 5f 69  cmp(appfs_path_i
3ab0: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3ac0: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 2c  dx]._cache_path,
3ad0: 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26 20 61   path) == 0 && a
3ae0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3af0: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
3b00: 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 69 64  cache_uid == uid
3b10: 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c 20 3d  ) {.....retval =
3b20: 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79 28   0;......memcpy(
3b30: 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 66 73  pathinfo, &appfs
3b40: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3b50: 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a 65  [hash_idx], size
3b60: 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a  of(*pathinfo));.
3b70: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f 63  ....pathinfo->_c
3b80: 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c  ache_path = NULL
3b90: 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09  ;....}...}..}...
3ba0: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
3bb0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
3bc0: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
3bd0: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
3be0: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
3bf0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
3c00: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
3c10: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
3c20: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
3c30: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28   !");....return(
3c40: 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65  -1);..}...if (re
3c50: 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 41  tval == 0) {...A
3c60: 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68  PPFS_DEBUG("Cach
3c70: 65 20 68 69 74 20 6f 6e 20 25 73 22 2c 20 70 61  e hit on %s", pa
3c80: 74 68 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  th);..} else {..
3c90: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
3ca0: 63 68 65 20 6d 69 73 73 20 6f 6e 20 25 73 22 2c  che miss on %s",
3cb0: 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 65 74   path);..}...ret
3cc0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
3cd0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
3ce0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
3cf0: 63 61 63 68 65 5f 61 64 64 28 63 6f 6e 73 74 20  cache_add(const 
3d00: 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f  char *path, uid_
3d10: 74 20 75 69 64 2c 20 73 74 72 75 63 74 20 61 70  t uid, struct ap
3d20: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61  pfs_pathinfo *pa
3d30: 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67  thinfo) {..unsig
3d40: 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78  ned int hash_idx
3d50: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
3d60: 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  et;...pthread_re
3d70: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3d80: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
3d90: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
3da0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
3db0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
3dc0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
3dd0: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
3de0: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
3df0: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
3e00: 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66  n;..}...if (appf
3e10: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3e20: 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61  e == NULL) {...a
3e30: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3e40: 61 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28 61 70  ache = calloc(ap
3e50: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3e60: 63 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65 6f 66  che_size, sizeof
3e70: 28 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (*appfs_path_inf
3e80: 6f 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a 0a 09  o_cache));..}...
3e90: 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66  hash_idx = (appf
3ea0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65  s_get_path_inode
3eb0: 28 70 61 74 68 29 20 2b 20 75 69 64 29 20 25 20  (path) + uid) % 
3ec0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3ed0: 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 69 66  cache_size;...if
3ee0: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
3ef0: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3f00: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d  ]._cache_path !=
3f10: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72 65 65 28   NULL) {...free(
3f20: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3f30: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
3f40: 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 09 7d  _cache_path);..}
3f50: 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70 70 66 73  ...memcpy(&appfs
3f60: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3f70: 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70 61 74 68  [hash_idx], path
3f80: 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28 2a 70 61  info, sizeof(*pa
3f90: 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61 70 70 66  thinfo));...appf
3fa0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3fb0: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
3fc0: 68 65 5f 70 61 74 68 20 3d 20 73 74 72 64 75 70  he_path = strdup
3fd0: 28 70 61 74 68 29 3b 0a 09 61 70 70 66 73 5f 70  (path);..appfs_p
3fe0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
3ff0: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4000: 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a 09 70 74  uid  = uid;...pt
4010: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
4020: 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ead_mutex_unlock
4030: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
4040: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
4050: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
4060: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
4070: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
4080: 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e  o unlock path_in
4090: 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21  fo cache mutex !
40a0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09  ");....return;..
40b0: 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73  }...return;.}..s
40c0: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
40d0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
40e0: 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74 20 63 68  ache_rm(const ch
40f0: 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20  ar *path, uid_t 
4100: 75 69 64 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64  uid) {..unsigned
4110: 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09   int hash_idx;..
4120: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
4130: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
4140: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
4150: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
4160: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
4170: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
4180: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
4190: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
41a0: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
41b0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
41c0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
41d0: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
41e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
41f0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68  = NULL) {...hash
4200: 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65  _idx = (appfs_ge
4210: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
4220: 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 70 66  h) + uid) % appf
4230: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4240: 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61  e_size;....if (a
4250: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4260: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
4270: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
4280: 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28 61 70  LL) {....free(ap
4290: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
42a0: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
42b0: 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09  ache_path);.....
42c0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
42d0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
42e0: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
42f0: 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68  LL;...}..}...pth
4300: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
4310: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
4320: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
4330: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
4340: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
4350: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
4360: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
4370: 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66   unlock path_inf
4380: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4390: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
43a0: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74  ...return;.}..st
43b0: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
43c0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
43d0: 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f 74 20  che_flush(uid_t 
43e0: 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73 69 7a  uid, int new_siz
43f0: 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  e) {..unsigned i
4400: 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  nt idx;..int pth
4410: 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  read_ret;...APPF
4420: 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68 69 6e  S_DEBUG("Flushin
4430: 67 20 41 70 70 46 53 20 63 61 63 68 65 20 28 75  g AppFS cache (u
4440: 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77 5f 73  id = %lli, new_s
4450: 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c 6f 6e  ize = %i)", (lon
4460: 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e 65 77  g long) uid, new
4470: 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72 65 61  _size);...pthrea
4480: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
4490: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
44a0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
44b0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
44c0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
44d0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
44e0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
44f0: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
4500: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
4510: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
4520: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4530: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
4540: 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b  ...for (idx = 0;
4550: 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70 61 74   idx < appfs_pat
4560: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
4570: 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 09 69  e; idx++) {....i
4580: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
4590: 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63  fo_cache[idx]._c
45a0: 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c  ache_path != NUL
45b0: 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75 69 64  L) {.....if (uid
45c0: 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29   != ((uid_t) -1)
45d0: 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61 70 70  ) {......if (app
45e0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
45f0: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75  he[idx]._cache_u
4600: 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09 09 09  id != uid) {....
4610: 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 09  ...continue;....
4620: 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66  ..}.....}......f
4630: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
4640: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
4650: 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09  cache_path);....
4660: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
4670: 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61  o_cache[idx]._ca
4680: 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b  che_path = NULL;
4690: 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 69  ....}...}..}...i
46a0: 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69 64 5f  f (uid == ((uid_
46b0: 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72 65 65  t) -1)) {...free
46c0: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
46d0: 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70 70 66  _cache);....appf
46e0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
46f0: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69 66 20  e = NULL;....if 
4700: 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d 31 29  (new_size != -1)
4710: 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68   {....appfs_path
4720: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
4730: 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09 09 7d   = new_size;...}
4740: 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  ..}...pthread_re
4750: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
4760: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
4770: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4780: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
4790: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
47a0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
47b0: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
47c0: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
47d0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
47e0: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75  eturn;..}...retu
47f0: 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e  rn;.}../* Get in
4800: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
4810: 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70 74 69  a path, and opti
4820: 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68 69 6c  onally list chil
4830: 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69  dren */.static i
4840: 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  nt appfs_get_pat
4850: 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63 68 61  h_info(const cha
4860: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
4870: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
4880: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54 63 6c  pathinfo) {..Tcl
4890: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
48a0: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 73  ..Tcl_Obj *attrs
48b0: 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76 61 6c  _dict, *attr_val
48c0: 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  ue;..const char 
48d0: 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 3b  *attr_value_str;
48e0: 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74  ..Tcl_WideInt at
48f0: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09  tr_value_wide;..
4900: 69 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  int attr_value_i
4910: 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  nt;..static __th
4920: 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74  read Tcl_Obj *at
4930: 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55  tr_key_type = NU
4940: 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65  LL, *attr_key_pe
4950: 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  rms = NULL, *att
4960: 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c  r_key_size = NUL
4970: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d  L, *attr_key_tim
4980: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
4990: 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c  key_source = NUL
49a0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69  L, *attr_key_chi
49b0: 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20  ldcount = NULL, 
49c0: 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  *attr_key_packag
49d0: 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20  ed = NULL;..int 
49e0: 63 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20  cache_ret;..int 
49f0: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  tcl_ret;..int re
4a00: 74 76 61 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75  tval;..uid_t fsu
4a10: 69 64 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30  id;...retval = 0
4a20: 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66  ;...fsuid = appf
4a30: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a  s_get_fsuid();..
4a40: 09 63 61 63 68 65 5f 72 65 74 20 3d 20 61 70 70  .cache_ret = app
4a50: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4a60: 5f 63 61 63 68 65 5f 67 65 74 28 70 61 74 68 2c  _cache_get(path,
4a70: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
4a80: 29 3b 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65  );..if (cache_re
4a90: 74 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28  t == 0) {...if (
4aa0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
4ab0: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
4ac0: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29  _DOES_NOT_EXIST)
4ad0: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
4ae0: 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f  G("Returning fro
4af0: 6d 20 63 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f  m cache: does no
4b00: 74 20 65 78 69 73 74 20 5c 22 25 73 5c 22 22 2c  t exist \"%s\"",
4b10: 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75   path);.....retu
4b20: 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d  rn(-ENOENT);...}
4b30: 0a 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
4b40: 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f  ->type == APPFS_
4b50: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
4b60: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
4b70: 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72  UG("Returning fr
4b80: 6f 6d 20 63 61 63 68 65 3a 20 69 6e 76 61 6c 69  om cache: invali
4b90: 64 20 6f 62 6a 65 63 74 20 5c 22 25 73 5c 22 22  d object \"%s\""
4ba0: 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74  , path);.....ret
4bb0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a  urn(-EIO);...}..
4bc0: 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a  ..return(0);..}.
4bd0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
4be0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
4bf0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
4c00: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
4c10: 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c  UG("error: Unabl
4c20: 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65  e to get an inte
4c30: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
4c40: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
4c50: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
4c60: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
4c70: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
4c80: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
4c90: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
4ca0: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74  "::appfs::getatt
4cb0: 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  r", path);..if (
4cc0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
4cd0: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
4ce0: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  UG("::appfs::get
4cf0: 61 74 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e  attr(%s) failed.
4d00: 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66  ", path);...appf
4d10: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
4d20: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
4d30: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
4d40: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
4d50: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
4d60: 09 09 29 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d  ..)....pathinfo-
4d70: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
4d80: 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f  THTYPE_DOES_NOT_
4d90: 45 58 49 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f  EXIST;....appfs_
4da0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
4db0: 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73  che_add(path, fs
4dc0: 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a  uid, pathinfo);.
4dd0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
4de0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
4df0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
4e00: 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09  turn(-ENOENT);..
4e10: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b 65 79  }...if (attr_key
4e20: 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _type == NULL) {
4e30: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
4e40: 62 74 63 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65  btcl(....attr_ke
4e50: 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d 20 54  y_type       = T
4e60: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
4e70: 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09  "type", -1);....
4e80: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20  attr_key_perms  
4e90: 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72      = Tcl_NewStr
4ea0: 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20  ingObj("perms", 
4eb0: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79  -1);....attr_key
4ec0: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63  _size       = Tc
4ed0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4ee0: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61  size", -1);....a
4ef0: 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20  ttr_key_time    
4f00: 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69     = Tcl_NewStri
4f10: 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31  ngObj("time", -1
4f20: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73  );....attr_key_s
4f30: 6f 75 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f  ource     = Tcl_
4f40: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f  NewStringObj("so
4f50: 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61  urce", -1);....a
4f60: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
4f70: 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  nt = Tcl_NewStri
4f80: 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e  ngObj("childcoun
4f90: 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  t", -1);....attr
4fa0: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 20 20  _key_packaged   
4fb0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
4fc0: 62 6a 28 22 70 61 63 6b 61 67 65 64 22 2c 20 2d  bj("packaged", -
4fd0: 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72  1);.....Tcl_Incr
4fe0: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
4ff0: 79 5f 74 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f  y_type);....Tcl_
5000: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74  IncrRefCount(att
5010: 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09  r_key_perms);...
5020: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
5030: 74 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29  t(attr_key_size)
5040: 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
5050: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74  Count(attr_key_t
5060: 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  ime);....Tcl_Inc
5070: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
5080: 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09 09 54  ey_source);....T
5090: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
50a0: 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f  attr_key_childco
50b0: 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  unt);....Tcl_Inc
50c0: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
50d0: 65 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a 09 09  ey_packaged);...
50e0: 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  )..}...appfs_cal
50f0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72  l_libtcl(...attr
5100: 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47 65 74  s_dict = Tcl_Get
5110: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
5120: 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  );...tcl_ret = T
5130: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5140: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5150: 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c  , attr_key_type,
5160: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
5170: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
5180: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
5190: 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74  PFS_DEBUG("[dict
51a0: 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66   get \"type\"] f
51b0: 61 69 6c 65 64 22 29 3b 0a 09 09 61 70 70 66 73  ailed");...appfs
51c0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
51d0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
51e0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
51f0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
5200: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
5210: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
5220: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
5230: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
5240: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
5250: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c  }...if (attr_val
5260: 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue == NULL) {...
5270: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
5280: 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65  or: Unable to ge
5290: 74 20 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c  t type for \"%s\
52a0: 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74  " from Tcl", pat
52b0: 68 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  h);....appfs_cal
52c0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
52d0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
52e0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
52f0: 09 7d 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70  .}...pathinfo->p
5300: 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61  ackaged = 0;..pa
5310: 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20  thinfo->inode = 
5320: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
5330: 6e 6f 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 70  node(path);...ap
5340: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5350: 0a 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  ...attr_value_st
5360: 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  r = Tcl_GetStrin
5370: 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a  g(attr_value);..
5380: 09 09 73 77 69 74 63 68 20 28 61 74 74 72 5f 76  ..switch (attr_v
5390: 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09  alue_str[0]) {..
53a0: 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64  ..case 'd': /* d
53b0: 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09  irectory */.....
53c0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
53d0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
53e0: 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 09 70  DIRECTORY;.....p
53f0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5400: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74  o.dir.childcount
5410: 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44   = 0;......Tcl_D
5420: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5430: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5440: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
5450: 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  t, &attr_value);
5460: 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61  .....if (attr_va
5470: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
5480: 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  ....tcl_ret = Tc
5490: 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d  l_GetWideIntFrom
54a0: 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76  Obj(NULL, attr_v
54b0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
54c0: 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66  e_wide);......if
54d0: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
54e0: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74  _OK) {.......pat
54f0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5500: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
5510: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
5520: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
5530: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
5540: 73 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20  se 'f': /* file 
5550: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
5560: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
5570: 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09  THTYPE_FILE;....
5580: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5590: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20  nfo.file.size = 
55a0: 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  0;.....pathinfo-
55b0: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65  >typeinfo.file.e
55c0: 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a 0a  xecutable = 0;..
55d0: 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
55e0: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
55f0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
5600: 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  size, &attr_valu
5610: 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72  e);.....if (attr
5620: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
5630: 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20 3d  {......tcl_ret =
5640: 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46   Tcl_GetWideIntF
5650: 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74  romObj(NULL, att
5660: 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76  r_value, &attr_v
5670: 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09  alue_wide);.....
5680: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20  .if (tcl_ret == 
5690: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09  TCL_OK) {.......
56a0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
56b0: 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 61  fo.file.size = a
56c0: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a  ttr_value_wide;.
56d0: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09  .....}.....}....
56e0: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
56f0: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
5700: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65  ict, attr_key_pe
5710: 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rms, &attr_value
5720: 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f  );.....if (attr_
5730: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
5740: 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65  ......attr_value
5750: 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74  _str = Tcl_GetSt
5760: 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29  ring(attr_value)
5770: 3b 0a 09 09 09 09 09 69 66 20 28 61 74 74 72 5f  ;......if (attr_
5780: 76 61 6c 75 65 5f 73 74 72 5b 30 5d 20 3d 3d 20  value_str[0] == 
5790: 27 78 27 29 20 7b 0a 09 09 09 09 09 09 70 61 74  'x') {.......pat
57a0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
57b0: 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 20  file.executable 
57c0: 3d 20 31 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09  = 1;......}.....
57d0: 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  }.....break;....
57e0: 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73 79 6d  case 's': /* sym
57f0: 6c 69 6e 6b 20 2a 2f 0a 09 09 09 09 70 61 74 68  link */.....path
5800: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
5810: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
5820: 49 4e 4b 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  INK;.....pathinf
5830: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
5840: 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09  ink.size = 0;...
5850: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5860: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
5870: 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a  rce[0] = '\0';..
5880: 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
5890: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
58a0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
58b0: 73 6f 75 72 63 65 2c 20 26 61 74 74 72 5f 76 61  source, &attr_va
58c0: 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74  lue);.....if (at
58d0: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
58e0: 29 20 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61  ) {......attr_va
58f0: 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65  lue_str = Tcl_Ge
5900: 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61  tStringFromObj(a
5910: 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72  ttr_value, &attr
5920: 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a 0a 09  _value_int); ...
5930: 09 09 09 09 69 66 20 28 28 61 74 74 72 5f 76 61  ....if ((attr_va
5940: 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d 20  lue_int + 1) <= 
5950: 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f 2d  sizeof(pathinfo-
5960: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  >typeinfo.symlin
5970: 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 09 09  k.source)) {....
5980: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5990: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69  einfo.symlink.si
59a0: 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f  ze = attr_value_
59b0: 69 6e 74 3b 0a 09 09 09 09 09 09 70 61 74 68 69  int;.......pathi
59c0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
59d0: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74  mlink.source[att
59e0: 72 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27  r_value_int] = '
59f0: 5c 30 27 3b 0a 0a 09 09 09 09 09 09 6d 65 6d 63  \0';........memc
5a00: 70 79 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  py(pathinfo->typ
5a10: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
5a20: 75 72 63 65 2c 20 61 74 74 72 5f 76 61 6c 75 65  urce, attr_value
5a30: 5f 73 74 72 2c 20 61 74 74 72 5f 76 61 6c 75 65  _str, attr_value
5a40: 5f 69 6e 74 29 3b 0a 09 09 09 09 09 7d 0a 09 09  _int);......}...
5a50: 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09  ..}.....break;..
5a60: 09 09 63 61 73 65 20 27 46 27 3a 20 2f 2a 20 70  ..case 'F': /* p
5a70: 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09 09 09 09  ipe/fifo */.....
5a80: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
5a90: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
5aa0: 46 49 46 4f 3b 0a 09 09 09 09 62 72 65 61 6b 3b  FIFO;.....break;
5ab0: 0a 09 09 09 63 61 73 65 20 27 53 27 3a 20 2f 2a  ....case 'S': /*
5ac0: 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73 6f 63   UNIX domain soc
5ad0: 6b 65 74 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ket */.....pathi
5ae0: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
5af0: 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45  S_PATHTYPE_SOCKE
5b00: 54 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  T;.....break;...
5b10: 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 72 65  .default:.....re
5b20: 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 09 09 7d  tval = -EIO;...}
5b30: 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
5b40: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
5b50: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
5b60: 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74 72 5f  packaged, &attr_
5b70: 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74  value);...if (at
5b80: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
5b90: 29 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d  ) {....pathinfo-
5ba0: 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 09  >packaged = 1;..
5bb0: 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62  .}....Tcl_DictOb
5bc0: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5bd0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5be0: 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f 76 61  y_time, &attr_va
5bf0: 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74 74 72  lue);...if (attr
5c00: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
5c10: 7b 0a 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  {....tcl_ret = T
5c20: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
5c30: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
5c40: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
5c50: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 69 66 20  ue_wide);....if 
5c60: 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f  (tcl_ret == TCL_
5c70: 4f 4b 29 20 7b 0a 09 09 09 09 70 61 74 68 69 6e  OK) {.....pathin
5c80: 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 72 5f  fo->time = attr_
5c90: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 7d  value_wide;....}
5ca0: 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 70  ...} else {....p
5cb0: 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20  athinfo->time = 
5cc0: 30 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65  0;...}....Tcl_Re
5cd0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 09  lease(interp);..
5ce0: 29 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20 3d  )...if (retval =
5cf0: 3d 20 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 67  = 0) {...appfs_g
5d00: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
5d10: 68 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75  he_add(path, fsu
5d20: 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09  id, pathinfo);..
5d30: 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53  } else {...APPFS
5d40: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 49  _DEBUG("error: I
5d50: 6e 76 61 6c 69 64 20 74 79 70 65 20 66 6f 72 20  nvalid type for 
5d60: 5c 22 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22  \"%s\" from Tcl"
5d70: 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 65  , path);..}...re
5d80: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
5d90: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70  .static char *ap
5da0: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
5db0: 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72  reate(const char
5dc0: 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49   *path) {..Tcl_I
5dd0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
5de0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c  const char *real
5df0: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f  _path;..int tcl_
5e00: 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  ret;...appfs_get
5e10: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
5e20: 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74  _flush(appfs_get
5e30: 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a  _fsuid(), -1);..
5e40: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
5e50: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
5e60: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
5e70: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ) {...return(NUL
5e80: 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  L);..}...appfs_c
5e90: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50  all_libtcl(Tcl_P
5ea0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
5eb0: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
5ec0: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
5ed0: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
5ee0: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
5ef0: 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74  appfs::prepare_t
5f00: 6f 5f 63 72 65 61 74 65 22 2c 20 70 61 74 68 29  o_create", path)
5f10: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
5f20: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
5f30: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
5f40: 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74  appfs::prepare_t
5f50: 6f 5f 63 72 65 61 74 65 28 25 73 29 20 66 61 69  o_create(%s) fai
5f60: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
5f70: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5f80: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
5f90: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
5fa0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
5fb0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
5fc0: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
5fd0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
5fe0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
5ff0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ;)....return(NUL
6000: 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  L);..}...appfs_c
6010: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65  all_libtcl(...re
6020: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
6030: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
6040: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66  terp);..)...appf
6050: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
6060: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
6070: 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70  );)...if (real_p
6080: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
6090: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
60a0: 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75  }...return(strdu
60b0: 70 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d  p(real_path));.}
60c0: 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61  ..static char *a
60d0: 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63  ppfs_localpath(c
60e0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29  onst char *path)
60f0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
6100: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
6110: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
6120: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
6130: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
6140: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
6150: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
6160: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
6170: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
6180: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72  ll_libtcl(Tcl_Pr
6190: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29  eserve(interp);)
61a0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
61b0: 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20  btcl(...tcl_ret 
61c0: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
61d0: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
61e0: 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 22  ppfs::localpath"
61f0: 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20  , path);..)..if 
6200: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
6210: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
6220: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f  BUG("::appfs::lo
6230: 63 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c  calpath(%s) fail
6240: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
6250: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6260: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
6270: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
6280: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
6290: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
62a0: 29 3b 0a 09 09 29 0a 0a 09 09 72 65 74 75 72 6e  );...)....return
62b0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
62c0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
62d0: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
62e0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
62f0: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  t(interp);..)...
6300: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6310: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
6320: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65  terp);)...if (re
6330: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
6340: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
6350: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73  );..}...return(s
6360: 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29  trdup(real_path)
6370: 29 3b 0a 7d 0a 0a 23 69 66 20 28 64 65 66 69 6e  );.}..#if (defin
6380: 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65 66  ed(DEBUG) && def
6390: 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f  ined(APPFS_EXIT_
63a0: 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65  PATH)) || define
63b0: 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54  d(APPFS_EXIT_PAT
63c0: 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53  H_ENABLE_MAJOR_S
63d0: 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73 74  ECURITY_HOLE).st
63e0: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
63f0: 65 78 69 74 28 76 6f 69 64 29 20 7b 0a 09 69 6e  exit(void) {..in
6400: 74 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  t global_interp_
6410: 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f  reset_key;...glo
6420: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
6430: 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65  _key = __sync_fe
6440: 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74  tch_and_add(&int
6450: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30  erp_reset_key, 0
6460: 29 3b 0a 09 5f 5f 73 79 6e 63 5f 66 65 74 63 68  );..__sync_fetch
6470: 5f 61 6e 64 5f 73 75 62 28 26 69 6e 74 65 72 70  _and_sub(&interp
6480: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 67 6c 6f 62  _reset_key, glob
6490: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
64a0: 6b 65 79 29 3b 0a 0a 09 77 68 69 6c 65 20 28 5f  key);...while (_
64b0: 5f 73 79 6e 63 5f 73 75 62 5f 61 6e 64 5f 66 65  _sync_sub_and_fe
64c0: 74 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73 65  tch(&interp_rese
64d0: 74 5f 6b 65 79 2c 20 31 29 20 3e 3d 20 30 29 20  t_key, 1) >= 0) 
64e0: 7b 0a 09 09 2f 2a 20 42 75 73 79 20 4c 6f 6f 70  {.../* Busy Loop
64f0: 20 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f 62 61 6c 5f   */..}...global_
6500: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6510: 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f   = __sync_fetch_
6520: 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f  and_add(&interp_
6530: 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09  reset_key, 0);..
6540: 69 66 20 28 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  if (global_inter
6550: 70 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 2d  p_reset_key != -
6560: 31 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  1) {...APPFS_DEB
6570: 55 47 28 22 45 72 72 6f 72 20 73 65 6e 64 69 6e  UG("Error sendin
6580: 67 20 6b 69 6c 6c 20 73 69 67 6e 61 6c 20 74 6f  g kill signal to
6590: 20 61 6c 6c 20 74 68 72 65 61 64 73 2c 20 61 62   all threads, ab
65a0: 6f 72 74 69 6e 67 20 61 6e 79 77 61 79 2e 22 29  orting anyway.")
65b0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74  ;..}...appfs_get
65c0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
65d0: 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a  _flush(-1, -1);.
65e0: 0a 09 66 75 73 65 5f 65 78 69 74 28 66 75 73 65  ..fuse_exit(fuse
65f0: 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 2d 3e  _get_context()->
6600: 66 75 73 65 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  fuse);...return;
6610: 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74 69  .}.#endif..stati
6620: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
6630: 5f 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20  _readlink(const 
6640: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72  char *path, char
6650: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
6660: 7a 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  ze) {..struct ap
6670: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
6680: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76  hinfo;..int retv
6690: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
66a0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
66b0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
66c0: 70 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66  path);...pathinf
66d0: 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  o.type = APPFS_P
66e0: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b  ATHTYPE_INVALID;
66f0: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66  ...retval = appf
6700: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
6710: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
6720: 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d  ;..if (retval !=
6730: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72   0) {...return(r
6740: 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20  etval);..}...if 
6750: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21  (pathinfo.type !
6760: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
6770: 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65  _SYMLINK) {...re
6780: 74 75 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09  turn(-EINVAL);..
6790: 7d 0a 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28  }...if ((strlen(
67a0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
67b0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
67c0: 29 20 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b  ) + 1) > size) {
67d0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45  ...return(-ENAME
67e0: 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d  TOOLONG);..}...m
67f0: 65 6d 63 70 79 28 62 75 66 2c 20 70 61 74 68 69  emcpy(buf, pathi
6800: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
6810: 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72  link.source, str
6820: 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  len(pathinfo.typ
6830: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
6840: 75 72 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65  urce) + 1);...re
6850: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
6860: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
6870: 65 5f 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20  e_getattr(const 
6880: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
6890: 63 74 20 73 74 61 74 20 2a 73 74 62 75 66 29 20  ct stat *stbuf) 
68a0: 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  {..struct appfs_
68b0: 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66  pathinfo pathinf
68c0: 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  o;..int retval;.
68d0: 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  ..retval = 0;...
68e0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
68f0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
6900: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69  ..)", path);..#i
6910: 66 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47  f (defined(DEBUG
6920: 29 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50  ) && defined(APP
6930: 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c  FS_EXIT_PATH)) |
6940: 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  | defined(APPFS_
6950: 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXIT_PATH_ENABLE
6960: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
6970: 48 4f 4c 45 29 0a 09 2f 2a 0a 09 20 2a 20 54 68  HOLE)../*.. * Th
6980: 69 73 20 69 73 20 61 20 6d 61 6a 6f 72 20 73 65  is is a major se
6990: 63 75 72 69 74 79 20 69 73 73 75 65 20 73 6f 20  curity issue so 
69a0: 77 65 20 63 61 6e 6e 6f 74 20 6c 65 74 20 69 74  we cannot let it
69b0: 20 62 65 20 63 6f 6d 70 69 6c 65 64 20 69 6e 74   be compiled int
69c0: 6f 0a 09 20 2a 20 61 6e 79 20 72 65 6c 65 61 73  o.. * any releas
69d0: 65 0a 09 20 2a 2f 0a 0a 09 69 66 20 28 73 74 72  e.. */...if (str
69e0: 63 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 69 74  cmp(path, "/exit
69f0: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70  ") == 0) {...app
6a00: 66 73 5f 65 78 69 74 28 29 3b 0a 09 7d 0a 23 65  fs_exit();..}.#e
6a10: 6e 64 69 66 0a 0a 09 70 61 74 68 69 6e 66 6f 2e  ndif...pathinfo.
6a20: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
6a30: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
6a40: 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f  .retval = appfs_
6a50: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61  get_path_info(pa
6a60: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a  th, &pathinfo);.
6a70: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30  .if (retval != 0
6a80: 29 20 7b 0a 09 09 69 66 20 28 72 65 74 76 61 6c  ) {...if (retval
6a90: 20 3d 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09   == -ENOENT) {..
6aa0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
6ab0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 72 65 74  et_path_info ret
6ac0: 75 72 6e 65 64 20 45 4e 4f 45 4e 54 2c 20 72 65  urned ENOENT, re
6ad0: 74 75 72 6e 69 6e 67 20 69 74 20 61 73 20 77 65  turning it as we
6ae0: 6c 6c 2e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20  ll.");...} else 
6af0: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
6b00: 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74  ("error: get_pat
6b10: 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b  h_info failed");
6b20: 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 72  ...}....return(r
6b30: 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  etval);..}...mem
6b40: 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69  set(stbuf, 0, si
6b50: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74  zeof(struct stat
6b60: 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ));...stbuf->st_
6b70: 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f  mtime = pathinfo
6b80: 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73  .time;..stbuf->s
6b90: 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e  t_ctime = pathin
6ba0: 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d  fo.time;..stbuf-
6bb0: 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68  >st_atime = path
6bc0: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75  info.time;..stbu
6bd0: 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61  f->st_ino   = pa
6be0: 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73  thinfo.inode;..s
6bf0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d  tbuf->st_mode  =
6c00: 20 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70 61   0;...switch (pa
6c10: 74 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a 09  thinfo.type) {..
6c20: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
6c30: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a 0a  TYPE_DIRECTORY:.
6c40: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
6c50: 65 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30 35  e = S_IFDIR | 05
6c60: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
6c70: 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61 74  _nlink = 2 + pat
6c80: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 64  hinfo.typeinfo.d
6c90: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09  ir.childcount;..
6ca0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
6cb0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
6cc0: 49 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74 68  ILE:....if (path
6cd0: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69  info.typeinfo.fi
6ce0: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b  le.executable) {
6cf0: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
6d00: 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20  ode = S_IFREG | 
6d10: 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65 20  0555;....} else 
6d20: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
6d30: 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c  mode = S_IFREG |
6d40: 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09 09   0444;....}.....
6d50: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
6d60: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
6d70: 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66  t_size = pathinf
6d80: 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  o.typeinfo.file.
6d90: 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  size;....break;.
6da0: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
6db0: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09  HTYPE_SYMLINK:..
6dc0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
6dd0: 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35   = S_IFLNK | 055
6de0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
6df0: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
6e00: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
6e10: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
6e20: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09  .symlink.size;..
6e30: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
6e40: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
6e50: 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d  OCKET:....stbuf-
6e60: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53  >st_mode = S_IFS
6e70: 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  OCK | 0555;....s
6e80: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
6e90: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
6ea0: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
6eb0: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
6ec0: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a  S_PATHTYPE_FIFO:
6ed0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
6ee0: 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30  de = S_IFIFO | 0
6ef0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
6f00: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
6f10: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
6f20: 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09   0;....break;...
6f30: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
6f40: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
6f50: 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ST:....retval = 
6f60: 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65  -ENOENT;.....bre
6f70: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
6f80: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
6f90: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
6fa0: 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  EIO;.....break;.
6fb0: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
6fc0: 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09  o.packaged) {...
6fd0: 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20  stbuf->st_uid   
6fe0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
6ff0: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
7000: 5f 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67  _gid   = appfs_g
7010: 65 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74  et_fsgid();...st
7020: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20  buf->st_mode |= 
7030: 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  0200;..}...retur
7040: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
7050: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
7060: 75 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73  use_readdir(cons
7070: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f  t char *path, vo
7080: 69 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69  id *buf, fuse_fi
7090: 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c  ll_dir_t filler,
70a0: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
70b0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
70c0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
70d0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
70e0: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c  ..Tcl_Obj **chil
70f0: 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64  dren;..int child
7100: 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a  ren_count, idx;.
7110: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
7120: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
7130: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
7140: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
7150: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
7160: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
7170: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
7180: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
7190: 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74  "error: Unable t
71a0: 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72  o get an interpr
71b0: 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72  eter");....retur
71c0: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  n(0);..}...appfs
71d0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
71e0: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
71f0: 29 3b 29 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66  );)...filler(buf
7200: 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b  , ".", NULL, 0);
7210: 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e  ..filler(buf, ".
7220: 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09  .", NULL, 0);...
7230: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
7240: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
7250: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65   2, "::appfs::ge
7260: 74 63 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68  tchildren", path
7270: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
7280: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
7290: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
72a0: 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e  pfs::getchildren
72b0: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
72c0: 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  ath);...appfs_ca
72d0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
72e0: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
72f0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
7300: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
7310: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
7320: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
7330: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
7340: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
7350: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70  turn(0);..}...ap
7360: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7370: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
7380: 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65  _ListObjGetEleme
7390: 6e 74 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  nts(interp, Tcl_
73a0: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
73b0: 65 72 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f  erp), &children_
73c0: 63 6f 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e  count, &children
73d0: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
73e0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
73f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50  ..APPFS_DEBUG("P
7400: 61 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20 63  arsing list of c
7410: 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68 20  hildren on path 
7420: 25 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  %s failed.", pat
7430: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
7440: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
7450: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
7460: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
7470: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
7480: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
7490: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
74a0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
74b0: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
74c0: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20  rn(0);..}...for 
74d0: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
74e0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20  children_count; 
74f0: 69 64 78 2b 2b 29 20 7b 0a 09 09 61 70 70 66 73  idx++) {...appfs
7500: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
7510: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c  .filler(buf, Tcl
7520: 5f 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64  _GetString(child
7530: 72 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c  ren[idx]), NULL,
7540: 20 30 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70   0);...)..}...ap
7550: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7560: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
7570: 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30  rp);)...return(0
7580: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
7590: 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e   appfs_fuse_open
75a0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
75b0: 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  h, struct fuse_f
75c0: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
75d0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
75e0: 65 72 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70  erp;..struct app
75f0: 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68  fs_pathinfo path
7600: 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61  info;..const cha
7610: 72 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d  r *real_path, *m
7620: 6f 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65  ode;..int gpi_re
7630: 74 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74  t, tcl_ret;..int
7640: 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42   fh;...APPFS_DEB
7650: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
7660: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
7670: 68 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20  h);...gpi_ret = 
7680: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7690: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
76a0: 6e 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d  nfo);...if ((fi-
76b0: 3e 66 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e  >flags & (O_WRON
76c0: 4c 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20  LY|O_CREAT)) == 
76d0: 28 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c  (O_CREAT|O_WRONL
76e0: 59 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66  Y)) {.../* The f
76f0: 69 6c 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61  ile will be crea
7700: 74 65 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e  ted if it does n
7710: 6f 74 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66  ot exist */...if
7720: 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26   (gpi_ret != 0 &
7730: 26 20 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e  & gpi_ret != -EN
7740: 4f 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53  OENT) {....APPFS
7750: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
7760: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
7770: 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  led");.....retur
7780: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a  n(gpi_ret);...}.
7790: 0a 09 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74  ...mode = "creat
77a0: 65 22 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57  e";..../*... * W
77b0: 65 20 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20  e have to clear 
77c0: 74 68 65 20 63 61 63 68 65 20 68 65 72 65 20 73  the cache here s
77d0: 6f 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65  o that the numbe
77e0: 72 20 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20  r of... * links 
77f0: 67 65 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20  gets maintained 
7800: 6f 6e 20 74 68 65 20 70 61 72 65 6e 74 20 64 69  on the parent di
7810: 72 65 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09  rectory... */...
7820: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7830: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
7840: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
7850: 29 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20  ), -1);..} else 
7860: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20  {.../* The file 
7870: 6d 75 73 74 20 61 6c 72 65 61 64 79 20 65 78 69  must already exi
7880: 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f  st */...if (gpi_
7890: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41  ret != 0) {....A
78a0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
78b0: 72 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  r: get_path_info
78c0: 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72   failed");.....r
78d0: 65 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a  eturn(gpi_ret);.
78e0: 09 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22  ..}....mode = ""
78f0: 3b 0a 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c  ;....if ((fi->fl
7900: 61 67 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20  ags & O_WRONLY) 
7910: 3d 3d 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09  == O_WRONLY) {..
7920: 09 09 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22  ..mode = "write"
7930: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70  ;...}..}...if (p
7940: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20  athinfo.type == 
7950: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
7960: 49 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 41 50  IRECTORY) {...AP
7970: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
7980: 3a 20 41 73 6b 65 64 20 74 6f 20 6f 70 65 6e 20  : Asked to open 
7990: 61 20 64 69 72 65 63 74 6f 72 79 2e 22 29 3b 0a  a directory.");.
79a0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44 49  ...return(-EISDI
79b0: 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20  R);..}...interp 
79c0: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
79d0: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
79e0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
79f0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
7a00: 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20  : Unable to get 
7a10: 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29  an interpreter")
7a20: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  ;....return(-EIO
7a30: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
7a40: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72  ll_libtcl(Tcl_Pr
7a50: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29  eserve(interp);)
7a60: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
7a70: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
7a80: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
7a90: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
7aa0: 2c 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63  , mode);..if (tc
7ab0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
7ac0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
7ad0: 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70  ("::appfs::openp
7ae0: 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c  ath(%s, %s) fail
7af0: 65 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65  ed.", path, mode
7b00: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
7b10: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
7b20: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
7b30: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
7b40: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
7b50: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
7b60: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
7b70: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
7b80: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
7b90: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
7ba0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7bb0: 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
7bc0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
7bd0: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a  lt(interp);..)..
7be0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7bf0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
7c00: 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72  nterp);)...if (r
7c10: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
7c20: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
7c30: 47 28 22 65 72 72 6f 72 3a 20 72 65 61 6c 5f 70  G("error: real_p
7c40: 61 74 68 20 77 61 73 20 4e 55 4c 4c 2e 22 29 0a  ath was NULL.").
7c50: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
7c60: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  ..}...APPFS_DEBU
7c70: 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65  G("Translated re
7c80: 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73  quest to open %s
7c90: 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28   to opening %s (
7ca0: 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c  mode = \"%s\")",
7cb0: 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68   path, real_path
7cc0: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20  , mode);...fh = 
7cd0: 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20  open(real_path, 
7ce0: 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29  fi->flags, 0600)
7cf0: 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20  ;...if (fh < 0) 
7d00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
7d10: 22 65 72 72 6f 72 3a 20 6f 70 65 6e 20 66 61 69  "error: open fai
7d20: 6c 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  led");....return
7d30: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
7d40: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a  ...fi->fh = fh;.
7d50: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7d60: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7d70: 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73  _fuse_close(cons
7d80: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
7d90: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
7da0: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20  nfo *fi) {..int 
7db0: 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70  close_ret;...app
7dc0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
7dd0: 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20  _cache_rm(path, 
7de0: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
7df0: 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20  ));...close_ret 
7e00: 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b  = close(fi->fh);
7e10: 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20  ..if (close_ret 
7e20: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
7e30: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 63 6c  DEBUG("error: cl
7e40: 6f 73 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09  ose failed");...
7e50: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
7e60: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
7e70: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
7e80: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
7e90: 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ad(const char *p
7ea0: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
7eb0: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
7ec0: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
7ed0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
7ee0: 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74   *fi) {..ssize_t
7ef0: 20 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20   read_ret;..int 
7f00: 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f  retval;...APPFS_
7f10: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
7f20: 74 68 20 3d 20 25 73 2c 20 62 75 66 2c 20 25 6c  th = %s, buf, %l
7f30: 6c 69 2c 20 25 6c 6c 69 2c 20 66 64 3d 25 6c 6c  li, %lli, fd=%ll
7f40: 69 29 22 2c 20 70 61 74 68 2c 20 28 6c 6f 6e 67  i)", path, (long
7f50: 20 6c 6f 6e 67 29 20 73 69 7a 65 2c 20 28 6c 6f   long) size, (lo
7f60: 6e 67 20 6c 6f 6e 67 29 20 6f 66 66 73 65 74 2c  ng long) offset,
7f70: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 2d   (long long) fi-
7f80: 3e 66 68 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  >fh);...retval =
7f90: 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a   0;...while (siz
7fa0: 65 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 61 64  e != 0) {...read
7fb0: 5f 72 65 74 20 3d 20 70 72 65 61 64 28 66 69 2d  _ret = pread(fi-
7fc0: 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20  >fh, buf, size, 
7fd0: 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28  offset);....if (
7fe0: 72 65 61 64 5f 72 65 74 20 3c 20 30 29 20 7b 0a  read_ret < 0) {.
7ff0: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8000: 65 72 72 6f 72 3a 20 72 65 61 64 20 66 61 69 6c  error: read fail
8010: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ed");.....return
8020: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09  (errno * -1);...
8030: 7d 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65  }....if (read_re
8040: 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62 72 65  t == 0) {....bre
8050: 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20  ak;...}....size 
8060: 2d 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 62  -= read_ret;...b
8070: 75 66 20 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b  uf  += read_ret;
8080: 0a 09 09 6f 66 66 73 65 74 20 2b 3d 20 72 65 61  ...offset += rea
8090: 64 5f 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20  d_ret;...retval 
80a0: 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 7d 0a  += read_ret;..}.
80b0: 0a 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29  ..if (size != 0)
80c0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
80d0: 28 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c  ("error: incompl
80e0: 65 74 65 20 72 65 61 64 20 28 74 68 69 73 20 6d  ete read (this m
80f0: 69 67 68 74 20 62 65 20 61 6e 20 65 72 72 6f 72  ight be an error
8100: 20 62 65 63 61 75 73 65 20 46 55 53 45 20 77 69   because FUSE wi
8110: 6c 6c 20 72 65 71 75 65 73 74 20 74 68 65 20 65  ll request the e
8120: 78 61 63 74 20 6c 65 6e 67 74 68 20 6f 66 20 74  xact length of t
8130: 68 65 20 66 69 6c 65 29 22 29 3b 0a 09 7d 0a 0a  he file)");..}..
8140: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65  .APPFS_DEBUG("Re
8150: 74 75 72 6e 69 6e 67 3a 20 25 69 22 2c 20 72 65  turning: %i", re
8160: 74 76 61 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28  tval);...return(
8170: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
8180: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8190: 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63 68  e_write(const ch
81a0: 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74 20  ar *path, const 
81b0: 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f  char *buf, size_
81c0: 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66  t size, off_t of
81d0: 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73  fset, struct fus
81e0: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
81f0: 20 7b 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74   {..ssize_t writ
8200: 65 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  e_ret;..int retv
8210: 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  al;...APPFS_DEBU
8220: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
8230: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
8240: 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  );...appfs_get_p
8250: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72  ath_info_cache_r
8260: 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65  m(path, appfs_ge
8270: 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 72 65  t_fsuid());...re
8280: 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c  tval = 0;...whil
8290: 65 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a  e (size != 0) {.
82a0: 09 09 77 72 69 74 65 5f 72 65 74 20 3d 20 70 77  ..write_ret = pw
82b0: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66  rite(fi->fh, buf
82c0: 2c 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b  , size, offset);
82d0: 0a 0a 09 09 69 66 20 28 77 72 69 74 65 5f 72 65  ....if (write_re
82e0: 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46  t < 0) {....APPF
82f0: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
8300: 77 72 69 74 65 20 66 61 69 6c 65 64 22 29 3b 0a  write failed");.
8310: 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
8320: 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69   * -1);...}....i
8330: 66 20 28 77 72 69 74 65 5f 72 65 74 20 3d 3d 20  f (write_ret == 
8340: 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  0) {....break;..
8350: 09 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 77 72  .}....size -= wr
8360: 69 74 65 5f 72 65 74 3b 0a 09 09 62 75 66 20 20  ite_ret;...buf  
8370: 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09  += write_ret;...
8380: 6f 66 66 73 65 74 20 2b 3d 20 77 72 69 74 65 5f  offset += write_
8390: 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d  ret;...retval +=
83a0: 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a   write_ret;..}..
83b0: 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20  .if (size != 0) 
83c0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
83d0: 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65  "error: incomple
83e0: 74 65 20 77 72 69 74 65 22 29 3b 0a 09 7d 0a 0a  te write");..}..
83f0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
8400: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
8410: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28  ppfs_fuse_mknod(
8420: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
8430: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64  , mode_t mode, d
8440: 65 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09  ev_t device) {..
8450: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
8460: 0a 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b  ..int mknod_ret;
8470: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8480: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
8490: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
84a0: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
84b0: 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48  IFCHR) == S_IFCH
84c0: 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  R) {...return(-E
84d0: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  PERM);..}...if (
84e0: 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29  (mode & S_IFBLK)
84f0: 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09   == S_IFBLK) {..
8500: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
8510: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
8520: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
8530: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
8540: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
8550: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
8560: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8570: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8580: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
8590: 0a 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b  ..mknod_ret = mk
85a0: 6e 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  nod(real_path, m
85b0: 6f 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09  ode, device);...
85c0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
85d0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
85e0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
85f0: 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72  );...if (mknod_r
8600: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
8610: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8620: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
8630: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
8640: 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65  ppfs_fuse_create
8650: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8660: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20  h, mode_t mode, 
8670: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
8680: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68  _info *fi) {..ch
8690: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
86a0: 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f  int fd;...APPFS_
86b0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
86c0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
86d0: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
86e0: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
86f0: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
8700: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
8710: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
8720: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
8730: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
8740: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
8750: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
8760: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
8770: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
8780: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
8790: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
87a0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
87b0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
87c0: 74 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72  ter();...fd = cr
87d0: 65 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  eat(real_path, m
87e0: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
87f0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
8800: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
8810: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
8820: 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74  (fd < 0) {...ret
8830: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8840: 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66  ..}...fi->fh = f
8850: 64 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  d;...return(0);.
8860: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
8870: 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74  pfs_fuse_truncat
8880: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
8890: 74 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20  th, off_t size) 
88a0: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
88b0: 74 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74  th;..int truncat
88c0: 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  e_ret;...APPFS_D
88d0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
88e0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
88f0: 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74  ath);...real_pat
8900: 68 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70  h = appfs_localp
8910: 61 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ath(path);..if (
8920: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
8930: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
8940: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
8950: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
8960: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
8970: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
8980: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
8990: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
89a0: 29 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65  );...truncate_re
89b0: 74 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61  t = truncate(rea
89c0: 6c 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a  l_path, size);..
89d0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
89e0: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
89f0: 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74  ...free(real_pat
8a00: 68 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61  h);...if (trunca
8a10: 74 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  te_ret != 0) {..
8a20: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
8a30: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
8a40: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
8a50: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e  nt appfs_fuse_un
8a60: 6c 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74  link_rmdir(const
8a70: 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09   char *path) {..
8a80: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
8a90: 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  rp;..int tcl_ret
8aa0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
8ab0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
8ac0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
8ad0: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
8ae0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
8af0: 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75  sh(appfs_get_fsu
8b00: 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74  id(), -1);...int
8b10: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
8b20: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
8b30: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
8b40: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
8b50: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
8b60: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
8b70: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
8b80: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
8b90: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
8ba0: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e   2, "::appfs::un
8bb0: 6c 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29  linkpath", path)
8bc0: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
8bd0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
8be0: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
8bf0: 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25  fs::unlinkpath(%
8c00: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
8c10: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
8c20: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
8c30: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
8c40: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
8c50: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
8c60: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
8c70: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8c80: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
8c90: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
8ca0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
8cb0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
8cc0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
8cd0: 65 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28  erp);)...return(
8ce0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
8cf0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64  t appfs_fuse_mkd
8d00: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
8d10: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
8d20: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
8d30: 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72  path;..int mkdir
8d40: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
8d50: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
8d60: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
8d70: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68  th);...real_path
8d80: 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65   = appfs_prepare
8d90: 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29  _to_create(path)
8da0: 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ;..if (real_path
8db0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
8dc0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
8dd0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
8de0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
8df0: 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d  ...mkdir_ret = m
8e00: 6b 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c 20  kdir(real_path, 
8e10: 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  mode);...appfs_s
8e20: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
8e30: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
8e40: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
8e50: 20 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20 30   (mkdir_ret != 0
8e60: 29 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f 20  ) {...if (errno 
8e70: 21 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09 09  != EEXIST) {....
8e80: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
8e90: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  1);...}..}...ret
8ea0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
8eb0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
8ec0: 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61  _chmod(const cha
8ed0: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
8ee0: 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  mode) {..Tcl_Int
8ef0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
8f00: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
8f10: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ath;..int tcl_re
8f20: 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09  t, chmod_ret;...
8f30: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
8f40: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
8f50: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
8f60: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
8f70: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
8f80: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
8f90: 64 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  d());...interp =
8fa0: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
8fb0: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
8fc0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
8fd0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8fe0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8ff0: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
9000: 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72  nterp);)...tcl_r
9010: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
9020: 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22  val(interp, 3, "
9030: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
9040: 68 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65  h", path, "write
9050: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
9060: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
9070: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
9080: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25  ppfs::openpath(%
9090: 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  s, %s) failed.",
90a0: 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b   path, "write");
90b0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
90c0: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
90d0: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
90e0: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
90f0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
9100: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70  erp));...)....ap
9110: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
9120: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
9130: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
9140: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9150: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
9160: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
9170: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
9180: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61  (interp);..)...a
9190: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
91a0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
91b0: 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61  erp);)...if (rea
91c0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
91d0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
91e0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
91f0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
9200: 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72  ter();...chmod_r
9210: 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f  et = chmod(real_
9220: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
9230: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
9240: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
9250: 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65  .return(chmod_re
9260: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
9270: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d  t appfs_fuse_sym
9280: 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20  link(const char 
9290: 2a 6f 6c 64 70 61 74 68 2c 20 63 6f 6e 73 74 20  *oldpath, const 
92a0: 63 68 61 72 20 2a 6e 65 77 70 61 74 68 29 20 7b  char *newpath) {
92b0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
92c0: 68 3b 0a 09 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f  h;..int symlink_
92d0: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
92e0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
92f0: 3d 20 25 73 2c 20 25 73 29 22 2c 20 6f 6c 64 70  = %s, %s)", oldp
9300: 61 74 68 2c 20 6e 65 77 70 61 74 68 29 3b 0a 0a  ath, newpath);..
9310: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70  .real_path = app
9320: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72  fs_prepare_to_cr
9330: 65 61 74 65 28 6e 65 77 70 61 74 68 29 3b 0a 09  eate(newpath);..
9340: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
9350: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
9360: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
9370: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
9380: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
9390: 73 79 6d 6c 69 6e 6b 5f 72 65 74 20 3d 20 73 79  symlink_ret = sy
93a0: 6d 6c 69 6e 6b 28 6f 6c 64 70 61 74 68 2c 20 72  mlink(oldpath, r
93b0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 61 70 70  eal_path);...app
93c0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
93d0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
93e0: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
93f0: 0a 09 69 66 20 28 73 79 6d 6c 69 6e 6b 5f 72 65  ..if (symlink_re
9400: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
9410: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
9420: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
9430: 7d 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33  }../*. * SQLite3
9440: 20 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72   mode: Execute r
9450: 61 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72  aw SQL and retur
9460: 6e 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69  n success or fai
9470: 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20  lure. */.static 
9480: 69 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65  int appfs_sqlite
9490: 33 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71  3(const char *sq
94a0: 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  l) {..Tcl_Interp
94b0: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
94c0: 20 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a   char *sql_ret;.
94d0: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
94e0: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63  interp = appfs_c
94f0: 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28  reate_TclInterp(
9500: 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65  NULL);..if (inte
9510: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
9520: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
9530: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
9540: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
9550: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ter.  Aborting.\
9560: 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  n");....return(1
9570: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
9580: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
9590: 28 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61  (interp, 5, "::a
95a0: 70 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c  ppfs::db", "eval
95b0: 22 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22  ", sql, "row", "
95c0: 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69  unset -nocomplai
95d0: 6e 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79  n row(*); parray
95e0: 20 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d   row; puts \"---
95f0: 2d 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20  -\"");..sql_ret 
9600: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
9610: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a  esult(interp);..
9620: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
9630: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
9640: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72  ntf(stderr, "[er
9650: 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f  ror] %s\n", sql_
9660: 72 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  ret);....return(
9670: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c  1);..}...if (sql
9680: 5f 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b  _ret && sql_ret[
9690: 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09  0] != '\0') {...
96a0: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73  printf("%s\n", s
96b0: 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65  ql_ret);..}...re
96c0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20  turn(0);.}../*. 
96d0: 2a 20 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63  * Tcl mode: Exec
96e0: 75 74 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20  ute raw Tcl and 
96f0: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
9700: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
9710: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74  atic int appfs_t
9720: 63 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74  cl(const char *t
9730: 63 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  cl) {..Tcl_Inter
9740: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73  p *interp;..cons
9750: 74 20 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75  t char *tcl_resu
9760: 6c 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  lt;..int tcl_ret
9770: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
9780: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
9790: 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28  erp(NULL);..if (
97a0: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
97b0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
97c0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
97d0: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
97e0: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69  rpreter.  Aborti
97f0: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75  ng.\n");....retu
9800: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  rn(1);..}...tcl_
9810: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
9820: 6e 74 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63  nterp, tcl);..tc
9830: 6c 5f 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47  l_result = Tcl_G
9840: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
9850: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63  nterp);...if (tc
9860: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
9870: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
9880: 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73  err, "[error] %s
9890: 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29  \n", tcl_result)
98a0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
98b0: 09 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73  .}...if (tcl_res
98c0: 75 6c 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c  ult && tcl_resul
98d0: 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a  t[0] != '\0') {.
98e0: 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c  ..printf("%s\n",
98f0: 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d   tcl_result);..}
9900: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
9910: 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61  ./*. * AppFSd Pa
9920: 63 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20  ckage for Tcl:. 
9930: 2a 20 20 20 20 20 20 20 20 20 42 72 69 64 67 65  *         Bridge
9940: 20 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69   for I/O operati
9950: 6f 6e 73 20 74 6f 20 72 65 71 75 65 73 74 20 69  ons to request i
9960: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74  nformation about
9970: 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20   the current. * 
9980: 20 20 20 20 20 20 20 20 74 72 61 6e 73 61 63 74          transact
9990: 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63  ion. */./*. * Tc
99a0: 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 67  l interface to g
99b0: 65 74 20 74 68 65 20 68 6f 6d 65 20 64 69 72 65  et the home dire
99c0: 63 74 6f 72 79 20 66 6f 72 20 74 68 65 20 75 73  ctory for the us
99d0: 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 22 63  er making the "c
99e0: 75 72 72 65 6e 74 22 0a 20 2a 20 46 55 53 45 20  urrent". * FUSE 
99f0: 49 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a  I/O request. */.
9a00: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
9a10: 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72  ppfs_get_homedir
9a20: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
9a30: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9a40: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
9a50: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
9a60: 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f  v[]) {..char *ho
9a70: 6d 65 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20  medir;..Tcl_Obj 
9a80: 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75  *homedir_obj;..u
9a90: 69 64 5f 74 20 66 73 75 69 64 3b 0a 09 73 74 61  id_t fsuid;..sta
9aa0: 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c  tic __thread Tcl
9ab0: 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64  _Obj *last_homed
9ac0: 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09  ir_obj = NULL;..
9ad0: 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20  static __thread 
9ae0: 75 69 64 5f 74 20 6c 61 73 74 5f 66 73 75 69 64  uid_t last_fsuid
9af0: 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20   = -1;..        
9b00: 69 66 20 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b  if (objc != 1) {
9b10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9b20: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
9b30: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
9b40: 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20  v, NULL);.      
9b50: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
9b60: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20  (TCL_ERROR);.   
9b70: 20 20 20 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d       }...fsuid =
9b80: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
9b90: 28 29 3b 0a 0a 09 69 66 20 28 66 73 75 69 64 20  ();...if (fsuid 
9ba0: 3d 3d 20 6c 61 73 74 5f 66 73 75 69 64 20 26 26  == last_fsuid &&
9bb0: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
9bc0: 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68  j != NULL) {...h
9bd0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73  omedir_obj = las
9be0: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a  t_homedir_obj;..
9bf0: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
9c00: 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  nt(homedir_obj);
9c10: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d  ..} else {...hom
9c20: 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74  edir = appfs_get
9c30: 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67  _homedir(appfs_g
9c40: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09  et_fsuid());....
9c50: 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e  if (homedir == N
9c60: 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  ULL) {....return
9c70: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d  (TCL_ERROR);...}
9c80: 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ....homedir_obj 
9c90: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
9ca0: 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b  bj(homedir, -1);
9cb0: 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72  ....free(homedir
9cc0: 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
9cd0: 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f  fCount(homedir_o
9ce0: 62 6a 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74  bj);....if (last
9cf0: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20  _homedir_obj != 
9d00: 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44  NULL) {....Tcl_D
9d10: 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74  ecrRefCount(last
9d20: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  _homedir_obj);..
9d30: 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  .}....last_homed
9d40: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
9d50: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
9d60: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
9d70: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
9d80: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d  homedir_obj);..}
9d90: 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65  ..       .Tcl_Se
9da0: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
9db0: 70 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  p, homedir_obj);
9dc0: 0a 0a 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  ...Tcl_DecrRefCo
9dd0: 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  unt(homedir_obj)
9de0: 3b 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ;..        retur
9df0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
9e00: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
9e10: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
9e20: 5f 66 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74  _fs_enter(Client
9e30: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
9e40: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
9e50: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
9e60: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
9e70: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
9e80: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
9e90: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
9ea0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9eb0: 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c   tcl_appfs_simul
9ec0: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
9ed0: 65 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  e(ClientData cd,
9ee0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
9ef0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
9f00: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
9f10: 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73  jv[]) {..appfs_s
9f20: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9f30: 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72  leave();...retur
9f40: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
9f50: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
9f60: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 43 6c 69  fs_get_fsuid(Cli
9f70: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
9f80: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
9f90: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
9fa0: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
9fb0: 20 7b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b   {..uid_t fsuid;
9fc0: 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73  ...fsuid = appfs
9fd0: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20  _get_fsuid();.. 
9fe0: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
9ff0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
a000: 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62  Tcl_NewWideIntOb
a010: 6a 28 66 73 75 69 64 29 29 3b 0a 0a 09 72 65 74  j(fsuid));...ret
a020: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
a030: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
a040: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 43  ppfs_get_fsgid(C
a050: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a060: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a070: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a080: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a090: 5d 29 20 7b 0a 09 67 69 64 5f 74 20 66 73 67 69  ]) {..gid_t fsgi
a0a0: 64 3b 0a 0a 09 66 73 67 69 64 20 3d 20 61 70 70  d;...fsgid = app
a0b0: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a  fs_get_fsgid();.
a0c0: 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74  .       .Tcl_Set
a0d0: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
a0e0: 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74  , Tcl_NewWideInt
a0f0: 4f 62 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09 72  Obj(fsgid));...r
a100: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
a110: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
a120: 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  _appfs_get_path_
a130: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
a140: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
a150: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
a160: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
a170: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
a180: 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f  v[]) {..int tcl_
a190: 72 65 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69  ret;..int new_si
a1a0: 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d  ze;...new_size =
a1b0: 20 2d 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20   -1;...if (objc 
a1c0: 3d 3d 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65  == 2) {...tcl_re
a1d0: 74 20 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46 72  t = Tcl_GetIntFr
a1e0: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
a1f0: 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65  jv[1], &new_size
a200: 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74  );...if (tcl_ret
a210: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
a220: 09 72 65 74 75 72 6e 28 74 63 6c 5f 72 65 74 29  .return(tcl_ret)
a230: 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66  ;...}..} else if
a240: 20 28 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62   (objc > 2 || ob
a250: 6a 63 20 3c 20 31 29 20 7b 0a 20 20 20 20 20 20  jc < 1) {.      
a260: 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72            Tcl_Wr
a270: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
a280: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65  p, 1, objv, "?ne
a290: 77 5f 63 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b  w_cache_size?");
a2a0: 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52  ...return(TCL_ER
a2b0: 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ROR);..}...appfs
a2c0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
a2d0: 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e  ache_flush(-1, n
a2e0: 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75  ew_size);...retu
a2f0: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
a300: 74 61 74 69 63 20 69 6e 74 20 41 70 70 66 73 64  tatic int Appfsd
a310: 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70  _Init(Tcl_Interp
a320: 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64   *interp) {.#ifd
a330: 65 66 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53  ef USE_TCL_STUBS
a340: 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74  ..if (Tcl_InitSt
a350: 75 62 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f  ubs(interp, TCL_
a360: 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30  VERSION, 0) == 0
a370: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43  L) {...return(TC
a380: 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e  L_ERROR);..}.#en
a390: 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65  dif...Tcl_Create
a3a0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
a3b0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f  p, "appfsd::get_
a3c0: 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70  homedir", tcl_ap
a3d0: 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c  pfs_get_homedir,
a3e0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
a3f0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
a400: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
a410: 66 73 64 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c  fsd::get_fsuid",
a420: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
a430: 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  suid, NULL, NULL
a440: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
a450: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
a460: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73   "appfsd::get_fs
a470: 67 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  gid", tcl_appfs_
a480: 67 65 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c  get_fsgid, NULL,
a490: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
a4a0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
a4b0: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73  terp, "appfsd::s
a4c0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
a4d0: 65 6e 74 65 72 22 2c 20 74 63 6c 5f 61 70 70 66  enter", tcl_appf
a4e0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
a4f0: 66 73 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20  fs_enter, NULL, 
a500: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
a510: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
a520: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69  erp, "appfsd::si
a530: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
a540: 65 61 76 65 22 2c 20 74 63 6c 5f 61 70 70 66 73  eave", tcl_appfs
a550: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
a560: 73 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e  s_leave, NULL, N
a570: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
a580: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
a590: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74  rp, "appfsd::get
a5a0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
a5b0: 5f 66 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70 70  _flush", tcl_app
a5c0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
a5d0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55  _cache_flush, NU
a5e0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c  LL, NULL);...Tcl
a5f0: 5f 50 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65  _PkgProvide(inte
a600: 72 70 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31  rp, "appfsd", "1
a610: 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  .0");...return(T
a620: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  CL_OK);.}../*. *
a630: 20 48 6f 74 2d 72 65 73 74 61 72 74 20 73 75 70   Hot-restart sup
a640: 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74  port. */./* Init
a650: 69 61 74 65 20 61 20 68 6f 74 2d 72 65 73 74 61  iate a hot-resta
a660: 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  rt */.static voi
a670: 64 20 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74  d appfs_hot_rest
a680: 61 72 74 28 76 6f 69 64 29 20 7b 0a 09 41 50 50  art(void) {..APP
a690: 46 53 5f 44 45 42 55 47 28 22 41 73 6b 65 64 20  FS_DEBUG("Asked 
a6a0: 74 6f 20 69 6e 69 74 69 61 74 65 20 68 6f 74 20  to initiate hot 
a6b0: 72 65 73 74 61 72 74 22 29 3b 0a 0a 09 61 70 70  restart");...app
a6c0: 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65  fs_tcl_ResetInte
a6d0: 72 70 73 28 29 3b 0a 09 61 70 70 66 73 5f 67 65  rps();..appfs_ge
a6e0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
a6f0: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b  e_flush(-1, -1);
a700: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a  ...return;.}../*
a710: 0a 20 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c  . * Signal handl
a720: 65 72 0a 20 2a 20 20 20 20 20 20 20 20 20 53 49  er. *         SI
a730: 47 48 55 50 20 69 6e 69 74 69 61 74 65 73 20 61  GHUP initiates a
a740: 20 68 6f 74 20 72 65 73 74 61 72 74 0a 20 2a 2f   hot restart. */
a750: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
a760: 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65  fs_signal_handle
a770: 72 28 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a  r(int sig) {../*
a780: 20 44 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73   Do not handle s
a790: 69 67 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55 53  ignals until FUS
a7a0: 45 20 68 61 73 20 62 65 65 6e 20 73 74 61 72 74  E has been start
a7b0: 65 64 20 2a 2f 0a 09 69 66 20 28 21 61 70 70 66  ed */..if (!appf
a7c0: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20  s_fuse_started) 
a7d0: 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  {...return;..}..
a7e0: 09 2f 2a 20 52 65 71 75 65 73 74 20 74 6f 20 70  ./* Request to p
a7f0: 65 72 66 6f 72 6d 20 61 20 22 68 6f 74 22 20 72  erform a "hot" r
a800: 65 73 74 61 72 74 20 2a 2f 0a 09 69 66 20 28 73  estart */..if (s
a810: 69 67 20 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a  ig == SIGHUP) {.
a820: 09 09 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74  ..appfs_hot_rest
a830: 61 72 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  art();..}...retu
a840: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72  rn;.}../*. * Ter
a850: 6d 69 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a  minate a thread.
a860: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
a870: 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f  appfs_terminate_
a880: 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61  interp_and_threa
a890: 64 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70 29  d(void *_interp)
a8a0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
a8b0: 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f  interp;...APPFS_
a8c0: 44 45 42 55 47 28 22 43 61 6c 6c 65 64 3a 20 5f  DEBUG("Called: _
a8d0: 69 6e 74 65 72 70 20 3d 20 25 70 22 2c 20 5f 69  interp = %p", _i
a8e0: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f 69  nterp);...if (_i
a8f0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
a900: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
a910: 54 65 72 6d 69 6e 61 74 69 6e 67 20 74 68 72 65  Terminating thre
a920: 61 64 20 77 69 74 68 20 6e 6f 20 69 6e 74 65 72  ad with no inter
a930: 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74  preter");....ret
a940: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70  urn;..}...interp
a950: 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 41 50   = _interp;...AP
a960: 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69  PFS_DEBUG("Termi
a970: 6e 61 74 69 6e 67 20 69 6e 74 65 72 70 72 65 74  nating interpret
a980: 65 72 20 64 75 65 20 74 6f 20 74 68 72 65 61 64  er due to thread
a990: 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a   termination");.
a9a0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
a9b0: 74 63 6c 28 0a 09 09 54 63 6c 5f 44 65 6c 65 74  tcl(...Tcl_Delet
a9c0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
a9d0: 0a 09 29 0a 0a 09 54 63 6c 5f 46 69 6e 61 6c 69  ..)...Tcl_Finali
a9e0: 7a 65 54 68 72 65 61 64 28 29 3b 0a 0a 09 72 65  zeThread();...re
a9f0: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 46  turn;.}../*. * F
aa00: 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 73  USE operations s
aa10: 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73 74 61  tructure. */.sta
aa20: 74 69 63 20 73 74 72 75 63 74 20 66 75 73 65 5f  tic struct fuse_
aa30: 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70 66 73  operations appfs
aa40: 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20 7b 0a  _operations = {.
aa50: 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20 61 70  ..getattr   = ap
aa60: 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72  pfs_fuse_getattr
aa70: 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20 3d 20  ,...readdir   = 
aa80: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64  appfs_fuse_readd
aa90: 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b 20 20  ir,...readlink  
aaa0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
aab0: 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20  dlink,...open   
aac0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
aad0: 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73 65 20  open,...release 
aae0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63    = appfs_fuse_c
aaf0: 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20 20 20  lose,...read    
ab00: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
ab10: 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20 20 20  ead,...write    
ab20: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72   = appfs_fuse_wr
ab30: 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20  ite,...mknod    
ab40: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b   = appfs_fuse_mk
ab50: 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20 20 20  nod,...create   
ab60: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72   = appfs_fuse_cr
ab70: 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61 74 65  eate,...truncate
ab80: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 74    = appfs_fuse_t
ab90: 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e  runcate,...unlin
aba0: 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  k    = appfs_fus
abb0: 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a  e_unlink_rmdir,.
abc0: 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20 61 70  ..rmdir     = ap
abd0: 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f  pfs_fuse_unlink_
abe0: 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72 20 20  rmdir,...mkdir  
abf0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
ac00: 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64 20 20  mkdir,...chmod  
ac10: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
ac20: 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e 6b  chmod,...symlink
ac30: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
ac40: 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f 2a 0a  symlink,.};../*.
ac50: 20 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20 70   * FUSE option p
ac60: 61 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b 0a  arsing callback.
ac70: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
ac80: 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62  ppfs_fuse_opt_cb
ac90: 28 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f 6e  (void *data, con
aca0: 73 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69 6e  st char *arg, in
acb0: 74 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66 75  t key, struct fu
acc0: 73 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67 73  se_args *outargs
acd0: 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e 74 20  ) {..static int 
ace0: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20  seen_cachedir = 
acf0: 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20 3d 3d 20  0;...if (key == 
ad00: 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f 4e 4f 4e  FUSE_OPT_KEY_NON
ad10: 4f 50 54 20 26 26 20 73 65 65 6e 5f 63 61 63 68  OPT && seen_cach
ad20: 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a 09 09 73  edir == 0) {...s
ad30: 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20 31  een_cachedir = 1
ad40: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 63 68 65  ;....appfs_cache
ad50: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
ad60: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
ad70: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 31 29 3b  ..}...return(1);
ad80: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20  .}../*. * Entry 
ad90: 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68 69 73 20  point into this 
ada0: 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74  program.. */.int
adb0: 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20   main(int argc, 
adc0: 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09  char **argv) {..
add0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73 74  Tcl_Interp *test
ade0: 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a  _interp;..char *
adf0: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
ae00: 72 3b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f  r;..struct fuse_
ae10: 61 72 67 73 20 61 72 67 73 20 3d 20 46 55 53 45  args args = FUSE
ae20: 5f 41 52 47 53 5f 49 4e 49 54 28 61 72 67 63 2c  _ARGS_INIT(argc,
ae30: 20 61 72 67 76 29 3b 0a 09 69 6e 74 20 70 74 68   argv);..int pth
ae40: 72 65 61 64 5f 72 65 74 3b 0a 09 76 6f 69 64 20  read_ret;..void 
ae50: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09 2f  *signal_ret;.../
ae60: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
ae70: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
ae80: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
ae90: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
aea0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
aeb0: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
aec0: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
aed0: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
aee0: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
aef0: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
af00: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
af10: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
af20: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
af30: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
af40: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
af50: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
af60: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
af70: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
af80: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
af90: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
afa0: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
afb0: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
afc0: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
afd0: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
afe0: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
aff0: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
b000: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
b010: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
b020: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
b030: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
b040: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
b050: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
b060: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
b070: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
b080: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
b090: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
b0a0: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
b0b0: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
b0c0: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
b0d0: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
b0e0: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
b0f0: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
b100: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
b110: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
b120: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
b130: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
b140: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
b150: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
b160: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
b170: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
b180: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
b190: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
b1a0: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
b1b0: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
b1c0: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
b1d0: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
b1e0: 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 65  erpKey, appfs_te
b1f0: 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61  rminate_interp_a
b200: 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09 69 66 20  nd_thread);..if 
b210: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
b220: 30 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  0) {...fprintf(s
b230: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
b240: 6f 20 63 72 65 61 74 65 20 54 53 44 20 6b 65 79  o create TSD key
b250: 20 66 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72 74   for Tcl.  Abort
b260: 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74  ing.\n");....ret
b270: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  urn(1);..}.../*.
b280: 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70 65  . * Manually spe
b290: 63 69 66 79 20 63 61 63 68 65 20 64 69 72 65 63  cify cache direc
b2a0: 74 6f 72 79 2c 20 77 69 74 68 6f 75 74 20 46 55  tory, without FU
b2b0: 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a 20  SE callback.. * 
b2c0: 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c 79  This option only
b2d0: 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74 20   works when not 
b2e0: 75 73 69 6e 67 20 46 55 53 45 2c 20 73 69 6e 63  using FUSE, sinc
b2f0: 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 20  e we.. * do not 
b300: 70 72 6f 63 65 73 73 20 69 74 20 77 69 74 68 20  process it with 
b310: 46 55 53 45 73 20 6f 70 74 69 6f 6e 20 70 72 6f  FUSEs option pro
b320: 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 69  cessing... */..i
b330: 66 20 28 61 72 67 63 20 3e 3d 20 32 29 20 7b 0a  f (argc >= 2) {.
b340: 09 09 69 66 20 28 73 74 72 63 6d 70 28 61 72 67  ..if (strcmp(arg
b350: 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64 69  v[0], "--cachedi
b360: 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 61  r") == 0) {....a
b370: 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20  ppfs_cachedir = 
b380: 73 74 72 64 75 70 28 61 72 67 76 5b 31 5d 29 3b  strdup(argv[1]);
b390: 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20 32 3b 0a  .....argc -= 2;.
b3a0: 09 09 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09 09  ...argv += 2;...
b3b0: 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 51  }..}.../*.. * SQ
b3c0: 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72 20  Lite3 mode, for 
b3d0: 72 75 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c 20  running raw SQL 
b3e0: 61 67 61 69 6e 73 74 20 74 68 65 20 63 61 63 68  against the cach
b3f0: 65 20 64 61 74 61 62 61 73 65 0a 09 20 2a 2f 0a  e database.. */.
b400: 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26  .if (argc == 2 &
b410: 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d  & strcmp(argv[0]
b420: 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22 29 20 3d  , "--sqlite3") =
b430: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
b440: 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28 61 72  appfs_sqlite3(ar
b450: 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a  gv[1]));..}.../*
b460: 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 66  .. * Tcl mode, f
b470: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 54  or running raw T
b480: 63 6c 20 69 6e 20 74 68 65 20 73 61 6d 65 20 65  cl in the same e
b490: 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46 53  nvironment AppFS
b4a0: 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e 20  d would.. * run 
b4b0: 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 28  code... */..if (
b4c0: 61 72 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72  argc == 2 && str
b4d0: 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d  cmp(argv[0], "--
b4e0: 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  tcl") == 0) {...
b4f0: 72 65 74 75 72 6e 28 61 70 70 66 73 5f 74 63 6c  return(appfs_tcl
b500: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
b510: 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61  ./*.. * Create a
b520: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
b530: 20 6a 75 73 74 20 74 6f 20 76 65 72 69 66 79 20   just to verify 
b540: 74 68 61 74 20 74 68 69 6e 67 73 20 61 72 65 20  that things are 
b550: 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09 20 2a 20  in working .. * 
b560: 6f 72 64 65 72 20 62 65 66 6f 72 65 20 77 65 20  order before we 
b570: 62 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 2e  become a daemon.
b580: 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69 6e 74 65  .. */..test_inte
b590: 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74  rp = appfs_creat
b5a0: 65 5f 54 63 6c 49 6e 74 65 72 70 28 26 74 65 73  e_TclInterp(&tes
b5b0: 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b  t_interp_error);
b5c0: 0a 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72  ..if (test_inter
b5d0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69  p == NULL) {...i
b5e0: 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  f (test_interp_e
b5f0: 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  rror == NULL) {.
b600: 09 09 09 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  ...test_interp_e
b610: 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20  rror = "Unknown 
b620: 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09 66  error";...}....f
b630: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
b640: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61  Unable to initia
b650: 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65 72 70 72  lize Tcl interpr
b660: 65 74 65 72 20 66 6f 72 20 41 70 70 46 53 64 3a  eter for AppFSd:
b670: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28  \n");...fprintf(
b680: 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20  stderr, "%s\n", 
b690: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
b6a0: 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  r);....return(1)
b6b0: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 65 6c 65 74  ;..}...Tcl_Delet
b6c0: 65 49 6e 74 65 72 70 28 74 65 73 74 5f 69 6e 74  eInterp(test_int
b6d0: 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 46 69 6e 61  erp);...Tcl_Fina
b6e0: 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e 55 4c  lizeNotifier(NUL
b6f0: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
b700: 69 73 74 65 72 20 61 20 73 69 67 6e 61 6c 20 68  ister a signal h
b710: 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72  andler for hot-r
b720: 65 73 74 61 72 74 20 72 65 71 75 65 73 74 73 0a  estart requests.
b730: 09 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74  . */..signal_ret
b740: 20 3d 20 73 69 67 6e 61 6c 28 53 49 47 48 55 50   = signal(SIGHUP
b750: 2c 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68  , appfs_signal_h
b760: 61 6e 64 6c 65 72 29 3b 0a 09 69 66 20 28 73 69  andler);..if (si
b770: 67 6e 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f  gnal_ret == SIG_
b780: 45 52 52 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ERR) {...fprintf
b790: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
b7a0: 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e   to install sign
b7b0: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
b7c0: 6f 74 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a  ot-restart\n");.
b7d0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
b7e0: 2c 20 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77  , "Hot-restart w
b7f0: 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c  ill not be avail
b800: 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09  able.\n");..}...
b810: 2f 2a 0a 09 20 2a 20 41 64 64 20 46 55 53 45 20  /*.. * Add FUSE 
b820: 61 72 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20  arguments which 
b830: 77 65 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79  we always supply
b840: 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f  .. */..fuse_opt_
b850: 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55 4c  parse(&args, NUL
b860: 4c 2c 20 4e 55 4c 4c 2c 20 61 70 70 66 73 5f 66  L, NULL, appfs_f
b870: 75 73 65 5f 6f 70 74 5f 63 62 29 3b 0a 09 66 75  use_opt_cb);..fu
b880: 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 26  se_opt_add_arg(&
b890: 61 72 67 73 2c 20 22 2d 6f 64 65 66 61 75 6c 74  args, "-odefault
b8a0: 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c 66 73 6e  _permissions,fsn
b8b0: 61 6d 65 3d 61 70 70 66 73 2c 73 75 62 74 79 70  ame=appfs,subtyp
b8c0: 65 3d 61 70 70 66 73 64 2c 75 73 65 5f 69 6e 6f  e=appfsd,use_ino
b8d0: 2c 6b 65 72 6e 65 6c 5f 63 61 63 68 65 2c 65 6e  ,kernel_cache,en
b8e0: 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30 2c 61 74  try_timeout=0,at
b8f0: 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c 62 69 67  tr_timeout=0,big
b900: 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c 68 61 72  _writes,intr,har
b910: 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a 09 69 66  d_remove");...if
b920: 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20 30 29   (getuid() == 0)
b930: 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 70 61   {...fuse_opt_pa
b940: 72 73 65 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c  rse(&args, NULL,
b950: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09   NULL, NULL);...
b960: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
b970: 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77  (&args, "-oallow
b980: 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a 0a 09 2f  _other");..}.../
b990: 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68 65 20  *.. * Enter the 
b9a0: 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d  FUSE main loop -
b9b0: 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 63  - this will proc
b9c0: 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65 6e 74  ess any argument
b9d0: 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72 74 20  s.. * and start 
b9e0: 73 65 72 76 69 63 69 6e 67 20 72 65 71 75 65 73  servicing reques
b9f0: 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ts... */..appfs_
ba00: 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d 20 31  fuse_started = 1
ba10: 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65 5f 6d  ;..return(fuse_m
ba20: 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c 20 61  ain(args.argc, a
ba30: 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70 66 73  rgs.argv, &appfs
ba40: 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e 55 4c  _operations, NUL
ba50: 4c 29 29 3b 0a 7d 0a 20 0a                       L));.}. .