Hex Artifact Content

Artifact 276d2f6247dccb5564c665c5d43405faaa07a750:


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 54 63 6c 5f 47 65 74 56 61 72 28  \n", Tcl_GetVar(
98a0: 69 6e 74 65 72 70 2c 20 22 65 72 72 6f 72 49 6e  interp, "errorIn
98b0: 66 6f 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f  fo", TCL_GLOBAL_
98c0: 4f 4e 4c 59 29 29 3b 0a 0a 09 09 72 65 74 75 72  ONLY));....retur
98d0: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74  n(1);..}...if (t
98e0: 63 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c  cl_result && tcl
98f0: 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c  _result[0] != '\
9900: 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22  0') {...printf("
9910: 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c  %s\n", tcl_resul
9920: 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  t);..}...return(
9930: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70  0);.}../*. * App
9940: 46 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20  FSd Package for 
9950: 54 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20  Tcl:. *         
9960: 42 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f  Bridge for I/O o
9970: 70 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71  perations to req
9980: 75 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  uest information
9990: 20 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65   about the curre
99a0: 6e 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72  nt. *         tr
99b0: 61 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a  ansaction. */./*
99c0: 0a 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63  . * Tcl interfac
99d0: 65 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d  e to get the hom
99e0: 65 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20  e directory for 
99f0: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
9a00: 74 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a  the "current". *
9a10: 20 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73   FUSE I/O reques
9a20: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t. */.static int
9a30: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68   tcl_appfs_get_h
9a40: 6f 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74  omedir(ClientDat
9a50: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
9a60: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
9a70: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
9a80: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68  ST objv[]) {..ch
9a90: 61 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63  ar *homedir;..Tc
9aa0: 6c 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f  l_Obj *homedir_o
9ab0: 62 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  bj;..uid_t fsuid
9ac0: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
9ad0: 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74  ad Tcl_Obj *last
9ae0: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e  _homedir_obj = N
9af0: 55 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74  ULL;..static __t
9b00: 68 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74  hread uid_t last
9b10: 5f 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20  _fsuid = -1;..  
9b20: 20 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21        if (objc !
9b30: 3d 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  = 1) {.         
9b40: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
9b50: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
9b60: 31 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a  1, objv, NULL);.
9b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9b80: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
9b90: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66  );.        }...f
9ba0: 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74  suid = appfs_get
9bb0: 5f 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28  _fsuid();...if (
9bc0: 66 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73  fsuid == last_fs
9bd0: 75 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65  uid && last_home
9be0: 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29  dir_obj != NULL)
9bf0: 20 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a   {...homedir_obj
9c00: 20 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f   = last_homedir_
9c10: 6f 62 6a 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72  obj;....Tcl_Incr
9c20: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72  RefCount(homedir
9c30: 5f 6f 62 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  _obj);..} else {
9c40: 0a 09 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70  ...homedir = app
9c50: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61  fs_get_homedir(a
9c60: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
9c70: 29 3b 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69  );....if (homedi
9c80: 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  r == NULL) {....
9c90: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
9ca0: 29 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69  );...}....homedi
9cb0: 72 5f 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53  r_obj = Tcl_NewS
9cc0: 74 72 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72  tringObj(homedir
9cd0: 2c 20 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68  , -1);....free(h
9ce0: 6f 6d 65 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f  omedir);....Tcl_
9cf0: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d  IncrRefCount(hom
9d00: 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66  edir_obj);....if
9d10: 20 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f   (last_homedir_o
9d20: 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  bj != NULL) {...
9d30: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e  .Tcl_DecrRefCoun
9d40: 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  t(last_homedir_o
9d50: 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74  bj);...}....last
9d60: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68  _homedir_obj = h
9d70: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61  omedir_obj;...la
9d80: 73 74 5f 66 73 75 69 64 20 3d 20 66 73 75 69 64  st_fsuid = fsuid
9d90: 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
9da0: 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62  Count(homedir_ob
9db0: 6a 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09  j);..}..       .
9dc0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
9dd0: 28 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72  (interp, homedir
9de0: 5f 6f 62 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63  _obj);...Tcl_Dec
9df0: 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69  rRefCount(homedi
9e00: 72 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20  r_obj);..       
9e10: 20 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b   return(TCL_OK);
9e20: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
9e30: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
9e40: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
9e50: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
9e60: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9e70: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
9e80: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
9e90: 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d  []) {..appfs_sim
9ea0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
9eb0: 74 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ter();...return(
9ec0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
9ed0: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
9ee0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
9ef0: 73 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61  s_leave(ClientDa
9f00: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
9f10: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
9f20: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
9f30: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61  NST objv[]) {..a
9f40: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
9f50: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
9f60: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
9f70: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
9f80: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75  cl_appfs_get_fsu
9f90: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
9fa0: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
9fb0: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
9fc0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
9fd0: 62 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20  bjv[]) {..uid_t 
9fe0: 66 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d  fsuid;...fsuid =
9ff0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
a000: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
a010: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
a020: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
a030: 65 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b  eIntObj(fsuid));
a040: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
a050: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
a060: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
a070: 73 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20  sgid(ClientData 
a080: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
a090: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
a0a0: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
a0b0: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f   objv[]) {..gid_
a0c0: 74 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64  t fsgid;...fsgid
a0d0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67   = appfs_get_fsg
a0e0: 69 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54  id();..       .T
a0f0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
a100: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57  interp, Tcl_NewW
a110: 69 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29  ideIntObj(fsgid)
a120: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
a130: 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  OK);.}..static i
a140: 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  nt tcl_appfs_get
a150: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
a160: 5f 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74  _flush(ClientDat
a170: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
a180: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
a190: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
a1a0: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e  ST objv[]) {..in
a1b0: 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  t tcl_ret;..int 
a1c0: 6e 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f  new_size;...new_
a1d0: 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20  size = -1;...if 
a1e0: 28 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09  (objc == 2) {...
a1f0: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
a200: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
a210: 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65  rp, objv[1], &ne
a220: 77 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74  w_size);...if (t
a230: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
a240: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63  ) {....return(tc
a250: 6c 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65  l_ret);...}..} e
a260: 6c 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32  lse if (objc > 2
a270: 20 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a   || objc < 1) {.
a280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a290: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
a2a0: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
a2b0: 2c 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69  , "?new_cache_si
a2c0: 7a 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28  ze?");...return(
a2d0: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a  TCL_ERROR);..}..
a2e0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
a2f0: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
a300: 28 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a  (-1, new_size);.
a310: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
a320: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a330: 41 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f  Appfsd_Init(Tcl_
a340: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20  Interp *interp) 
a350: 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c  {.#ifdef USE_TCL
a360: 5f 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f  _STUBS..if (Tcl_
a370: 49 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70  InitStubs(interp
a380: 2c 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30  , TCL_VERSION, 0
a390: 29 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74  ) == 0L) {...ret
a3a0: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
a3b0: 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f  .}.#endif...Tcl_
a3c0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
a3d0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
a3e0: 3a 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20  ::get_homedir", 
a3f0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
a400: 6d 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  medir, NULL, NUL
a410: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
a420: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
a430: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66  , "appfsd::get_f
a440: 73 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73  suid", tcl_appfs
a450: 5f 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c  _get_fsuid, NULL
a460: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
a470: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
a480: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
a490: 67 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f  get_fsgid", tcl_
a4a0: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c  appfs_get_fsgid,
a4b0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
a4c0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
a4d0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
a4e0: 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73  fsd::simulate_us
a4f0: 65 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63  er_fs_enter", tc
a500: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
a510: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20  _user_fs_enter, 
a520: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
a530: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
a540: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
a550: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
a560: 72 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c  r_fs_leave", tcl
a570: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
a580: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e  user_fs_leave, N
a590: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
a5a0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
a5b0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
a5c0: 64 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  d::get_path_info
a5d0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74  _cache_flush", t
a5e0: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74  cl_appfs_get_pat
a5f0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
a600: 73 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  sh, NULL, NULL);
a610: 0a 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64  ...Tcl_PkgProvid
a620: 65 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  e(interp, "appfs
a630: 64 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65  d", "1.0");...re
a640: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
a650: 0a 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61  ./*. * Hot-resta
a660: 72 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f  rt support. */./
a670: 2a 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74  * Initiate a hot
a680: 2d 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74  -restart */.stat
a690: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f  ic void appfs_ho
a6a0: 74 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20  t_restart(void) 
a6b0: 7b 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  {..APPFS_DEBUG("
a6c0: 41 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74  Asked to initiat
a6d0: 65 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b  e hot restart");
a6e0: 0a 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73  ...appfs_tcl_Res
a6f0: 65 74 49 6e 74 65 72 70 73 28 29 3b 0a 09 61 70  etInterps();..ap
a700: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
a710: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31  o_cache_flush(-1
a720: 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  , -1);...return;
a730: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c  .}../*. * Signal
a740: 20 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20   handler. *     
a750: 20 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69      SIGHUP initi
a760: 61 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61  ates a hot resta
a770: 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rt. */.static vo
a780: 69 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f  id appfs_signal_
a790: 68 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29  handler(int sig)
a7a0: 20 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61   {../* Do not ha
a7b0: 6e 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74  ndle signals unt
a7c0: 69 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e  il FUSE has been
a7d0: 20 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20   started */..if 
a7e0: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
a7f0: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
a800: 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73  ;..}.../* Reques
a810: 74 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22  t to perform a "
a820: 68 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a  hot" restart */.
a830: 09 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48  .if (sig == SIGH
a840: 55 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f  UP) {...appfs_ho
a850: 74 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a  t_restart();..}.
a860: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
a870: 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74   * Terminate a t
a880: 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63  hread. */.static
a890: 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d   void appfs_term
a8a0: 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64  inate_interp_and
a8b0: 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a 5f 69  _thread(void *_i
a8c0: 6e 74 65 72 70 29 20 7b 0a 09 54 63 6c 5f 49 6e  nterp) {..Tcl_In
a8d0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 0a 09  terp *interp;...
a8e0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 6c  APPFS_DEBUG("Cal
a8f0: 6c 65 64 3a 20 5f 69 6e 74 65 72 70 20 3d 20 25  led: _interp = %
a900: 70 22 2c 20 5f 69 6e 74 65 72 70 29 3b 0a 0a 09  p", _interp);...
a910: 69 66 20 28 5f 69 6e 74 65 72 70 20 3d 3d 20 4e  if (_interp == N
a920: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
a930: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
a940: 67 20 74 68 72 65 61 64 20 77 69 74 68 20 6e 6f  g thread with no
a950: 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a   interpreter");.
a960: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
a970: 69 6e 74 65 72 70 20 3d 20 5f 69 6e 74 65 72 70  interp = _interp
a980: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
a990: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 69 6e 74  "Terminating int
a9a0: 65 72 70 72 65 74 65 72 20 64 75 65 20 74 6f 20  erpreter due to 
a9b0: 74 68 72 65 61 64 20 74 65 72 6d 69 6e 61 74 69  thread terminati
a9c0: 6f 6e 22 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61  on");...appfs_ca
a9d0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c  ll_libtcl(...Tcl
a9e0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
a9f0: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 54 63 6c 5f  terp);..)...Tcl_
aa00: 46 69 6e 61 6c 69 7a 65 54 68 72 65 61 64 28 29  FinalizeThread()
aa10: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  ;...return;.}../
aa20: 2a 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74  *. * FUSE operat
aa30: 69 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20  ions structure. 
aa40: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  */.static struct
aa50: 20 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73   fuse_operations
aa60: 20 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e   appfs_operation
aa70: 73 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20  s = {...getattr 
aa80: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67    = appfs_fuse_g
aa90: 65 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69  etattr,...readdi
aaa0: 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  r   = appfs_fuse
aab0: 5f 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64  _readdir,...read
aac0: 6c 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75  link  = appfs_fu
aad0: 73 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f  se_readlink,...o
aae0: 70 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73  pen      = appfs
aaf0: 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65  _fuse_open,...re
ab00: 6c 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f  lease   = appfs_
ab10: 66 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65  fuse_close,...re
ab20: 61 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  ad      = appfs_
ab30: 66 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69  fuse_read,...wri
ab40: 74 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  te     = appfs_f
ab50: 75 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e  use_write,...mkn
ab60: 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  od     = appfs_f
ab70: 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65  use_mknod,...cre
ab80: 61 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ate    = appfs_f
ab90: 75 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72  use_create,...tr
aba0: 75 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f  uncate  = appfs_
abb0: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09  fuse_truncate,..
abc0: 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70  .unlink    = app
abd0: 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72  fs_fuse_unlink_r
abe0: 6d 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20  mdir,...rmdir   
abf0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75    = appfs_fuse_u
ac00: 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d  nlink_rmdir,...m
ac10: 6b 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73  kdir     = appfs
ac20: 5f 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63  _fuse_mkdir,...c
ac30: 68 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73  hmod     = appfs
ac40: 5f 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73  _fuse_chmod,...s
ac50: 79 6d 6c 69 6e 6b 20 20 20 3d 20 61 70 70 66 73  ymlink   = appfs
ac60: 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d  _fuse_symlink,.}
ac70: 3b 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70  ;../*. * FUSE op
ac80: 74 69 6f 6e 20 70 61 72 73 69 6e 67 20 63 61 6c  tion parsing cal
ac90: 6c 62 61 63 6b 0a 20 2a 2f 0a 73 74 61 74 69 63  lback. */.static
aca0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
acb0: 6f 70 74 5f 63 62 28 76 6f 69 64 20 2a 64 61 74  opt_cb(void *dat
acc0: 61 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61  a, const char *a
acd0: 72 67 2c 20 69 6e 74 20 6b 65 79 2c 20 73 74 72  rg, int key, str
ace0: 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 2a 6f  uct fuse_args *o
acf0: 75 74 61 72 67 73 29 20 7b 0a 09 73 74 61 74 69  utargs) {..stati
ad00: 63 20 69 6e 74 20 73 65 65 6e 5f 63 61 63 68 65  c int seen_cache
ad10: 64 69 72 20 3d 20 30 3b 0a 0a 09 69 66 20 28 6b  dir = 0;...if (k
ad20: 65 79 20 3d 3d 20 46 55 53 45 5f 4f 50 54 5f 4b  ey == FUSE_OPT_K
ad30: 45 59 5f 4e 4f 4e 4f 50 54 20 26 26 20 73 65 65  EY_NONOPT && see
ad40: 6e 5f 63 61 63 68 65 64 69 72 20 3d 3d 20 30 29  n_cachedir == 0)
ad50: 20 7b 0a 09 09 73 65 65 6e 5f 63 61 63 68 65 64   {...seen_cached
ad60: 69 72 20 3d 20 31 3b 0a 0a 09 09 61 70 70 66 73  ir = 1;....appfs
ad70: 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74 72 64  _cachedir = strd
ad80: 75 70 28 61 72 67 29 3b 0a 0a 09 09 72 65 74 75  up(arg);....retu
ad90: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  rn(0);..}...retu
ada0: 72 6e 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  rn(1);.}../*. * 
adb0: 45 6e 74 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f  Entry point into
adc0: 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20   this program.. 
add0: 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20  */.int main(int 
ade0: 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67  argc, char **arg
adf0: 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  v) {..Tcl_Interp
ae00: 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09   *test_interp;..
ae10: 63 68 61 72 20 2a 74 65 73 74 5f 69 6e 74 65 72  char *test_inter
ae20: 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72 75 63 74  p_error;..struct
ae30: 20 66 75 73 65 5f 61 72 67 73 20 61 72 67 73 20   fuse_args args 
ae40: 3d 20 46 55 53 45 5f 41 52 47 53 5f 49 4e 49 54  = FUSE_ARGS_INIT
ae50: 28 61 72 67 63 2c 20 61 72 67 76 29 3b 0a 09 69  (argc, argv);..i
ae60: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a  nt pthread_ret;.
ae70: 09 76 6f 69 64 20 2a 73 69 67 6e 61 6c 5f 72 65  .void *signal_re
ae80: 74 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 6b 69 70  t;.../*.. * Skip
ae90: 20 70 61 73 73 65 64 20 70 72 6f 67 72 61 6d 20   passed program 
aea0: 6e 61 6d 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61  name.. */..if (a
aeb0: 72 67 63 20 3d 3d 20 30 20 7c 7c 20 61 72 67 76  rgc == 0 || argv
aec0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
aed0: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 09 61 72 67  turn(1);..}..arg
aee0: 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09  c--;..argv++;...
aef0: 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61  /*.. * Set globa
af00: 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 74 68 65  l variables, the
af10: 73 65 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e  se should be con
af20: 66 69 67 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f  figuration optio
af30: 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ns... */..appfs_
af40: 63 61 63 68 65 64 69 72 20 3d 20 41 50 50 46 53  cachedir = APPFS
af50: 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a  _CACHEDIR;.../*.
af60: 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76  . * Set global v
af70: 61 72 69 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f  ariable for "boo
af80: 74 20 74 69 6d 65 22 20 74 6f 20 73 65 74 20 61  t time" to set a
af90: 20 74 69 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f   time on directo
afa0: 72 69 65 73 0a 09 20 2a 20 74 68 61 74 20 77 65  ries.. * that we
afb0: 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70   fake... */..app
afc0: 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69  fs_boottime = ti
afd0: 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  me(NULL);.../*..
afe0: 20 2a 20 52 65 67 69 73 74 65 72 20 22 73 68 61   * Register "sha
aff0: 31 22 20 61 6e 64 20 22 61 70 70 66 73 64 22 20  1" and "appfsd" 
b000: 70 61 63 6b 61 67 65 20 77 69 74 68 20 6c 69 62  package with lib
b010: 74 63 6c 20 73 6f 20 74 68 61 74 20 61 6e 79 20  tcl so that any 
b020: 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72 70 72 65  new.. * interpre
b030: 74 65 72 73 20 63 72 65 61 74 65 64 20 28 77 68  ters created (wh
b040: 69 63 68 20 61 72 65 20 64 6f 6e 65 20 64 79 6e  ich are done dyn
b050: 61 6d 69 63 61 6c 6c 79 20 62 79 20 46 55 53 45  amically by FUSE
b060: 29 20 63 61 6e 20 68 61 76 65 0a 09 20 2a 20 74  ) can have.. * t
b070: 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 63  he appropriate c
b080: 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e  onfiguration don
b090: 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e  e automatically.
b0a0: 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69  .. */..Tcl_Stati
b0b0: 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22  cPackage(NULL, "
b0c0: 73 68 61 31 22 2c 20 53 68 61 31 5f 49 6e 69 74  sha1", Sha1_Init
b0d0: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74  , NULL);..Tcl_St
b0e0: 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c  aticPackage(NULL
b0f0: 2c 20 22 61 70 70 66 73 64 22 2c 20 41 70 70 66  , "appfsd", Appf
b100: 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a  sd_Init, NULL);.
b110: 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20  ../*.. * Create 
b120: 61 20 74 68 72 65 61 64 2d 73 70 65 63 69 66 69  a thread-specifi
b130: 63 2d 64 61 74 61 20 28 54 53 44 29 20 6b 65 79  c-data (TSD) key
b140: 20 66 6f 72 20 65 61 63 68 20 74 68 72 65 61 64   for each thread
b150: 20 74 6f 20 72 65 66 65 72 0a 09 20 2a 20 74 6f   to refer.. * to
b160: 20 69 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74   its own Tcl int
b170: 65 72 70 72 65 74 65 72 2e 20 20 54 63 6c 20 69  erpreter.  Tcl i
b180: 6e 74 65 72 70 72 65 74 65 72 73 20 6d 75 73 74  nterpreters must
b190: 20 62 65 20 75 6e 69 71 75 65 20 70 65 72 0a 09   be unique per..
b1a0: 20 2a 20 74 68 72 65 61 64 20 61 6e 64 20 6e 65   * thread and ne
b1b0: 77 20 74 68 72 65 61 64 73 20 61 72 65 20 64 79  w threads are dy
b1c0: 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65 61 74 65  namically create
b1d0: 64 20 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a  d by FUSE... */.
b1e0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
b1f0: 74 68 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74  thread_key_creat
b200: 65 28 26 69 6e 74 65 72 70 4b 65 79 2c 20 61 70  e(&interpKey, ap
b210: 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e  pfs_terminate_in
b220: 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 29  terp_and_thread)
b230: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
b240: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72  et != 0) {...fpr
b250: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
b260: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54  able to create T
b270: 53 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20  SD key for Tcl. 
b280: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
b290: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
b2a0: 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c  .../*.. * Manual
b2b0: 6c 79 20 73 70 65 63 69 66 79 20 63 61 63 68 65  ly specify cache
b2c0: 20 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68   directory, with
b2d0: 6f 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63  out FUSE callbac
b2e0: 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f  k.. * This optio
b2f0: 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65  n only works whe
b300: 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45  n not using FUSE
b310: 2c 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64  , since we.. * d
b320: 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74  o not process it
b330: 20 77 69 74 68 20 46 55 53 45 73 20 6f 70 74 69   with FUSEs opti
b340: 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09  on processing...
b350: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d   */..if (argc >=
b360: 20 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63   2) {...if (strc
b370: 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63  mp(argv[0], "--c
b380: 61 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20  achedir") == 0) 
b390: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68 65  {....appfs_cache
b3a0: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
b3b0: 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20  v[1]);.....argc 
b3c0: 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d  -= 2;....argv +=
b3d0: 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a   2;...}..}.../*.
b3e0: 09 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65  . * SQLite3 mode
b3f0: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
b400: 77 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68  w SQL against th
b410: 65 20 63 61 63 68 65 20 64 61 74 61 62 61 73 65  e cache database
b420: 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20  .. */..if (argc 
b430: 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61  == 2 && strcmp(a
b440: 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74  rgv[0], "--sqlit
b450: 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72  e3") == 0) {...r
b460: 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69  eturn(appfs_sqli
b470: 74 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  te3(argv[1]));..
b480: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d  }.../*.. * Tcl m
b490: 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67  ode, for running
b4a0: 20 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20   raw Tcl in the 
b4b0: 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  same environment
b4c0: 20 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20   AppFSd would.. 
b4d0: 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f  * run code... */
b4e0: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20  ..if (argc == 2 
b4f0: 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30  && strcmp(argv[0
b500: 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30  ], "--tcl") == 0
b510: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70  ) {...return(app
b520: 66 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29  fs_tcl(argv[1]))
b530: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72  ;..}.../*.. * Cr
b540: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
b550: 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76  preter just to v
b560: 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67  erify that thing
b570: 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67  s are in working
b580: 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f   .. * order befo
b590: 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64  re we become a d
b5a0: 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73  aemon... */..tes
b5b0: 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  t_interp = appfs
b5c0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
b5d0: 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  p(&test_interp_e
b5e0: 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74  rror);..if (test
b5f0: 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  _interp == NULL)
b600: 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e   {...if (test_in
b610: 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55  terp_error == NU
b620: 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e  LL) {....test_in
b630: 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e  terp_error = "Un
b640: 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09  known error";...
b650: 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  }....fprintf(std
b660: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
b670: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69  initialize Tcl i
b680: 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41  nterpreter for A
b690: 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70  ppFSd:\n");...fp
b6a0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
b6b0: 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72  s\n", test_inter
b6c0: 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74  p_error);....ret
b6d0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c  urn(1);..}...Tcl
b6e0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65  _DeleteInterp(te
b6f0: 73 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63  st_interp);...Tc
b700: 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69  l_FinalizeNotifi
b710: 65 72 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  er(NULL);.../*..
b720: 20 2a 20 52 65 67 69 73 74 65 72 20 61 20 73 69   * Register a si
b730: 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72  gnal handler for
b740: 20 68 6f 74 2d 72 65 73 74 61 72 74 20 72 65 71   hot-restart req
b750: 75 65 73 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e  uests.. */..sign
b760: 61 6c 5f 72 65 74 20 3d 20 73 69 67 6e 61 6c 28  al_ret = signal(
b770: 53 49 47 48 55 50 2c 20 61 70 70 66 73 5f 73 69  SIGHUP, appfs_si
b780: 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09  gnal_handler);..
b790: 69 66 20 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d  if (signal_ret =
b7a0: 3d 20 53 49 47 5f 45 52 52 29 20 7b 0a 09 09 66  = SIG_ERR) {...f
b7b0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
b7c0: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c  Unable to instal
b7d0: 6c 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72  l signal handler
b7e0: 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74   for hot-restart
b7f0: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28  \n");...fprintf(
b800: 73 74 64 65 72 72 2c 20 22 48 6f 74 2d 72 65 73  stderr, "Hot-res
b810: 74 61 72 74 20 77 69 6c 6c 20 6e 6f 74 20 62 65  tart will not be
b820: 20 61 76 61 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b   available.\n");
b830: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 41 64 64  ..}.../*.. * Add
b840: 20 46 55 53 45 20 61 72 67 75 6d 65 6e 74 73 20   FUSE arguments 
b850: 77 68 69 63 68 20 77 65 20 61 6c 77 61 79 73 20  which we always 
b860: 73 75 70 70 6c 79 0a 09 20 2a 2f 0a 09 66 75 73  supply.. */..fus
b870: 65 5f 6f 70 74 5f 70 61 72 73 65 28 26 61 72 67  e_opt_parse(&arg
b880: 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 61  s, NULL, NULL, a
b890: 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62  ppfs_fuse_opt_cb
b8a0: 29 3b 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  );..fuse_opt_add
b8b0: 5f 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 64  _arg(&args, "-od
b8c0: 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f  efault_permissio
b8d0: 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c  ns,fsname=appfs,
b8e0: 73 75 62 74 79 70 65 3d 61 70 70 66 73 64 2c 75  subtype=appfsd,u
b8f0: 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61  se_ino,kernel_ca
b900: 63 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75  che,entry_timeou
b910: 74 3d 30 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74  t=0,attr_timeout
b920: 3d 30 2c 62 69 67 5f 77 72 69 74 65 73 2c 69 6e  =0,big_writes,in
b930: 74 72 2c 68 61 72 64 5f 72 65 6d 6f 76 65 22 29  tr,hard_remove")
b940: 3b 0a 0a 09 69 66 20 28 67 65 74 75 69 64 28 29  ;...if (getuid()
b950: 20 3d 3d 20 30 29 20 7b 0a 09 09 66 75 73 65 5f   == 0) {...fuse_
b960: 6f 70 74 5f 70 61 72 73 65 28 26 61 72 67 73 2c  opt_parse(&args,
b970: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c   NULL, NULL, NUL
b980: 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61  L);...fuse_opt_a
b990: 64 64 5f 61 72 67 28 26 61 72 67 73 2c 20 22 2d  dd_arg(&args, "-
b9a0: 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a  oallow_other");.
b9b0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74 65  .}.../*.. * Ente
b9c0: 72 20 74 68 65 20 46 55 53 45 20 6d 61 69 6e 20  r the FUSE main 
b9d0: 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77 69 6c  loop -- this wil
b9e0: 6c 20 70 72 6f 63 65 73 73 20 61 6e 79 20 61 72  l process any ar
b9f0: 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64 20  guments.. * and 
ba00: 73 74 61 72 74 20 73 65 72 76 69 63 69 6e 67 20  start servicing 
ba10: 72 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a 09  requests... */..
ba20: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
ba30: 65 64 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e 28  ed = 1;..return(
ba40: 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e 61  fuse_main(args.a
ba50: 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c 20  rgc, args.argv, 
ba60: 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e  &appfs_operation
ba70: 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a     s, NULL));.}. .