Hex Artifact Content

Artifact b7668e46f2bc4ccf5afcdce1cf75d8c10509a485:


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 20 28 64 65 66 69 6e 65 64 28 44 45 42  #if (defined(DEB
5460: 55 47 29 20 26 26 20 64 65 66 69 6e 65 64 28 41  UG) && defined(A
5470: 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29  PPFS_EXIT_PATH))
5480: 20 7c 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46   || defined(APPF
5490: 53 5f 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42  S_EXIT_PATH_ENAB
54a0: 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54  LE_MAJOR_SECURIT
54b0: 59 5f 48 4f 4c 45 29 0a 73 74 61 74 69 63 20 76  Y_HOLE).static v
54c0: 6f 69 64 20 61 70 70 66 73 5f 65 78 69 74 28 76  oid appfs_exit(v
54d0: 6f 69 64 29 20 7b 0a 09 69 6e 74 20 67 6c 6f 62  oid) {..int glob
54e0: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
54f0: 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e  key;...global_in
5500: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d  terp_reset_key =
5510: 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e   __sync_fetch_an
5520: 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72 65  d_add(&interp_re
5530: 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f  set_key, 0);..__
5540: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 73  sync_fetch_and_s
5550: 75 62 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  ub(&interp_reset
5560: 5f 6b 65 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74  _key, global_int
5570: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 3b 0a  erp_reset_key);.
5580: 0a 09 77 68 69 6c 65 20 28 5f 5f 73 79 6e 63 5f  ..while (__sync_
5590: 73 75 62 5f 61 6e 64 5f 66 65 74 63 68 28 26 69  sub_and_fetch(&i
55a0: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c  nterp_reset_key,
55b0: 20 31 29 20 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a   1) >= 0) {.../*
55c0: 20 42 75 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d   Busy Loop */..}
55d0: 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  ...global_interp
55e0: 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73  _reset_key = __s
55f0: 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64  ync_fetch_and_ad
5600: 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  d(&interp_reset_
5610: 6b 65 79 2c 20 30 29 3b 0a 09 69 66 20 28 67 6c  key, 0);..if (gl
5620: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
5630: 74 5f 6b 65 79 20 21 3d 20 2d 31 29 20 7b 0a 09  t_key != -1) {..
5640: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 72  .APPFS_DEBUG("Er
5650: 72 6f 72 20 73 65 6e 64 69 6e 67 20 6b 69 6c 6c  ror sending kill
5660: 20 73 69 67 6e 61 6c 20 74 6f 20 61 6c 6c 20 74   signal to all t
5670: 68 72 65 61 64 73 2c 20 61 62 6f 72 74 69 6e 67  hreads, aborting
5680: 20 61 6e 79 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a   anyway.");..}..
5690: 09 66 75 73 65 5f 65 78 69 74 28 66 75 73 65 5f  .fuse_exit(fuse_
56a0: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 2d 3e 66  get_context()->f
56b0: 75 73 65 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  use);...appfs_ge
56c0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
56d0: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b  e_flush(-1, -1);
56e0: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e  ...return;.}.#en
56f0: 64 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  dif..static int 
5700: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c  appfs_fuse_readl
5710: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
5720: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
5730: 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a   size_t size) {.
5740: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
5750: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
5760: 0a 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30  ..int retval = 0
5770: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5780: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
5790: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
57a0: 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  ...pathinfo.type
57b0: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
57c0: 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74  E_INVALID;...ret
57d0: 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  val = appfs_get_
57e0: 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20  path_info(path, 
57f0: 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20  &pathinfo);..if 
5800: 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a  (retval != 0) {.
5810: 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
5820: 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  ;..}...if (pathi
5830: 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46  nfo.type != APPF
5840: 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49  S_PATHTYPE_SYMLI
5850: 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  NK) {...return(-
5860: 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66  EINVAL);..}...if
5870: 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e   ((strlen(pathin
5880: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
5890: 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29  ink.source) + 1)
58a0: 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74   > size) {...ret
58b0: 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e  urn(-ENAMETOOLON
58c0: 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28  G);..}...memcpy(
58d0: 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79  buf, pathinfo.ty
58e0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
58f0: 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61  ource, strlen(pa
5900: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
5910: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20  symlink.source) 
5920: 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30  + 1);...return(0
5930: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
5940: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
5950: 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ttr(const char *
5960: 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74 61  path, struct sta
5970: 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72  t *stbuf) {..str
5980: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
5990: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e  fo pathinfo;..in
59a0: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76  t retval;...retv
59b0: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
59c0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
59d0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
59e0: 70 61 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66  path);..#if (def
59f0: 69 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64  ined(DEBUG) && d
5a00: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49  efined(APPFS_EXI
5a10: 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69  T_PATH)) || defi
5a20: 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50  ned(APPFS_EXIT_P
5a30: 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52  ATH_ENABLE_MAJOR
5a40: 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a  _SECURITY_HOLE).
5a50: 09 2f 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20  ./*.. * This is 
5a60: 61 20 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79  a major security
5a70: 20 69 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e   issue so we can
5a80: 6e 6f 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f  not let it be co
5a90: 6d 70 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20  mpiled into.. * 
5aa0: 61 6e 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f  any release.. */
5ab0: 0a 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61  ...if (strcmp(pa
5ac0: 74 68 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20  th, "/exit") == 
5ad0: 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69  0) {...appfs_exi
5ae0: 74 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  t();..}.#endif..
5af0: 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d  .pathinfo.type =
5b00: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
5b10: 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61  INVALID;...retva
5b20: 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61  l = appfs_get_pa
5b30: 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70  th_info(path, &p
5b40: 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72  athinfo);..if (r
5b50: 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09  etval != 0) {...
5b60: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
5b70: 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75  .}...memset(stbu
5b80: 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72  f, 0, sizeof(str
5b90: 75 63 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74  uct stat));...st
5ba0: 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20  buf->st_mtime = 
5bb0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
5bc0: 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20  stbuf->st_ctime 
5bd0: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
5be0: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d  ..stbuf->st_atim
5bf0: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d  e = pathinfo.tim
5c00: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e  e;..stbuf->st_in
5c10: 6f 20 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69  o   = pathinfo.i
5c20: 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  node;..stbuf->st
5c30: 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 73 77  _mode  = 0;...sw
5c40: 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e 74  itch (pathinfo.t
5c50: 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41 50  ype) {...case AP
5c60: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
5c70: 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75 66  ECTORY:....stbuf
5c80: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
5c90: 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  DIR | 0555;....s
5ca0: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
5cb0: 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74 79   2 + pathinfo.ty
5cc0: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
5cd0: 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b 3b  count;....break;
5ce0: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
5cf0: 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09 09  THTYPE_FILE:....
5d00: 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  if (pathinfo.typ
5d10: 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75  einfo.file.execu
5d20: 74 61 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62  table) {.....stb
5d30: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
5d40: 49 46 52 45 47 20 7c 20 30 35 35 35 3b 0a 09 09  IFREG | 0555;...
5d50: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 73 74  .} else {.....st
5d60: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
5d70: 5f 49 46 52 45 47 20 7c 20 30 34 34 34 3b 0a 09  _IFREG | 0444;..
5d80: 09 09 7d 0a 0a 09 09 09 73 74 62 75 66 2d 3e 73  ..}.....stbuf->s
5d90: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
5da0: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
5db0: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e   pathinfo.typein
5dc0: 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 09 09  fo.file.size;...
5dd0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
5de0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
5df0: 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74 62 75 66 2d  MLINK:....stbuf-
5e00: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 4c  >st_mode = S_IFL
5e10: 4e 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74  NK | 0555;....st
5e20: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20  buf->st_nlink = 
5e30: 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  1;....stbuf->st_
5e40: 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e  size = pathinfo.
5e50: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
5e60: 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b  .size;....break;
5e70: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
5e80: 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 3a 0a 09  THTYPE_SOCKET:..
5e90: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
5ea0: 20 3d 20 53 5f 49 46 53 4f 43 4b 20 7c 20 30 35   = S_IFSOCK | 05
5eb0: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
5ec0: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
5ed0: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
5ee0: 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  0;....break;...c
5ef0: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
5f00: 50 45 5f 46 49 46 4f 3a 0a 09 09 09 73 74 62 75  PE_FIFO:....stbu
5f10: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
5f20: 46 49 46 4f 20 7c 20 30 35 35 35 3b 0a 09 09 09  FIFO | 0555;....
5f30: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
5f40: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
5f50: 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62  t_size = 0;....b
5f60: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
5f70: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53  FS_PATHTYPE_DOES
5f80: 5f 4e 4f 54 5f 45 58 49 53 54 3a 0a 09 09 09 72  _NOT_EXIST:....r
5f90: 65 74 76 61 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b  etval = -ENOENT;
5fa0: 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  .....break;...ca
5fb0: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
5fc0: 45 5f 49 4e 56 41 4c 49 44 3a 0a 09 09 09 72 65  E_INVALID:....re
5fd0: 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 0a 09 09  tval = -EIO;....
5fe0: 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20  .break;..}...if 
5ff0: 28 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67  (pathinfo.packag
6000: 65 64 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e 73  ed) {...stbuf->s
6010: 74 5f 75 69 64 20 20 20 3d 20 61 70 70 66 73 5f  t_uid   = appfs_
6020: 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 09 09 73  get_fsuid();...s
6030: 74 62 75 66 2d 3e 73 74 5f 67 69 64 20 20 20 3d  tbuf->st_gid   =
6040: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64   appfs_get_fsgid
6050: 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f  ();...stbuf->st_
6060: 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09 7d  mode |= 0200;..}
6070: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
6080: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
6090: 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64   appfs_fuse_read
60a0: 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  dir(const char *
60b0: 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c  path, void *buf,
60c0: 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74   fuse_fill_dir_t
60d0: 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f   filler, off_t o
60e0: 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75  ffset, struct fu
60f0: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
6100: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
6110: 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62  *interp;..Tcl_Ob
6120: 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 69  j **children;..i
6130: 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e  nt children_coun
6140: 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74 63 6c  t, idx;..int tcl
6150: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
6160: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
6170: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
6180: 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  th);...interp = 
6190: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
61a0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
61b0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
61c0: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  rn(0);..}...Tcl_
61d0: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
61e0: 3b 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20  ;...filler(buf, 
61f0: 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09  ".", NULL, 0);..
6200: 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22  filler(buf, ".."
6210: 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63  , NULL, 0);...tc
6220: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
6230: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
6240: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63  , "::appfs::getc
6250: 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b  hildren", path);
6260: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
6270: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
6280: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
6290: 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25  s::getchildren(%
62a0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
62b0: 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  h);...APPFS_DEBU
62c0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
62d0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
62e0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
62f0: 29 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61  ));....Tcl_Relea
6300: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72  se(interp);....r
6310: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74  eturn(0);..}...t
6320: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73  cl_ret = Tcl_Lis
6330: 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28  tObjGetElements(
6340: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f  interp, Tcl_GetO
6350: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  bjResult(interp)
6360: 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e  , &children_coun
6370: 74 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09  t, &children);..
6380: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
6390: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
63a0: 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20  _DEBUG("Parsing 
63b0: 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e  list of children
63c0: 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c   on path %s fail
63d0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41  ed.", path);...A
63e0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
63f0: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
6400: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
6410: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
6420: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
6430: 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30  rp);....return(0
6440: 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78  );..}...for (idx
6450: 20 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c   = 0; idx < chil
6460: 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b  dren_count; idx+
6470: 2b 29 20 7b 0a 09 09 66 69 6c 6c 65 72 28 62 75  +) {...filler(bu
6480: 66 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  f, Tcl_GetString
6490: 28 63 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c  (children[idx]),
64a0: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a 09   NULL, 0);..}...
64b0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
64c0: 72 70 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29  rp);...return(0)
64d0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
64e0: 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28  appfs_fuse_open(
64f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6500: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
6510: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
6520: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6530: 72 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66  rp;..struct appf
6540: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69  s_pathinfo pathi
6550: 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  nfo;..const char
6560: 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f   *real_path, *mo
6570: 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74  de;..int gpi_ret
6580: 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  , tcl_ret;..int 
6590: 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  fh;...APPFS_DEBU
65a0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
65b0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
65c0: 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61  );...gpi_ret = a
65d0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
65e0: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e  fo(path, &pathin
65f0: 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e  fo);...if ((fi->
6600: 66 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c  flags & (O_WRONL
6610: 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28  Y|O_CREAT)) == (
6620: 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59  O_CREAT|O_WRONLY
6630: 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69  )) {.../* The fi
6640: 6c 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74  le will be creat
6650: 65 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f  ed if it does no
6660: 74 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20  t exist */...if 
6670: 28 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26  (gpi_ret != 0 &&
6680: 20 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f   gpi_ret != -ENO
6690: 45 4e 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  ENT) {....return
66a0: 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a  (gpi_ret);...}..
66b0: 09 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65  ..mode = "create
66c0: 22 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65  ";..../*... * We
66d0: 20 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20 74   have to clear t
66e0: 68 65 20 63 61 63 68 65 20 68 65 72 65 20 73 6f  he cache here so
66f0: 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72   that the number
6700: 20 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67   of... * links g
6710: 65 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f  ets maintained o
6720: 6e 20 74 68 65 20 70 61 72 65 6e 74 20 64 69 72  n the parent dir
6730: 65 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61  ectory... */...a
6740: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6750: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
6760: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
6770: 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  , -1);..} else {
6780: 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d  .../* The file m
6790: 75 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73  ust already exis
67a0: 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72  t */...if (gpi_r
67b0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65  et != 0) {....re
67c0: 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09  turn(gpi_ret);..
67d0: 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b  .}....mode = "";
67e0: 0a 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61  ....if ((fi->fla
67f0: 67 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d  gs & O_WRONLY) =
6800: 3d 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09  = O_WRONLY) {...
6810: 09 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b  .mode = "write";
6820: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61  ...}..}...if (pa
6830: 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41  thinfo.type == A
6840: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
6850: 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 72 65 74  RECTORY) {...ret
6860: 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d  urn(-EISDIR);..}
6870: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
6880: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
6890: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
68a0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LL) {...return(-
68b0: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50  EIO);..}...Tcl_P
68c0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
68d0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
68e0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
68f0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
6900: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
6910: 2c 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63  , mode);..if (tc
6920: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
6930: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
6940: 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70  ("::appfs::openp
6950: 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c  ath(%s, %s) fail
6960: 65 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65  ed.", path, mode
6970: 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  );...APPFS_DEBUG
6980: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
6990: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
69a0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
69b0: 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73  );....Tcl_Releas
69c0: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  e(interp);....re
69d0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
69e0: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
69f0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
6a00: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f  (interp);...Tcl_
6a10: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
6a20: 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ...if (real_path
6a30: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
6a40: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
6a50: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 72  .APPFS_DEBUG("Tr
6a60: 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73 74  anslated request
6a70: 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f   to open %s to o
6a80: 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20  pening %s (mode 
6a90: 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68  = \"%s\")", path
6aa0: 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64  , real_path, mod
6ab0: 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28  e);...fh = open(
6ac0: 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66  real_path, fi->f
6ad0: 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69  lags, 0600);...i
6ae0: 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 72  f (fh < 0) {...r
6af0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
6b00: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a  ..fi->fh = fh;..
6b10: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
6b20: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
6b30: 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74  fuse_close(const
6b40: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72   char *path, str
6b50: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
6b60: 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63  fo *fi) {..int c
6b70: 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66  lose_ret;...appf
6b80: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
6b90: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61  cache_rm(path, a
6ba0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
6bb0: 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d  );...close_ret =
6bc0: 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a   close(fi->fh);.
6bd0: 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21  .if (close_ret !
6be0: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
6bf0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  -EIO);..}...retu
6c00: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
6c10: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
6c20: 72 65 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20  read(const char 
6c30: 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66  *path, char *buf
6c40: 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f  , size_t size, o
6c50: 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72  ff_t offset, str
6c60: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
6c70: 66 6f 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74  fo *fi) {..off_t
6c80: 20 6c 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69   lseek_ret;..ssi
6c90: 7a 65 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 0a  ze_t read_ret;..
6ca0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
6cb0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
6cc0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
6cd0: 6c 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65  lseek_ret = lsee
6ce0: 6b 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74  k(fi->fh, offset
6cf0: 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66  , SEEK_SET);..if
6d00: 20 28 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f   (lseek_ret != o
6d10: 66 66 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72  ffset) {...retur
6d20: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65  n(-EIO);..}...re
6d30: 61 64 5f 72 65 74 20 3d 20 72 65 61 64 28 66 69  ad_ret = read(fi
6d40: 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29  ->fh, buf, size)
6d50: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 61 64 5f  ;...return(read_
6d60: 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  ret);.}..static 
6d70: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 77  int appfs_fuse_w
6d80: 72 69 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20  rite(const char 
6d90: 2a 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61  *path, const cha
6da0: 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73  r *buf, size_t s
6db0: 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65  ize, off_t offse
6dc0: 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  t, struct fuse_f
6dd0: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
6de0: 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74  .off_t lseek_ret
6df0: 3b 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65  ;..ssize_t write
6e00: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
6e10: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
6e20: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
6e30: 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  th);...appfs_get
6e40: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
6e50: 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f  _rm(path, appfs_
6e60: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09  get_fsuid());...
6e70: 6c 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65  lseek_ret = lsee
6e80: 6b 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74  k(fi->fh, offset
6e90: 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66  , SEEK_SET);..if
6ea0: 20 28 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f   (lseek_ret != o
6eb0: 66 66 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72  ffset) {...retur
6ec0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 77 72  n(-EIO);..}...wr
6ed0: 69 74 65 5f 72 65 74 20 3d 20 77 72 69 74 65 28  ite_ret = write(
6ee0: 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a  fi->fh, buf, siz
6ef0: 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 77 72 69  e);...return(wri
6f00: 74 65 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74  te_ret);.}..stat
6f10: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
6f20: 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68  e_mknod(const ch
6f30: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
6f40: 20 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76   mode, dev_t dev
6f50: 69 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  ice) {..char *re
6f60: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b  al_path;..int mk
6f70: 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  nod_ret;...APPFS
6f80: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
6f90: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
6fa0: 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d   path);...if ((m
6fb0: 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d  ode & S_IFCHR) =
6fc0: 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72  = S_IFCHR) {...r
6fd0: 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09  eturn(-EPERM);..
6fe0: 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20  }...if ((mode & 
6ff0: 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46  S_IFBLK) == S_IF
7000: 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  BLK) {...return(
7010: 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65  -EPERM);..}...re
7020: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
7030: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
7040: 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  e(path);..if (re
7050: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
7060: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
7070: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
7080: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
7090: 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f  nter();...mknod_
70a0: 72 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c  ret = mknod(real
70b0: 5f 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76  _path, mode, dev
70c0: 69 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ice);...appfs_si
70d0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
70e0: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
70f0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
7100: 28 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29  (mknod_ret != 0)
7110: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
7120: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
7130: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
7140: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
7150: 65 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  e_create(const c
7160: 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f  har *path, mode_
7170: 74 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66  t mode, struct f
7180: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
7190: 69 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  i) {..char *real
71a0: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a  _path;..int fd;.
71b0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
71c0: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
71d0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
71e0: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
71f0: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52  FCHR) == S_IFCHR
7200: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
7210: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  ERM);..}...if ((
7220: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20  mode & S_IFBLK) 
7230: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09  == S_IFBLK) {...
7240: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
7250: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  .}...real_path =
7260: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
7270: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
7280: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
7290: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
72a0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
72b0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
72c0: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
72d0: 09 66 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c  .fd = creat(real
72e0: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
72f0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
7300: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
7310: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
7320: 29 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29  );...if (fd < 0)
7330: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
7340: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69  o * -1);..}...fi
7350: 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74  ->fh = fd;...ret
7360: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
7370: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
7380: 5f 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20  _truncate(const 
7390: 63 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f  char *path, off_
73a0: 74 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20  t size) {..char 
73b0: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
73c0: 20 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a   truncate_ret;..
73d0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
73e0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
73f0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
7400: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
7410: 73 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61 74 68  s_localpath(path
7420: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
7430: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
7440: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
7450: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
7460: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70  _info_cache_rm(p
7470: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66  ath, appfs_get_f
7480: 73 75 69 64 28 29 29 3b 0a 0a 09 61 70 70 66 73  suid());...appfs
7490: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
74a0: 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75  s_enter();...tru
74b0: 6e 63 61 74 65 5f 72 65 74 20 3d 20 74 72 75 6e  ncate_ret = trun
74c0: 63 61 74 65 28 72 65 61 6c 5f 70 61 74 68 2c 20  cate(real_path, 
74d0: 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  size);...appfs_s
74e0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
74f0: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
7500: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
7510: 20 28 74 72 75 6e 63 61 74 65 5f 72 65 74 20 21   (truncate_ret !
7520: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
7530: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
7540: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7550: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7560: 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64  _fuse_unlink_rmd
7570: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
7580: 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ath) {..Tcl_Inte
7590: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74  rp *interp;..int
75a0: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46   tcl_ret;...APPF
75b0: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
75c0: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
75d0: 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73  , path);...appfs
75e0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
75f0: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
7600: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
7610: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
7620: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
7630: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
7640: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
7650: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c  (-EIO);..}...tcl
7660: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
7670: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
7680: 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e   "::appfs::unlin
7690: 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09  kpath", path);..
76a0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
76b0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
76c0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
76d0: 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20  :unlinkpath(%s) 
76e0: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
76f0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
7700: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
7710: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
7720: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
7730: 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ....Tcl_Release(
7740: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
7750: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54  rn(-EIO);..}...T
7760: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
7770: 70 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  p);...return(0);
7780: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
7790: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28  ppfs_fuse_mkdir(
77a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
77b0: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b  , mode_t mode) {
77c0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
77d0: 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65  h;..int mkdir_re
77e0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
77f0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
7800: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
7810: 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  ;...real_path = 
7820: 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f  appfs_prepare_to
7830: 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09  _create(path);..
7840: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
7850: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
7860: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
7870: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
7880: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
7890: 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69  mkdir_ret = mkdi
78a0: 72 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64  r(real_path, mod
78b0: 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  e);...appfs_simu
78c0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
78d0: 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61  ve();...free(rea
78e0: 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d  l_path);...if (m
78f0: 6b 64 69 72 5f 72 65 74 20 21 3d 20 30 29 20 7b  kdir_ret != 0) {
7900: 0a 09 09 69 66 20 28 65 72 72 6e 6f 20 21 3d 20  ...if (errno != 
7910: 45 45 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74  EEXIST) {....ret
7920: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
7930: 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  ...}..}...return
7940: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
7950: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68  nt appfs_fuse_ch
7960: 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  mod(const char *
7970: 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64  path, mode_t mod
7980: 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  e) {..Tcl_Interp
7990: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
79a0: 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68   char *real_path
79b0: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20  ;..int tcl_ret, 
79c0: 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50  chmod_ret;...APP
79d0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
79e0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
79f0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  ", path);...appf
7a00: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
7a10: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61  cache_rm(path, a
7a20: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
7a30: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
7a40: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
7a50: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
7a60: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
7a70: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (-EIO);..}...Tcl
7a80: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
7a90: 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  );...tcl_ret = a
7aa0: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
7ab0: 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66  terp, 3, "::appf
7ac0: 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61  s::openpath", pa
7ad0: 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69  th, "write");..i
7ae0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
7af0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
7b00: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
7b10: 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29  openpath(%s, %s)
7b20: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c   failed.", path,
7b30: 20 22 77 72 69 74 65 22 29 3b 0a 09 09 41 50 50   "write");...APP
7b40: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
7b50: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
7b60: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
7b70: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63  (interp));....Tc
7b80: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7b90: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  );....return(-EI
7ba0: 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  O);..}...real_pa
7bb0: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
7bc0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
7bd0: 3b 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ;...Tcl_Release(
7be0: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72  interp);...if (r
7bf0: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
7c00: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
7c10: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73  O);..}...appfs_s
7c20: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
7c30: 65 6e 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64  enter();...chmod
7c40: 5f 72 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61  _ret = chmod(rea
7c50: 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a  l_path, mode);..
7c60: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
7c70: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
7c80: 0a 0a 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f  ...return(chmod_
7c90: 72 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53  ret);.}../*. * S
7ca0: 51 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65  QLite3 mode: Exe
7cb0: 63 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64  cute raw SQL and
7cc0: 20 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20   return success 
7cd0: 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73  or failure. */.s
7ce0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7cf0: 73 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68  sqlite3(const ch
7d00: 61 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f  ar *sql) {..Tcl_
7d10: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
7d20: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c  .const char *sql
7d30: 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  _ret;..int tcl_r
7d40: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
7d50: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
7d60: 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66  nterp(NULL);..if
7d70: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
7d80: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
7d90: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
7da0: 20 63 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e   create a Tcl in
7db0: 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72  terpreter.  Abor
7dc0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65  ting.\n");....re
7dd0: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63  turn(1);..}...tc
7de0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
7df0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35  l_Eval(interp, 5
7e00: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c  , "::appfs::db",
7e10: 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72   "eval", sql, "r
7e20: 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63  ow", "unset -noc
7e30: 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20  omplain row(*); 
7e40: 70 61 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73  parray row; puts
7e50: 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71   \"----\"");..sq
7e60: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53  l_ret = Tcl_GetS
7e70: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
7e80: 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72  rp);...if (tcl_r
7e90: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
7ea0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
7eb0: 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22  , "[error] %s\n"
7ec0: 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72  , sql_ret);....r
7ed0: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69  eturn(1);..}...i
7ee0: 66 20 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71  f (sql_ret && sq
7ef0: 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27  l_ret[0] != '\0'
7f00: 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73  ) {...printf("%s
7f10: 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09  \n", sql_ret);..
7f20: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
7f30: 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65  ../*. * Tcl mode
7f40: 3a 20 45 78 65 63 75 74 65 20 72 61 77 20 54 63  : Execute raw Tc
7f50: 6c 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63  l and return suc
7f60: 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a  cess or failure.
7f70: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
7f80: 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63  ppfs_tcl(const c
7f90: 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c  har *tcl) {..Tcl
7fa0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
7fb0: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63  ..const char *tc
7fc0: 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74  l_result;..int t
7fd0: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
7fe0: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
7ff0: 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b  TclInterp(NULL);
8000: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
8010: 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74  NULL) {...fprint
8020: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
8030: 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63  e to create a Tc
8040: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20  l interpreter.  
8050: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
8060: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
8070: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
8080: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c  Eval(interp, tcl
8090: 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d  );..tcl_result =
80a0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
80b0: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
80c0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
80d0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
80e0: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72  tf(stderr, "[err
80f0: 6f 72 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72  or] %s\n", tcl_r
8100: 65 73 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72  esult);....retur
8110: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74  n(1);..}...if (t
8120: 63 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c  cl_result && tcl
8130: 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c  _result[0] != '\
8140: 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22  0') {...printf("
8150: 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c  %s\n", tcl_resul
8160: 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  t);..}...return(
8170: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70  0);.}../*. * App
8180: 46 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20  FSd Package for 
8190: 54 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20  Tcl:. *         
81a0: 42 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f  Bridge for I/O o
81b0: 70 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71  perations to req
81c0: 75 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  uest information
81d0: 20 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65   about the curre
81e0: 6e 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72  nt. *         tr
81f0: 61 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a  ansaction. */./*
8200: 0a 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63  . * Tcl interfac
8210: 65 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d  e to get the hom
8220: 65 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20  e directory for 
8230: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
8240: 74 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a  the "current". *
8250: 20 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73   FUSE I/O reques
8260: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t. */.static int
8270: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68   tcl_appfs_get_h
8280: 6f 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74  omedir(ClientDat
8290: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
82a0: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
82b0: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
82c0: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68  ST objv[]) {..ch
82d0: 61 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63  ar *homedir;..Tc
82e0: 6c 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f  l_Obj *homedir_o
82f0: 62 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  bj;..uid_t fsuid
8300: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
8310: 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74  ad Tcl_Obj *last
8320: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e  _homedir_obj = N
8330: 55 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74  ULL;..static __t
8340: 68 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74  hread uid_t last
8350: 5f 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20  _fsuid = -1;..  
8360: 20 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21        if (objc !
8370: 3d 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  = 1) {.         
8380: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
8390: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
83a0: 31 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a  1, objv, NULL);.
83b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83c0: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
83d0: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66  );.        }...f
83e0: 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74  suid = appfs_get
83f0: 5f 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28  _fsuid();...if (
8400: 66 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73  fsuid == last_fs
8410: 75 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65  uid && last_home
8420: 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29  dir_obj != NULL)
8430: 20 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a   {...homedir_obj
8440: 20 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f   = last_homedir_
8450: 6f 62 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  obj;..} else {..
8460: 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73  .homedir = appfs
8470: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70  _get_homedir(app
8480: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
8490: 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20  ....if (homedir 
84a0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65  == NULL) {....re
84b0: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
84c0: 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f  ...}....homedir_
84d0: 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72  obj = Tcl_NewStr
84e0: 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20  ingObj(homedir, 
84f0: 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d  -1);....free(hom
8500: 65 64 69 72 29 3b 0a 0a 09 09 69 66 20 28 6c 61  edir);....if (la
8510: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21  st_homedir_obj !
8520: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c  = NULL) {....Tcl
8530: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61  _DecrRefCount(la
8540: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  st_homedir_obj);
8550: 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d  ...}....last_hom
8560: 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64  edir_obj = homed
8570: 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66  ir_obj;...last_f
8580: 73 75 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09  suid = fsuid;...
8590: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
85a0: 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  t(last_homedir_o
85b0: 62 6a 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20  bj);..}..       
85c0: 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c  .Tcl_SetObjResul
85d0: 74 28 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69  t(interp, homedi
85e0: 72 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20  r_obj);..       
85f0: 20 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b   return(TCL_OK);
8600: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
8610: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
8620: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
8630: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
8640: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
8650: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
8660: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
8670: 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d  []) {..appfs_sim
8680: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
8690: 74 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ter();...return(
86a0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
86b0: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
86c0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
86d0: 73 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61  s_leave(ClientDa
86e0: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
86f0: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
8700: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
8710: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61  NST objv[]) {..a
8720: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
8730: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
8740: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
8750: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
8760: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75  cl_appfs_get_fsu
8770: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
8780: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
8790: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
87a0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
87b0: 62 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20  bjv[]) {..uid_t 
87c0: 66 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d  fsuid;...fsuid =
87d0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
87e0: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
87f0: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
8800: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
8810: 65 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b  eIntObj(fsuid));
8820: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
8830: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
8840: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
8850: 73 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20  sgid(ClientData 
8860: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
8870: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
8880: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
8890: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f   objv[]) {..gid_
88a0: 74 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64  t fsgid;...fsgid
88b0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67   = appfs_get_fsg
88c0: 69 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54  id();..       .T
88d0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
88e0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57  interp, Tcl_NewW
88f0: 69 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29  ideIntObj(fsgid)
8900: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
8910: 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  OK);.}..static i
8920: 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  nt tcl_appfs_get
8930: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
8940: 5f 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74  _flush(ClientDat
8950: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
8960: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
8970: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
8980: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e  ST objv[]) {..in
8990: 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  t tcl_ret;..int 
89a0: 6e 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f  new_size;...new_
89b0: 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20  size = -1;...if 
89c0: 28 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09  (objc == 2) {...
89d0: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
89e0: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
89f0: 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65  rp, objv[1], &ne
8a00: 77 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74  w_size);...if (t
8a10: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
8a20: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63  ) {....return(tc
8a30: 6c 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65  l_ret);...}..} e
8a40: 6c 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32  lse if (objc > 2
8a50: 20 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a   || objc < 1) {.
8a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a70: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
8a80: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
8a90: 2c 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69  , "?new_cache_si
8aa0: 7a 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28  ze?");...return(
8ab0: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a  TCL_ERROR);..}..
8ac0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
8ad0: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
8ae0: 28 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a  (-1, new_size);.
8af0: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
8b00: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8b10: 41 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f  Appfsd_Init(Tcl_
8b20: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20  Interp *interp) 
8b30: 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c  {.#ifdef USE_TCL
8b40: 5f 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f  _STUBS..if (Tcl_
8b50: 49 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70  InitStubs(interp
8b60: 2c 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30  , TCL_VERSION, 0
8b70: 29 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74  ) == 0L) {...ret
8b80: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
8b90: 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f  .}.#endif...Tcl_
8ba0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
8bb0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
8bc0: 3a 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20  ::get_homedir", 
8bd0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
8be0: 6d 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  medir, NULL, NUL
8bf0: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
8c00: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
8c10: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66  , "appfsd::get_f
8c20: 73 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73  suid", tcl_appfs
8c30: 5f 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c  _get_fsuid, NULL
8c40: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
8c50: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
8c60: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
8c70: 67 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f  get_fsgid", tcl_
8c80: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c  appfs_get_fsgid,
8c90: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
8ca0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
8cb0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
8cc0: 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73  fsd::simulate_us
8cd0: 65 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63  er_fs_enter", tc
8ce0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
8cf0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20  _user_fs_enter, 
8d00: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
8d10: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
8d20: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
8d30: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
8d40: 72 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c  r_fs_leave", tcl
8d50: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
8d60: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e  user_fs_leave, N
8d70: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
8d80: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
8d90: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
8da0: 64 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  d::get_path_info
8db0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74  _cache_flush", t
8dc0: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74  cl_appfs_get_pat
8dd0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
8de0: 73 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  sh, NULL, NULL);
8df0: 0a 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64  ...Tcl_PkgProvid
8e00: 65 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  e(interp, "appfs
8e10: 64 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65  d", "1.0");...re
8e20: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
8e30: 0a 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61  ./*. * Hot-resta
8e40: 72 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f  rt support. */./
8e50: 2a 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74  * Initiate a hot
8e60: 2d 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74  -restart */.stat
8e70: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f  ic void appfs_ho
8e80: 74 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20  t_restart(void) 
8e90: 7b 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  {..APPFS_DEBUG("
8ea0: 41 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74  Asked to initiat
8eb0: 65 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b  e hot restart");
8ec0: 0a 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73  ...appfs_tcl_Res
8ed0: 65 74 49 6e 74 65 72 70 73 28 29 3b 0a 09 61 70  etInterps();..ap
8ee0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
8ef0: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31  o_cache_flush(-1
8f00: 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  , -1);...return;
8f10: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c  .}../*. * Signal
8f20: 20 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20   handler. *     
8f30: 20 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69      SIGHUP initi
8f40: 61 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61  ates a hot resta
8f50: 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rt. */.static vo
8f60: 69 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f  id appfs_signal_
8f70: 68 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29  handler(int sig)
8f80: 20 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61   {../* Do not ha
8f90: 6e 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74  ndle signals unt
8fa0: 69 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e  il FUSE has been
8fb0: 20 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20   started */..if 
8fc0: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
8fd0: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
8fe0: 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73  ;..}.../* Reques
8ff0: 74 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22  t to perform a "
9000: 68 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a  hot" restart */.
9010: 09 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48  .if (sig == SIGH
9020: 55 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f  UP) {...appfs_ho
9030: 74 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a  t_restart();..}.
9040: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
9050: 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74   * Terminate a t
9060: 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63  hread. */.static
9070: 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d   void appfs_term
9080: 69 6e 61 74 65 5f 69 6e 74 65 72 70 28 76 6f 69  inate_interp(voi
9090: 64 20 2a 5f 69 6e 74 65 72 70 29 20 7b 0a 09 54  d *_interp) {..T
90a0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
90b0: 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  p;...APPFS_DEBUG
90c0: 28 22 43 61 6c 6c 65 64 3a 20 5f 69 6e 74 65 72  ("Called: _inter
90d0: 70 20 3d 20 25 70 22 2c 20 5f 69 6e 74 65 72 70  p = %p", _interp
90e0: 29 3b 0a 0a 09 69 66 20 28 5f 69 6e 74 65 72 70  );...if (_interp
90f0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
9100: 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69  PFS_DEBUG("Termi
9110: 6e 61 74 69 6e 67 20 74 68 72 65 61 64 20 77 69  nating thread wi
9120: 74 68 20 6e 6f 20 69 6e 74 65 72 70 72 65 74 65  th no interprete
9130: 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  r");....return;.
9140: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 5f 69  .}...interp = _i
9150: 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44  nterp;...APPFS_D
9160: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
9170: 67 20 69 6e 74 65 72 70 72 65 74 65 72 20 64 75  g interpreter du
9180: 65 20 74 6f 20 74 68 72 65 61 64 20 74 65 72 6d  e to thread term
9190: 69 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09 54 63 6c  ination");...Tcl
91a0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
91b0: 74 65 72 70 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  terp);...return;
91c0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f  .}../*. * FUSE o
91d0: 70 65 72 61 74 69 6f 6e 73 20 73 74 72 75 63 74  perations struct
91e0: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 73  ure. */.static s
91f0: 74 72 75 63 74 20 66 75 73 65 5f 6f 70 65 72 61  truct fuse_opera
9200: 74 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70 65 72  tions appfs_oper
9210: 61 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e 67 65 74  ations = {...get
9220: 61 74 74 72 20 20 20 3d 20 61 70 70 66 73 5f 66  attr   = appfs_f
9230: 75 73 65 5f 67 65 74 61 74 74 72 2c 0a 09 2e 72  use_getattr,...r
9240: 65 61 64 64 69 72 20 20 20 3d 20 61 70 70 66 73  eaddir   = appfs
9250: 5f 66 75 73 65 5f 72 65 61 64 64 69 72 2c 0a 09  _fuse_readdir,..
9260: 2e 72 65 61 64 6c 69 6e 6b 20 20 3d 20 61 70 70  .readlink  = app
9270: 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b  fs_fuse_readlink
9280: 2c 0a 09 2e 6f 70 65 6e 20 20 20 20 20 20 3d 20  ,...open      = 
9290: 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 2c  appfs_fuse_open,
92a0: 0a 09 2e 72 65 6c 65 61 73 65 20 20 20 3d 20 61  ...release   = a
92b0: 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 2c  ppfs_fuse_close,
92c0: 0a 09 2e 72 65 61 64 20 20 20 20 20 20 3d 20 61  ...read      = a
92d0: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 2c 0a  ppfs_fuse_read,.
92e0: 09 2e 77 72 69 74 65 20 20 20 20 20 3d 20 61 70  ..write     = ap
92f0: 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65 2c 0a  pfs_fuse_write,.
9300: 09 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d 20 61 70  ..mknod     = ap
9310: 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 2c 0a  pfs_fuse_mknod,.
9320: 09 2e 63 72 65 61 74 65 20 20 20 20 3d 20 61 70  ..create    = ap
9330: 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 2c  pfs_fuse_create,
9340: 0a 09 2e 74 72 75 6e 63 61 74 65 20 20 3d 20 61  ...truncate  = a
9350: 70 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61  ppfs_fuse_trunca
9360: 74 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20 20 20 20  te,...unlink    
9370: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c  = appfs_fuse_unl
9380: 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 72 6d 64  ink_rmdir,...rmd
9390: 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ir     = appfs_f
93a0: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
93b0: 2c 0a 09 2e 6d 6b 64 69 72 20 20 20 20 20 3d 20  ,...mkdir     = 
93c0: 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72  appfs_fuse_mkdir
93d0: 2c 0a 09 2e 63 68 6d 6f 64 20 20 20 20 20 3d 20  ,...chmod     = 
93e0: 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64  appfs_fuse_chmod
93f0: 2c 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45  ,.};../*. * FUSE
9400: 20 6f 70 74 69 6f 6e 20 70 61 72 73 69 6e 67 20   option parsing 
9410: 63 61 6c 6c 62 61 63 6b 0a 20 2a 2f 0a 73 74 61  callback. */.sta
9420: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
9430: 73 65 5f 6f 70 74 5f 63 62 28 76 6f 69 64 20 2a  se_opt_cb(void *
9440: 64 61 74 61 2c 20 63 6f 6e 73 74 20 63 68 61 72  data, const char
9450: 20 2a 61 72 67 2c 20 69 6e 74 20 6b 65 79 2c 20   *arg, int key, 
9460: 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73  struct fuse_args
9470: 20 2a 6f 75 74 61 72 67 73 29 20 7b 0a 09 73 74   *outargs) {..st
9480: 61 74 69 63 20 69 6e 74 20 73 65 65 6e 5f 63 61  atic int seen_ca
9490: 63 68 65 64 69 72 20 3d 20 30 3b 0a 0a 09 69 66  chedir = 0;...if
94a0: 20 28 6b 65 79 20 3d 3d 20 46 55 53 45 5f 4f 50   (key == FUSE_OP
94b0: 54 5f 4b 45 59 5f 4e 4f 4e 4f 50 54 20 26 26 20  T_KEY_NONOPT && 
94c0: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 3d  seen_cachedir ==
94d0: 20 30 29 20 7b 0a 09 09 73 65 65 6e 5f 63 61 63   0) {...seen_cac
94e0: 68 65 64 69 72 20 3d 20 31 3b 0a 0a 09 09 61 70  hedir = 1;....ap
94f0: 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73  pfs_cachedir = s
9500: 74 72 64 75 70 28 61 72 67 29 3b 0a 0a 09 09 72  trdup(arg);....r
9510: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 72  eturn(0);..}...r
9520: 65 74 75 72 6e 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a  eturn(1);.}../*.
9530: 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20 69   * Entry point i
9540: 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61 6d  nto this program
9550: 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69  .. */.int main(i
9560: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
9570: 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  argv) {..Tcl_Int
9580: 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72 70  erp *test_interp
9590: 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69 6e  ;..char *test_in
95a0: 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72  terp_error;..str
95b0: 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61 72  uct fuse_args ar
95c0: 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f 49  gs = FUSE_ARGS_I
95d0: 4e 49 54 28 61 72 67 63 2c 20 61 72 67 76 29 3b  NIT(argc, argv);
95e0: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
95f0: 74 3b 0a 09 76 6f 69 64 20 2a 73 69 67 6e 61 6c  t;..void *signal
9600: 5f 72 65 74 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  _ret;.../*.. * S
9610: 6b 69 70 20 70 61 73 73 65 64 20 70 72 6f 67 72  kip passed progr
9620: 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f 0a 09 69 66  am name.. */..if
9630: 20 28 61 72 67 63 20 3d 3d 20 30 20 7c 7c 20 61   (argc == 0 || a
9640: 72 67 76 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  rgv == NULL) {..
9650: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 09  .return(1);..}..
9660: 61 72 67 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b  argc--;..argv++;
9670: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c  .../*.. * Set gl
9680: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20  obal variables, 
9690: 74 68 65 73 65 20 73 68 6f 75 6c 64 20 62 65 20  these should be 
96a0: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 6f 70  configuration op
96b0: 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  tions... */..app
96c0: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 41 50  fs_cachedir = AP
96d0: 50 46 53 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09  PFS_CACHEDIR;...
96e0: 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61  /*.. * Set globa
96f0: 6c 20 76 61 72 69 61 62 6c 65 20 66 6f 72 20 22  l variable for "
9700: 62 6f 6f 74 20 74 69 6d 65 22 20 74 6f 20 73 65  boot time" to se
9710: 74 20 61 20 74 69 6d 65 20 6f 6e 20 64 69 72 65  t a time on dire
9720: 63 74 6f 72 69 65 73 0a 09 20 2a 20 74 68 61 74  ctories.. * that
9730: 20 77 65 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09   we fake... */..
9740: 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d  appfs_boottime =
9750: 20 74 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f   time(NULL);.../
9760: 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 72 20 22  *.. * Register "
9770: 73 68 61 31 22 20 61 6e 64 20 22 61 70 70 66 73  sha1" and "appfs
9780: 64 22 20 70 61 63 6b 61 67 65 20 77 69 74 68 20  d" package with 
9790: 6c 69 62 74 63 6c 20 73 6f 20 74 68 61 74 20 61  libtcl so that a
97a0: 6e 79 20 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72  ny new.. * inter
97b0: 70 72 65 74 65 72 73 20 63 72 65 61 74 65 64 20  preters created 
97c0: 28 77 68 69 63 68 20 61 72 65 20 64 6f 6e 65 20  (which are done 
97d0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 62 79 20 46  dynamically by F
97e0: 55 53 45 29 20 63 61 6e 20 68 61 76 65 0a 09 20  USE) can have.. 
97f0: 2a 20 74 68 65 20 61 70 70 72 6f 70 72 69 61 74  * the appropriat
9800: 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20  e configuration 
9810: 64 6f 6e 65 20 61 75 74 6f 6d 61 74 69 63 61 6c  done automatical
9820: 6c 79 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74  ly... */..Tcl_St
9830: 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c  aticPackage(NULL
9840: 2c 20 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49  , "sha1", Sha1_I
9850: 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  nit, NULL);..Tcl
9860: 5f 53 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e  _StaticPackage(N
9870: 55 4c 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41  ULL, "appfsd", A
9880: 70 70 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c  ppfsd_Init, NULL
9890: 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61  );.../*.. * Crea
98a0: 74 65 20 61 20 74 68 72 65 61 64 2d 73 70 65 63  te a thread-spec
98b0: 69 66 69 63 2d 64 61 74 61 20 28 54 53 44 29 20  ific-data (TSD) 
98c0: 6b 65 79 20 66 6f 72 20 65 61 63 68 20 74 68 72  key for each thr
98d0: 65 61 64 20 74 6f 20 72 65 66 65 72 0a 09 20 2a  ead to refer.. *
98e0: 20 74 6f 20 69 74 73 20 6f 77 6e 20 54 63 6c 20   to its own Tcl 
98f0: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 54 63  interpreter.  Tc
9900: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 6d  l interpreters m
9910: 75 73 74 20 62 65 20 75 6e 69 71 75 65 20 70 65  ust be unique pe
9920: 72 0a 09 20 2a 20 74 68 72 65 61 64 20 61 6e 64  r.. * thread and
9930: 20 6e 65 77 20 74 68 72 65 61 64 73 20 61 72 65   new threads are
9940: 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65   dynamically cre
9950: 61 74 65 64 20 62 79 20 46 55 53 45 2e 0a 09 20  ated by FUSE... 
9960: 2a 2f 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  */..pthread_ret 
9970: 3d 20 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72  = pthread_key_cr
9980: 65 61 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c  eate(&interpKey,
9990: 20 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65   appfs_terminate
99a0: 5f 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 70  _interp);..if (p
99b0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
99c0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
99d0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
99e0: 63 72 65 61 74 65 20 54 53 44 20 6b 65 79 20 66  create TSD key f
99f0: 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e  or Tcl.  Abortin
9a00: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72  g.\n");....retur
9a10: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  n(1);..}.../*.. 
9a20: 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70 65 63 69  * Manually speci
9a30: 66 79 20 63 61 63 68 65 20 64 69 72 65 63 74 6f  fy cache directo
9a40: 72 79 2c 20 77 69 74 68 6f 75 74 20 46 55 53 45  ry, without FUSE
9a50: 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a 20 54 68   callback.. * Th
9a60: 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c 79 20 77  is option only w
9a70: 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74 20 75 73  orks when not us
9a80: 69 6e 67 20 46 55 53 45 2c 20 73 69 6e 63 65 20  ing FUSE, since 
9a90: 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 20 70 72  we.. * do not pr
9aa0: 6f 63 65 73 73 20 69 74 20 77 69 74 68 20 46 55  ocess it with FU
9ab0: 53 45 73 20 6f 70 74 69 6f 6e 20 70 72 6f 63 65  SEs option proce
9ac0: 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 69 66 20  ssing... */..if 
9ad0: 28 61 72 67 63 20 3e 3d 20 32 29 20 7b 0a 09 09  (argc >= 2) {...
9ae0: 69 66 20 28 73 74 72 63 6d 70 28 61 72 67 76 5b  if (strcmp(argv[
9af0: 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64 69 72 22  0], "--cachedir"
9b00: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 61 70 70  ) == 0) {....app
9b10: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74  fs_cachedir = st
9b20: 72 64 75 70 28 61 72 67 76 5b 31 5d 29 3b 0a 0a  rdup(argv[1]);..
9b30: 09 09 09 61 72 67 63 20 2d 3d 20 32 3b 0a 09 09  ...argc -= 2;...
9b40: 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09 09 7d 0a  .argv += 2;...}.
9b50: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 51 4c 69  .}.../*.. * SQLi
9b60: 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75  te3 mode, for ru
9b70: 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c 20 61 67  nning raw SQL ag
9b80: 61 69 6e 73 74 20 74 68 65 20 63 61 63 68 65 20  ainst the cache 
9b90: 64 61 74 61 62 61 73 65 0a 09 20 2a 2f 0a 09 69  database.. */..i
9ba0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
9bb0: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
9bc0: 22 2d 2d 73 71 6c 69 74 65 33 22 29 20 3d 3d 20  "--sqlite3") == 
9bd0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70  0) {...return(ap
9be0: 70 66 73 5f 73 71 6c 69 74 65 33 28 61 72 67 76  pfs_sqlite3(argv
9bf0: 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  [1]));..}.../*..
9c00: 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 66 6f 72   * Tcl mode, for
9c10: 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 54 63 6c   running raw Tcl
9c20: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 65 6e 76   in the same env
9c30: 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46 53 64 20  ironment AppFSd 
9c40: 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e 20 63 6f  would.. * run co
9c50: 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72  de... */..if (ar
9c60: 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d  gc == 2 && strcm
9c70: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 74 63  p(argv[0], "--tc
9c80: 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  l") == 0) {...re
9c90: 74 75 72 6e 28 61 70 70 66 73 5f 74 63 6c 28 61  turn(appfs_tcl(a
9ca0: 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f  rgv[1]));..}.../
9cb0: 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20 54  *.. * Create a T
9cc0: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 6a  cl interpreter j
9cd0: 75 73 74 20 74 6f 20 76 65 72 69 66 79 20 74 68  ust to verify th
9ce0: 61 74 20 74 68 69 6e 67 73 20 61 72 65 20 69 6e  at things are in
9cf0: 20 77 6f 72 6b 69 6e 67 20 0a 09 20 2a 20 6f 72   working .. * or
9d00: 64 65 72 20 62 65 66 6f 72 65 20 77 65 20 62 65  der before we be
9d10: 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 2e 0a 09  come a daemon...
9d20: 20 2a 2f 0a 09 74 65 73 74 5f 69 6e 74 65 72 70   */..test_interp
9d30: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
9d40: 54 63 6c 49 6e 74 65 72 70 28 26 74 65 73 74 5f  TclInterp(&test_
9d50: 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 09  interp_error);..
9d60: 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 20  if (test_interp 
9d70: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 66 20  == NULL) {...if 
9d80: 28 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72  (test_interp_err
9d90: 6f 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  or == NULL) {...
9da0: 09 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72  .test_interp_err
9db0: 6f 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20 65 72  or = "Unknown er
9dc0: 72 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09 66 70 72  ror";...}....fpr
9dd0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
9de0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
9df0: 7a 65 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ze Tcl interpret
9e00: 65 72 20 66 6f 72 20 41 70 70 46 53 64 3a 5c 6e  er for AppFSd:\n
9e10: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ");...fprintf(st
9e20: 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20 74 65  derr, "%s\n", te
9e30: 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29  st_interp_error)
9e40: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
9e50: 09 7d 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  .}..Tcl_DeleteIn
9e60: 74 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70  terp(test_interp
9e70: 29 3b 0a 09 54 63 6c 5f 46 69 6e 61 6c 69 7a 65  );..Tcl_Finalize
9e80: 4e 6f 74 69 66 69 65 72 28 4e 55 4c 4c 29 3b 0a  Notifier(NULL);.
9e90: 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74 65  ../*.. * Registe
9ea0: 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c  r a signal handl
9eb0: 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61  er for hot-resta
9ec0: 72 74 20 72 65 71 75 65 73 74 73 0a 09 20 2a 2f  rt requests.. */
9ed0: 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73  ..signal_ret = s
9ee0: 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20 61 70  ignal(SIGHUP, ap
9ef0: 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c  pfs_signal_handl
9f00: 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c  er);..if (signal
9f10: 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52 52 29  _ret == SIG_ERR)
9f20: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
9f30: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
9f40: 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c 20 68  install signal h
9f50: 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72  andler for hot-r
9f60: 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09 66 70  estart\n");...fp
9f70: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 48  rintf(stderr, "H
9f80: 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c 6c 20  ot-restart will 
9f90: 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65  not be available
9fa0: 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  .\n");..}.../*..
9fb0: 20 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75   * Add FUSE argu
9fc0: 6d 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61  ments which we a
9fd0: 6c 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a  lways supply.. *
9fe0: 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73  /..fuse_opt_pars
9ff0: 65 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e  e(&args, NULL, N
a000: 55 4c 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f  ULL, appfs_fuse_
a010: 6f 70 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f  opt_cb);..fuse_o
a020: 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73  pt_add_arg(&args
a030: 2c 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72  , "-odefault_per
a040: 6d 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d  missions,fsname=
a050: 61 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70  appfs,subtype=ap
a060: 70 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72  pfsd,use_ino,ker
a070: 6e 65 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f  nel_cache,entry_
a080: 74 69 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74  timeout=0,attr_t
a090: 69 6d 65 6f 75 74 3d 30 2c 62 69 67 5f 77 72 69  imeout=0,big_wri
a0a0: 74 65 73 2c 69 6e 74 72 2c 68 61 72 64 5f 72 65  tes,intr,hard_re
a0b0: 6d 6f 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65  move");...if (ge
a0c0: 74 75 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09  tuid() == 0) {..
a0d0: 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28  .fuse_opt_parse(
a0e0: 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  &args, NULL, NUL
a0f0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65  L, NULL);...fuse
a100: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72  _opt_add_arg(&ar
a110: 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68  gs, "-oallow_oth
a120: 65 72 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  er");..}.../*.. 
a130: 2a 20 45 6e 74 65 72 20 74 68 65 20 46 55 53 45  * Enter the FUSE
a140: 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68   main loop -- th
a150: 69 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20  is will process 
a160: 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20  any arguments.. 
a170: 2a 20 61 6e 64 20 73 74 61 72 74 20 73 65 72 76  * and start serv
a180: 69 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a  icing requests..
a190: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65  . */..appfs_fuse
a1a0: 5f 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72  _started = 1;..r
a1b0: 65 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28  eturn(fuse_main(
a1c0: 61 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e  args.argc, args.
a1d0: 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65  argv, &appfs_ope
a1e0: 72 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b  rations, NULL));
a1f0: 0a 7d 0a 20 0a                                   .}. .