Hex Artifact Content

Artifact 4a8cebc0f0fc5ec0a7923b7761e4f3dfd9fabf98:


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 23 64 65 66 69 6e 65 20 41 50 50  EBUG.#define APP
01e0: 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b  FS_DEBUG(x...) {
01f0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
0200: 20 22 5b 64 65 62 75 67 5d 20 25 73 3a 25 69 3a   "[debug] %s:%i:
0210: 25 73 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f 2c  %s: ", __FILE__,
0220: 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e   __LINE__, __fun
0230: 63 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73 74  c__); fprintf(st
0240: 64 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e 74  derr, x); fprint
0250: 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b  f(stderr, "\n");
0260: 20 7d 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65   }.#else.#define
0270: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e   APPFS_DEBUG(x..
0280: 2e 29 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a  .) /**/.#endif..
0290: 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c 20 50  /*. * SHA1 Tcl P
02a0: 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c 69 7a  ackage initializ
02b0: 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a  er, from sha1.o.
02c0: 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69   */.int Sha1_Ini
02d0: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
02e0: 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68  terp);../*. * Th
02f0: 72 65 61 64 20 53 70 65 63 69 66 69 63 20 44 61  read Specific Da
0300: 74 61 20 28 54 53 44 29 20 66 6f 72 20 54 63 6c  ta (TSD) for Tcl
0310: 20 49 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72   Interpreter for
0320: 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
0330: 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70  ead. */.static p
0340: 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74  thread_key_t int
0350: 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47  erpKey;../*. * G
0360: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c  lobal variables,
0370: 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c 6c 20   needed for all 
0380: 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e 6c 79  threads but only
0390: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 65 66   initialized bef
03a0: 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53 45 20  ore any. * FUSE 
03b0: 74 68 72 65 61 64 73 20 61 72 65 20 63 72 65 61  threads are crea
03c0: 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68  ted. */.const ch
03d0: 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68 65 64  ar *appfs_cached
03e0: 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66 73  ir;.time_t appfs
03f0: 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61  _boottime;.int a
0400: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
0410: 64 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c  d = 0;../*. * Gl
0420: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
0430: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67  or AppFS caching
0440: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0450: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f  ex_t appfs_path_
0460: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
0470: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0480: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e  _INITIALIZER;.in
0490: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
04a0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38  o_cache_size = 8
04b0: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66  209;.struct appf
04c0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66  s_pathinfo *appf
04d0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
04e0: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 2f 2a 0a 20 2a  e = NULL;../*. *
04f0: 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   Global variable
0500: 73 20 66 6f 72 20 41 70 70 46 53 20 54 63 6c 20  s for AppFS Tcl 
0510: 49 6e 74 65 72 70 72 65 74 65 72 20 72 65 73 74  Interpreter rest
0520: 61 72 74 69 6e 67 0a 20 2a 2f 0a 69 6e 74 20 69  arting. */.int i
0530: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
0540: 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  = 0;../*. * AppF
0550: 53 20 50 61 74 68 20 54 79 70 65 3a 20 20 44 65  S Path Type:  De
0560: 73 63 72 69 62 65 73 20 74 68 65 20 74 79 70 65  scribes the type
0570: 20 6f 66 20 70 61 74 68 20 61 20 67 69 76 65 6e   of path a given
0580: 20 66 69 6c 65 20 69 73 0a 20 2a 2f 0a 74 79 70   file is. */.typ
0590: 65 64 65 66 20 65 6e 75 6d 20 7b 0a 09 41 50 50  edef enum {..APP
05a0: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
05b0: 4c 49 44 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  LID,..APPFS_PATH
05c0: 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58  TYPE_DOES_NOT_EX
05d0: 49 53 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  IST,..APPFS_PATH
05e0: 54 59 50 45 5f 46 49 4c 45 2c 0a 09 41 50 50 46  TYPE_FILE,..APPF
05f0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
0600: 54 4f 52 59 2c 0a 09 41 50 50 46 53 5f 50 41 54  TORY,..APPFS_PAT
0610: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09  HTYPE_SYMLINK,..
0620: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
0630: 4f 43 4b 45 54 2c 0a 09 41 50 50 46 53 5f 50 41  OCKET,..APPFS_PA
0640: 54 48 54 59 50 45 5f 46 49 46 4f 2c 0a 7d 20 61  THTYPE_FIFO,.} a
0650: 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 3b  ppfs_pathtype_t;
0660: 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61  ../*. * AppFS Pa
0670: 74 68 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a  th Information:.
0680: 20 2a 20 20 20 20 20 20 20 20 20 43 6f 6d 70 6c   *         Compl
0690: 65 74 65 6c 79 20 64 65 73 63 72 69 62 65 73 20  etely describes 
06a0: 61 20 73 70 65 63 69 66 69 63 20 70 61 74 68 2c  a specific path,
06b0: 20 68 6f 77 20 69 74 20 73 68 6f 75 6c 64 20 62   how it should b
06c0: 65 20 72 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a  e returned to. *
06d0: 20 20 20 20 20 20 20 20 20 74 6f 20 74 68 65 20           to the 
06e0: 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63  kernel. */.struc
06f0: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
0700: 20 7b 0a 09 61 70 70 66 73 5f 70 61 74 68 74 79   {..appfs_pathty
0710: 70 65 5f 74 20 74 79 70 65 3b 0a 09 74 69 6d 65  pe_t type;..time
0720: 5f 74 20 74 69 6d 65 3b 0a 09 63 68 61 72 20 68  _t time;..char h
0730: 6f 73 74 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69  ostname[256];..i
0740: 6e 74 20 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e  nt packaged;..un
0750: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
0760: 20 69 6e 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b   inode;..union {
0770: 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69  ...struct {....i
0780: 6e 74 20 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09  nt childcount;..
0790: 09 7d 20 64 69 72 3b 0a 09 09 73 74 72 75 63 74  .} dir;...struct
07a0: 20 7b 0a 09 09 09 69 6e 74 20 65 78 65 63 75 74   {....int execut
07b0: 61 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73  able;....off_t s
07c0: 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09  ize;...} file;..
07d0: 09 73 74 72 75 63 74 20 7b 0a 09 09 09 6f 66 66  .struct {....off
07e0: 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63 68 61 72  _t size;....char
07f0: 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09   source[256];...
0800: 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79  } symlink;..} ty
0810: 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74  peinfo;.../* Att
0820: 72 69 62 75 74 65 73 20 75 73 65 64 20 6f 6e 6c  ributes used onl
0830: 79 20 66 6f 72 20 63 61 63 68 69 6e 67 20 65 6e  y for caching en
0840: 74 72 69 65 73 20 2a 2f 0a 09 63 68 61 72 20 2a  tries */..char *
0850: 5f 63 61 63 68 65 5f 70 61 74 68 3b 0a 09 75 69  _cache_path;..ui
0860: 64 5f 74 20 5f 63 61 63 68 65 5f 75 69 64 3b 0a  d_t _cache_uid;.
0870: 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61 74 65  };../*. * Create
0880: 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72   a new Tcl inter
0890: 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d 70 6c  preter and compl
08a0: 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65  etely initialize
08b0: 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54   it. */.static T
08c0: 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73  cl_Interp *appfs
08d0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
08e0: 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72 5f 73  p(char **error_s
08f0: 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f 49 6e  tring) {..Tcl_In
0900: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69  terp *interp;..i
0910: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50  nt tcl_ret;...AP
0920: 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74  PFS_DEBUG("Creat
0930: 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65  ing new Tcl inte
0940: 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 20  rpreter for TID 
0950: 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69  = 0x%llx", (unsi
0960: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
0970: 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b  pthread_self());
0980: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f  ...interp = Tcl_
0990: 43 72 65 61 74 65 49 6e 74 65 72 70 28 29 3b 0a  CreateInterp();.
09a0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
09b0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
09c0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
09d0: 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 49   to create Tcl I
09e0: 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f  nterpreter.  Abo
09f0: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69  rting.\n");....i
0a00: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
0a10: 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72   {....*error_str
0a20: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22 55 6e  ing = strdup("Un
0a30: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54  able to create T
0a40: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
0a50: 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e  );...}....return
0a60: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (NULL);..}...Tcl
0a70: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
0a80: 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54  );...tcl_ret = T
0a90: 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b  cl_Init(interp);
0aa0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
0ab0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
0ac0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
0ad0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
0ae0: 7a 65 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e  ze Tcl.  Abortin
0af0: 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74  g.\n");...fprint
0b00: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
0b10: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
0b20: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0b30: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
0b40: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
0b50: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
0b60: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
0b70: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
0b80: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d  lt(interp));...}
0b90: 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ....Tcl_Release(
0ba0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 41 50 50 46  interp);....APPF
0bb0: 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61  S_DEBUG("Termina
0bc0: 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72  ting Tcl interpr
0bd0: 65 74 65 72 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f  eter.");....Tcl_
0be0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
0bf0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
0c00: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  NULL);..}...tcl_
0c10: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
0c20: 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20  nterp, "package 
0c30: 69 66 6e 65 65 64 65 64 20 73 68 61 31 20 31 2e  ifneeded sha1 1.
0c40: 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20  0 [list load {} 
0c50: 73 68 61 31 5d 22 29 3b 0a 09 69 66 20 28 74 63  sha1]");..if (tc
0c60: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
0c70: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
0c80: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
0c90: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 53  initialize Tcl S
0ca0: 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  HA1.  Aborting.\
0cb0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
0cc0: 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f  tderr, "Tcl Erro
0cd0: 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  r is: %s\n", Tcl
0ce0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
0cf0: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66  (interp));....if
0d00: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
0d10: 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  {....*error_stri
0d20: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
0d30: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
0d40: 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09  interp));...}...
0d50: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
0d60: 65 72 70 29 3b 0a 0a 09 09 41 50 50 46 53 5f 44  erp);....APPFS_D
0d70: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
0d80: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
0d90: 72 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c  r.");....Tcl_Del
0da0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
0db0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
0dc0: 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  L);..}...tcl_ret
0dd0: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
0de0: 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e  rp, "package ifn
0df0: 65 65 64 65 64 20 61 70 70 66 73 64 20 31 2e 30  eeded appfsd 1.0
0e00: 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 61   [list load {} a
0e10: 70 70 66 73 64 5d 22 29 3b 0a 09 69 66 20 28 74  ppfsd]");..if (t
0e20: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
0e30: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
0e40: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
0e50: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
0e60: 41 70 70 46 53 20 50 61 63 6b 61 67 65 2e 20 20  AppFS Package.  
0e70: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
0e80: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0e90: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
0ea0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
0eb0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0ec0: 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  p));....if (erro
0ed0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
0ee0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
0ef0: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
0f00: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0f10: 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52  ));...}....Tcl_R
0f20: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
0f30: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
0f40: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
0f50: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
0f60: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
0f70: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  erp(interp);....
0f80: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
0f90: 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 22  .../*.. * Load "
0fa0: 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68 65 20  pki.tcl" in the 
0fb0: 73 61 6d 65 20 77 61 79 20 61 73 20 61 70 70 66  same way as appf
0fc0: 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65 6c 6f  sd.tcl (see belo
0fd0: 77 29 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74  w).. */..tcl_ret
0fe0: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
0ff0: 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20  rp, "".#include 
1000: 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 22 22 29  "pki.tcl.h".."")
1010: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
1020: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
1030: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1040: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1050: 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20 41 62  ize Tcl PKI.  Ab
1060: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
1070: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1080: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1090: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
10a0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
10b0: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
10c0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
10d0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
10e0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
10f0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1100: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c  ;...}....Tcl_Rel
1110: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  ease(interp);...
1120: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
1130: 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e  rminating Tcl in
1140: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
1150: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
1160: 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  p(interp);....re
1170: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1180: 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 74 68 65  ./*.. * Load the
1190: 20 22 61 70 70 66 73 64 2e 74 63 6c 22 20 73 63   "appfsd.tcl" sc
11a0: 72 69 70 74 2c 20 77 68 69 63 68 20 69 73 20 22  ript, which is "
11b0: 63 6f 6d 70 69 6c 65 64 22 20 69 6e 74 6f 20 61  compiled" into a
11c0: 20 43 20 68 65 61 64 65 72 0a 09 20 2a 20 73 6f   C header.. * so
11d0: 20 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f   that it does no
11e0: 74 20 6e 65 65 64 20 74 6f 20 65 78 69 73 74 20  t need to exist 
11f0: 6f 6e 20 74 68 65 20 66 69 6c 65 73 79 73 74 65  on the filesyste
1200: 6d 20 61 6e 64 20 63 61 6e 20 62 65 0a 09 20 2a  m and can be.. *
1210: 20 64 69 72 65 63 74 6c 79 20 65 76 61 6c 75 61   directly evalua
1220: 74 65 64 2e 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72  ted... */..tcl_r
1230: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
1240: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
1250: 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 22  e "appfsd.tcl.h"
1260: 0a 09 22 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f  .."");..if (tcl_
1270: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
1280: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1290: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  r, "Unable to in
12a0: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70  itialize Tcl App
12b0: 46 53 20 73 63 72 69 70 74 2e 20 20 41 62 6f 72  FS script.  Abor
12c0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72  ting.\n");...fpr
12d0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
12e0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
12f0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1300: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1310: 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74  ....if (error_st
1320: 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f  ring) {....*erro
1330: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
1340: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
1350: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1360: 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61  ..}....Tcl_Relea
1370: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 41  se(interp);....A
1380: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
1390: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
13a0: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 54  rpreter.");....T
13b0: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
13c0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
13d0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
13e0: 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c  *.. * Set global
13f0: 20 76 61 72 69 61 62 6c 65 73 20 66 72 6f 6d 20   variables from 
1400: 43 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09 69  C to Tcl.. */..i
1410: 66 20 28 54 63 6c 5f 53 65 74 56 61 72 28 69 6e  f (Tcl_SetVar(in
1420: 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  terp, "::appfs::
1430: 63 61 63 68 65 64 69 72 22 2c 20 61 70 70 66 73  cachedir", appfs
1440: 5f 63 61 63 68 65 64 69 72 2c 20 54 43 4c 5f 47  _cachedir, TCL_G
1450: 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e  LOBAL_ONLY) == N
1460: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
1470: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
1480: 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69   to set cache di
1490: 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73  rectory.  This s
14a0: 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c  hould never fail
14b0: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72  .\n");....if (er
14c0: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
14d0: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
14e0: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
14f0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1500: 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c  rp));...}....Tcl
1510: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
1520: 3b 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  ;....APPFS_DEBUG
1530: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63  ("Terminating Tc
1540: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
1550: 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  ;....Tcl_DeleteI
1560: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
1570: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1580: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74  .}.../*.. * Init
1590: 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 70 66  ialize the "appf
15a0: 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d  sd.tcl" environm
15b0: 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 74 20  ent, which must 
15c0: 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a 09 20  be done after.. 
15d0: 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  * global variabl
15e0: 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f  es are set... */
15f0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
1600: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Eval(interp, "::
1610: 61 70 70 66 73 3a 3a 69 6e 69 74 22 29 3b 0a 09  appfs::init");..
1620: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
1630: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
1640: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1650: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
1660: 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69 70   Tcl AppFS scrip
1670: 74 20 28 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74  t (::appfs::init
1680: 29 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  ).  Aborting.\n"
1690: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
16a0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
16b0: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
16c0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
16d0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28  nterp));....if (
16e0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
16f0: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
1700: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
1710: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
1720: 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54  terp));...}....T
1730: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1740: 70 29 3b 0a 0a 09 09 41 50 50 46 53 5f 44 45 42  p);....APPFS_DEB
1750: 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20  UG("Terminating 
1760: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
1770: 22 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74  ");....Tcl_Delet
1780: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
1790: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
17a0: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69  ;..}.../*.. * Hi
17b0: 64 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d  de some Tcl comm
17c0: 61 6e 64 73 20 74 68 61 74 20 77 65 20 64 6f 20  ands that we do 
17d0: 6e 6f 74 20 63 61 72 65 20 74 6f 20 75 73 65 20  not care to use 
17e0: 61 6e 64 20 77 68 69 63 68 20 6d 61 79 0a 09 20  and which may.. 
17f0: 2a 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d  * slow down run-
1800: 74 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e  time operations.
1810: 0a 09 20 2a 2f 0a 09 54 63 6c 5f 48 69 64 65 43  .. */..Tcl_HideC
1820: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
1830: 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22  auto_load_index"
1840: 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64  , "auto_load_ind
1850: 65 78 22 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43  ex");..Tcl_HideC
1860: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
1870: 75 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f  unknown", "unkno
1880: 77 6e 22 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43  wn");..Tcl_HideC
1890: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
18a0: 65 78 69 74 22 2c 20 22 65 78 69 74 22 29 3b 0a  exit", "exit");.
18b0: 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65  ../*.. * Release
18c0: 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76   the hold we hav
18d0: 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72  e on the interpr
18e0: 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20  eter so that it 
18f0: 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74  may be.. * delet
1900: 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a  ed if needed.. *
1910: 2f 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  /..Tcl_Release(i
1920: 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nterp);.../*.. *
1930: 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d 70   Return the comp
1940: 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a  letely initializ
1950: 65 64 20 69 6e 74 65 72 70 72 65 74 65 72 0a 09  ed interpreter..
1960: 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e 74 65   */..return(inte
1970: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65  rp);.}../*. * Re
1980: 74 75 72 6e 20 74 68 65 20 74 68 72 65 61 64 2d  turn the thread-
1990: 73 70 65 63 69 66 69 63 20 54 63 6c 20 69 6e 74  specific Tcl int
19a0: 65 72 70 72 65 74 65 72 2c 20 63 72 65 61 74 69  erpreter, creati
19b0: 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65 64 0a  ng it if needed.
19c0: 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49   */.static Tcl_I
19d0: 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54 63 6c  nterp *appfs_Tcl
19e0: 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b 0a 09  Interp(void) {..
19f0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1a00: 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  rp;..int pthread
1a10: 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f  _ret;..static __
1a20: 74 68 72 65 61 64 20 69 6e 74 20 74 68 72 65 61  thread int threa
1a30: 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  d_interp_reset_k
1a40: 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 67 6c 6f  ey = 0;..int glo
1a50: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
1a60: 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69  _key;...global_i
1a70: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
1a80: 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61  = __sync_fetch_a
1a90: 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72  nd_add(&interp_r
1aa0: 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 0a 09  eset_key, 0);...
1ab0: 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65 61 64  interp = pthread
1ac0: 5f 67 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _getspecific(int
1ad0: 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28 69 6e  erpKey);..if (in
1ae0: 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 26 26 20  terp != NULL && 
1af0: 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65  thread_interp_re
1b00: 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c 6f 62 61  set_key != globa
1b10: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
1b20: 65 79 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  ey) {...APPFS_DE
1b30: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
1b40: 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 74 65 72   old interpreter
1b50: 20 61 6e 64 20 72 65 73 74 61 72 74 69 6e 67 20   and restarting 
1b60: 64 75 65 20 74 6f 20 72 65 73 65 74 20 72 65 71  due to reset req
1b70: 75 65 73 74 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f  uest.");....Tcl_
1b80: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1b90: 65 72 70 29 3b 0a 0a 09 09 69 6e 74 65 72 70 20  erp);....interp 
1ba0: 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 70 74 68 72 65  = NULL;....pthre
1bb0: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
1bc0: 5f 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _setspecific(int
1bd0: 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b  erpKey, interp);
1be0: 0a 09 7d 0a 0a 09 74 68 72 65 61 64 5f 69 6e 74  ..}...thread_int
1bf0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20  erp_reset_key = 
1c00: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
1c10: 73 65 74 5f 6b 65 79 3b 0a 0a 09 69 66 20 28 69  set_key;...if (i
1c20: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
1c30: 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
1c40: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
1c50: 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69 66 20  rp(NULL);....if 
1c60: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
1c70: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c   {....return(NUL
1c80: 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68 72 65  L);...}....pthre
1c90: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
1ca0: 5f 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _setspecific(int
1cb0: 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b  erpKey, interp);
1cc0: 0a 09 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ...if (pthread_r
1cd0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41 50  et != 0) {....AP
1ce0: 50 46 53 5f 44 45 42 55 47 28 22 70 74 68 72 65  PFS_DEBUG("pthre
1cf0: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 29  ad_setspecific()
1d00: 20 66 61 69 6c 65 64 2e 20 20 54 65 72 6d 69 6e   failed.  Termin
1d10: 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70  ating Tcl interp
1d20: 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 09 54 63  reter.");.....Tc
1d30: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
1d40: 6e 74 65 72 70 29 3b 0a 0a 09 09 09 72 65 74 75  nterp);.....retu
1d50: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d  rn(NULL);...}..}
1d60: 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70  ...return(interp
1d70: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c  );.}../*. * Eval
1d80: 75 61 74 65 20 61 20 54 63 6c 20 73 63 72 69 70  uate a Tcl scrip
1d90: 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 62 79  t constructed by
1da0: 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67 20 61   concatenating a
1db0: 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74 72 69   bunch of C stri
1dc0: 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65 72 2e  ngs. * together.
1dd0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
1de0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54  appfs_Tcl_Eval(T
1df0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
1e00: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e  p, int objc, con
1e10: 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e  st char *cmd, ..
1e20: 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a  .) {..Tcl_Obj **
1e30: 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61  objv;..const cha
1e40: 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74  r *arg;..va_list
1e50: 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65 74 76   argp;..int retv
1e60: 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66  al;..int i;...if
1e70: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
1e80: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c  ) {...return(TCL
1e90: 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62  _ERROR);..}...ob
1ea0: 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b  jv = (void *) ck
1eb0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62  alloc(sizeof(*ob
1ec0: 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 09 6f 62  jv) * objc);..ob
1ed0: 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65 77 53  jv[0] = Tcl_NewS
1ee0: 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20 2d 31  tringObj(cmd, -1
1ef0: 29 3b 0a 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  );..Tcl_IncrRefC
1f00: 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a  ount(objv[0]);..
1f10: 09 76 61 5f 73 74 61 72 74 28 61 72 67 70 2c 20  .va_start(argp, 
1f20: 63 6d 64 29 3b 0a 09 66 6f 72 20 28 69 20 3d 20  cmd);..for (i = 
1f30: 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  1; i < objc; i++
1f40: 29 20 7b 0a 09 09 61 72 67 20 3d 20 76 61 5f 61  ) {...arg = va_a
1f50: 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63  rg(argp, const c
1f60: 68 61 72 20 2a 29 3b 0a 09 09 6f 62 6a 76 5b 69  har *);...objv[i
1f70: 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  ] = Tcl_NewStrin
1f80: 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a 09  gObj(arg, -1);..
1f90: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
1fa0: 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 09  t(objv[i]);..}..
1fb0: 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a 0a 09  va_end(argp);...
1fc0: 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61  retval = Tcl_Eva
1fd0: 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62  lObjv(interp, ob
1fe0: 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a 0a 09  jc, objv, 0);...
1ff0: 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20  for (i = 0; i < 
2000: 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 54  objc; i++) {...T
2010: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
2020: 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 0a 09 63  objv[i]);..}...c
2030: 6b 66 72 65 65 28 28 76 6f 69 64 20 2a 29 20 6f  kfree((void *) o
2040: 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65 74 76  bjv);...if (retv
2050: 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  al != TCL_OK) {.
2060: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
2070: 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65  cl command faile
2080: 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63  d, ::errorInfo c
2090: 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20  ontains: %s\n", 
20a0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
20b0: 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22  p, "::errorInfo"
20c0: 2c 20 30 29 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  , 0));..}...retu
20d0: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f  rn(retval);.}../
20e0: 2a 0a 20 2a 20 52 65 71 75 65 73 74 20 61 6c 6c  *. * Request all
20f0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
2100: 73 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74  s restart. */.st
2110: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
2120: 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73  tcl_ResetInterps
2130: 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f  (void) {..APPFS_
2140: 44 45 42 55 47 28 22 52 65 71 75 65 73 74 69 6e  DEBUG("Requestin
2150: 67 20 72 65 73 65 74 20 6f 66 20 61 6c 6c 20 69  g reset of all i
2160: 6e 74 65 72 70 72 65 74 65 72 73 2e 22 29 3b 0a  nterpreters.");.
2170: 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 5f 61 6e 64  ..__sync_add_and
2180: 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72  _fetch(&interp_r
2190: 65 73 65 74 5f 6b 65 79 2c 20 31 29 3b 0a 0a 09  eset_key, 1);...
21a0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
21b0: 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 55   Determine the U
21c0: 49 44 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ID for the user 
21d0: 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65  making the curre
21e0: 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79 73 74  nt FUSE filesyst
21f0: 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54  em request.. * T
2200: 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64  his will be used
2210: 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75   to lookup the u
2220: 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63  ser's home direc
2230: 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73  tory so we can s
2240: 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63  earch for. * loc
2250: 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69  ally modified fi
2260: 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20  les.. */.static 
2270: 75 69 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f  uid_t appfs_get_
2280: 66 73 75 69 64 28 76 6f 69 64 29 20 7b 0a 09 73  fsuid(void) {..s
2290: 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65  truct fuse_conte
22a0: 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21  xt *ctx;...if (!
22b0: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
22c0: 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67  ed) {...return(g
22d0: 65 74 75 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63  etuid());..}...c
22e0: 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f  tx = fuse_get_co
22f0: 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74  ntext();..if (ct
2300: 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f  x == NULL) {.../
2310: 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b  * Unable to look
2320: 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65  up user for some
2330: 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20   reason */.../* 
2340: 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76  Return an unpriv
2350: 69 6c 65 67 65 64 20 75 73 65 72 20 49 44 20 2a  ileged user ID *
2360: 2f 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  /...return(1);..
2370: 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e  }...return(ctx->
2380: 75 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44  uid);.}../*. * D
2390: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 47 49 44  etermine the GID
23a0: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
23b0: 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  king the current
23c0: 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d   FUSE filesystem
23d0: 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69   request.. * Thi
23e0: 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74  s will be used t
23f0: 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65  o lookup the use
2400: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
2410: 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61  ry so we can sea
2420: 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c  rch for. * local
2430: 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65  ly modified file
2440: 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69  s.. */.static gi
2450: 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73  d_t appfs_get_fs
2460: 67 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72  gid(void) {..str
2470: 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74  uct fuse_context
2480: 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70   *ctx;...if (!ap
2490: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
24a0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74  ) {...return(get
24b0: 67 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78  gid());..}...ctx
24c0: 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74   = fuse_get_cont
24d0: 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20  ext();..if (ctx 
24e0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20  == NULL) {.../* 
24f0: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70  Unable to lookup
2500: 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72   user for some r
2510: 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65  eason */.../* Re
2520: 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c  turn an unprivil
2530: 65 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a  eged user ID */.
2540: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
2550: 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67 69  ..return(ctx->gi
2560: 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  d);.}..static vo
2570: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
2580: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
2590: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
25a0: 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  d(appfs_get_fsui
25b0: 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d());..setfsgid(
25c0: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
25d0: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  ));.}..static vo
25e0: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
25f0: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
2600: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
2610: 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d(0);..setfsgid(
2620: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f  0);.}../*. * Loo
2630: 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69  k up the home di
2640: 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69  rectory for a gi
2650: 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20  ven UID. *      
2660: 20 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74    Returns a C st
2670: 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ring containing 
2680: 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20  the user's home 
2690: 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c  directory or NUL
26a0: 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74  L if. *        t
26b0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
26c0: 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f  irectory does no
26d0: 74 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f  t exist or is no
26e0: 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20  t correctly. *  
26f0: 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64        configured
2700: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  . */.static char
2710: 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65   *appfs_get_home
2720: 64 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29  dir(uid_t fsuid)
2730: 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77   {..struct passw
2740: 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74  d entry, *result
2750: 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73  ;..struct stat s
2760: 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b  tbuf;..char buf[
2770: 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a  1024], *retval;.
2780: 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74  .int gpu_ret, st
2790: 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65  at_ret;...gpu_re
27a0: 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66  t = getpwuid_r(f
27b0: 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75  suid, &entry, bu
27c0: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20  f, sizeof(buf), 
27d0: 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67  &result);..if (g
27e0: 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  pu_ret != 0) {..
27f0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
2800: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
2810: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20  ..) returned in 
2820: 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67  failure", (unsig
2830: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
2840: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
2850: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
2860: 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29  (result == NULL)
2870: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2880: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
2890: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
28a0: 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28   NULL result", (
28b0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
28c0: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
28d0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
28e0: 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77  ..if (result->pw
28f0: 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  _dir == NULL) {.
2900: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
2910: 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20  etpwuid_r(%llu, 
2920: 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55  ...) returned NU
2930: 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  LL home director
2940: 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  y", (unsigned lo
2950: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
2960: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
2970: 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20  ;..}...stat_ret 
2980: 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70  = stat(result->p
2990: 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a  w_dir, &stbuf);.
29a0: 09 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d  .if (stat_ret !=
29b0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
29c0: 42 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65  BUG("stat(%s) re
29d0: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
29e0: 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64  e", result->pw_d
29f0: 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ir);....return(N
2a00: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  ULL);..}...if (s
2a10: 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66  tbuf.st_uid != f
2a20: 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f  suid) {...APPFS_
2a30: 44 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d  DEBUG("UID mis-m
2a40: 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c  atch on user %ll
2a50: 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  u's home directo
2a60: 72 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f  ry (%s).  It's o
2a70: 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a  wned by %llu.",.
2a80: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
2a90: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
2aa0: 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e  ,...    result->
2ab0: 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75  pw_dir,...    (u
2ac0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
2ad0: 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a  g) stbuf.st_uid.
2ae0: 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ..);....return(N
2af0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61  ULL);..}...retva
2b00: 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c  l = strdup(resul
2b10: 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65  t->pw_dir);...re
2b20: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
2b30: 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20  ./*. * Generate 
2b40: 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67  an inode for a g
2b50: 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20  iven path.  The 
2b60: 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20  inode should be 
2b70: 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68  computed in such
2b80: 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69  . * a way that i
2b90: 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f  t is unlikely to
2ba0: 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61   be duplicated a
2bb0: 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73  nd remains the s
2bc0: 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a  ame for a given.
2bd0: 20 2a 20 66 69 6c 65 0a 20 2a 2f 0a 23 69 66 20   * file. */.#if 
2be0: 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34 39  UINT_MAX < 42949
2bf0: 36 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e 74  67295.#error Int
2c00: 65 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f 6f  eger size is too
2c10: 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a 73   small .#endif.s
2c20: 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 6c  tatic unsigned l
2c30: 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f 67  ong long appfs_g
2c40: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63 6f  et_path_inode(co
2c50: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
2c60: 7b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09  {..int retval;..
2c70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a  const char *p;..
2c80: 09 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09  .retval = 10;...
2c90: 66 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a  for (p = path; *
2ca0: 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76  p; p++) {...retv
2cb0: 61 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30  al %= 4290960290
2cc0: 55 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d  ULL;...retval +=
2cd0: 20 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c   *p;...retval <<
2ce0: 3d 20 36 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  = 6;..}...retval
2cf0: 20 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20   += 10;..retval 
2d00: 25 3d 20 34 32 39 34 39 36 37 32 38 36 55 4c 4c  %= 4294967286ULL
2d10: 3b 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31 30 3b  ;..retval += 10;
2d20: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
2d30: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68  );.}../*. * Cach
2d40: 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20  e Get Path Info 
2d50: 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65  lookups for spee
2d60: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
2d70: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
2d80: 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63  info_cache_get(c
2d90: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
2da0: 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75   uid_t uid, stru
2db0: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
2dc0: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
2dd0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73  unsigned int has
2de0: 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72  h_idx;..int pthr
2df0: 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  ead_ret;..int re
2e00: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
2e10: 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65   1;...pthread_re
2e20: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
2e30: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
2e40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
2e50: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
2e60: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
2e70: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
2e80: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
2e90: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
2ea0: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
2eb0: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  n(-1);..}...if (
2ec0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2ed0: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
2ee0: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61  ...hash_idx = (a
2ef0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
2f00: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29  ode(path) + uid)
2f10: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
2f20: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
2f30: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
2f40: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
2f50: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
2f60: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  h != NULL) {....
2f70: 69 66 20 28 73 74 72 63 6d 70 28 61 70 70 66 73  if (strcmp(appfs
2f80: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
2f90: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
2fa0: 65 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d 3d  e_path, path) ==
2fb0: 20 30 20 26 26 20 61 70 70 66 73 5f 70 61 74 68   0 && appfs_path
2fc0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
2fd0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64  _idx]._cache_uid
2fe0: 20 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 72   == uid) {.....r
2ff0: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09  etval = 0;......
3000: 6d 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2c  memcpy(pathinfo,
3010: 20 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   &appfs_path_inf
3020: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3030: 5d 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69  ], sizeof(*pathi
3040: 6e 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 69  nfo));.....pathi
3050: 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68  nfo->_cache_path
3060: 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09   = NULL;....}...
3070: 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72  }..}...pthread_r
3080: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
3090: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
30a0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
30b0: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
30c0: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
30d0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
30e0: 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63  "Unable to unloc
30f0: 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68  k path_info cach
3100: 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09  e mutex !");....
3110: 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a  return(-1);..}..
3120: 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30  .if (retval == 0
3130: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
3140: 47 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e 20  G("Cache hit on 
3150: 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65  %s", path);..} e
3160: 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  lse {...APPFS_DE
3170: 42 55 47 28 22 43 61 63 68 65 20 6d 69 73 73 20  BUG("Cache miss 
3180: 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09  on %s", path);..
3190: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
31a0: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  l);.}..static vo
31b0: 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  id appfs_get_pat
31c0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64  h_info_cache_add
31d0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
31e0: 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74  h, uid_t uid, st
31f0: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
3200: 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b  nfo *pathinfo) {
3210: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  ..unsigned int h
3220: 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74  ash_idx;..int pt
3230: 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68  hread_ret;...pth
3240: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
3250: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
3260: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3270: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
3280: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
3290: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
32a0: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
32b0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
32c0: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
32d0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
32e0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
32f0: 66 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c  fo_cache == NULL
3300: 29 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 68  ) {...appfs_path
3310: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 61  _info_cache = ca
3320: 6c 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68 5f  lloc(appfs_path_
3330: 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c  info_cache_size,
3340: 20 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70   sizeof(*appfs_p
3350: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29  ath_info_cache))
3360: 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20  ;..}...hash_idx 
3370: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
3380: 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20  h_inode(path) + 
3390: 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74  uid) % appfs_pat
33a0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
33b0: 65 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  e;...if (appfs_p
33c0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
33d0: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
33e0: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
33f0: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
3400: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
3410: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
3420: 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  th);..}...memcpy
3430: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
3440: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3450: 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a  ], pathinfo, siz
3460: 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b  eof(*pathinfo));
3470: 0a 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
3480: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3490: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
34a0: 20 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a 09   strdup(path);..
34b0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
34c0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
34d0: 5f 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75 69  _cache_uid  = ui
34e0: 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  d;...pthread_ret
34f0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
3500: 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  _unlock(&appfs_p
3510: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
3520: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
3530: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
3540: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
3550: 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20  nable to unlock 
3560: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
3570: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
3580: 74 75 72 6e 3b 0a 09 7d 0a 09 72 65 74 75 72 6e  turn;..}..return
3590: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
35a0: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
35b0: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f  info_cache_rm(co
35c0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
35d0: 75 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e  uid_t uid) {..un
35e0: 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f  signed int hash_
35f0: 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61  idx;..int pthrea
3600: 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64  d_ret;...pthread
3610: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
3620: 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73  utex_lock(&appfs
3630: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3640: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
3650: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
3660: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3670: 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20  "Unable to lock 
3680: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
3690: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
36a0: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61  turn;..}...if (a
36b0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
36c0: 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  ache != NULL) {.
36d0: 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
36e0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
36f0: 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20  de(path) + uid) 
3700: 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  % appfs_path_inf
3710: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09  o_cache_size;...
3720: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
3730: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3740: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3750: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 66   != NULL) {....f
3760: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
3770: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3780: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29  dx]._cache_path)
3790: 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68  ;.....appfs_path
37a0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
37b0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
37c0: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d  h = NULL;...}..}
37d0: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
37e0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75   pthread_mutex_u
37f0: 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  nlock(&appfs_pat
3800: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
3810: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
3820: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
3830: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3840: 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61  ble to unlock pa
3850: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
3860: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
3870: 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b  rn;..}...return;
3880: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
3890: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
38a0: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
38b0: 75 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20 6e  uid_t uid, int n
38c0: 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69  ew_size) {..unsi
38d0: 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69  gned int idx;..i
38e0: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a  nt pthread_ret;.
38f0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 46  ..APPFS_DEBUG("F
3900: 6c 75 73 68 69 6e 67 20 41 70 70 46 53 20 63 61  lushing AppFS ca
3910: 63 68 65 20 28 75 69 64 20 3d 20 25 6c 6c 69 2c  che (uid = %lli,
3920: 20 6e 65 77 5f 73 69 7a 65 20 3d 20 25 69 29 22   new_size = %i)"
3930: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69  , (long long) ui
3940: 64 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09  d, new_size);...
3950: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
3960: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
3970: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
3980: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
3990: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
39a0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
39b0: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
39c0: 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  o lock path_info
39d0: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
39e0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
39f0: 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
3a00: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e  _info_cache != N
3a10: 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20 28 69 64  ULL) {...for (id
3a20: 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 61 70 70  x = 0; idx < app
3a30: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3a40: 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20  he_size; idx++) 
3a50: 7b 0a 09 09 09 69 66 20 28 61 70 70 66 73 5f 70  {....if (appfs_p
3a60: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69  ath_info_cache[i
3a70: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
3a80: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 69  != NULL) {.....i
3a90: 66 20 28 75 69 64 20 21 3d 20 28 28 75 69 64 5f  f (uid != ((uid_
3aa0: 74 29 20 2d 31 29 29 20 7b 0a 09 09 09 09 09 69  t) -1)) {......i
3ab0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3ac0: 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63  fo_cache[idx]._c
3ad0: 61 63 68 65 5f 75 69 64 20 21 3d 20 75 69 64 29  ache_uid != uid)
3ae0: 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74 69 6e 75   {.......continu
3af0: 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a  e;......}.....}.
3b00: 0a 09 09 09 09 66 72 65 65 28 61 70 70 66 73 5f  .....free(appfs_
3b10: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3b20: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3b30: 29 3b 0a 0a 09 09 09 09 61 70 70 66 73 5f 70 61  );......appfs_pa
3b40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64  th_info_cache[id
3b50: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
3b60: 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a   NULL;....}...}.
3b70: 09 7d 0a 0a 09 69 66 20 28 75 69 64 20 3d 3d 20  .}...if (uid == 
3b80: 28 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a  ((uid_t) -1)) {.
3b90: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
3ba0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 3b 0a 0a  h_info_cache);..
3bb0: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
3bc0: 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a  o_cache = NULL;.
3bd0: 0a 09 09 69 66 20 28 6e 65 77 5f 73 69 7a 65 20  ...if (new_size 
3be0: 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61 70 70 66  != -1) {....appf
3bf0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3c00: 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f 73 69 7a  e_size = new_siz
3c10: 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72  e;...}..}...pthr
3c20: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
3c30: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
3c40: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3c50: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
3c60: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
3c70: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
3c80: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
3c90: 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  unlock path_info
3ca0: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
3cb0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
3cc0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20  ..return;.}../* 
3cd0: 47 65 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  Get information 
3ce0: 61 62 6f 75 74 20 61 20 70 61 74 68 2c 20 61 6e  about a path, an
3cf0: 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73  d optionally lis
3d00: 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74  t children */.st
3d10: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 67  atic int appfs_g
3d20: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e  et_path_info(con
3d30: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
3d40: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
3d50: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20  info *pathinfo) 
3d60: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
3d70: 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20  nterp;..Tcl_Obj 
3d80: 2a 61 74 74 72 73 5f 64 69 63 74 2c 20 2a 61 74  *attrs_dict, *at
3d90: 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f 6e 73 74  tr_value;..const
3da0: 20 63 68 61 72 20 2a 61 74 74 72 5f 76 61 6c 75   char *attr_valu
3db0: 65 5f 73 74 72 3b 0a 09 54 63 6c 5f 57 69 64 65  e_str;..Tcl_Wide
3dc0: 49 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 77  Int attr_value_w
3dd0: 69 64 65 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76  ide;..int attr_v
3de0: 61 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69  alue_int;..stati
3df0: 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f  c __thread Tcl_O
3e00: 62 6a 20 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70  bj *attr_key_typ
3e10: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
3e20: 6b 65 79 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c  key_perms = NULL
3e30: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65  , *attr_key_size
3e40: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
3e50: 65 79 5f 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20  ey_time = NULL, 
3e60: 2a 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65  *attr_key_source
3e70: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
3e80: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ey_childcount = 
3e90: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
3ea0: 70 61 63 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b  packaged = NULL;
3eb0: 0a 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74 3b  ..int cache_ret;
3ec0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09  ..int tcl_ret;..
3ed0: 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09 66  uid_t fsuid;...f
3ee0: 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74  suid = appfs_get
3ef0: 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63 61 63 68  _fsuid();...cach
3f00: 65 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65  e_ret = appfs_ge
3f10: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
3f20: 65 5f 67 65 74 28 70 61 74 68 2c 20 66 73 75 69  e_get(path, fsui
3f30: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69  d, pathinfo);..i
3f40: 66 20 28 63 61 63 68 65 5f 72 65 74 20 3d 3d 20  f (cache_ret == 
3f50: 30 29 20 7b 0a 09 09 69 66 20 28 70 61 74 68 69  0) {...if (pathi
3f60: 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50  nfo->type == APP
3f70: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53  FS_PATHTYPE_DOES
3f80: 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b 0a 09 09  _NOT_EXIST) {...
3f90: 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29  .return(-ENOENT)
3fa0: 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 70 61 74  ;...}....if (pat
3fb0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41  hinfo->type == A
3fc0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
3fd0: 56 41 4c 49 44 29 20 7b 0a 09 09 09 72 65 74 75  VALID) {....retu
3fe0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09  rn(-EIO);...}...
3ff0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
4000: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
4010: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
4020: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
4030: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
4040: 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65  O);..}...Tcl_Pre
4050: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a  serve(interp);..
4060: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
4070: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
4080: 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67  , 2, "::appfs::g
4090: 65 74 61 74 74 72 22 2c 20 70 61 74 68 29 3b 0a  etattr", path);.
40a0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
40b0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
40c0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
40d0: 3a 3a 67 65 74 61 74 74 72 28 25 73 29 20 66 61  ::getattr(%s) fa
40e0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
40f0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
4100: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
4110: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
4120: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
4130: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
4140: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
4150: 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54  E_DOES_NOT_EXIST
4160: 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70  ;....appfs_get_p
4170: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61  ath_info_cache_a
4180: 64 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20  dd(path, fsuid, 
4190: 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 09 54 63  pathinfo);....Tc
41a0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
41b0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e  );....return(-EN
41c0: 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  OENT);..}...if (
41d0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d  attr_key_type ==
41e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 74 74 72 5f   NULL) {...attr_
41f0: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d  key_type       =
4200: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
4210: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09  j("type", -1);..
4220: 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20  .attr_key_perms 
4230: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
4240: 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c  ringObj("perms",
4250: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
4260: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63  _size       = Tc
4270: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4280: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  size", -1);...at
4290: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20  tr_key_time     
42a0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
42b0: 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29  gObj("time", -1)
42c0: 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ;...attr_key_sou
42d0: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  rce     = Tcl_Ne
42e0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72  wStringObj("sour
42f0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72  ce", -1);...attr
4300: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20  _key_childcount 
4310: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
4320: 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c  bj("childcount",
4330: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
4340: 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63  _packaged   = Tc
4350: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4360: 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a  packaged", -1);.
4370: 09 7d 0a 0a 09 61 74 74 72 73 5f 64 69 63 74 20  .}...attrs_dict 
4380: 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  = Tcl_GetObjResu
4390: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 74 63 6c  lt(interp);..tcl
43a0: 5f 72 65 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f  _ret = Tcl_DictO
43b0: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
43c0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
43d0: 65 79 5f 74 79 70 65 2c 20 26 61 74 74 72 5f 76  ey_type, &attr_v
43e0: 61 6c 75 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f  alue);..if (tcl_
43f0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
4400: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4410: 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70 65  [dict get \"type
4420: 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09  \"] failed");...
4430: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
4440: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
4450: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
4460: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
4470: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
4480: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
4490: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  -EIO);..}...if (
44a0: 61 74 74 72 5f 76 61 6c 75 65 20 3d 3d 20 4e 55  attr_value == NU
44b0: 4c 4c 29 20 7b 0a 09 09 54 63 6c 5f 52 65 6c 65  LL) {...Tcl_Rele
44c0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
44d0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
44e0: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
44f0: 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61 74 68  kaged = 0;..path
4500: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70  info->inode = ap
4510: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
4520: 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 74 74 72  de(path);...attr
4530: 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c  _value_str = Tcl
4540: 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f  _GetString(attr_
4550: 76 61 6c 75 65 29 3b 0a 0a 09 54 63 6c 5f 44 65  value);...Tcl_De
4560: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
4570: 76 61 6c 75 65 29 3b 0a 0a 09 73 77 69 74 63 68  value);...switch
4580: 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72   (attr_value_str
4590: 5b 30 5d 29 20 7b 0a 09 09 63 61 73 65 20 27 64  [0]) {...case 'd
45a0: 27 3a 20 2f 2a 20 64 69 72 65 63 74 6f 72 79 20  ': /* directory 
45b0: 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  */....pathinfo->
45c0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
45d0: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b  HTYPE_DIRECTORY;
45e0: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
45f0: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
4600: 63 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 54  count = 0;.....T
4610: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
4620: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
4630: 2c 20 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64  , attr_key_child
4640: 63 6f 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c  count, &attr_val
4650: 75 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72  ue);....if (attr
4660: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
4670: 7b 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20  {.....tcl_ret = 
4680: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
4690: 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72  omObj(NULL, attr
46a0: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
46b0: 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69  lue_wide);.....i
46c0: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
46d0: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74  L_OK) {......pat
46e0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
46f0: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
4700: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
4710: 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c  ;.....}......Tcl
4720: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 61 74  _DecrRefCount(at
4730: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 7d 0a  tr_value);....}.
4740: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
4750: 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a  e 'f': /* file *
4760: 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  /....pathinfo->t
4770: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
4780: 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09 70 61  TYPE_FILE;....pa
4790: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
47a0: 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b 0a  .file.size = 0;.
47b0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
47c0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75  einfo.file.execu
47d0: 74 61 62 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 54  table = 0;.....T
47e0: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
47f0: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
4800: 2c 20 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c  , attr_key_size,
4810: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
4820: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
4830: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
4840: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
4850: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
4860: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
4870: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
4880: 64 65 29 3b 0a 09 09 09 09 69 66 20 28 74 63 6c  de);.....if (tcl
4890: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
48a0: 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  {......pathinfo-
48b0: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  >typeinfo.file.s
48c0: 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65  ize = attr_value
48d0: 5f 77 69 64 65 3b 0a 09 09 09 09 7d 0a 0a 09 09  _wide;.....}....
48e0: 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75  ..Tcl_DecrRefCou
48f0: 6e 74 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  nt(attr_value);.
4900: 09 09 09 7d 0a 0a 09 09 09 54 63 6c 5f 44 69 63  ...}.....Tcl_Dic
4910: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
4920: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
4930: 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61 74 74  _key_perms, &att
4940: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 20  r_value);....if 
4950: 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e  (attr_value != N
4960: 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74 72 5f  ULL) {.....attr_
4970: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f  value_str = Tcl_
4980: 47 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f 76  GetString(attr_v
4990: 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61  alue);.....if (a
49a0: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d  ttr_value_str[0]
49b0: 20 3d 3d 20 27 78 27 29 20 7b 0a 09 09 09 09 09   == 'x') {......
49c0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
49d0: 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62  fo.file.executab
49e0: 6c 65 20 3d 20 31 3b 0a 09 09 09 09 7d 0a 0a 09  le = 1;.....}...
49f0: 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  ...Tcl_DecrRefCo
4a00: 75 6e 74 28 61 74 74 72 5f 76 61 6c 75 65 29 3b  unt(attr_value);
4a10: 0a 09 09 09 7d 0a 09 09 09 62 72 65 61 6b 3b 0a  ....}....break;.
4a20: 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73  ..case 's': /* s
4a30: 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 70 61 74  ymlink */....pat
4a40: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
4a50: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d  PFS_PATHTYPE_SYM
4a60: 4c 49 4e 4b 3b 0a 09 09 09 70 61 74 68 69 6e 66  LINK;....pathinf
4a70: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
4a80: 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09  ink.size = 0;...
4a90: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
4aa0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
4ab0: 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  ce[0] = '\0';...
4ac0: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
4ad0: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
4ae0: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f  ict, attr_key_so
4af0: 75 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  urce, &attr_valu
4b00: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
4b10: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
4b20: 0a 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f  .....attr_value_
4b30: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
4b40: 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f  ingFromObj(attr_
4b50: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
4b60: 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 69  ue_int); ......i
4b70: 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69  f ((attr_value_i
4b80: 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f  nt + 1) <= sizeo
4b90: 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  f(pathinfo->type
4ba0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
4bb0: 72 63 65 29 29 20 7b 0a 09 09 09 09 09 70 61 74  rce)) {......pat
4bc0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
4bd0: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61  symlink.size = a
4be0: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09  ttr_value_int;..
4bf0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
4c00: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
4c10: 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65  ource[attr_value
4c20: 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  _int] = '\0';...
4c30: 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69  ....memcpy(pathi
4c40: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
4c50: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74  mlink.source, at
4c60: 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74  tr_value_str, at
4c70: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09  tr_value_int);..
4c80: 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f 44 65  ...}......Tcl_De
4c90: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
4ca0: 76 61 6c 75 65 29 3b 0a 09 09 09 7d 0a 09 09 09  value);....}....
4cb0: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 46  break;...case 'F
4cc0: 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66 6f 20  ': /* pipe/fifo 
4cd0: 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  */....pathinfo->
4ce0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
4cf0: 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09 09 09 62  HTYPE_FIFO;....b
4d00: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 53 27  reak;...case 'S'
4d10: 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e  : /* UNIX domain
4d20: 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 70 61   socket */....pa
4d30: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
4d40: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f  PPFS_PATHTYPE_SO
4d50: 43 4b 45 54 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  CKET;....break;.
4d60: 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 54 63  ..default:....Tc
4d70: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 61  l_DecrRefCount(a
4d80: 74 74 72 73 5f 64 69 63 74 29 3b 0a 0a 09 09 09  ttrs_dict);.....
4d90: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
4da0: 72 70 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  rp);.....return(
4db0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  -EIO);..}...Tcl_
4dc0: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
4dd0: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
4de0: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
4df0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
4e00: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
4e10: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 70 61 74  != NULL) {...pat
4e20: 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20  hinfo->packaged 
4e30: 3d 20 31 3b 0a 0a 09 09 54 63 6c 5f 44 65 63 72  = 1;....Tcl_Decr
4e40: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 76 61  RefCount(attr_va
4e50: 6c 75 65 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44  lue);..}...Tcl_D
4e60: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
4e70: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
4e80: 74 72 5f 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74  tr_key_time, &at
4e90: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66 20 28  tr_value);..if (
4ea0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
4eb0: 4c 4c 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20  LL) {...tcl_ret 
4ec0: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
4ed0: 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74  FromObj(NULL, at
4ee0: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
4ef0: 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 69  value_wide);...i
4f00: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
4f10: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 70 61 74 68 69  L_OK) {....pathi
4f20: 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 72  nfo->time = attr
4f30: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 7d  _value_wide;...}
4f40: 0a 0a 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43  ....Tcl_DecrRefC
4f50: 6f 75 6e 74 28 61 74 74 72 5f 76 61 6c 75 65 29  ount(attr_value)
4f60: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 70 61  ;..} else {...pa
4f70: 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 30  thinfo->time = 0
4f80: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 52 65 6c 65 61  ;..}...Tcl_Relea
4f90: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 61 70  se(interp);...ap
4fa0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4fb0: 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68  o_cache_add(path
4fc0: 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66  , fsuid, pathinf
4fd0: 6f 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  o);...return(0);
4fe0: 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20  .}..static char 
4ff0: 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74  *appfs_prepare_t
5000: 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  o_create(const c
5010: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
5020: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5030: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
5040: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
5050: 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f  cl_ret;...appfs_
5060: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
5070: 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f  che_flush(appfs_
5080: 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29  get_fsuid(), -1)
5090: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
50a0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
50b0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
50c0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
50d0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  NULL);..}...Tcl_
50e0: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
50f0: 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  ;...tcl_ret = ap
5100: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
5110: 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73  erp, 2, "::appfs
5120: 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  ::prepare_to_cre
5130: 61 74 65 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ate", path);..if
5140: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
5150: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
5160: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70  EBUG("::appfs::p
5170: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
5180: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
5190: 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45  ath);...APPFS_DE
51a0: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
51b0: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
51c0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
51d0: 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c  rp));....Tcl_Rel
51e0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  ease(interp);...
51f0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
5200: 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  }...real_path = 
5210: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
5220: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 54  ult(interp);...T
5230: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
5240: 70 29 3b 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70  p);...if (real_p
5250: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
5260: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
5270: 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75  }...return(strdu
5280: 70 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d  p(real_path));.}
5290: 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61  ..static char *a
52a0: 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63  ppfs_localpath(c
52b0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29  onst char *path)
52c0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
52d0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
52e0: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
52f0: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
5300: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5310: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5320: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5330: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
5340: 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73  );..}...Tcl_Pres
5350: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  erve(interp);...
5360: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
5370: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
5380: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f   2, "::appfs::lo
5390: 63 61 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b  calpath", path);
53a0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
53b0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
53c0: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
53d0: 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29  s::localpath(%s)
53e0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
53f0: 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5400: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
5410: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
5420: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
5430: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
5440: 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74  );..}...real_pat
5450: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
5460: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
5470: 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
5480: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72 65  nterp);...if (re
5490: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
54a0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
54b0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73  );..}...return(s
54c0: 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29  trdup(real_path)
54d0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
54e0: 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64   appfs_fuse_read
54f0: 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20  link(const char 
5500: 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66  *path, char *buf
5510: 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b  , size_t size) {
5520: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
5530: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
5540: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20  ;..int retval = 
5550: 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  0;...APPFS_DEBUG
5560: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
5570: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
5580: 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70  ;...pathinfo.typ
5590: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
55a0: 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65  PE_INVALID;...re
55b0: 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74  tval = appfs_get
55c0: 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c  _path_info(path,
55d0: 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66   &pathinfo);..if
55e0: 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b   (retval != 0) {
55f0: 0a 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
5600: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  );..}...if (path
5610: 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50  info.type != APP
5620: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
5630: 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  INK) {...return(
5640: 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69  -EINVAL);..}...i
5650: 66 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69  f ((strlen(pathi
5660: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
5670: 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31  link.source) + 1
5680: 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65  ) > size) {...re
5690: 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f  turn(-ENAMETOOLO
56a0: 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  NG);..}...memcpy
56b0: 28 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74  (buf, pathinfo.t
56c0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
56d0: 73 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70  source, strlen(p
56e0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
56f0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29  .symlink.source)
5700: 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28   + 1);...return(
5710: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
5720: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74  t appfs_fuse_get
5730: 61 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20  attr(const char 
5740: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74  *path, struct st
5750: 61 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74  at *stbuf) {..st
5760: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
5770: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69  nfo pathinfo;..i
5780: 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74  nt retval;...ret
5790: 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53  val = 0;...APPFS
57a0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
57b0: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
57c0: 20 70 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e   path);...pathin
57d0: 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  fo.type = APPFS_
57e0: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
57f0: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70  ;...retval = app
5800: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
5810: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
5820: 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21  );..if (retval !
5830: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
5840: 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65  retval);..}...me
5850: 6d 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73  mset(stbuf, 0, s
5860: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61  izeof(struct sta
5870: 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74  t));...stbuf->st
5880: 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66  _mtime = pathinf
5890: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e  o.time;..stbuf->
58a0: 73 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69  st_ctime = pathi
58b0: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
58c0: 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74  ->st_atime = pat
58d0: 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62  hinfo.time;..stb
58e0: 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70  uf->st_ino   = p
58f0: 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09  athinfo.inode;..
5900: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20  stbuf->st_mode  
5910: 3d 20 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70  = 0;...switch (p
5920: 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a  athinfo.type) {.
5930: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
5940: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a  HTYPE_DIRECTORY:
5950: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
5960: 64 65 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30  de = S_IFDIR | 0
5970: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
5980: 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61  t_nlink = 2 + pa
5990: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
59a0: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a  dir.childcount;.
59b0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
59c0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
59d0: 46 49 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74  FILE:....if (pat
59e0: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
59f0: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20  ile.executable) 
5a00: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
5a10: 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c  mode = S_IFREG |
5a20: 20 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65   0555;....} else
5a30: 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74   {.....stbuf->st
5a40: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20  _mode = S_IFREG 
5a50: 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09  | 0444;....}....
5a60: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
5a70: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
5a80: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
5a90: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
5aa0: 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b  .size;....break;
5ab0: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
5ac0: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a  THTYPE_SYMLINK:.
5ad0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
5ae0: 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35  e = S_IFLNK | 05
5af0: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
5b00: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
5b10: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
5b20: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
5b30: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a  o.symlink.size;.
5b40: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
5b50: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
5b60: 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66  SOCKET:....stbuf
5b70: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
5b80: 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09  SOCK | 0555;....
5b90: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
5ba0: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
5bb0: 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62  t_size = 0;....b
5bc0: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
5bd0: 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f  FS_PATHTYPE_FIFO
5be0: 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  :....stbuf->st_m
5bf0: 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20  ode = S_IFIFO | 
5c00: 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e  0555;....stbuf->
5c10: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
5c20: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
5c30: 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  = 0;....break;..
5c40: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
5c50: 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58  TYPE_DOES_NOT_EX
5c60: 49 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d  IST:....retval =
5c70: 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72   -ENOENT;.....br
5c80: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
5c90: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
5ca0: 49 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ID:....retval = 
5cb0: 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b  -EIO;.....break;
5cc0: 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e  ..}...if (pathin
5cd0: 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09  fo.packaged) {..
5ce0: 09 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20  .stbuf->st_uid  
5cf0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75   = appfs_get_fsu
5d00: 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73  id();...stbuf->s
5d10: 74 5f 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f  t_gid   = appfs_
5d20: 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73  get_fsgid();...s
5d30: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d  tbuf->st_mode |=
5d40: 20 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75   0200;..}...retu
5d50: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73  rn(retval);.}..s
5d60: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
5d70: 66 75 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e  fuse_readdir(con
5d80: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76  st char *path, v
5d90: 6f 69 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66  oid *buf, fuse_f
5da0: 69 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72  ill_dir_t filler
5db0: 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20  , off_t offset, 
5dc0: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
5dd0: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63  _info *fi) {..Tc
5de0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5df0: 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69  ;..Tcl_Obj **chi
5e00: 6c 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c  ldren;..int chil
5e10: 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b  dren_count, idx;
5e20: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
5e30: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
5e40: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
5e50: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
5e60: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5e70: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5e80: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5e90: 20 7b 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a   {...return(0);.
5ea0: 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76  .}...Tcl_Preserv
5eb0: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 66 69 6c  e(interp);...fil
5ec0: 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e 55  ler(buf, ".", NU
5ed0: 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72 28  LL, 0);..filler(
5ee0: 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c  buf, "..", NULL,
5ef0: 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d   0);...tcl_ret =
5f00: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
5f10: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70  interp, 2, "::ap
5f20: 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e  pfs::getchildren
5f30: 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74  ", path);..if (t
5f40: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
5f50: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
5f60: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63  G("::appfs::getc
5f70: 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69 6c  hildren(%s) fail
5f80: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41  ed.", path);...A
5f90: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
5fa0: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
5fb0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5fc0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
5fd0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
5fe0: 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30  rp);....return(0
5ff0: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
6000: 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74  = Tcl_ListObjGet
6010: 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c  Elements(interp,
6020: 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c   Tcl_GetObjResul
6030: 74 28 69 6e 74 65 72 70 29 2c 20 26 63 68 69 6c  t(interp), &chil
6040: 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 26 63 68 69  dren_count, &chi
6050: 6c 64 72 65 6e 29 3b 0a 09 69 66 20 28 74 63 6c  ldren);..if (tcl
6060: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
6070: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
6080: 22 50 61 72 73 69 6e 67 20 6c 69 73 74 20 6f 66  "Parsing list of
6090: 20 63 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74   children on pat
60a0: 68 20 25 73 20 66 61 69 6c 65 64 2e 22 2c 20 70  h %s failed.", p
60b0: 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45  ath);...APPFS_DE
60c0: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
60d0: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
60e0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
60f0: 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c  rp));....Tcl_Rel
6100: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  ease(interp);...
6110: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
6120: 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69  .for (idx = 0; i
6130: 64 78 20 3c 20 63 68 69 6c 64 72 65 6e 5f 63 6f  dx < children_co
6140: 75 6e 74 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09  unt; idx++) {...
6150: 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f  filler(buf, Tcl_
6160: 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64 72  GetString(childr
6170: 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20  en[idx]), NULL, 
6180: 30 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 65 63  0);..}...Tcl_Dec
6190: 72 52 65 66 43 6f 75 6e 74 28 63 68 69 6c 64 72  rRefCount(childr
61a0: 65 6e 29 3b 0a 0a 09 54 63 6c 5f 52 65 6c 65 61  en);...Tcl_Relea
61b0: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 72 65  se(interp);...re
61c0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
61d0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
61e0: 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68 61  e_open(const cha
61f0: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
6200: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
6210: 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  fi) {..Tcl_Inter
6220: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73 74 72 75  p *interp;..stru
6230: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
6240: 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 63 6f 6e  o pathinfo;..con
6250: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
6260: 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69 6e 74 20  th, *mode;..int 
6270: 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f 72 65 74  gpi_ret, tcl_ret
6280: 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09 41 50 50  ;..int fh;...APP
6290: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
62a0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
62b0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67 70 69 5f  ", path);...gpi_
62c0: 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  ret = appfs_get_
62d0: 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20  path_info(path, 
62e0: 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 69 66  &pathinfo);...if
62f0: 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 28   ((fi->flags & (
6300: 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45 41 54  O_WRONLY|O_CREAT
6310: 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54 7c 4f  )) == (O_CREAT|O
6320: 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09 2f 2a  _WRONLY)) {.../*
6330: 20 54 68 65 20 66 69 6c 65 20 77 69 6c 6c 20 62   The file will b
6340: 65 20 63 72 65 61 74 65 64 20 69 66 20 69 74 20  e created if it 
6350: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 2a  does not exist *
6360: 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20  /...if (gpi_ret 
6370: 21 3d 20 30 20 26 26 20 67 70 69 5f 72 65 74 20  != 0 && gpi_ret 
6380: 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09 09  != -ENOENT) {...
6390: 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65 74 29  .return(gpi_ret)
63a0: 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20  ;...}....mode = 
63b0: 22 63 72 65 61 74 65 22 3b 0a 0a 09 09 2f 2a 0a  "create";..../*.
63c0: 09 09 20 2a 20 57 65 20 68 61 76 65 20 74 6f 20  .. * We have to 
63d0: 63 6c 65 61 72 20 74 68 65 20 63 61 63 68 65 20  clear the cache 
63e0: 68 65 72 65 20 73 6f 20 74 68 61 74 20 74 68 65  here so that the
63f0: 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09 20 2a 20   number of... * 
6400: 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61 69 6e 74  links gets maint
6410: 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 70 61 72  ained on the par
6420: 65 6e 74 20 64 69 72 65 63 74 6f 72 79 0a 09 09  ent directory...
6430: 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67 65 74 5f   */...appfs_get_
6440: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
6450: 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f  flush(appfs_get_
6460: 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 09 7d  fsuid(), -1);..}
6470: 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20 54 68 65   else {.../* The
6480: 20 66 69 6c 65 20 6d 75 73 74 20 61 6c 72 65 61   file must alrea
6490: 64 79 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66  dy exist */...if
64a0: 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30 29 20   (gpi_ret != 0) 
64b0: 7b 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f  {....return(gpi_
64c0: 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64  ret);...}....mod
64d0: 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66 20 28 28  e = "";....if ((
64e0: 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f 5f 57 52  fi->flags & O_WR
64f0: 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f 4e 4c  ONLY) == O_WRONL
6500: 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20 3d 20 22  Y) {....mode = "
6510: 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09 7d 0a 0a  write";...}..}..
6520: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
6530: 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48  pe == APPFS_PATH
6540: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 29 20  TYPE_DIRECTORY) 
6550: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44  {...return(-EISD
6560: 49 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70  IR);..}...interp
6570: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
6580: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
6590: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
65a0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
65b0: 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  ..Tcl_Preserve(i
65c0: 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f 72 65  nterp);...tcl_re
65d0: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
65e0: 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a  al(interp, 3, ":
65f0: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
6600: 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a  ", path, mode);.
6610: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
6620: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
6630: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
6640: 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25  ::openpath(%s, %
6650: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
6660: 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 41 50 50 46  h, mode);...APPF
6670: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
6680: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
6690: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
66a0: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c  interp));....Tcl
66b0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
66c0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  ;....return(-EIO
66d0: 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74  );..}...real_pat
66e0: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
66f0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
6700: 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
6710: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72 65  nterp);...if (re
6720: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
6730: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
6740: 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45  );..}...APPFS_DE
6750: 42 55 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20  BUG("Translated 
6760: 72 65 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20  request to open 
6770: 25 73 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73  %s to opening %s
6780: 20 28 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29   (mode = \"%s\")
6790: 22 2c 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61  ", path, real_pa
67a0: 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20  th, mode);...fh 
67b0: 3d 20 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68  = open(real_path
67c0: 2c 20 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30  , fi->flags, 060
67d0: 30 29 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30  0);...if (fh < 0
67e0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
67f0: 4f 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20  O);..}...fi->fh 
6800: 3d 20 66 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30  = fh;...return(0
6810: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
6820: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73   appfs_fuse_clos
6830: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
6840: 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  th, struct fuse_
6850: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
6860: 0a 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b  ..int close_ret;
6870: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
6880: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28  h_info_cache_rm(
6890: 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f  path, appfs_get_
68a0: 66 73 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73  fsuid());...clos
68b0: 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69  e_ret = close(fi
68c0: 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73  ->fh);..if (clos
68d0: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  e_ret != 0) {...
68e0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
68f0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
6900: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6910: 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e 73  s_fuse_read(cons
6920: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68  t char *path, ch
6930: 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20  ar *buf, size_t 
6940: 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73  size, off_t offs
6950: 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  et, struct fuse_
6960: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
6970: 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65  ..off_t lseek_re
6980: 74 3b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61 64  t;..ssize_t read
6990: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
69a0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
69b0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
69c0: 74 68 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74  th);...lseek_ret
69d0: 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c   = lseek(fi->fh,
69e0: 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45   offset, SEEK_SE
69f0: 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72  T);..if (lseek_r
6a00: 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a  et != offset) {.
6a10: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
6a20: 09 7d 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d 20  .}...read_ret = 
6a30: 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66  read(fi->fh, buf
6a40: 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72  , size);...retur
6a50: 6e 28 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a  n(read_ret);.}..
6a60: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
6a70: 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f 6e 73  _fuse_write(cons
6a80: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 6f  t char *path, co
6a90: 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c 20 73  nst char *buf, s
6aa0: 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f  ize_t size, off_
6ab0: 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74  t offset, struct
6ac0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
6ad0: 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c 73  *fi) {..off_t ls
6ae0: 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65 5f  eek_ret;..ssize_
6af0: 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 0a 09 41  t write_ret;...A
6b00: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
6b10: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
6b20: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70  .)", path);...ap
6b30: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
6b40: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c  o_cache_rm(path,
6b50: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
6b60: 28 29 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74  ());...lseek_ret
6b70: 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c   = lseek(fi->fh,
6b80: 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45   offset, SEEK_SE
6b90: 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72  T);..if (lseek_r
6ba0: 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a  et != offset) {.
6bb0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
6bc0: 09 7d 0a 0a 09 77 72 69 74 65 5f 72 65 74 20 3d  .}...write_ret =
6bd0: 20 77 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62   write(fi->fh, b
6be0: 75 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74  uf, size);...ret
6bf0: 75 72 6e 28 77 72 69 74 65 5f 72 65 74 29 3b 0a  urn(write_ret);.
6c00: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
6c10: 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63  pfs_fuse_mknod(c
6c20: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
6c30: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65   mode_t mode, de
6c40: 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63  v_t device) {..c
6c50: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
6c60: 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a  .int mknod_ret;.
6c70: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
6c80: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
6c90: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
6ca0: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
6cb0: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52  FCHR) == S_IFCHR
6cc0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
6cd0: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  ERM);..}...if ((
6ce0: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20  mode & S_IFBLK) 
6cf0: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09  == S_IFBLK) {...
6d00: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
6d10: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  .}...real_path =
6d20: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
6d30: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
6d40: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
6d50: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6d60: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
6d70: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
6d80: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
6d90: 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e  .mknod_ret = mkn
6da0: 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  od(real_path, mo
6db0: 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61  de, device);...a
6dc0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
6dd0: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
6de0: 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29  .free(real_path)
6df0: 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65  ;...if (mknod_re
6e00: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
6e10: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
6e20: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
6e30: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
6e40: 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28  pfs_fuse_create(
6e50: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6e60: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73  , mode_t mode, s
6e70: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
6e80: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61  info *fi) {..cha
6e90: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
6ea0: 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44  nt fd;...APPFS_D
6eb0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
6ec0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
6ed0: 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64  ath);...if ((mod
6ee0: 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20  e & S_IFCHR) == 
6ef0: 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74  S_IFCHR) {...ret
6f00: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
6f10: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
6f20: 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c  IFBLK) == S_IFBL
6f30: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  K) {...return(-E
6f40: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c  PERM);..}...real
6f50: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
6f60: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
6f70: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
6f80: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
6f90: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
6fa0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
6fb0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
6fc0: 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65  er();...fd = cre
6fd0: 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  at(real_path, mo
6fe0: 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  de);...appfs_sim
6ff0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
7000: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
7010: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
7020: 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75  fd < 0) {...retu
7030: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
7040: 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64  .}...fi->fh = fd
7050: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
7060: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
7070: 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65  fs_fuse_truncate
7080: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
7090: 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b  h, off_t size) {
70a0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
70b0: 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65  h;..int truncate
70c0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
70d0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
70e0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
70f0: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68  th);...real_path
7100: 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61   = appfs_localpa
7110: 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  th(path);..if (r
7120: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
7130: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
7140: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67  O);..}...appfs_g
7150: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
7160: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66  he_rm(path, appf
7170: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
7180: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
7190: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
71a0: 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74  ;...truncate_ret
71b0: 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c   = truncate(real
71c0: 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09  _path, size);...
71d0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
71e0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
71f0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
7200: 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74  );...if (truncat
7210: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  e_ret != 0) {...
7220: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
7230: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
7240: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
7250: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c  t appfs_fuse_unl
7260: 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20  ink_rmdir(const 
7270: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
7280: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
7290: 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  p;..int tcl_ret;
72a0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
72b0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
72c0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
72d0: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
72e0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
72f0: 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  h(appfs_get_fsui
7300: 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65  d(), -1);...inte
7310: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
7320: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
7330: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
7340: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
7350: 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  }...tcl_ret = ap
7360: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
7370: 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73  erp, 2, "::appfs
7380: 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20 70  ::unlinkpath", p
7390: 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  ath);..if (tcl_r
73a0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
73b0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
73c0: 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61  :appfs::unlinkpa
73d0: 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  th(%s) failed.",
73e0: 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f   path);...APPFS_
73f0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
7400: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
7410: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
7420: 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52  terp));....Tcl_R
7430: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
7440: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
7450: 0a 09 7d 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73  ..}...Tcl_Releas
7460: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 72 65 74  e(interp);...ret
7470: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
7480: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
7490: 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68 61  _mkdir(const cha
74a0: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
74b0: 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a 72  mode) {..char *r
74c0: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d  eal_path;..int m
74d0: 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50 46  kdir_ret;...APPF
74e0: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
74f0: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
7500: 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f  , path);...real_
7510: 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65  path = appfs_pre
7520: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70  pare_to_create(p
7530: 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f  ath);..if (real_
7540: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
7550: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
7560: 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  .}...appfs_simul
7570: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
7580: 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65 74  r();...mkdir_ret
7590: 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70 61   = mkdir(real_pa
75a0: 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70  th, mode);...app
75b0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
75c0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
75d0: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
75e0: 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74 20  ..if (mkdir_ret 
75f0: 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65 72  != 0) {...if (er
7600: 72 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20 7b  rno != EEXIST) {
7610: 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
7620: 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a   * -1);...}..}..
7630: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
7640: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7650: 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73 74  fuse_chmod(const
7660: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64   char *path, mod
7670: 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63 6c  e_t mode) {..Tcl
7680: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
7690: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65  ..const char *re
76a0: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63  al_path;..int tc
76b0: 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65 74  l_ret, chmod_ret
76c0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
76d0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
76e0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
76f0: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
7700: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28  h_info_cache_rm(
7710: 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f  path, appfs_get_
7720: 66 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74 65  fsuid());...inte
7730: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
7740: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
7750: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
7760: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
7770: 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65  }...Tcl_Preserve
7780: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f  (interp);...tcl_
7790: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
77a0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20  Eval(interp, 3, 
77b0: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
77c0: 74 68 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74  th", path, "writ
77d0: 65 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  e");..if (tcl_re
77e0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
77f0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
7800: 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28  appfs::openpath(
7810: 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22  %s, %s) failed."
7820: 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 29  , path, "write")
7830: 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
7840: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
7850: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
7860: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
7870: 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65  ;....Tcl_Release
7880: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74  (interp);....ret
7890: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
78a0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f  real_path = Tcl_
78b0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
78c0: 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 52  interp);...Tcl_R
78d0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
78e0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
78f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
7900: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
7910: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
7920: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
7930: 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63 68  ..chmod_ret = ch
7940: 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  mod(real_path, m
7950: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
7960: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
7970: 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e  eave();...return
7980: 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a  (chmod_ret);.}..
7990: 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f  /*. * SQLite3 mo
79a0: 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77 20  de: Execute raw 
79b0: 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e 20 73  SQL and return s
79c0: 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72  uccess or failur
79d0: 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e. */.static int
79e0: 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28 63   appfs_sqlite3(c
79f0: 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 29 20  onst char *sql) 
7a00: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
7a10: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
7a20: 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69 6e  ar *sql_ret;..in
7a30: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74  t tcl_ret;...int
7a40: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
7a50: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
7a60: 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  L);..if (interp 
7a70: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72  == NULL) {...fpr
7a80: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
7a90: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61  able to create a
7aa0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
7ab0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
7ac0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
7ad0: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  .}...tcl_ret = a
7ae0: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
7af0: 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70 70 66  terp, 5, "::appf
7b00: 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22 2c 20  s::db", "eval", 
7b10: 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75 6e 73  sql, "row", "uns
7b20: 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72  et -nocomplain r
7b30: 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20 72 6f  ow(*); parray ro
7b40: 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22  w; puts \"----\"
7b50: 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d 20 54  ");..sql_ret = T
7b60: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
7b70: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66  lt(interp);...if
7b80: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
7b90: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
7ba0: 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72  (stderr, "[error
7bb0: 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74  ] %s\n", sql_ret
7bc0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
7bd0: 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f 72 65  ..}...if (sql_re
7be0: 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30 5d 20  t && sql_ret[0] 
7bf0: 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69  != '\0') {...pri
7c00: 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71 6c 5f  ntf("%s\n", sql_
7c10: 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  ret);..}...retur
7c20: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54  n(0);.}../*. * T
7c30: 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75 74 65  cl mode: Execute
7c40: 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72 65 74   raw Tcl and ret
7c50: 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72 20 66  urn success or f
7c60: 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69  ailure. */.stati
7c70: 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63 6c 28  c int appfs_tcl(
7c80: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 29  const char *tcl)
7c90: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
7ca0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
7cb0: 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b  har *tcl_result;
7cc0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
7cd0: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
7ce0: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
7cf0: 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74  (NULL);..if (int
7d00: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
7d10: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
7d20: 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61   "Unable to crea
7d30: 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72  te a Tcl interpr
7d40: 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e  eter.  Aborting.
7d50: 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  \n");....return(
7d60: 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  1);..}...tcl_ret
7d70: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
7d80: 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f 72  rp, tcl);..tcl_r
7d90: 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74 53  esult = Tcl_GetS
7da0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
7db0: 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72  rp);...if (tcl_r
7dc0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
7dd0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
7de0: 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22  , "[error] %s\n"
7df0: 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 0a  , tcl_result);..
7e00: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
7e10: 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c 74  ..if (tcl_result
7e20: 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b 30   && tcl_result[0
7e30: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
7e40: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74 63  rintf("%s\n", tc
7e50: 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09  l_result);..}...
7e60: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a  return(0);.}../*
7e70: 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b 61  . * AppFSd Packa
7e80: 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20 20  ge for Tcl:. *  
7e90: 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66 6f         Bridge fo
7ea0: 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e 73  r I/O operations
7eb0: 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66 6f   to request info
7ec0: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68  rmation about th
7ed0: 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20 20  e current. *    
7ee0: 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f 6e       transaction
7ef0: 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20 69  . */./*. * Tcl i
7f00: 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65 74 20  nterface to get 
7f10: 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  the home directo
7f20: 72 79 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ry for the user 
7f30: 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75 72 72  making the "curr
7f40: 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49 2f 4f  ent". * FUSE I/O
7f50: 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74 61   request. */.sta
7f60: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
7f70: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 43 6c  s_get_homedir(Cl
7f80: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
7f90: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
7fa0: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
7fb0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
7fc0: 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65 64  ) {..char *homed
7fd0: 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68 6f  ir;..Tcl_Obj *ho
7fe0: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64 5f  medir_obj;..uid_
7ff0: 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74 69 63  t fsuid;..static
8000: 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62   __thread Tcl_Ob
8010: 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  j *last_homedir_
8020: 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74 61  obj = NULL;..sta
8030: 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75 69 64  tic __thread uid
8040: 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20 3d 20  _t last_fsuid = 
8050: 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 20  -1;..        if 
8060: 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20 20  (objc != 1) {.  
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
8080: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
8090: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
80a0: 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20  NULL);.         
80b0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54 43         return(TC
80c0: 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 20 20  L_ERROR);.      
80d0: 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61 70    }...fsuid = ap
80e0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
80f0: 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d 3d 20  ...if (fsuid == 
8100: 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20 6c 61  last_fsuid && la
8110: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21  st_homedir_obj !
8120: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d 65  = NULL) {...home
8130: 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f 68  dir_obj = last_h
8140: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 7d 20 65  omedir_obj;..} e
8150: 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64 69 72 20  lse {...homedir 
8160: 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65  = appfs_get_home
8170: 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f 66 73  dir(appfs_get_fs
8180: 75 69 64 28 29 29 3b 0a 0a 09 09 69 66 20 28 68  uid());....if (h
8190: 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20  omedir == NULL) 
81a0: 7b 0a 09 09 09 72 65 74 75 72 6e 28 54 43 4c 5f  {....return(TCL_
81b0: 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a 09 09 68  ERROR);...}....h
81c0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 54 63 6c  omedir_obj = Tcl
81d0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 68 6f  _NewStringObj(ho
81e0: 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a 09 09 66  medir, -1);....f
81f0: 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a 0a 09  ree(homedir);...
8200: 09 69 66 20 28 6c 61 73 74 5f 68 6f 6d 65 64 69  .if (last_homedi
8210: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b  r_obj != NULL) {
8220: 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43  ....Tcl_DecrRefC
8230: 6f 75 6e 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69  ount(last_homedi
8240: 72 5f 6f 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c  r_obj);...}....l
8250: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ast_homedir_obj 
8260: 3d 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09  = homedir_obj;..
8270: 09 6c 61 73 74 5f 66 73 75 69 64 20 3d 20 66 73  .last_fsuid = fs
8280: 75 69 64 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72  uid;....Tcl_Incr
8290: 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68 6f  RefCount(last_ho
82a0: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a 0a  medir_obj);..}..
82b0: 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f         .Tcl_SetO
82c0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
82d0: 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a   homedir_obj);..
82e0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54          return(T
82f0: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
8300: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
8310: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
8320: 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44 61 74  _enter(ClientDat
8330: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
8340: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
8350: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
8360: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
8370: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
8380: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
8390: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
83a0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
83b0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
83c0: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 43  _user_fs_leave(C
83d0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
83e0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
83f0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
8400: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
8410: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
8420: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
8430: 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  ve();...return(T
8440: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
8450: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
8460: 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65 6e 74  get_fsuid(Client
8470: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
8480: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
8490: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
84a0: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
84b0: 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09  .uid_t fsuid;...
84c0: 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65  fsuid = appfs_ge
84d0: 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20 20 20  t_fsuid();..    
84e0: 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65     .Tcl_SetObjRe
84f0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
8500: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 66  _NewWideIntObj(f
8510: 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75 72 6e  suid));...return
8520: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
8530: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
8540: 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c 69 65  s_get_fsgid(Clie
8550: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
8560: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
8570: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
8580: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
8590: 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64 3b 0a  {..gid_t fsgid;.
85a0: 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66 73 5f  ..fsgid = appfs_
85b0: 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20 20  get_fsgid();..  
85c0: 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a       .Tcl_SetObj
85d0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
85e0: 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a  cl_NewWideIntObj
85f0: 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65 74 75  (fsgid));...retu
8600: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
8610: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
8620: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
8630: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 43 6c  o_cache_flush(Cl
8640: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
8650: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
8660: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
8670: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
8680: 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  ) {..int tcl_ret
8690: 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65 3b  ;..int new_size;
86a0: 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d 31  ...new_size = -1
86b0: 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d 20  ;...if (objc == 
86c0: 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20 3d  2) {...tcl_ret =
86d0: 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f   Tcl_GetIntFromO
86e0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
86f0: 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b 0a  1], &new_size);.
8700: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
8710: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72 65   TCL_OK) {....re
8720: 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a 09  turn(tcl_ret);..
8730: 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6f  .}..} else if (o
8740: 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63 20  bjc > 2 || objc 
8750: 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  < 1) {.         
8760: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
8770: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
8780: 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f 63  1, objv, "?new_c
8790: 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09 09  ache_size?");...
87a0: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
87b0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65  );..}...appfs_ge
87c0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
87d0: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77 5f  e_flush(-1, new_
87e0: 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28  size);...return(
87f0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
8800: 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f 49 6e  ic int Appfsd_In
8810: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
8820: 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65 66 20  nterp) {.#ifdef 
8830: 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09 69  USE_TCL_STUBS..i
8840: 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75 62 73  f (Tcl_InitStubs
8850: 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45 52  (interp, TCL_VER
8860: 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29 20  SION, 0) == 0L) 
8870: 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45  {...return(TCL_E
8880: 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69 66  RROR);..}.#endif
8890: 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ...Tcl_CreateObj
88a0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
88b0: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f 6d  "appfsd::get_hom
88c0: 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70 66 73  edir", tcl_appfs
88d0: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e 55  _get_homedir, NU
88e0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
88f0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
8900: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
8910: 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c 20 74 63  ::get_fsuid", tc
8920: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
8930: 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  d, NULL, NULL);.
8940: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
8950: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
8960: 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67 69 64  ppfsd::get_fsgid
8970: 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  ", tcl_appfs_get
8980: 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55  _fsgid, NULL, NU
8990: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
89a0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
89b0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75  p, "appfsd::simu
89c0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
89d0: 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73  er", tcl_appfs_s
89e0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
89f0: 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  enter, NULL, NUL
8a00: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
8a10: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
8a20: 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75 6c  , "appfsd::simul
8a30: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
8a40: 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73 69  e", tcl_appfs_si
8a50: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
8a60: 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  eave, NULL, NULL
8a70: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
8a80: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
8a90: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 70 61   "appfsd::get_pa
8aa0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
8ab0: 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ush", tcl_appfs_
8ac0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
8ad0: 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c 2c  che_flush, NULL,
8ae0: 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50 6b   NULL);...Tcl_Pk
8af0: 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70 2c  gProvide(interp,
8b00: 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30 22   "appfsd", "1.0"
8b10: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
8b20: 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 48 6f  OK);.}../*. * Ho
8b30: 74 2d 72 65 73 74 61 72 74 20 73 75 70 70 6f 72  t-restart suppor
8b40: 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61 74  t. */./* Initiat
8b50: 65 20 61 20 68 6f 74 2d 72 65 73 74 61 72 74 20  e a hot-restart 
8b60: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
8b70: 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74  ppfs_hot_restart
8b80: 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f  (void) {..APPFS_
8b90: 44 45 42 55 47 28 22 41 73 6b 65 64 20 74 6f 20  DEBUG("Asked to 
8ba0: 69 6e 69 74 69 61 74 65 20 68 6f 74 20 72 65 73  initiate hot res
8bb0: 74 61 72 74 22 29 3b 0a 0a 09 61 70 70 66 73 5f  tart");...appfs_
8bc0: 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73  tcl_ResetInterps
8bd0: 28 29 3b 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  ();..appfs_get_p
8be0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
8bf0: 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a 09  lush(-1, -1);...
8c00: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
8c10: 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 0a   Signal handler.
8c20: 20 2a 20 20 20 20 20 20 20 20 20 53 49 47 48 55   *         SIGHU
8c30: 50 20 69 6e 69 74 69 61 74 65 73 20 61 20 68 6f  P initiates a ho
8c40: 74 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74  t restart. */.st
8c50: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
8c60: 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 28 69  signal_handler(i
8c70: 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a 20 44 6f  nt sig) {../* Do
8c80: 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73 69 67 6e   not handle sign
8c90: 61 6c 73 20 75 6e 74 69 6c 20 46 55 53 45 20 68  als until FUSE h
8ca0: 61 73 20 62 65 65 6e 20 73 74 61 72 74 65 64 20  as been started 
8cb0: 2a 2f 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66  */..if (!appfs_f
8cc0: 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09  use_started) {..
8cd0: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f 2a  .return;..}.../*
8ce0: 20 52 65 71 75 65 73 74 20 74 6f 20 70 65 72 66   Request to perf
8cf0: 6f 72 6d 20 61 20 22 68 6f 74 22 20 72 65 73 74  orm a "hot" rest
8d00: 61 72 74 20 2a 2f 0a 09 69 66 20 28 73 69 67 20  art */..if (sig 
8d10: 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a 09 09 61  == SIGHUP) {...a
8d20: 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74  ppfs_hot_restart
8d30: 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b  ();..}...return;
8d40: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72 6d 69 6e  .}../*. * Termin
8d50: 61 74 65 20 61 20 74 68 72 65 61 64 0a 20 2a 2f  ate a thread. */
8d60: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
8d70: 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74  fs_terminate_int
8d80: 65 72 70 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72  erp(void *_inter
8d90: 70 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  p) {..Tcl_Interp
8da0: 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46   *interp;...APPF
8db0: 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 65 64 3a  S_DEBUG("Called:
8dc0: 20 5f 69 6e 74 65 72 70 20 3d 20 25 70 22 2c 20   _interp = %p", 
8dd0: 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28  _interp);...if (
8de0: 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  _interp == NULL)
8df0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8e00: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 74 68  ("Terminating th
8e10: 72 65 61 64 20 77 69 74 68 20 6e 6f 20 69 6e 74  read with no int
8e20: 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72  erpreter");....r
8e30: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65  eturn;..}...inte
8e40: 72 70 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09  rp = _interp;...
8e50: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72  APPFS_DEBUG("Ter
8e60: 6d 69 6e 61 74 69 6e 67 20 69 6e 74 65 72 70 72  minating interpr
8e70: 65 74 65 72 20 64 75 65 20 74 6f 20 74 68 72 65  eter due to thre
8e80: 61 64 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29  ad termination")
8e90: 3b 0a 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  ;...Tcl_DeleteIn
8ea0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09  terp(interp);...
8eb0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
8ec0: 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73   FUSE operations
8ed0: 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73   structure. */.s
8ee0: 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75 73  tatic struct fus
8ef0: 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70  e_operations app
8f00: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20  fs_operations = 
8f10: 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20  {...getattr   = 
8f20: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
8f30: 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20  tr,...readdir   
8f40: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
8f50: 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b  ddir,...readlink
8f60: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
8f70: 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20  eadlink,...open 
8f80: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
8f90: 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73  e_open,...releas
8fa0: 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  e   = appfs_fuse
8fb0: 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20  _close,...read  
8fc0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
8fd0: 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20  _read,...write  
8fe0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
8ff0: 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20  write,...mknod  
9000: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
9010: 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20  mknod,...create 
9020: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
9030: 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61  create,...trunca
9040: 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  te  = appfs_fuse
9050: 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c  _truncate,...unl
9060: 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ink    = appfs_f
9070: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
9080: 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20  ,...rmdir     = 
9090: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e  appfs_fuse_unlin
90a0: 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72  k_rmdir,...mkdir
90b0: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
90c0: 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64  e_mkdir,...chmod
90d0: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
90e0: 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a 2f 2a 0a  e_chmod,.};../*.
90f0: 20 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20 70   * FUSE option p
9100: 61 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b 0a  arsing callback.
9110: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
9120: 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62  ppfs_fuse_opt_cb
9130: 28 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f 6e  (void *data, con
9140: 73 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69 6e  st char *arg, in
9150: 74 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66 75  t key, struct fu
9160: 73 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67 73  se_args *outargs
9170: 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e 74 20  ) {..static int 
9180: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20  seen_cachedir = 
9190: 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20 3d 3d 20  0;...if (key == 
91a0: 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f 4e 4f 4e  FUSE_OPT_KEY_NON
91b0: 4f 50 54 20 26 26 20 73 65 65 6e 5f 63 61 63 68  OPT && seen_cach
91c0: 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a 09 09 73  edir == 0) {...s
91d0: 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20 31  een_cachedir = 1
91e0: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 63 68 65  ;....appfs_cache
91f0: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
9200: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
9210: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 31 29 3b  ..}...return(1);
9220: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20  .}../*. * Entry 
9230: 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68 69 73 20  point into this 
9240: 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74  program.. */.int
9250: 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20   main(int argc, 
9260: 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09  char **argv) {..
9270: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73 74  Tcl_Interp *test
9280: 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a  _interp;..char *
9290: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
92a0: 72 3b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f  r;..struct fuse_
92b0: 61 72 67 73 20 61 72 67 73 20 3d 20 46 55 53 45  args args = FUSE
92c0: 5f 41 52 47 53 5f 49 4e 49 54 28 61 72 67 63 2c  _ARGS_INIT(argc,
92d0: 20 61 72 67 76 29 3b 0a 09 69 6e 74 20 70 74 68   argv);..int pth
92e0: 72 65 61 64 5f 72 65 74 3b 0a 09 76 6f 69 64 20  read_ret;..void 
92f0: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09 2f  *signal_ret;.../
9300: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
9310: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
9320: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
9330: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
9340: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
9350: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
9360: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
9370: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
9380: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
9390: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
93a0: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
93b0: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
93c0: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
93d0: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
93e0: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
93f0: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
9400: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
9410: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
9420: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
9430: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
9440: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
9450: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
9460: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
9470: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
9480: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
9490: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
94a0: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
94b0: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
94c0: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
94d0: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
94e0: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
94f0: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
9500: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
9510: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
9520: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
9530: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
9540: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
9550: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
9560: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
9570: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
9580: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
9590: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
95a0: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
95b0: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
95c0: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
95d0: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
95e0: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
95f0: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
9600: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
9610: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
9620: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
9630: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
9640: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
9650: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
9660: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
9670: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
9680: 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 65  erpKey, appfs_te
9690: 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 29 3b  rminate_interp);
96a0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
96b0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69  t != 0) {...fpri
96c0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
96d0: 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53  ble to create TS
96e0: 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20  D key for Tcl.  
96f0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
9700: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
9710: 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c  ../*.. * Manuall
9720: 79 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20  y specify cache 
9730: 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f  directory, witho
9740: 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b  ut FUSE callback
9750: 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e  .. * This option
9760: 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e   only works when
9770: 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c   not using FUSE,
9780: 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f   since we.. * do
9790: 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20   not process it 
97a0: 77 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f  with FUSEs optio
97b0: 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20  n processing... 
97c0: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20  */..if (argc >= 
97d0: 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d  2) {...if (strcm
97e0: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61  p(argv[0], "--ca
97f0: 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b  chedir") == 0) {
9800: 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64  ....appfs_cached
9810: 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76  ir = strdup(argv
9820: 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d  [1]);.....argc -
9830: 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20  = 2;....argv += 
9840: 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09  2;...}..}.../*..
9850: 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c   * SQLite3 mode,
9860: 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77   for running raw
9870: 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65   SQL against the
9880: 20 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a   cache database.
9890: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
98a0: 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72  = 2 && strcmp(ar
98b0: 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65  gv[0], "--sqlite
98c0: 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  3") == 0) {...re
98d0: 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74  turn(appfs_sqlit
98e0: 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d  e3(argv[1]));..}
98f0: 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f  .../*.. * Tcl mo
9900: 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20  de, for running 
9910: 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73  raw Tcl in the s
9920: 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  ame environment 
9930: 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a  AppFSd would.. *
9940: 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a   run code... */.
9950: 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26  .if (argc == 2 &
9960: 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d  & strcmp(argv[0]
9970: 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29  , "--tcl") == 0)
9980: 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66   {...return(appf
9990: 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b  s_tcl(argv[1]));
99a0: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65  ..}.../*.. * Cre
99b0: 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70  ate a Tcl interp
99c0: 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65  reter just to ve
99d0: 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67 73  rify that things
99e0: 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20   are in working 
99f0: 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72  .. * order befor
9a00: 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61  e we become a da
9a10: 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74  emon... */..test
9a20: 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  _interp = appfs_
9a30: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
9a40: 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72  (&test_interp_er
9a50: 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f  ror);..if (test_
9a60: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
9a70: 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74  {...if (test_int
9a80: 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c  erp_error == NUL
9a90: 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74  L) {....test_int
9aa0: 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b  erp_error = "Unk
9ab0: 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d  nown error";...}
9ac0: 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
9ad0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
9ae0: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e  nitialize Tcl in
9af0: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41 70  terpreter for Ap
9b00: 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72  pFSd:\n");...fpr
9b10: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73  intf(stderr, "%s
9b20: 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70  \n", test_interp
9b30: 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75  _error);....retu
9b40: 72 6e 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44  rn(1);..}..Tcl_D
9b50: 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73 74  eleteInterp(test
9b60: 5f 69 6e 74 65 72 70 29 3b 0a 09 54 63 6c 5f 46  _interp);..Tcl_F
9b70: 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28  inalizeNotifier(
9b80: 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  NULL);.../*.. * 
9b90: 52 65 67 69 73 74 65 72 20 61 20 73 69 67 6e 61  Register a signa
9ba0: 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f  l handler for ho
9bb0: 74 2d 72 65 73 74 61 72 74 20 72 65 71 75 65 73  t-restart reques
9bc0: 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f  ts.. */..signal_
9bd0: 72 65 74 20 3d 20 73 69 67 6e 61 6c 28 53 49 47  ret = signal(SIG
9be0: 48 55 50 2c 20 61 70 70 66 73 5f 73 69 67 6e 61  HUP, appfs_signa
9bf0: 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66 20  l_handler);..if 
9c00: 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20 53  (signal_ret == S
9c10: 49 47 5f 45 52 52 29 20 7b 0a 09 09 66 70 72 69  IG_ERR) {...fpri
9c20: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
9c30: 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73  ble to install s
9c40: 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f  ignal handler fo
9c50: 72 20 68 6f 74 2d 72 65 73 74 61 72 74 5c 6e 22  r hot-restart\n"
9c60: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
9c70: 65 72 72 2c 20 22 48 6f 74 2d 72 65 73 74 61 72  err, "Hot-restar
9c80: 74 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76  t will not be av
9c90: 61 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d  ailable.\n");..}
9ca0: 0a 0a 09 2f 2a 0a 09 20 2a 20 41 64 64 20 46 55  .../*.. * Add FU
9cb0: 53 45 20 61 72 67 75 6d 65 6e 74 73 20 77 68 69  SE arguments whi
9cc0: 63 68 20 77 65 20 61 6c 77 61 79 73 20 73 75 70  ch we always sup
9cd0: 70 6c 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f  ply.. */..fuse_o
9ce0: 70 74 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20  pt_parse(&args, 
9cf0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 61 70 70 66  NULL, NULL, appf
9d00: 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62 29 3b 0a  s_fuse_opt_cb);.
9d10: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
9d20: 67 28 26 61 72 67 73 2c 20 22 2d 6f 64 65 66 61  g(&args, "-odefa
9d30: 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c  ult_permissions,
9d40: 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75 62  fsname=appfs,sub
9d50: 74 79 70 65 3d 61 70 70 66 73 64 2c 75 73 65 5f  type=appfsd,use_
9d60: 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63 68 65  ino,kernel_cache
9d70: 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30  ,entry_timeout=0
9d80: 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c  ,attr_timeout=0,
9d90: 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c  big_writes,intr,
9da0: 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a  hard_remove");..
9db0: 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d  .if (getuid() ==
9dc0: 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74   0) {...fuse_opt
9dd0: 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55  _parse(&args, NU
9de0: 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  LL, NULL, NULL);
9df0: 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ...fuse_opt_add_
9e00: 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c  arg(&args, "-oal
9e10: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a  low_other");..}.
9e20: 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74  ../*.. * Enter t
9e30: 68 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f  he FUSE main loo
9e40: 70 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70  p -- this will p
9e50: 72 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d  rocess any argum
9e60: 65 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61  ents.. * and sta
9e70: 72 74 20 73 65 72 76 69 63 69 6e 67 20 72 65 71  rt servicing req
9e80: 75 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  uests... */..app
9e90: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20  fs_fuse_started 
9ea0: 3d 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73  = 1;..return(fus
9eb0: 65 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63  e_main(args.argc
9ec0: 2c 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70  , args.argv, &ap
9ed0: 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20  pfs_operations, 
9ee0: 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a              NULL));.}. .