Hex Artifact Content

Artifact 3133466dffb8370cf719ab6b13cfb28a806d42e7:


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 69 66 20 28 67 6c 6f 62 61 6c  ..}...if (global
1bf0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
1c00: 79 20 3d 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50  y == -1) {...APP
1c10: 46 53 5f 44 45 42 55 47 28 22 4e 6f 74 20 63 72  FS_DEBUG("Not cr
1c20: 65 61 74 69 6e 67 20 61 20 6e 65 77 20 69 6e 74  eating a new int
1c30: 65 72 70 72 65 74 65 72 20 73 69 6e 63 65 20 77  erpreter since w
1c40: 65 20 61 72 65 20 74 65 72 6d 69 6e 61 74 69 6e  e are terminatin
1c50: 67 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  g.");....return(
1c60: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 68 72 65  NULL);..}...thre
1c70: 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  ad_interp_reset_
1c80: 6b 65 79 20 3d 20 67 6c 6f 62 61 6c 5f 69 6e 74  key = global_int
1c90: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a  erp_reset_key;..
1ca0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
1cb0: 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72 70 20  ULL) {...interp 
1cc0: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
1cd0: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
1ce0: 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ...if (interp ==
1cf0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75   NULL) {....retu
1d00: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09  rn(NULL);...}...
1d10: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
1d20: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66  thread_setspecif
1d30: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e  ic(interpKey, in
1d40: 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70 74 68  terp);...if (pth
1d50: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
1d60: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
1d70: 22 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63  "pthread_setspec
1d80: 69 66 69 63 28 29 20 66 61 69 6c 65 64 2e 20 20  ific() failed.  
1d90: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
1da0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
1db0: 0a 09 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  ....Tcl_DeleteIn
1dc0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09  terp(interp);...
1dd0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1de0: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
1df0: 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20  interp);.}../*. 
1e00: 2a 20 45 76 61 6c 75 61 74 65 20 61 20 54 63 6c  * Evaluate a Tcl
1e10: 20 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75 63   script construc
1e20: 74 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e 61  ted by concatena
1e30: 74 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66 20  ting a bunch of 
1e40: 43 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f 67  C strings. * tog
1e50: 65 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74 69  ether.. */.stati
1e60: 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c 5f  c int appfs_Tcl_
1e70: 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70 20  Eval(Tcl_Interp 
1e80: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
1e90: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
1ea0: 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f  md, ...) {..Tcl_
1eb0: 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e  Obj **objv;..con
1ec0: 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09 76  st char *arg;..v
1ed0: 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69 6e  a_list argp;..in
1ee0: 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 69  t retval;..int i
1ef0: 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ;...if (interp =
1f00: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
1f10: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
1f20: 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64  }...objv = (void
1f30: 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65   *) ckalloc(size
1f40: 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63  of(*objv) * objc
1f50: 29 3b 0a 0a 09 6f 62 6a 76 5b 30 5d 20 3d 20 54  );...objv[0] = T
1f60: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
1f70: 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 54 63 6c 5f  cmd, -1);...Tcl_
1f80: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a  IncrRefCount(obj
1f90: 76 5b 30 5d 29 3b 0a 0a 09 76 61 5f 73 74 61 72  v[0]);...va_star
1fa0: 74 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 66  t(argp, cmd);..f
1fb0: 6f 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f  or (i = 1; i < o
1fc0: 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72  bjc; i++) {...ar
1fd0: 67 20 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c  g = va_arg(argp,
1fe0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a   const char *);.
1ff0: 0a 09 09 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c  ...objv[i] = Tcl
2000: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 72  _NewStringObj(ar
2010: 67 2c 20 2d 31 29 3b 0a 0a 09 09 54 63 6c 5f 49  g, -1);....Tcl_I
2020: 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76  ncrRefCount(objv
2030: 5b 69 5d 29 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64  [i]);..}..va_end
2040: 28 61 72 67 70 29 3b 0a 0a 09 72 65 74 76 61 6c  (argp);...retval
2050: 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28   = Tcl_EvalObjv(
2060: 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62  interp, objc, ob
2070: 6a 76 2c 20 30 29 3b 0a 0a 09 66 6f 72 20 28 69  jv, 0);...for (i
2080: 20 3d 20 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20   = 0; i < objc; 
2090: 69 2b 2b 29 20 7b 0a 09 09 54 63 6c 5f 44 65 63  i++) {...Tcl_Dec
20a0: 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69  rRefCount(objv[i
20b0: 5d 29 3b 0a 09 7d 0a 0a 09 63 6b 66 72 65 65 28  ]);..}...ckfree(
20c0: 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a  (void *) objv);.
20d0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
20e0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
20f0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 63 6f 6d  S_DEBUG("Tcl com
2100: 6d 61 6e 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65  mand failed, ::e
2110: 72 72 6f 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e  rrorInfo contain
2120: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
2130: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a  tVar(interp, "::
2140: 65 72 72 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b  errorInfo", 0));
2150: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  ..}...return(ret
2160: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52  val);.}../*. * R
2170: 65 71 75 65 73 74 20 61 6c 6c 20 54 63 6c 20 69  equest all Tcl i
2180: 6e 74 65 72 70 72 65 74 65 72 73 20 72 65 73 74  nterpreters rest
2190: 61 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76  art. */.static v
21a0: 6f 69 64 20 61 70 70 66 73 5f 74 63 6c 5f 52 65  oid appfs_tcl_Re
21b0: 73 65 74 49 6e 74 65 72 70 73 28 76 6f 69 64 29  setInterps(void)
21c0: 20 7b 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28   {..APPFS_DEBUG(
21d0: 22 52 65 71 75 65 73 74 69 6e 67 20 72 65 73 65  "Requesting rese
21e0: 74 20 6f 66 20 61 6c 6c 20 69 6e 74 65 72 70 72  t of all interpr
21f0: 65 74 65 72 73 2e 22 29 3b 0a 0a 09 5f 5f 73 79  eters.");...__sy
2200: 6e 63 5f 61 64 64 5f 61 6e 64 5f 66 65 74 63 68  nc_add_and_fetch
2210: 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  (&interp_reset_k
2220: 65 79 2c 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e  ey, 1);...return
2230: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72  ;.}../*. * Deter
2240: 6d 69 6e 65 20 74 68 65 20 55 49 44 20 66 6f 72  mine the UID for
2250: 20 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67   the user making
2260: 20 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53   the current FUS
2270: 45 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71  E filesystem req
2280: 75 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69  uest.. * This wi
2290: 6c 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f  ll be used to lo
22a0: 6f 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20  okup the user's 
22b0: 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73  home directory s
22c0: 6f 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20  o we can search 
22d0: 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d  for. * locally m
22e0: 6f 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20  odified files.. 
22f0: 2a 2f 0a 73 74 61 74 69 63 20 75 69 64 5f 74 20  */.static uid_t 
2300: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
2310: 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20  void) {..struct 
2320: 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74  fuse_context *ct
2330: 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f  x;...if (!appfs_
2340: 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a  fuse_started) {.
2350: 09 09 72 65 74 75 72 6e 28 67 65 74 75 69 64 28  ..return(getuid(
2360: 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66  ));..}...ctx = f
2370: 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28  use_get_context(
2380: 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e  );..if (ctx == N
2390: 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62  ULL) {.../* Unab
23a0: 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65  le to lookup use
23b0: 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f  r for some reaso
23c0: 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e  n */.../* Return
23d0: 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64   an unprivileged
23e0: 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 72 65   user ID */...re
23f0: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65  turn(1);..}...re
2400: 74 75 72 6e 28 63 74 78 2d 3e 75 69 64 29 3b 0a  turn(ctx->uid);.
2410: 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69  }../*. * Determi
2420: 6e 65 20 74 68 65 20 47 49 44 20 66 6f 72 20 74  ne the GID for t
2430: 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74  he user making t
2440: 68 65 20 63 75 72 72 65 6e 74 20 46 55 53 45 20  he current FUSE 
2450: 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71 75 65  filesystem reque
2460: 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c 6c  st.. * This will
2470: 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f 6b   be used to look
2480: 75 70 20 74 68 65 20 75 73 65 72 27 73 20 68 6f  up the user's ho
2490: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73 6f 20  me directory so 
24a0: 77 65 20 63 61 6e 20 73 65 61 72 63 68 20 66 6f  we can search fo
24b0: 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64  r. * locally mod
24c0: 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a 2f  ified files.. */
24d0: 0a 73 74 61 74 69 63 20 67 69 64 5f 74 20 61 70  .static gid_t ap
24e0: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 76 6f  pfs_get_fsgid(vo
24f0: 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66 75  id) {..struct fu
2500: 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b  se_context *ctx;
2510: 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66 75  ...if (!appfs_fu
2520: 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09  se_started) {...
2530: 72 65 74 75 72 6e 28 67 65 74 67 69 64 28 29 29  return(getgid())
2540: 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73  ;..}...ctx = fus
2550: 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b  e_get_context();
2560: 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c  ..if (ctx == NUL
2570: 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65  L) {.../* Unable
2580: 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20   to lookup user 
2590: 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20  for some reason 
25a0: 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20 61  */.../* Return a
25b0: 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64 20 75  n unprivileged u
25c0: 73 65 72 20 49 44 20 2a 2f 0a 09 09 72 65 74 75  ser ID */...retu
25d0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  rn(1);..}...retu
25e0: 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a  rn(ctx->gid);.}.
25f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
2600: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
2610: 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29 20  _fs_enter(void) 
2620: 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70 66  {..setfsuid(appf
2630: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
2640: 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73 5f  .setfsgid(appfs_
2650: 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d 0a  get_fsgid());.}.
2660: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
2670: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
2680: 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29 20  _fs_leave(void) 
2690: 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b 0a  {..setfsuid(0);.
26a0: 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d 0a  .setfsgid(0);.}.
26b0: 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74  ./*. * Look up t
26c0: 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  he home director
26d0: 79 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49  y for a given UI
26e0: 44 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74 75  D. *        Retu
26f0: 72 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20 63  rns a C string c
2700: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73  ontaining the us
2710: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74  er's home direct
2720: 6f 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20  ory or NULL if. 
2730: 2a 20 20 20 20 20 20 20 20 74 68 65 20 75 73 65  *        the use
2740: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
2750: 72 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  ry does not exis
2760: 74 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72  t or is not corr
2770: 65 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20  ectly. *        
2780: 63 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73  configured. */.s
2790: 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66  tatic char *appf
27a0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69  s_get_homedir(ui
27b0: 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74  d_t fsuid) {..st
27c0: 72 75 63 74 20 70 61 73 73 77 64 20 65 6e 74 72  ruct passwd entr
27d0: 79 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72  y, *result;..str
27e0: 75 63 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a  uct stat stbuf;.
27f0: 09 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c  .char buf[1024],
2800: 20 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67   *retval;..int g
2810: 70 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74  pu_ret, stat_ret
2820: 3b 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65  ;...gpu_ret = ge
2830: 74 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20  tpwuid_r(fsuid, 
2840: 26 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a  &entry, buf, siz
2850: 65 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c  eof(buf), &resul
2860: 74 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74  t);..if (gpu_ret
2870: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
2880: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64  _DEBUG("getpwuid
2890: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65  _r(%llu, ...) re
28a0: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
28b0: 65 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  e", (unsigned lo
28c0: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
28d0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
28e0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c  ;..}...if (resul
28f0: 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  t == NULL) {...A
2900: 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74 70  PPFS_DEBUG("getp
2910: 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e  wuid_r(%llu, ...
2920: 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20  ) returned NULL 
2930: 72 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e  result", (unsign
2940: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
2950: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  uid);....return(
2960: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
2970: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d  result->pw_dir =
2980: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
2990: 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69  S_DEBUG("getpwui
29a0: 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72  d_r(%llu, ...) r
29b0: 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d  eturned NULL hom
29c0: 65 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75  e directory", (u
29d0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
29e0: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65  g) fsuid);....re
29f0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
2a00: 09 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74  .stat_ret = stat
2a10: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c  (result->pw_dir,
2a20: 20 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73   &stbuf);..if (s
2a30: 74 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  tat_ret != 0) {.
2a40: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 73  ..APPFS_DEBUG("s
2a50: 74 61 74 28 25 73 29 20 72 65 74 75 72 6e 65 64  tat(%s) returned
2a60: 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65   in failure", re
2a70: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a  sult->pw_dir);..
2a80: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
2a90: 09 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73  .}...if (stbuf.s
2aa0: 74 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29 20  t_uid != fsuid) 
2ab0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
2ac0: 22 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f  "UID mis-match o
2ad0: 6e 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f  n user %llu's ho
2ae0: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 28 25 73  me directory (%s
2af0: 29 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62  ).  It's owned b
2b00: 79 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20  y %llu.",...    
2b10: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
2b20: 6f 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20  ong) fsuid,...  
2b30: 20 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72    result->pw_dir
2b40: 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65  ,...    (unsigne
2b50: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62  d long long) stb
2b60: 75 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a  uf.st_uid...);..
2b70: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
2b80: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74  .}...retval = st
2b90: 72 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f  rdup(result->pw_
2ba0: 64 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72  dir);...return(r
2bb0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  etval);.}../*. *
2bc0: 20 47 65 6e 65 72 61 74 65 20 61 6e 20 69 6e 6f   Generate an ino
2bd0: 64 65 20 66 6f 72 20 61 20 67 69 76 65 6e 20 70  de for a given p
2be0: 61 74 68 2e 20 20 54 68 65 20 69 6e 6f 64 65 20  ath.  The inode 
2bf0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6d 70 75 74  should be comput
2c00: 65 64 20 69 6e 20 73 75 63 68 0a 20 2a 20 61 20  ed in such. * a 
2c10: 77 61 79 20 74 68 61 74 20 69 74 20 69 73 20 75  way that it is u
2c20: 6e 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20 64 75  nlikely to be du
2c30: 70 6c 69 63 61 74 65 64 20 61 6e 64 20 72 65 6d  plicated and rem
2c40: 61 69 6e 73 20 74 68 65 20 73 61 6d 65 20 66 6f  ains the same fo
2c50: 72 20 61 20 67 69 76 65 6e 0a 20 2a 20 66 69 6c  r a given. * fil
2c60: 65 0a 20 2a 2f 0a 23 69 66 20 55 49 4e 54 5f 4d  e. */.#if UINT_M
2c70: 41 58 20 3c 20 34 32 39 34 39 36 37 32 39 35 0a  AX < 4294967295.
2c80: 23 65 72 72 6f 72 20 49 6e 74 65 67 65 72 20 73  #error Integer s
2c90: 69 7a 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c 6c  ize is too small
2ca0: 20 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 20   .#endif.static 
2cb0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
2cc0: 6e 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ng appfs_get_pat
2cd0: 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68  h_inode(const ch
2ce0: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 69 6e 74  ar *path) {..int
2cf0: 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74 20   retval;..const 
2d00: 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74 76 61  char *p;...retva
2d10: 6c 20 3d 20 31 30 3b 0a 0a 09 66 6f 72 20 28 70  l = 10;...for (p
2d20: 20 3d 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b   = path; *p; p++
2d30: 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 25 3d 20  ) {...retval %= 
2d40: 34 32 39 30 39 36 30 32 39 30 55 4c 4c 3b 0a 09  4290960290ULL;..
2d50: 09 72 65 74 76 61 6c 20 2b 3d 20 2a 70 3b 0a 09  .retval += *p;..
2d60: 09 72 65 74 76 61 6c 20 3c 3c 3d 20 36 3b 0a 09  .retval <<= 6;..
2d70: 7d 0a 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31 30  }...retval += 10
2d80: 3b 0a 09 72 65 74 76 61 6c 20 25 3d 20 34 32 39  ;..retval %= 429
2d90: 34 39 36 37 32 38 36 55 4c 4c 3b 0a 09 72 65 74  4967286ULL;..ret
2da0: 76 61 6c 20 2b 3d 20 31 30 3b 0a 0a 09 72 65 74  val += 10;...ret
2db0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
2dc0: 2f 2a 0a 20 2a 20 43 61 63 68 65 20 47 65 74 20  /*. * Cache Get 
2dd0: 50 61 74 68 20 49 6e 66 6f 20 6c 6f 6f 6b 75 70  Path Info lookup
2de0: 73 20 66 6f 72 20 73 70 65 65 64 0a 20 2a 2f 0a  s for speed. */.
2df0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
2e00: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
2e10: 61 63 68 65 5f 67 65 74 28 63 6f 6e 73 74 20 63  ache_get(const c
2e20: 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74  har *path, uid_t
2e30: 20 75 69 64 2c 20 73 74 72 75 63 74 20 61 70 70   uid, struct app
2e40: 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74  fs_pathinfo *pat
2e50: 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e  hinfo) {..unsign
2e60: 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b  ed int hash_idx;
2e70: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
2e80: 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  t;..int retval;.
2e90: 0a 09 72 65 74 76 61 6c 20 3d 20 31 3b 0a 0a 09  ..retval = 1;...
2ea0: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
2eb0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
2ec0: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
2ed0: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
2ee0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
2ef0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
2f00: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
2f10: 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  o lock path_info
2f20: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
2f30: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 3b  ;....return(-1);
2f40: 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  ..}...if (appfs_
2f50: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
2f60: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73  != NULL) {...has
2f70: 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67  h_idx = (appfs_g
2f80: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
2f90: 74 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 70  th) + uid) % app
2fa0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
2fb0: 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28  he_size;....if (
2fc0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2fd0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
2fe0: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e  _cache_path != N
2ff0: 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 74  ULL) {....if (st
3000: 72 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68 5f  rcmp(appfs_path_
3010: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3020: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3030: 2c 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26 20  , path) == 0 && 
3040: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3050: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
3060: 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 69  _cache_uid == ui
3070: 64 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c 20  d) {.....retval 
3080: 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79  = 0;......memcpy
3090: 28 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 66  (pathinfo, &appf
30a0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
30b0: 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a  e[hash_idx], siz
30c0: 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b  eof(*pathinfo));
30d0: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f  .....pathinfo->_
30e0: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c  cache_path = NUL
30f0: 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a  L;....}...}..}..
3100: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
3110: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
3120: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
3130: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
3140: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
3150: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
3160: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
3170: 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68  e to unlock path
3180: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
3190: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
31a0: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72  (-1);..}...if (r
31b0: 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09  etval == 0) {...
31c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63  APPFS_DEBUG("Cac
31d0: 68 65 20 68 69 74 20 6f 6e 20 25 73 22 2c 20 70  he hit on %s", p
31e0: 61 74 68 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  ath);..} else {.
31f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43  ..APPFS_DEBUG("C
3200: 61 63 68 65 20 6d 69 73 73 20 6f 6e 20 25 73 22  ache miss on %s"
3210: 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 65  , path);..}...re
3220: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
3230: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
3240: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
3250: 5f 63 61 63 68 65 5f 61 64 64 28 63 6f 6e 73 74  _cache_add(const
3260: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64   char *path, uid
3270: 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74 20 61  _t uid, struct a
3280: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70  ppfs_pathinfo *p
3290: 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69  athinfo) {..unsi
32a0: 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64  gned int hash_id
32b0: 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  x;..int pthread_
32c0: 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72  ret;...pthread_r
32d0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
32e0: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  ex_lock(&appfs_p
32f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
3300: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
3310: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
3320: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
3330: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61  nable to lock pa
3340: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
3350: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
3360: 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70  rn;..}...if (app
3370: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3380: 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  he == NULL) {...
3390: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
33a0: 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28 61  cache = calloc(a
33b0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
33c0: 61 63 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65 6f  ache_size, sizeo
33d0: 66 28 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f(*appfs_path_in
33e0: 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a 0a  fo_cache));..}..
33f0: 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70  .hash_idx = (app
3400: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
3410: 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20 25  e(path) + uid) %
3420: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
3430: 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 69  _cache_size;...i
3440: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3450: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3460: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
3470: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72 65 65  = NULL) {...free
3480: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
3490: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
34a0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 09  ._cache_path);..
34b0: 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70 70 66  }...memcpy(&appf
34c0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
34d0: 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70 61 74  e[hash_idx], pat
34e0: 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28 2a 70  hinfo, sizeof(*p
34f0: 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61 70 70  athinfo));...app
3500: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3510: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
3520: 63 68 65 5f 70 61 74 68 20 3d 20 73 74 72 64 75  che_path = strdu
3530: 70 28 70 61 74 68 29 3b 0a 09 61 70 70 66 73 5f  p(path);..appfs_
3540: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3550: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
3560: 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a 09 70  _uid  = uid;...p
3570: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
3580: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
3590: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
35a0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
35b0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
35c0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
35d0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
35e0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
35f0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
3600: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
3610: 09 7d 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73  .}..return;.}..s
3620: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
3630: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
3640: 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74 20 63 68  ache_rm(const ch
3650: 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20  ar *path, uid_t 
3660: 75 69 64 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64  uid) {..unsigned
3670: 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09   int hash_idx;..
3680: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
3690: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
36a0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
36b0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
36c0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
36d0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
36e0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
36f0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
3700: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
3710: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
3720: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
3730: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
3740: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
3750: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68  = NULL) {...hash
3760: 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65  _idx = (appfs_ge
3770: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
3780: 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 70 66  h) + uid) % appf
3790: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
37a0: 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61  e_size;....if (a
37b0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
37c0: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
37d0: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
37e0: 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28 61 70  LL) {....free(ap
37f0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3800: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
3810: 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09  ache_path);.....
3820: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3830: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
3840: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
3850: 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68  LL;...}..}...pth
3860: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
3870: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
3880: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
3890: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
38a0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
38b0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
38c0: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
38d0: 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66   unlock path_inf
38e0: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
38f0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
3900: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74  ...return;.}..st
3910: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
3920: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
3930: 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f 74 20  che_flush(uid_t 
3940: 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73 69 7a  uid, int new_siz
3950: 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  e) {..unsigned i
3960: 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  nt idx;..int pth
3970: 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  read_ret;...APPF
3980: 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68 69 6e  S_DEBUG("Flushin
3990: 67 20 41 70 70 46 53 20 63 61 63 68 65 20 28 75  g AppFS cache (u
39a0: 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77 5f 73  id = %lli, new_s
39b0: 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c 6f 6e  ize = %i)", (lon
39c0: 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e 65 77  g long) uid, new
39d0: 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72 65 61  _size);...pthrea
39e0: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
39f0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
3a00: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3a10: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
3a20: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
3a30: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
3a40: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
3a50: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
3a60: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
3a70: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
3a80: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3a90: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
3aa0: 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b  ...for (idx = 0;
3ab0: 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70 61 74   idx < appfs_pat
3ac0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
3ad0: 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 09 69  e; idx++) {....i
3ae0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3af0: 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63  fo_cache[idx]._c
3b00: 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c  ache_path != NUL
3b10: 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75 69 64  L) {.....if (uid
3b20: 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29   != ((uid_t) -1)
3b30: 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61 70 70  ) {......if (app
3b40: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3b50: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75  he[idx]._cache_u
3b60: 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09 09 09  id != uid) {....
3b70: 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 09  ...continue;....
3b80: 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66  ..}.....}......f
3b90: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
3ba0: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
3bb0: 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09  cache_path);....
3bc0: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
3bd0: 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61  o_cache[idx]._ca
3be0: 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b  che_path = NULL;
3bf0: 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 69  ....}...}..}...i
3c00: 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69 64 5f  f (uid == ((uid_
3c10: 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72 65 65  t) -1)) {...free
3c20: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
3c30: 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70 70 66  _cache);....appf
3c40: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3c50: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69 66 20  e = NULL;....if 
3c60: 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d 31 29  (new_size != -1)
3c70: 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68   {....appfs_path
3c80: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
3c90: 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09 09 7d   = new_size;...}
3ca0: 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  ..}...pthread_re
3cb0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3cc0: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
3cd0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
3ce0: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
3cf0: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3d00: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3d10: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
3d20: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
3d30: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
3d40: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75  eturn;..}...retu
3d50: 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e  rn;.}../* Get in
3d60: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
3d70: 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70 74 69  a path, and opti
3d80: 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68 69 6c  onally list chil
3d90: 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69  dren */.static i
3da0: 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  nt appfs_get_pat
3db0: 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63 68 61  h_info(const cha
3dc0: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
3dd0: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
3de0: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54 63 6c  pathinfo) {..Tcl
3df0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
3e00: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 73  ..Tcl_Obj *attrs
3e10: 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76 61 6c  _dict, *attr_val
3e20: 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  ue;..const char 
3e30: 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 3b  *attr_value_str;
3e40: 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74  ..Tcl_WideInt at
3e50: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09  tr_value_wide;..
3e60: 69 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  int attr_value_i
3e70: 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  nt;..static __th
3e80: 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74  read Tcl_Obj *at
3e90: 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55  tr_key_type = NU
3ea0: 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65  LL, *attr_key_pe
3eb0: 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  rms = NULL, *att
3ec0: 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c  r_key_size = NUL
3ed0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d  L, *attr_key_tim
3ee0: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
3ef0: 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c  key_source = NUL
3f00: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69  L, *attr_key_chi
3f10: 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20  ldcount = NULL, 
3f20: 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  *attr_key_packag
3f30: 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20  ed = NULL;..int 
3f40: 63 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20  cache_ret;..int 
3f50: 74 63 6c 5f 72 65 74 3b 0a 09 75 69 64 5f 74 20  tcl_ret;..uid_t 
3f60: 66 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d  fsuid;...fsuid =
3f70: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
3f80: 28 29 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20  ();...cache_ret 
3f90: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
3fa0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28  _info_cache_get(
3fb0: 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74  path, fsuid, pat
3fc0: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 63 61 63  hinfo);..if (cac
3fd0: 68 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09  he_ret == 0) {..
3fe0: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74  .if (pathinfo->t
3ff0: 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54  ype == APPFS_PAT
4000: 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45  HTYPE_DOES_NOT_E
4010: 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72  XIST) {....retur
4020: 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a  n(-ENOENT);...}.
4030: 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d  ...if (pathinfo-
4040: 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  >type == APPFS_P
4050: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29  ATHTYPE_INVALID)
4060: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 49   {....return(-EI
4070: 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72  O);...}....retur
4080: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72  n(0);..}...inter
4090: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
40a0: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
40b0: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
40c0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
40d0: 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65 28  ...Tcl_Preserve(
40e0: 69 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f 72  interp);...tcl_r
40f0: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
4100: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
4110: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72  ::appfs::getattr
4120: 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74  ", path);..if (t
4130: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
4140: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
4150: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  G("::appfs::geta
4160: 74 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ttr(%s) failed."
4170: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
4180: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
4190: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
41a0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
41b0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 70 61 74 68  nterp));....path
41c0: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
41d0: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53  FS_PATHTYPE_DOES
41e0: 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61  _NOT_EXIST;....a
41f0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4200: 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74  fo_cache_add(pat
4210: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e  h, fsuid, pathin
4220: 66 6f 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65  fo);....Tcl_Rele
4230: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
4240: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b  return(-ENOENT);
4250: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b  ..}...if (attr_k
4260: 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29  ey_type == NULL)
4270: 20 7b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 74 79   {...attr_key_ty
4280: 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  pe       = Tcl_N
4290: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70  ewStringObj("typ
42a0: 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f  e", -1);...attr_
42b0: 6b 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20 3d  key_perms      =
42c0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
42d0: 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b 0a  j("perms", -1);.
42e0: 09 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20  ..attr_key_size 
42f0: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
4300: 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65 22 2c  tringObj("size",
4310: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
4320: 5f 74 69 6d 65 20 20 20 20 20 20 20 3d 20 54 63  _time       = Tc
4330: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4340: 74 69 6d 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  time", -1);...at
4350: 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 20 20  tr_key_source   
4360: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
4370: 67 4f 62 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d  gObj("source", -
4380: 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 63  1);...attr_key_c
4390: 68 69 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f  hildcount = Tcl_
43a0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68  NewStringObj("ch
43b0: 69 6c 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a  ildcount", -1);.
43c0: 09 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61  ..attr_key_packa
43d0: 67 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53  ged   = Tcl_NewS
43e0: 74 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67  tringObj("packag
43f0: 65 64 22 2c 20 2d 31 29 3b 0a 09 7d 0a 0a 09 61  ed", -1);..}...a
4400: 74 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f  ttrs_dict = Tcl_
4410: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
4420: 65 72 70 29 3b 0a 09 74 63 6c 5f 72 65 74 20 3d  erp);..tcl_ret =
4430: 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28   Tcl_DictObjGet(
4440: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
4450: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70  ct, attr_key_typ
4460: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
4470: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
4480: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
4490: 46 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20  FS_DEBUG("[dict 
44a0: 67 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61  get \"type\"] fa
44b0: 69 6c 65 64 22 29 3b 0a 09 09 41 50 50 46 53 5f  iled");...APPFS_
44c0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
44d0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
44e0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
44f0: 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52  terp));....Tcl_R
4500: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
4510: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
4520: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76  ..}...if (attr_v
4530: 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  alue == NULL) {.
4540: 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
4550: 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e  terp);....return
4560: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74  (-EIO);..}...pat
4570: 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20  hinfo->packaged 
4580: 3d 20 30 3b 0a 09 70 61 74 68 69 6e 66 6f 2d 3e  = 0;..pathinfo->
4590: 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65  inode = appfs_ge
45a0: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
45b0: 68 29 3b 0a 0a 09 61 74 74 72 5f 76 61 6c 75 65  h);...attr_value
45c0: 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74  _str = Tcl_GetSt
45d0: 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29  ring(attr_value)
45e0: 3b 0a 0a 09 73 77 69 74 63 68 20 28 61 74 74 72  ;...switch (attr
45f0: 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b  _value_str[0]) {
4600: 0a 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20  ...case 'd': /* 
4610: 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09  directory */....
4620: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
4630: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
4640: 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 70 61  DIRECTORY;....pa
4650: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
4660: 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20  .dir.childcount 
4670: 3d 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63  = 0;.....Tcl_Dic
4680: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
4690: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
46a0: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c  _key_childcount,
46b0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
46c0: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
46d0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
46e0: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
46f0: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
4700: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
4710: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
4720: 64 65 29 3b 0a 09 09 09 09 69 66 20 28 74 63 6c  de);.....if (tcl
4730: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
4740: 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  {......pathinfo-
4750: 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  >typeinfo.dir.ch
4760: 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f  ildcount = attr_
4770: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09  value_wide;.....
4780: 7d 0a 09 09 09 7d 0a 0a 09 09 09 62 72 65 61 6b  }....}.....break
4790: 3b 0a 09 09 63 61 73 65 20 27 66 27 3a 20 2f 2a  ;...case 'f': /*
47a0: 20 66 69 6c 65 20 2a 2f 0a 09 09 09 70 61 74 68   file */....path
47b0: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
47c0: 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45  FS_PATHTYPE_FILE
47d0: 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  ;....pathinfo->t
47e0: 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a  ypeinfo.file.siz
47f0: 65 20 3d 20 30 3b 0a 09 09 09 70 61 74 68 69 6e  e = 0;....pathin
4800: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
4810: 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30  e.executable = 0
4820: 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ;.....Tcl_DictOb
4830: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
4840: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
4850: 79 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61  y_size, &attr_va
4860: 6c 75 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74  lue);....if (att
4870: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
4880: 20 7b 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d   {.....tcl_ret =
4890: 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46   Tcl_GetWideIntF
48a0: 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74  romObj(NULL, att
48b0: 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76  r_value, &attr_v
48c0: 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09  alue_wide);.....
48d0: 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54  if (tcl_ret == T
48e0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61  CL_OK) {......pa
48f0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
4900: 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74  .file.size = att
4910: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09  r_value_wide;...
4920: 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 54 63 6c  ..}....}.....Tcl
4930: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
4940: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
4950: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20  attr_key_perms, 
4960: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
4970: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
4980: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 61  != NULL) {.....a
4990: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20  ttr_value_str = 
49a0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74  Tcl_GetString(at
49b0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69  tr_value);.....i
49c0: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  f (attr_value_st
49d0: 72 5b 30 5d 20 3d 3d 20 27 78 27 29 20 7b 0a 09  r[0] == 'x') {..
49e0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
49f0: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63  peinfo.file.exec
4a00: 75 74 61 62 6c 65 20 3d 20 31 3b 0a 09 09 09 09  utable = 1;.....
4a10: 7d 0a 09 09 09 7d 0a 09 09 09 62 72 65 61 6b 3b  }....}....break;
4a20: 0a 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20  ...case 's': /* 
4a30: 73 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 70 61  symlink */....pa
4a40: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
4a50: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
4a60: 4d 4c 49 4e 4b 3b 0a 09 09 09 70 61 74 68 69 6e  MLINK;....pathin
4a70: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
4a80: 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09  link.size = 0;..
4a90: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
4aa0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
4ab0: 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a  rce[0] = '\0';..
4ac0: 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
4ad0: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
4ae0: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73  dict, attr_key_s
4af0: 6f 75 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c  ource, &attr_val
4b00: 75 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72  ue);....if (attr
4b10: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
4b20: 7b 0a 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65  {.....attr_value
4b30: 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74  _str = Tcl_GetSt
4b40: 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72  ringFromObj(attr
4b50: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
4b60: 6c 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09  lue_int); ......
4b70: 69 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f  if ((attr_value_
4b80: 69 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65  int + 1) <= size
4b90: 6f 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  of(pathinfo->typ
4ba0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
4bb0: 75 72 63 65 29 29 20 7b 0a 09 09 09 09 09 70 61  urce)) {......pa
4bc0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
4bd0: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20  .symlink.size = 
4be0: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a  attr_value_int;.
4bf0: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
4c00: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
4c10: 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75  source[attr_valu
4c20: 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a  e_int] = '\0';..
4c30: 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68  .....memcpy(path
4c40: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
4c50: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61  ymlink.source, a
4c60: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61  ttr_value_str, a
4c70: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a  ttr_value_int);.
4c80: 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 72  ....}....}....br
4c90: 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 46 27 3a  eak;...case 'F':
4ca0: 20 2f 2a 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f   /* pipe/fifo */
4cb0: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
4cc0: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
4cd0: 59 50 45 5f 46 49 46 4f 3b 0a 09 09 09 62 72 65  YPE_FIFO;....bre
4ce0: 61 6b 3b 0a 09 09 63 61 73 65 20 27 53 27 3a 20  ak;...case 'S': 
4cf0: 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73  /* UNIX domain s
4d00: 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 70 61 74 68  ocket */....path
4d10: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
4d20: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b  FS_PATHTYPE_SOCK
4d30: 45 54 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  ET;....break;...
4d40: 64 65 66 61 75 6c 74 3a 0a 09 09 09 54 63 6c 5f  default:....Tcl_
4d50: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
4d60: 0a 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  .....return(-EIO
4d70: 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 69 63 74  );..}...Tcl_Dict
4d80: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
4d90: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
4da0: 6b 65 79 5f 70 61 63 6b 61 67 65 64 2c 20 26 61  key_packaged, &a
4db0: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66 20  ttr_value);..if 
4dc0: 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e  (attr_value != N
4dd0: 55 4c 4c 29 20 7b 0a 09 09 70 61 74 68 69 6e 66  ULL) {...pathinf
4de0: 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b  o->packaged = 1;
4df0: 0a 09 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f 62  ..}...Tcl_DictOb
4e00: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
4e10: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
4e20: 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f 76 61  y_time, &attr_va
4e30: 6c 75 65 29 3b 0a 09 69 66 20 28 61 74 74 72 5f  lue);..if (attr_
4e40: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
4e50: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
4e60: 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f  _GetWideIntFromO
4e70: 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61  bj(NULL, attr_va
4e80: 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  lue, &attr_value
4e90: 5f 77 69 64 65 29 3b 0a 09 09 69 66 20 28 74 63  _wide);...if (tc
4ea0: 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29  l_ret == TCL_OK)
4eb0: 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e   {....pathinfo->
4ec0: 74 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75  time = attr_valu
4ed0: 65 5f 77 69 64 65 3b 0a 09 09 7d 0a 09 7d 20 65  e_wide;...}..} e
4ee0: 6c 73 65 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f  lse {...pathinfo
4ef0: 2d 3e 74 69 6d 65 20 3d 20 30 3b 0a 09 7d 0a 0a  ->time = 0;..}..
4f00: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
4f10: 65 72 70 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  erp);...appfs_ge
4f20: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
4f30: 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69  e_add(path, fsui
4f40: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  d, pathinfo);...
4f50: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
4f60: 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73  atic char *appfs
4f70: 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  _prepare_to_crea
4f80: 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  te(const char *p
4f90: 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ath) {..Tcl_Inte
4fa0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e  rp *interp;..con
4fb0: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
4fc0: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  th;..int tcl_ret
4fd0: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
4fe0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
4ff0: 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73  ush(appfs_get_fs
5000: 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e  uid(), -1);...in
5010: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
5020: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
5030: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
5040: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
5050: 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72  ..}...Tcl_Preser
5060: 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 74 63  ve(interp);...tc
5070: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
5080: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
5090: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70  , "::appfs::prep
50a0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20  are_to_create", 
50b0: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
50c0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
50d0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
50e0: 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65  ::appfs::prepare
50f0: 5f 74 6f 5f 63 72 65 61 74 65 28 25 73 29 20 66  _to_create(%s) f
5100: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
5110: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
5120: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
5130: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
5140: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
5150: 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
5160: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
5170: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
5180: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
5190: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
51a0: 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 52 65 6c  terp);...Tcl_Rel
51b0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  ease(interp);...
51c0: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
51d0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
51e0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
51f0: 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c  turn(strdup(real
5200: 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74  _path));.}..stat
5210: 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 6c  ic char *appfs_l
5220: 6f 63 61 6c 70 61 74 68 28 63 6f 6e 73 74 20 63  ocalpath(const c
5230: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
5240: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5250: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
5260: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
5270: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
5280: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
5290: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
52a0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
52b0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
52c0: 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  ..Tcl_Preserve(i
52d0: 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f 72 65  nterp);...tcl_re
52e0: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
52f0: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
5300: 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74  :appfs::localpat
5310: 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  h", path);..if (
5320: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
5330: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
5340: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63  UG("::appfs::loc
5350: 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c 65  alpath(%s) faile
5360: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
5370: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
5380: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
5390: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
53a0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72  t(interp));....r
53b0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
53c0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
53d0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
53e0: 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c  t(interp);...Tcl
53f0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
5400: 3b 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  ;...if (real_pat
5410: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
5420: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
5430: 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70 28  ..return(strdup(
5440: 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a  real_path));.}..
5450: 23 69 66 64 65 66 20 41 50 50 46 53 5f 45 58 49  #ifdef APPFS_EXI
5460: 54 5f 50 41 54 48 0a 73 74 61 74 69 63 20 76 6f  T_PATH.static vo
5470: 69 64 20 61 70 70 66 73 5f 65 78 69 74 28 76 6f  id appfs_exit(vo
5480: 69 64 29 20 7b 0a 09 69 6e 74 20 67 6c 6f 62 61  id) {..int globa
5490: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
54a0: 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74  ey;...global_int
54b0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20  erp_reset_key = 
54c0: 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64  __sync_fetch_and
54d0: 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73  _add(&interp_res
54e0: 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f 73  et_key, 0);..__s
54f0: 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 73 75  ync_fetch_and_su
5500: 62 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  b(&interp_reset_
5510: 6b 65 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74 65  key, global_inte
5520: 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 3b 0a 0a  rp_reset_key);..
5530: 09 77 68 69 6c 65 20 28 5f 5f 73 79 6e 63 5f 73  .while (__sync_s
5540: 75 62 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e  ub_and_fetch(&in
5550: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
5560: 31 29 20 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a 20  1) >= 0) {.../* 
5570: 42 75 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a  Busy Loop */..}.
5580: 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  ..global_interp_
5590: 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79  reset_key = __sy
55a0: 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64  nc_fetch_and_add
55b0: 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  (&interp_reset_k
55c0: 65 79 2c 20 30 29 3b 0a 09 69 66 20 28 67 6c 6f  ey, 0);..if (glo
55d0: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
55e0: 5f 6b 65 79 20 21 3d 20 2d 31 29 20 7b 0a 09 09  _key != -1) {...
55f0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 72 72  APPFS_DEBUG("Err
5600: 6f 72 20 73 65 6e 64 69 6e 67 20 6b 69 6c 6c 20  or sending kill 
5610: 73 69 67 6e 61 6c 20 74 6f 20 61 6c 6c 20 74 68  signal to all th
5620: 72 65 61 64 73 2c 20 61 62 6f 72 74 69 6e 67 20  reads, aborting 
5630: 61 6e 79 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09  anyway.");..}...
5640: 66 75 73 65 5f 65 78 69 74 28 66 75 73 65 5f 67  fuse_exit(fuse_g
5650: 65 74 5f 63 6f 6e 74 65 78 74 28 29 2d 3e 66 75  et_context()->fu
5660: 73 65 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  se);...appfs_get
5670: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
5680: 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a  _flush(-1, -1);.
5690: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e 64  ..return;.}.#end
56a0: 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  if..static int a
56b0: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69  ppfs_fuse_readli
56c0: 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  nk(const char *p
56d0: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
56e0: 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09  size_t size) {..
56f0: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
5700: 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a  hinfo pathinfo;.
5710: 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30 3b  .int retval = 0;
5720: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5730: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
5740: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
5750: 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20  ..pathinfo.type 
5760: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
5770: 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76  _INVALID;...retv
5780: 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70  al = appfs_get_p
5790: 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26  ath_info(path, &
57a0: 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28  pathinfo);..if (
57b0: 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09  retval != 0) {..
57c0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
57d0: 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e  ..}...if (pathin
57e0: 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46 53  fo.type != APPFS
57f0: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e  _PATHTYPE_SYMLIN
5800: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  K) {...return(-E
5810: 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  INVAL);..}...if 
5820: 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66  ((strlen(pathinf
5830: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
5840: 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 20  nk.source) + 1) 
5850: 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74 75  > size) {...retu
5860: 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47  rn(-ENAMETOOLONG
5870: 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62  );..}...memcpy(b
5880: 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79 70  uf, pathinfo.typ
5890: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
58a0: 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61 74  urce, strlen(pat
58b0: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73  hinfo.typeinfo.s
58c0: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b  ymlink.source) +
58d0: 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29   1);...return(0)
58e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
58f0: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
5900: 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  tr(const char *p
5910: 61 74 68 2c 20 73 74 72 75 63 74 20 73 74 61 74  ath, struct stat
5920: 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72 75   *stbuf) {..stru
5930: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
5940: 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74  o pathinfo;..int
5950: 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61   retval;...retva
5960: 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44  l = 0;...APPFS_D
5970: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
5980: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
5990: 61 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66 69  ath);..#if (defi
59a0: 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65  ned(DEBUG) && de
59b0: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54  fined(APPFS_EXIT
59c0: 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e  _PATH)) || defin
59d0: 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41  ed(APPFS_EXIT_PA
59e0: 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f  TH_ENABLE_MAJOR_
59f0: 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09  SECURITY_HOLE)..
5a00: 2f 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20 61  /*.. * This is a
5a10: 20 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79 20   major security 
5a20: 69 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e 6e  issue so we cann
5a30: 6f 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f 6d  ot let it be com
5a40: 70 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61  piled into.. * a
5a50: 6e 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a  ny release.. */.
5a60: 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74  ..if (strcmp(pat
5a70: 68 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20 30  h, "/exit") == 0
5a80: 29 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69 74  ) {...appfs_exit
5a90: 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09  ();..}.#endif...
5aa0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20  pathinfo.type = 
5ab0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
5ac0: 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c  NVALID;...retval
5ad0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74   = appfs_get_pat
5ae0: 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61  h_info(path, &pa
5af0: 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65  thinfo);..if (re
5b00: 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72  tval != 0) {...r
5b10: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09  eturn(retval);..
5b20: 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66  }...memset(stbuf
5b30: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75  , 0, sizeof(stru
5b40: 63 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62  ct stat));...stb
5b50: 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70  uf->st_mtime = p
5b60: 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73  athinfo.time;..s
5b70: 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d  tbuf->st_ctime =
5b80: 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a   pathinfo.time;.
5b90: 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65  .stbuf->st_atime
5ba0: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65   = pathinfo.time
5bb0: 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f  ;..stbuf->st_ino
5bc0: 20 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e     = pathinfo.in
5bd0: 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ode;..stbuf->st_
5be0: 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 73 77 69  mode  = 0;...swi
5bf0: 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  tch (pathinfo.ty
5c00: 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41 50 50  pe) {...case APP
5c10: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45  FS_PATHTYPE_DIRE
5c20: 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75 66 2d  CTORY:....stbuf-
5c30: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 44  >st_mode = S_IFD
5c40: 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74  IR | 0555;....st
5c50: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20  buf->st_nlink = 
5c60: 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74 79 70  2 + pathinfo.typ
5c70: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63  einfo.dir.childc
5c80: 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  ount;....break;.
5c90: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
5ca0: 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09 09 69  HTYPE_FILE:....i
5cb0: 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  f (pathinfo.type
5cc0: 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74  info.file.execut
5cd0: 61 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62 75  able) {.....stbu
5ce0: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
5cf0: 46 52 45 47 20 7c 20 30 35 35 35 3b 0a 09 09 09  FREG | 0555;....
5d00: 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 73 74 62  } else {.....stb
5d10: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
5d20: 49 46 52 45 47 20 7c 20 30 34 34 34 3b 0a 09 09  IFREG | 0444;...
5d30: 09 7d 0a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  .}.....stbuf->st
5d40: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
5d50: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
5d60: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
5d70: 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 09 09 09  o.file.size;....
5d80: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50  break;...case AP
5d90: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d  PFS_PATHTYPE_SYM
5da0: 4c 49 4e 4b 3a 0a 09 09 09 73 74 62 75 66 2d 3e  LINK:....stbuf->
5db0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 4c 4e  st_mode = S_IFLN
5dc0: 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62  K | 0555;....stb
5dd0: 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31  uf->st_nlink = 1
5de0: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73  ;....stbuf->st_s
5df0: 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74  ize = pathinfo.t
5e00: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
5e10: 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  size;....break;.
5e20: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
5e30: 48 54 59 50 45 5f 53 4f 43 4b 45 54 3a 0a 09 09  HTYPE_SOCKET:...
5e40: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
5e50: 3d 20 53 5f 49 46 53 4f 43 4b 20 7c 20 30 35 35  = S_IFSOCK | 055
5e60: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
5e70: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
5e80: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30  buf->st_size = 0
5e90: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
5ea0: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
5eb0: 45 5f 46 49 46 4f 3a 0a 09 09 09 73 74 62 75 66  E_FIFO:....stbuf
5ec0: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
5ed0: 49 46 4f 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  IFO | 0555;....s
5ee0: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
5ef0: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
5f00: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
5f10: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
5f20: 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f  S_PATHTYPE_DOES_
5f30: 4e 4f 54 5f 45 58 49 53 54 3a 0a 09 09 09 72 65  NOT_EXIST:....re
5f40: 74 76 61 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a  tval = -ENOENT;.
5f50: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
5f60: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
5f70: 5f 49 4e 56 41 4c 49 44 3a 0a 09 09 09 72 65 74  _INVALID:....ret
5f80: 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09  val = -EIO;.....
5f90: 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28  break;..}...if (
5fa0: 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65  pathinfo.package
5fb0: 64 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d) {...stbuf->st
5fc0: 5f 75 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67  _uid   = appfs_g
5fd0: 65 74 5f 66 73 75 69 64 28 29 3b 0a 09 09 73 74  et_fsuid();...st
5fe0: 62 75 66 2d 3e 73 74 5f 67 69 64 20 20 20 3d 20  buf->st_gid   = 
5ff0: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
6000: 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  );...stbuf->st_m
6010: 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a  ode |= 0200;..}.
6020: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
6030: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
6040: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64  appfs_fuse_readd
6050: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
6060: 61 74 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20  ath, void *buf, 
6070: 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20  fuse_fill_dir_t 
6080: 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66  filler, off_t of
6090: 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73  fset, struct fus
60a0: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
60b0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
60c0: 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a  interp;..Tcl_Obj
60d0: 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e   **children;..in
60e0: 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74  t children_count
60f0: 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f  , idx;..int tcl_
6100: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
6110: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
6120: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
6130: 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  h);...interp = a
6140: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
6150: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
6160: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6170: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50  n(0);..}...Tcl_P
6180: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
6190: 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22  ...filler(buf, "
61a0: 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66  .", NULL, 0);..f
61b0: 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c  iller(buf, "..",
61c0: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c   NULL, 0);...tcl
61d0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
61e0: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
61f0: 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68   "::appfs::getch
6200: 69 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a  ildren", path);.
6210: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
6220: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
6230: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
6240: 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25 73  ::getchildren(%s
6250: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
6260: 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  );...APPFS_DEBUG
6270: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
6280: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
6290: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
62a0: 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73  );....Tcl_Releas
62b0: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  e(interp);....re
62c0: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74 63  turn(0);..}...tc
62d0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74  l_ret = Tcl_List
62e0: 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69  ObjGetElements(i
62f0: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62  nterp, Tcl_GetOb
6300: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c  jResult(interp),
6310: 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74   &children_count
6320: 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69  , &children);..i
6330: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
6340: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
6350: 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20 6c  DEBUG("Parsing l
6360: 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e 20  ist of children 
6370: 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c 65  on path %s faile
6380: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
6390: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
63a0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
63b0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
63c0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54  t(interp));....T
63d0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
63e0: 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  p);....return(0)
63f0: 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20  ;..}...for (idx 
6400: 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64  = 0; idx < child
6410: 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b  ren_count; idx++
6420: 29 20 7b 0a 09 09 66 69 6c 6c 65 72 28 62 75 66  ) {...filler(buf
6430: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
6440: 63 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c 20  children[idx]), 
6450: 4e 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a 09 54  NULL, 0);..}...T
6460: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
6470: 70 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  p);...return(0);
6480: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
6490: 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63  ppfs_fuse_open(c
64a0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
64b0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
64c0: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54  e_info *fi) {..T
64d0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
64e0: 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73  p;..struct appfs
64f0: 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e  _pathinfo pathin
6500: 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  fo;..const char 
6510: 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64  *real_path, *mod
6520: 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c  e;..int gpi_ret,
6530: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66   tcl_ret;..int f
6540: 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  h;...APPFS_DEBUG
6550: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
6560: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
6570: 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70  ;...gpi_ret = ap
6580: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
6590: 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66  o(path, &pathinf
65a0: 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66  o);...if ((fi->f
65b0: 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59  lags & (O_WRONLY
65c0: 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f  |O_CREAT)) == (O
65d0: 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29  _CREAT|O_WRONLY)
65e0: 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c  ) {.../* The fil
65f0: 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65  e will be create
6600: 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74  d if it does not
6610: 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28   exist */...if (
6620: 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20  gpi_ret != 0 && 
6630: 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45  gpi_ret != -ENOE
6640: 4e 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28  NT) {....return(
6650: 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09  gpi_ret);...}...
6660: 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22  .mode = "create"
6670: 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20  ;..../*... * We 
6680: 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68  have to clear th
6690: 65 20 63 61 63 68 65 20 68 65 72 65 20 73 6f 20  e cache here so 
66a0: 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20  that the number 
66b0: 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65  of... * links ge
66c0: 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e  ts maintained on
66d0: 20 74 68 65 20 70 61 72 65 6e 74 20 64 69 72 65   the parent dire
66e0: 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70  ctory... */...ap
66f0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
6700: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70  o_cache_flush(ap
6710: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c  pfs_get_fsuid(),
6720: 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a   -1);..} else {.
6730: 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75  ../* The file mu
6740: 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73 74  st already exist
6750: 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65   */...if (gpi_re
6760: 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74  t != 0) {....ret
6770: 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09  urn(gpi_ret);...
6780: 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a  }....mode = "";.
6790: 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67  ...if ((fi->flag
67a0: 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d  s & O_WRONLY) ==
67b0: 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09   O_WRONLY) {....
67c0: 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a  mode = "write";.
67d0: 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74  ..}..}...if (pat
67e0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50  hinfo.type == AP
67f0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
6800: 45 43 54 4f 52 59 29 20 7b 0a 09 09 72 65 74 75  ECTORY) {...retu
6810: 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a  rn(-EISDIR);..}.
6820: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
6830: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
6840: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
6850: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
6860: 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72  IO);..}...Tcl_Pr
6870: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a  eserve(interp);.
6880: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
6890: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
68a0: 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 3, "::appfs::
68b0: 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c  openpath", path,
68c0: 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63 6c   mode);..if (tcl
68d0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
68e0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
68f0: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
6900: 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65  th(%s, %s) faile
6910: 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29  d.", path, mode)
6920: 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
6930: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
6940: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
6950: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
6960: 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65  ;....Tcl_Release
6970: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74  (interp);....ret
6980: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
6990: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f  real_path = Tcl_
69a0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
69b0: 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 52  interp);...Tcl_R
69c0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
69d0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
69e0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
69f0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
6a00: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 72 61  APPFS_DEBUG("Tra
6a10: 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73 74 20  nslated request 
6a20: 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70  to open %s to op
6a30: 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d  ening %s (mode =
6a40: 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c   \"%s\")", path,
6a50: 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65   real_path, mode
6a60: 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72  );...fh = open(r
6a70: 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c  eal_path, fi->fl
6a80: 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66  ags, 0600);...if
6a90: 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 72 65   (fh < 0) {...re
6aa0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
6ab0: 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09  .fi->fh = fh;...
6ac0: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
6ad0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
6ae0: 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 20  use_close(const 
6af0: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
6b00: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
6b10: 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63 6c  o *fi) {..int cl
6b20: 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73  ose_ret;...appfs
6b30: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
6b40: 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70  ache_rm(path, ap
6b50: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
6b60: 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d 20  ;...close_ret = 
6b70: 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a 09  close(fi->fh);..
6b80: 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21 3d  if (close_ret !=
6b90: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d   0) {...return(-
6ba0: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  EIO);..}...retur
6bb0: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
6bc0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72  int appfs_fuse_r
6bd0: 65 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ead(const char *
6be0: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
6bf0: 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66   size_t size, of
6c00: 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75  f_t offset, stru
6c10: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
6c20: 6f 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20  o *fi) {..off_t 
6c30: 6c 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a  lseek_ret;..ssiz
6c40: 65 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 0a 09  e_t read_ret;...
6c50: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
6c60: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
6c70: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 6c  ..)", path);...l
6c80: 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b  seek_ret = lseek
6c90: 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c  (fi->fh, offset,
6ca0: 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20   SEEK_SET);..if 
6cb0: 28 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66  (lseek_ret != of
6cc0: 66 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e  fset) {...return
6cd0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61  (-EIO);..}...rea
6ce0: 64 5f 72 65 74 20 3d 20 72 65 61 64 28 66 69 2d  d_ret = read(fi-
6cf0: 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29 3b  >fh, buf, size);
6d00: 0a 0a 09 72 65 74 75 72 6e 28 72 65 61 64 5f 72  ...return(read_r
6d10: 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  et);.}..static i
6d20: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72  nt appfs_fuse_wr
6d30: 69 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ite(const char *
6d40: 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72  path, const char
6d50: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
6d60: 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74  ze, off_t offset
6d70: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
6d80: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
6d90: 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b  off_t lseek_ret;
6da0: 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65 5f  ..ssize_t write_
6db0: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
6dc0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
6dd0: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
6de0: 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  h);...appfs_get_
6df0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
6e00: 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67  rm(path, appfs_g
6e10: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 6c  et_fsuid());...l
6e20: 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b  seek_ret = lseek
6e30: 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c  (fi->fh, offset,
6e40: 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20   SEEK_SET);..if 
6e50: 28 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66  (lseek_ret != of
6e60: 66 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e  fset) {...return
6e70: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 77 72 69  (-EIO);..}...wri
6e80: 74 65 5f 72 65 74 20 3d 20 77 72 69 74 65 28 66  te_ret = write(f
6e90: 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65  i->fh, buf, size
6ea0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 77 72 69 74  );...return(writ
6eb0: 65 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69  e_ret);.}..stati
6ec0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
6ed0: 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68 61  _mknod(const cha
6ee0: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
6ef0: 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76 69  mode, dev_t devi
6f00: 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  ce) {..char *rea
6f10: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e  l_path;..int mkn
6f20: 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  od_ret;...APPFS_
6f30: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
6f40: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
6f50: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
6f60: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
6f70: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
6f80: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
6f90: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
6fa0: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
6fb0: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
6fc0: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
6fd0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
6fe0: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
6ff0: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
7000: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
7010: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
7020: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
7030: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
7040: 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72  ter();...mknod_r
7050: 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f  et = mknod(real_
7060: 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76 69  path, mode, devi
7070: 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ce);...appfs_sim
7080: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
7090: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
70a0: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
70b0: 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29 20  mknod_ret != 0) 
70c0: 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  {...return(errno
70d0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74   * -1);..}...ret
70e0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
70f0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
7100: 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68  _create(const ch
7110: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
7120: 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66 75   mode, struct fu
7130: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
7140: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
7150: 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a  path;..int fd;..
7160: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
7170: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
7180: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
7190: 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46  if ((mode & S_IF
71a0: 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29  CHR) == S_IFCHR)
71b0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45   {...return(-EPE
71c0: 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d  RM);..}...if ((m
71d0: 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d  ode & S_IFBLK) =
71e0: 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72  = S_IFBLK) {...r
71f0: 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09  eturn(-EPERM);..
7200: 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  }...real_path = 
7210: 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f  appfs_prepare_to
7220: 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09  _create(path);..
7230: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
7240: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
7250: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
7260: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
7270: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
7280: 66 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c 5f  fd = creat(real_
7290: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
72a0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
72b0: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
72c0: 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29  .free(real_path)
72d0: 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29 20  ;...if (fd < 0) 
72e0: 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  {...return(errno
72f0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d   * -1);..}...fi-
7300: 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74 75  >fh = fd;...retu
7310: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
7320: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
7330: 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20 63  truncate(const c
7340: 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f 74  har *path, off_t
7350: 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20 2a   size) {..char *
7360: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
7370: 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a 09  truncate_ret;...
7380: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
7390: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
73a0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72  ..)", path);...r
73b0: 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73  eal_path = appfs
73c0: 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61 74 68 29  _localpath(path)
73d0: 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ;..if (real_path
73e0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
73f0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
7400: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
7410: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
7420: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
7430: 75 69 64 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f  uid());...appfs_
7440: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
7450: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e  _enter();...trun
7460: 63 61 74 65 5f 72 65 74 20 3d 20 74 72 75 6e 63  cate_ret = trunc
7470: 61 74 65 28 72 65 61 6c 5f 70 61 74 68 2c 20 73  ate(real_path, s
7480: 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ize);...appfs_si
7490: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
74a0: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
74b0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
74c0: 28 74 72 75 6e 63 61 74 65 5f 72 65 74 20 21 3d  (truncate_ret !=
74d0: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65   0) {...return(e
74e0: 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a  rrno * -1);..}..
74f0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
7500: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7510: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
7520: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
7530: 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  th) {..Tcl_Inter
7540: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20  p *interp;..int 
7550: 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  tcl_ret;...APPFS
7560: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
7570: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
7580: 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f   path);...appfs_
7590: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
75a0: 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f  che_flush(appfs_
75b0: 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29  get_fsuid(), -1)
75c0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
75d0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
75e0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
75f0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
7600: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  -EIO);..}...tcl_
7610: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
7620: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
7630: 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b  "::appfs::unlink
7640: 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69  path", path);..i
7650: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
7660: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
7670: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
7680: 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20 66  unlinkpath(%s) f
7690: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
76a0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
76b0: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
76c0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
76d0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
76e0: 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
76f0: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
7700: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63  n(-EIO);..}...Tc
7710: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7720: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
7730: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
7740: 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63  pfs_fuse_mkdir(c
7750: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
7760: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a   mode_t mode) {.
7770: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
7780: 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74  ;..int mkdir_ret
7790: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
77a0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
77b0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
77c0: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
77d0: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
77e0: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69  create(path);..i
77f0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
7800: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
7810: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
7820: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
7830: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d  _fs_enter();...m
7840: 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72  kdir_ret = mkdir
7850: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
7860: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
7870: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
7880: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
7890: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b  _path);...if (mk
78a0: 64 69 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  dir_ret != 0) {.
78b0: 09 09 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45  ..if (errno != E
78c0: 45 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75  EXIST) {....retu
78d0: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
78e0: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
78f0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
7900: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d  t appfs_fuse_chm
7910: 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  od(const char *p
7920: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
7930: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
7940: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
7950: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
7960: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63  ..int tcl_ret, c
7970: 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  hmod_ret;...APPF
7980: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
7990: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
79a0: 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73  , path);...appfs
79b0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
79c0: 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70  ache_rm(path, ap
79d0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
79e0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
79f0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
7a00: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
7a10: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
7a20: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  -EIO);..}...Tcl_
7a30: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
7a40: 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  ;...tcl_ret = ap
7a50: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
7a60: 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73  erp, 3, "::appfs
7a70: 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74  ::openpath", pat
7a80: 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66  h, "write");..if
7a90: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
7aa0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
7ab0: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f  EBUG("::appfs::o
7ac0: 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20  penpath(%s, %s) 
7ad0: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20  failed.", path, 
7ae0: 22 77 72 69 74 65 22 29 3b 0a 09 09 41 50 50 46  "write");...APPF
7af0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
7b00: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
7b10: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
7b20: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c  interp));....Tcl
7b30: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
7b40: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  ;....return(-EIO
7b50: 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74  );..}...real_pat
7b60: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
7b70: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
7b80: 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
7b90: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72 65  nterp);...if (re
7ba0: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
7bb0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
7bc0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
7bd0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
7be0: 6e 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f  nter();...chmod_
7bf0: 72 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c  ret = chmod(real
7c00: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
7c10: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
7c20: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
7c30: 0a 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72  ..return(chmod_r
7c40: 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51  et);.}../*. * SQ
7c50: 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63  Lite3 mode: Exec
7c60: 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20  ute raw SQL and 
7c70: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
7c80: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
7c90: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73  atic int appfs_s
7ca0: 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61  qlite3(const cha
7cb0: 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *sql) {..Tcl_I
7cc0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
7cd0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f  const char *sql_
7ce0: 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ret;..int tcl_re
7cf0: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
7d00: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
7d10: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20  terp(NULL);..if 
7d20: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
7d30: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
7d40: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
7d50: 63 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74  create a Tcl int
7d60: 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74  erpreter.  Abort
7d70: 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74  ing.\n");....ret
7d80: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c  urn(1);..}...tcl
7d90: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
7da0: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c  _Eval(interp, 5,
7db0: 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20   "::appfs::db", 
7dc0: 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f  "eval", sql, "ro
7dd0: 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f  w", "unset -noco
7de0: 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70  mplain row(*); p
7df0: 61 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20  array row; puts 
7e00: 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c  \"----\"");..sql
7e10: 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74  _ret = Tcl_GetSt
7e20: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
7e30: 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65  p);...if (tcl_re
7e40: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
7e50: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
7e60: 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c   "[error] %s\n",
7e70: 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65   sql_ret);....re
7e80: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66  turn(1);..}...if
7e90: 20 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c   (sql_ret && sql
7ea0: 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29  _ret[0] != '\0')
7eb0: 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c   {...printf("%s\
7ec0: 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d  n", sql_ret);..}
7ed0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
7ee0: 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a  ./*. * Tcl mode:
7ef0: 20 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c   Execute raw Tcl
7f00: 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63   and return succ
7f10: 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20  ess or failure. 
7f20: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
7f30: 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68  pfs_tcl(const ch
7f40: 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f  ar *tcl) {..Tcl_
7f50: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
7f60: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  .const char *tcl
7f70: 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63  _result;..int tc
7f80: 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20  l_ret;...interp 
7f90: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
7fa0: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
7fb0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
7fc0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
7fd0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
7fe0: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
7ff0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
8000: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
8010: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
8020: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
8030: 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29  val(interp, tcl)
8040: 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20  ;..tcl_result = 
8050: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
8060: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ult(interp);...i
8070: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
8080: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
8090: 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f  f(stderr, "[erro
80a0: 72 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65  r] %s\n", tcl_re
80b0: 73 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e  sult);....return
80c0: 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63  (1);..}...if (tc
80d0: 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f  l_result && tcl_
80e0: 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30  result[0] != '\0
80f0: 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25  ') {...printf("%
8100: 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74  s\n", tcl_result
8110: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
8120: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  );.}../*. * AppF
8130: 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54  Sd Package for T
8140: 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42  cl:. *         B
8150: 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70  ridge for I/O op
8160: 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75  erations to requ
8170: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  est information 
8180: 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e  about the curren
8190: 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61  t. *         tra
81a0: 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a  nsaction. */./*.
81b0: 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65   * Tcl interface
81c0: 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65   to get the home
81d0: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74   directory for t
81e0: 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74  he user making t
81f0: 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20  he "current". * 
8200: 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74  FUSE I/O request
8210: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
8220: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
8230: 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61  medir(ClientData
8240: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
8250: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
8260: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
8270: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61  T objv[]) {..cha
8280: 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c  r *homedir;..Tcl
8290: 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62  _Obj *homedir_ob
82a0: 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b  j;..uid_t fsuid;
82b0: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61  ..static __threa
82c0: 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f  d Tcl_Obj *last_
82d0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55  homedir_obj = NU
82e0: 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  LL;..static __th
82f0: 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f  read uid_t last_
8300: 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20  fsuid = -1;..   
8310: 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d       if (objc !=
8320: 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20   1) {.          
8330: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e        Tcl_WrongN
8340: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
8350: 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20  , objv, NULL);. 
8360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
8370: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
8380: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73  ;.        }...fs
8390: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  uid = appfs_get_
83a0: 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66  fsuid();...if (f
83b0: 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75  suid == last_fsu
83c0: 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64  id && last_homed
83d0: 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20  ir_obj != NULL) 
83e0: 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  {...homedir_obj 
83f0: 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  = last_homedir_o
8400: 62 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  bj;..} else {...
8410: 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f  homedir = appfs_
8420: 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66  get_homedir(appf
8430: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
8440: 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d  ...if (homedir =
8450: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74  = NULL) {....ret
8460: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
8470: 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f  ..}....homedir_o
8480: 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  bj = Tcl_NewStri
8490: 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d  ngObj(homedir, -
84a0: 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65  1);....free(home
84b0: 64 69 72 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73  dir);....if (las
84c0: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d  t_homedir_obj !=
84d0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f   NULL) {....Tcl_
84e0: 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73  DecrRefCount(las
84f0: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t_homedir_obj);.
8500: 09 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65  ..}....last_home
8510: 64 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69  dir_obj = homedi
8520: 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73  r_obj;...last_fs
8530: 75 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09  uid = fsuid;....
8540: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
8550: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  (last_homedir_ob
8560: 6a 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09  j);..}..       .
8570: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
8580: 28 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72  (interp, homedir
8590: 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20  _obj);..        
85a0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
85b0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
85c0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
85d0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43  _user_fs_enter(C
85e0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
85f0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
8600: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
8610: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
8620: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
8630: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
8640: 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  er();...return(T
8650: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
8660: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
8670: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
8680: 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74  _leave(ClientDat
8690: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
86a0: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
86b0: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
86c0: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
86d0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
86e0: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
86f0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
8700: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
8710: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
8720: 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  d(ClientData cd,
8730: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
8740: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
8750: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
8760: 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66  jv[]) {..uid_t f
8770: 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20  suid;...fsuid = 
8780: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
8790: 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f  );..       .Tcl_
87a0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
87b0: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65  erp, Tcl_NewWide
87c0: 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a  IntObj(fsuid));.
87d0: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
87e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
87f0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73  tcl_appfs_get_fs
8800: 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63  gid(ClientData c
8810: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
8820: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
8830: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
8840: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74  objv[]) {..gid_t
8850: 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20   fsgid;...fsgid 
8860: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
8870: 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63  d();..       .Tc
8880: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
8890: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69  nterp, Tcl_NewWi
88a0: 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29  deIntObj(fsgid))
88b0: 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f  ;...return(TCL_O
88c0: 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  K);.}..static in
88d0: 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f  t tcl_appfs_get_
88e0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
88f0: 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61  flush(ClientData
8900: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
8910: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
8920: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
8930: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74  T objv[]) {..int
8940: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e   tcl_ret;..int n
8950: 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73  ew_size;...new_s
8960: 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28  ize = -1;...if (
8970: 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74  objc == 2) {...t
8980: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
8990: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
89a0: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77  p, objv[1], &new
89b0: 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63  _size);...if (tc
89c0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
89d0: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c   {....return(tcl
89e0: 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c  _ret);...}..} el
89f0: 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20  se if (objc > 2 
8a00: 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20  || objc < 1) {. 
8a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
8a20: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
8a30: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
8a40: 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a   "?new_cache_siz
8a50: 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54  e?");...return(T
8a60: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
8a70: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
8a80: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
8a90: 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a  -1, new_size);..
8aa0: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
8ab0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41  .}..static int A
8ac0: 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49  ppfsd_Init(Tcl_I
8ad0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b  nterp *interp) {
8ae0: 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f  .#ifdef USE_TCL_
8af0: 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49  STUBS..if (Tcl_I
8b00: 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c  nitStubs(interp,
8b10: 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29   TCL_VERSION, 0)
8b20: 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75   == 0L) {...retu
8b30: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
8b40: 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43  }.#endif...Tcl_C
8b50: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
8b60: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
8b70: 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74  :get_homedir", t
8b80: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
8b90: 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  edir, NULL, NULL
8ba0: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
8bb0: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
8bc0: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73   "appfsd::get_fs
8bd0: 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  uid", tcl_appfs_
8be0: 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c  get_fsuid, NULL,
8bf0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
8c00: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
8c10: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67  terp, "appfsd::g
8c20: 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61  et_fsgid", tcl_a
8c30: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20  ppfs_get_fsgid, 
8c40: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
8c50: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
8c60: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
8c70: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
8c80: 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c  r_fs_enter", tcl
8c90: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
8ca0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e  user_fs_enter, N
8cb0: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
8cc0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
8cd0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
8ce0: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  d::simulate_user
8cf0: 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f  _fs_leave", tcl_
8d00: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8d10: 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55  ser_fs_leave, NU
8d20: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
8d30: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
8d40: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
8d50: 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  ::get_path_info_
8d60: 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63  cache_flush", tc
8d70: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  l_appfs_get_path
8d80: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
8d90: 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  h, NULL, NULL);.
8da0: 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65  ..Tcl_PkgProvide
8db0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
8dc0: 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74  ", "1.0");...ret
8dd0: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
8de0: 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72  /*. * Hot-restar
8df0: 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a  t support. */./*
8e00: 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d   Initiate a hot-
8e10: 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69  restart */.stati
8e20: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74  c void appfs_hot
8e30: 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b  _restart(void) {
8e40: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41  ..APPFS_DEBUG("A
8e50: 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65  sked to initiate
8e60: 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a   hot restart");.
8e70: 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65  ..appfs_tcl_Rese
8e80: 74 49 6e 74 65 72 70 73 28 29 3b 0a 09 61 70 70  tInterps();..app
8e90: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
8ea0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
8eb0: 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a   -1);...return;.
8ec0: 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20  }../*. * Signal 
8ed0: 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 20  handler. *      
8ee0: 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69 61     SIGHUP initia
8ef0: 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61 72  tes a hot restar
8f00: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t. */.static voi
8f10: 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68  d appfs_signal_h
8f20: 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29 20  andler(int sig) 
8f30: 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e  {../* Do not han
8f40: 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 69  dle signals unti
8f50: 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e 20  l FUSE has been 
8f60: 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 28  started */..if (
8f70: 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  !appfs_fuse_star
8f80: 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b  ted) {...return;
8f90: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74  ..}.../* Request
8fa0: 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 68   to perform a "h
8fb0: 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a 09  ot" restart */..
8fc0: 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48 55  if (sig == SIGHU
8fd0: 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74  P) {...appfs_hot
8fe0: 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a  _restart();..}..
8ff0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
9000: 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74 68  * Terminate a th
9010: 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20  read. */.static 
9020: 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d 69  void appfs_termi
9030: 6e 61 74 65 5f 69 6e 74 65 72 70 28 76 6f 69 64  nate_interp(void
9040: 20 2a 5f 69 6e 74 65 72 70 29 20 7b 0a 09 54 63   *_interp) {..Tc
9050: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
9060: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
9070: 22 43 61 6c 6c 65 64 3a 20 5f 69 6e 74 65 72 70  "Called: _interp
9080: 20 3d 20 25 70 22 2c 20 5f 69 6e 74 65 72 70 29   = %p", _interp)
9090: 3b 0a 0a 09 69 66 20 28 5f 69 6e 74 65 72 70 20  ;...if (_interp 
90a0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
90b0: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
90c0: 61 74 69 6e 67 20 74 68 72 65 61 64 20 77 69 74  ating thread wit
90d0: 68 20 6e 6f 20 69 6e 74 65 72 70 72 65 74 65 72  h no interpreter
90e0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09  ");....return;..
90f0: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 5f 69 6e  }...interp = _in
9100: 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45  terp;...APPFS_DE
9110: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
9120: 20 69 6e 74 65 72 70 72 65 74 65 72 20 64 75 65   interpreter due
9130: 20 74 6f 20 74 68 72 65 61 64 20 74 65 72 6d 69   to thread termi
9140: 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09 54 63 6c 5f  nation");...Tcl_
9150: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
9160: 65 72 70 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a  erp);...return;.
9170: 7d 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70  }../*. * FUSE op
9180: 65 72 61 74 69 6f 6e 73 20 73 74 72 75 63 74 75  erations structu
9190: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 73 74  re. */.static st
91a0: 72 75 63 74 20 66 75 73 65 5f 6f 70 65 72 61 74  ruct fuse_operat
91b0: 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70 65 72 61  ions appfs_opera
91c0: 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e 67 65 74 61  tions = {...geta
91d0: 74 74 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ttr   = appfs_fu
91e0: 73 65 5f 67 65 74 61 74 74 72 2c 0a 09 2e 72 65  se_getattr,...re
91f0: 61 64 64 69 72 20 20 20 3d 20 61 70 70 66 73 5f  addir   = appfs_
9200: 66 75 73 65 5f 72 65 61 64 64 69 72 2c 0a 09 2e  fuse_readdir,...
9210: 72 65 61 64 6c 69 6e 6b 20 20 3d 20 61 70 70 66  readlink  = appf
9220: 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 2c  s_fuse_readlink,
9230: 0a 09 2e 6f 70 65 6e 20 20 20 20 20 20 3d 20 61  ...open      = a
9240: 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a  ppfs_fuse_open,.
9250: 09 2e 72 65 6c 65 61 73 65 20 20 20 3d 20 61 70  ..release   = ap
9260: 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 2c 0a  pfs_fuse_close,.
9270: 09 2e 72 65 61 64 20 20 20 20 20 20 3d 20 61 70  ..read      = ap
9280: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 2c 0a 09  pfs_fuse_read,..
9290: 2e 77 72 69 74 65 20 20 20 20 20 3d 20 61 70 70  .write     = app
92a0: 66 73 5f 66 75 73 65 5f 77 72 69 74 65 2c 0a 09  fs_fuse_write,..
92b0: 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d 20 61 70 70  .mknod     = app
92c0: 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09  fs_fuse_mknod,..
92d0: 2e 63 72 65 61 74 65 20 20 20 20 3d 20 61 70 70  .create    = app
92e0: 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 2c 0a  fs_fuse_create,.
92f0: 09 2e 74 72 75 6e 63 61 74 65 20 20 3d 20 61 70  ..truncate  = ap
9300: 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74  pfs_fuse_truncat
9310: 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d  e,...unlink    =
9320: 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69   appfs_fuse_unli
9330: 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 72 6d 64 69  nk_rmdir,...rmdi
9340: 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  r     = appfs_fu
9350: 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c  se_unlink_rmdir,
9360: 0a 09 2e 6d 6b 64 69 72 20 20 20 20 20 3d 20 61  ...mkdir     = a
9370: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 2c  ppfs_fuse_mkdir,
9380: 0a 09 2e 63 68 6d 6f 64 20 20 20 20 20 3d 20 61  ...chmod     = a
9390: 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 2c  ppfs_fuse_chmod,
93a0: 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20  .};../*. * FUSE 
93b0: 6f 70 74 69 6f 6e 20 70 61 72 73 69 6e 67 20 63  option parsing c
93c0: 61 6c 6c 62 61 63 6b 0a 20 2a 2f 0a 73 74 61 74  allback. */.stat
93d0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
93e0: 65 5f 6f 70 74 5f 63 62 28 76 6f 69 64 20 2a 64  e_opt_cb(void *d
93f0: 61 74 61 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ata, const char 
9400: 2a 61 72 67 2c 20 69 6e 74 20 6b 65 79 2c 20 73  *arg, int key, s
9410: 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20  truct fuse_args 
9420: 2a 6f 75 74 61 72 67 73 29 20 7b 0a 09 73 74 61  *outargs) {..sta
9430: 74 69 63 20 69 6e 74 20 73 65 65 6e 5f 63 61 63  tic int seen_cac
9440: 68 65 64 69 72 20 3d 20 30 3b 0a 0a 09 69 66 20  hedir = 0;...if 
9450: 28 6b 65 79 20 3d 3d 20 46 55 53 45 5f 4f 50 54  (key == FUSE_OPT
9460: 5f 4b 45 59 5f 4e 4f 4e 4f 50 54 20 26 26 20 73  _KEY_NONOPT && s
9470: 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 3d 20  een_cachedir == 
9480: 30 29 20 7b 0a 09 09 73 65 65 6e 5f 63 61 63 68  0) {...seen_cach
9490: 65 64 69 72 20 3d 20 31 3b 0a 0a 09 09 61 70 70  edir = 1;....app
94a0: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74  fs_cachedir = st
94b0: 72 64 75 70 28 61 72 67 29 3b 0a 0a 09 09 72 65  rdup(arg);....re
94c0: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 72 65  turn(0);..}...re
94d0: 74 75 72 6e 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20  turn(1);.}../*. 
94e0: 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20 69 6e  * Entry point in
94f0: 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e  to this program.
9500: 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 6e  . */.int main(in
9510: 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61  t argc, char **a
9520: 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  rgv) {..Tcl_Inte
9530: 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 3b  rp *test_interp;
9540: 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69 6e 74  ..char *test_int
9550: 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72 75  erp_error;..stru
9560: 63 74 20 66 75 73 65 5f 61 72 67 73 20 61 72 67  ct fuse_args arg
9570: 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f 49 4e  s = FUSE_ARGS_IN
9580: 49 54 28 61 72 67 63 2c 20 61 72 67 76 29 3b 0a  IT(argc, argv);.
9590: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
95a0: 3b 0a 09 76 6f 69 64 20 2a 73 69 67 6e 61 6c 5f  ;..void *signal_
95b0: 72 65 74 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 6b  ret;.../*.. * Sk
95c0: 69 70 20 70 61 73 73 65 64 20 70 72 6f 67 72 61  ip passed progra
95d0: 6d 20 6e 61 6d 65 0a 09 20 2a 2f 0a 09 69 66 20  m name.. */..if 
95e0: 28 61 72 67 63 20 3d 3d 20 30 20 7c 7c 20 61 72  (argc == 0 || ar
95f0: 67 76 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  gv == NULL) {...
9600: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 09 61  return(1);..}..a
9610: 72 67 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a  rgc--;..argv++;.
9620: 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f  ../*.. * Set glo
9630: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 74  bal variables, t
9640: 68 65 73 65 20 73 68 6f 75 6c 64 20 62 65 20 63  hese should be c
9650: 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 6f 70 74  onfiguration opt
9660: 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  ions... */..appf
9670: 73 5f 63 61 63 68 65 64 69 72 20 3d 20 41 50 50  s_cachedir = APP
9680: 46 53 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09 2f  FS_CACHEDIR;.../
9690: 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c  *.. * Set global
96a0: 20 76 61 72 69 61 62 6c 65 20 66 6f 72 20 22 62   variable for "b
96b0: 6f 6f 74 20 74 69 6d 65 22 20 74 6f 20 73 65 74  oot time" to set
96c0: 20 61 20 74 69 6d 65 20 6f 6e 20 64 69 72 65 63   a time on direc
96d0: 74 6f 72 69 65 73 0a 09 20 2a 20 74 68 61 74 20  tories.. * that 
96e0: 77 65 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61  we fake... */..a
96f0: 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d 20  ppfs_boottime = 
9700: 74 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a  time(NULL);.../*
9710: 0a 09 20 2a 20 52 65 67 69 73 74 65 72 20 22 73  .. * Register "s
9720: 68 61 31 22 20 61 6e 64 20 22 61 70 70 66 73 64  ha1" and "appfsd
9730: 22 20 70 61 63 6b 61 67 65 20 77 69 74 68 20 6c  " package with l
9740: 69 62 74 63 6c 20 73 6f 20 74 68 61 74 20 61 6e  ibtcl so that an
9750: 79 20 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72 70  y new.. * interp
9760: 72 65 74 65 72 73 20 63 72 65 61 74 65 64 20 28  reters created (
9770: 77 68 69 63 68 20 61 72 65 20 64 6f 6e 65 20 64  which are done d
9780: 79 6e 61 6d 69 63 61 6c 6c 79 20 62 79 20 46 55  ynamically by FU
9790: 53 45 29 20 63 61 6e 20 68 61 76 65 0a 09 20 2a  SE) can have.. *
97a0: 20 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65   the appropriate
97b0: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 64   configuration d
97c0: 6f 6e 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c  one automaticall
97d0: 79 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74 61  y... */..Tcl_Sta
97e0: 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c  ticPackage(NULL,
97f0: 20 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49 6e   "sha1", Sha1_In
9800: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  it, NULL);..Tcl_
9810: 53 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55  StaticPackage(NU
9820: 4c 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41 70  LL, "appfsd", Ap
9830: 70 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29  pfsd_Init, NULL)
9840: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74  ;.../*.. * Creat
9850: 65 20 61 20 74 68 72 65 61 64 2d 73 70 65 63 69  e a thread-speci
9860: 66 69 63 2d 64 61 74 61 20 28 54 53 44 29 20 6b  fic-data (TSD) k
9870: 65 79 20 66 6f 72 20 65 61 63 68 20 74 68 72 65  ey for each thre
9880: 61 64 20 74 6f 20 72 65 66 65 72 0a 09 20 2a 20  ad to refer.. * 
9890: 74 6f 20 69 74 73 20 6f 77 6e 20 54 63 6c 20 69  to its own Tcl i
98a0: 6e 74 65 72 70 72 65 74 65 72 2e 20 20 54 63 6c  nterpreter.  Tcl
98b0: 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 6d 75   interpreters mu
98c0: 73 74 20 62 65 20 75 6e 69 71 75 65 20 70 65 72  st be unique per
98d0: 0a 09 20 2a 20 74 68 72 65 61 64 20 61 6e 64 20  .. * thread and 
98e0: 6e 65 77 20 74 68 72 65 61 64 73 20 61 72 65 20  new threads are 
98f0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65 61  dynamically crea
9900: 74 65 64 20 62 79 20 46 55 53 45 2e 0a 09 20 2a  ted by FUSE... *
9910: 2f 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  /..pthread_ret =
9920: 20 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72 65   pthread_key_cre
9930: 61 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c 20  ate(&interpKey, 
9940: 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f  appfs_terminate_
9950: 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 70 74  interp);..if (pt
9960: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
9970: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
9980: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
9990: 72 65 61 74 65 20 54 53 44 20 6b 65 79 20 66 6f  reate TSD key fo
99a0: 72 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67  r Tcl.  Aborting
99b0: 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  .\n");....return
99c0: 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  (1);..}.../*.. *
99d0: 20 4d 61 6e 75 61 6c 6c 79 20 73 70 65 63 69 66   Manually specif
99e0: 79 20 63 61 63 68 65 20 64 69 72 65 63 74 6f 72  y cache director
99f0: 79 2c 20 77 69 74 68 6f 75 74 20 46 55 53 45 20  y, without FUSE 
9a00: 63 61 6c 6c 62 61 63 6b 0a 09 20 2a 20 54 68 69  callback.. * Thi
9a10: 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c 79 20 77 6f  s option only wo
9a20: 72 6b 73 20 77 68 65 6e 20 6e 6f 74 20 75 73 69  rks when not usi
9a30: 6e 67 20 46 55 53 45 2c 20 73 69 6e 63 65 20 77  ng FUSE, since w
9a40: 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 20 70 72 6f  e.. * do not pro
9a50: 63 65 73 73 20 69 74 20 77 69 74 68 20 46 55 53  cess it with FUS
9a60: 45 73 20 6f 70 74 69 6f 6e 20 70 72 6f 63 65 73  Es option proces
9a70: 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 69 66 20 28  sing... */..if (
9a80: 61 72 67 63 20 3e 3d 20 32 29 20 7b 0a 09 09 69  argc >= 2) {...i
9a90: 66 20 28 73 74 72 63 6d 70 28 61 72 67 76 5b 30  f (strcmp(argv[0
9aa0: 5d 2c 20 22 2d 2d 63 61 63 68 65 64 69 72 22 29  ], "--cachedir")
9ab0: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 61 70 70 66   == 0) {....appf
9ac0: 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74 72  s_cachedir = str
9ad0: 64 75 70 28 61 72 67 76 5b 31 5d 29 3b 0a 0a 09  dup(argv[1]);...
9ae0: 09 09 61 72 67 63 20 2d 3d 20 32 3b 0a 09 09 09  ..argc -= 2;....
9af0: 61 72 67 76 20 2b 3d 20 32 3b 0a 09 09 7d 0a 09  argv += 2;...}..
9b00: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 51 4c 69 74  }.../*.. * SQLit
9b10: 65 33 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e  e3 mode, for run
9b20: 6e 69 6e 67 20 72 61 77 20 53 51 4c 20 61 67 61  ning raw SQL aga
9b30: 69 6e 73 74 20 74 68 65 20 63 61 63 68 65 20 64  inst the cache d
9b40: 61 74 61 62 61 73 65 0a 09 20 2a 2f 0a 09 69 66  atabase.. */..if
9b50: 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20 73   (argc == 2 && s
9b60: 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22  trcmp(argv[0], "
9b70: 2d 2d 73 71 6c 69 74 65 33 22 29 20 3d 3d 20 30  --sqlite3") == 0
9b80: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70  ) {...return(app
9b90: 66 73 5f 73 71 6c 69 74 65 33 28 61 72 67 76 5b  fs_sqlite3(argv[
9ba0: 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  1]));..}.../*.. 
9bb0: 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 66 6f 72 20  * Tcl mode, for 
9bc0: 72 75 6e 6e 69 6e 67 20 72 61 77 20 54 63 6c 20  running raw Tcl 
9bd0: 69 6e 20 74 68 65 20 73 61 6d 65 20 65 6e 76 69  in the same envi
9be0: 72 6f 6e 6d 65 6e 74 20 41 70 70 46 53 64 20 77  ronment AppFSd w
9bf0: 6f 75 6c 64 0a 09 20 2a 20 72 75 6e 20 63 6f 64  ould.. * run cod
9c00: 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67  e... */..if (arg
9c10: 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70  c == 2 && strcmp
9c20: 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 74 63 6c  (argv[0], "--tcl
9c30: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74  ") == 0) {...ret
9c40: 75 72 6e 28 61 70 70 66 73 5f 74 63 6c 28 61 72  urn(appfs_tcl(ar
9c50: 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a  gv[1]));..}.../*
9c60: 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20 54 63  .. * Create a Tc
9c70: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 6a 75  l interpreter ju
9c80: 73 74 20 74 6f 20 76 65 72 69 66 79 20 74 68 61  st to verify tha
9c90: 74 20 74 68 69 6e 67 73 20 61 72 65 20 69 6e 20  t things are in 
9ca0: 77 6f 72 6b 69 6e 67 20 0a 09 20 2a 20 6f 72 64  working .. * ord
9cb0: 65 72 20 62 65 66 6f 72 65 20 77 65 20 62 65 63  er before we bec
9cc0: 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 2e 0a 09 20  ome a daemon... 
9cd0: 2a 2f 0a 09 74 65 73 74 5f 69 6e 74 65 72 70 20  */..test_interp 
9ce0: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
9cf0: 63 6c 49 6e 74 65 72 70 28 26 74 65 73 74 5f 69  clInterp(&test_i
9d00: 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 09 69  nterp_error);..i
9d10: 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 20 3d  f (test_interp =
9d20: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 66 20 28  = NULL) {...if (
9d30: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
9d40: 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  r == NULL) {....
9d50: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
9d60: 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20 65 72 72  r = "Unknown err
9d70: 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09 66 70 72 69  or";...}....fpri
9d80: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
9d90: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
9da0: 65 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  e Tcl interprete
9db0: 72 20 66 6f 72 20 41 70 70 46 53 64 3a 5c 6e 22  r for AppFSd:\n"
9dc0: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
9dd0: 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20 74 65 73  err, "%s\n", tes
9de0: 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b  t_interp_error);
9df0: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
9e00: 7d 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  }..Tcl_DeleteInt
9e10: 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29  erp(test_interp)
9e20: 3b 0a 09 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 4e  ;..Tcl_FinalizeN
9e30: 6f 74 69 66 69 65 72 28 4e 55 4c 4c 29 3b 0a 0a  otifier(NULL);..
9e40: 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 72  ./*.. * Register
9e50: 20 61 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65   a signal handle
9e60: 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72  r for hot-restar
9e70: 74 20 72 65 71 75 65 73 74 73 0a 09 20 2a 2f 0a  t requests.. */.
9e80: 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73 69  .signal_ret = si
9e90: 67 6e 61 6c 28 53 49 47 48 55 50 2c 20 61 70 70  gnal(SIGHUP, app
9ea0: 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65  fs_signal_handle
9eb0: 72 29 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c 5f  r);..if (signal_
9ec0: 72 65 74 20 3d 3d 20 53 49 47 5f 45 52 52 29 20  ret == SIG_ERR) 
9ed0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
9ee0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
9ef0: 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c 20 68 61  nstall signal ha
9f00: 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65  ndler for hot-re
9f10: 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09 66 70 72  start\n");...fpr
9f20: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 48 6f  intf(stderr, "Ho
9f30: 74 2d 72 65 73 74 61 72 74 20 77 69 6c 6c 20 6e  t-restart will n
9f40: 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65 2e  ot be available.
9f50: 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  \n");..}.../*.. 
9f60: 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d  * Add FUSE argum
9f70: 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c  ents which we al
9f80: 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f  ways supply.. */
9f90: 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
9fa0: 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  (&args, NULL, NU
9fb0: 4c 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f  LL, appfs_fuse_o
9fc0: 70 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70  pt_cb);..fuse_op
9fd0: 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c  t_add_arg(&args,
9fe0: 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d   "-odefault_perm
9ff0: 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61  issions,fsname=a
a000: 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70  ppfs,subtype=app
a010: 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e  fsd,use_ino,kern
a020: 65 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74  el_cache,entry_t
a030: 69 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69  imeout=0,attr_ti
a040: 6d 65 6f 75 74 3d 30 2c 62 69 67 5f 77 72 69 74  meout=0,big_writ
a050: 65 73 2c 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d  es,intr,hard_rem
a060: 6f 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74  ove");...if (get
a070: 75 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09  uid() == 0) {...
a080: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 26  fuse_opt_parse(&
a090: 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  args, NULL, NULL
a0a0: 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f  , NULL);...fuse_
a0b0: 6f 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67  opt_add_arg(&arg
a0c0: 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65  s, "-oallow_othe
a0d0: 72 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  r");..}.../*.. *
a0e0: 20 45 6e 74 65 72 20 74 68 65 20 46 55 53 45 20   Enter the FUSE 
a0f0: 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69  main loop -- thi
a100: 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20 61  s will process a
a110: 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a  ny arguments.. *
a120: 20 61 6e 64 20 73 74 61 72 74 20 73 65 72 76 69   and start servi
a130: 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a 09  cing requests...
a140: 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65 5f   */..appfs_fuse_
a150: 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72 65  started = 1;..re
a160: 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61  turn(fuse_main(a
a170: 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e 61  rgs.argc, args.a
a180: 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65 72  rgv, &appfs_oper
a190: 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a  ations, NULL));.
a1a0: 7d 0a 20 0a                                      }. .