Hex Artifact Content

Artifact cb5c5230ccfa7c640936479a94e96ec42024cfdb:


0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45  #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e  _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69 64  clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a  ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 69 67 6e 61 6c  #include <signal
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6c 69  .h>.#include <li
0080: 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  mits.h>.#include
0090: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
00a0: 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e 0a  lude <stdarg.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
00c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75 6e  .h>.#include <un
00d0: 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  istd.h>.#include
00e0: 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63 6c   <errno.h>.#incl
00f0: 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69  ude <fcntl.h>.#i
0100: 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e  nclude <stdio.h>
0110: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65 2e  .#include <fuse.
0120: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77 64  h>.#include <pwd
0130: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63  .h>.#include <tc
0140: 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44 65 66 61  l.h>../*. * Defa
0150: 75 6c 74 20 63 61 63 68 65 20 64 69 72 65 63 74  ult cache direct
0160: 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64 65 66 20  ory. */.#ifndef 
0170: 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 0a 23  APPFS_CACHEDIR.#
0180: 64 65 66 69 6e 65 20 41 50 50 46 53 5f 43 41 43  define APPFS_CAC
0190: 48 45 44 49 52 20 22 2f 76 61 72 2f 63 61 63 68  HEDIR "/var/cach
01a0: 65 2f 61 70 70 66 73 22 0a 23 65 6e 64 69 66 0a  e/appfs".#endif.
01b0: 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67 20 6d 61  ./* Debugging ma
01c0: 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65 66 20 44  cros */.#ifdef D
01d0: 45 42 55 47 0a 23 64 65 66 69 6e 65 20 41 50 50  EBUG.#define APP
01e0: 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b  FS_DEBUG(x...) {
01f0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
0200: 20 22 5b 64 65 62 75 67 5d 20 25 73 3a 25 69 3a   "[debug] %s:%i:
0210: 25 73 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f 2c  %s: ", __FILE__,
0220: 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e   __LINE__, __fun
0230: 63 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73 74  c__); fprintf(st
0240: 64 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e 74  derr, x); fprint
0250: 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b  f(stderr, "\n");
0260: 20 7d 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65   }.#else.#define
0270: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e   APPFS_DEBUG(x..
0280: 2e 29 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a  .) /**/.#endif..
0290: 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c 20 50  /*. * SHA1 Tcl P
02a0: 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c 69 7a  ackage initializ
02b0: 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a  er, from sha1.o.
02c0: 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69   */.int Sha1_Ini
02d0: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
02e0: 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68  terp);../*. * Th
02f0: 72 65 61 64 20 53 70 65 63 69 66 69 63 20 44 61  read Specific Da
0300: 74 61 20 28 54 53 44 29 20 66 6f 72 20 54 63 6c  ta (TSD) for Tcl
0310: 20 49 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72   Interpreter for
0320: 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
0330: 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70  ead. */.static p
0340: 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74  thread_key_t int
0350: 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47  erpKey;../*. * G
0360: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c  lobal variables,
0370: 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c 6c 20   needed for all 
0380: 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e 6c 79  threads but only
0390: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 65 66   initialized bef
03a0: 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53 45 20  ore any. * FUSE 
03b0: 74 68 72 65 61 64 73 20 61 72 65 20 63 72 65 61  threads are crea
03c0: 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68  ted. */.const ch
03d0: 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68 65 64  ar *appfs_cached
03e0: 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66 73  ir;.time_t appfs
03f0: 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61  _boottime;.int a
0400: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
0410: 64 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c  d = 0;../*. * Gl
0420: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
0430: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67  or AppFS caching
0440: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0450: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f  ex_t appfs_path_
0460: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
0470: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0480: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e  _INITIALIZER;.in
0490: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
04a0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38  o_cache_size = 8
04b0: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66  209;.struct appf
04c0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66  s_pathinfo *appf
04d0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
04e0: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 2f 2a 0a 20 2a  e = NULL;../*. *
04f0: 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   Global variable
0500: 73 20 66 6f 72 20 41 70 70 46 53 20 54 63 6c 20  s for AppFS Tcl 
0510: 49 6e 74 65 72 70 72 65 74 65 72 20 72 65 73 74  Interpreter rest
0520: 61 72 74 69 6e 67 0a 20 2a 2f 0a 69 6e 74 20 69  arting. */.int i
0530: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
0540: 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  = 0;../*. * AppF
0550: 53 20 50 61 74 68 20 54 79 70 65 3a 20 20 44 65  S Path Type:  De
0560: 73 63 72 69 62 65 73 20 74 68 65 20 74 79 70 65  scribes the type
0570: 20 6f 66 20 70 61 74 68 20 61 20 67 69 76 65 6e   of path a given
0580: 20 66 69 6c 65 20 69 73 0a 20 2a 2f 0a 74 79 70   file is. */.typ
0590: 65 64 65 66 20 65 6e 75 6d 20 7b 0a 09 41 50 50  edef enum {..APP
05a0: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
05b0: 4c 49 44 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  LID,..APPFS_PATH
05c0: 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58  TYPE_DOES_NOT_EX
05d0: 49 53 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  IST,..APPFS_PATH
05e0: 54 59 50 45 5f 46 49 4c 45 2c 0a 09 41 50 50 46  TYPE_FILE,..APPF
05f0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
0600: 54 4f 52 59 2c 0a 09 41 50 50 46 53 5f 50 41 54  TORY,..APPFS_PAT
0610: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09  HTYPE_SYMLINK,..
0620: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
0630: 4f 43 4b 45 54 2c 0a 09 41 50 50 46 53 5f 50 41  OCKET,..APPFS_PA
0640: 54 48 54 59 50 45 5f 46 49 46 4f 2c 0a 7d 20 61  THTYPE_FIFO,.} a
0650: 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 3b  ppfs_pathtype_t;
0660: 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61  ../*. * AppFS Pa
0670: 74 68 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a  th Information:.
0680: 20 2a 20 20 20 20 20 20 20 20 20 43 6f 6d 70 6c   *         Compl
0690: 65 74 65 6c 79 20 64 65 73 63 72 69 62 65 73 20  etely describes 
06a0: 61 20 73 70 65 63 69 66 69 63 20 70 61 74 68 2c  a specific path,
06b0: 20 68 6f 77 20 69 74 20 73 68 6f 75 6c 64 20 62   how it should b
06c0: 65 20 72 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a  e returned to. *
06d0: 20 20 20 20 20 20 20 20 20 74 6f 20 74 68 65 20           to the 
06e0: 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63  kernel. */.struc
06f0: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
0700: 20 7b 0a 09 61 70 70 66 73 5f 70 61 74 68 74 79   {..appfs_pathty
0710: 70 65 5f 74 20 74 79 70 65 3b 0a 09 74 69 6d 65  pe_t type;..time
0720: 5f 74 20 74 69 6d 65 3b 0a 09 63 68 61 72 20 68  _t time;..char h
0730: 6f 73 74 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69  ostname[256];..i
0740: 6e 74 20 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e  nt packaged;..un
0750: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
0760: 20 69 6e 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b   inode;..union {
0770: 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69  ...struct {....i
0780: 6e 74 20 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09  nt childcount;..
0790: 09 7d 20 64 69 72 3b 0a 09 09 73 74 72 75 63 74  .} dir;...struct
07a0: 20 7b 0a 09 09 09 69 6e 74 20 65 78 65 63 75 74   {....int execut
07b0: 61 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73  able;....off_t s
07c0: 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09  ize;...} file;..
07d0: 09 73 74 72 75 63 74 20 7b 0a 09 09 09 6f 66 66  .struct {....off
07e0: 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63 68 61 72  _t size;....char
07f0: 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09   source[256];...
0800: 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79  } symlink;..} ty
0810: 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74  peinfo;.../* Att
0820: 72 69 62 75 74 65 73 20 75 73 65 64 20 6f 6e 6c  ributes used onl
0830: 79 20 66 6f 72 20 63 61 63 68 69 6e 67 20 65 6e  y for caching en
0840: 74 72 69 65 73 20 2a 2f 0a 09 63 68 61 72 20 2a  tries */..char *
0850: 5f 63 61 63 68 65 5f 70 61 74 68 3b 0a 09 75 69  _cache_path;..ui
0860: 64 5f 74 20 5f 63 61 63 68 65 5f 75 69 64 3b 0a  d_t _cache_uid;.
0870: 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61 74 65  };../*. * Create
0880: 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72   a new Tcl inter
0890: 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d 70 6c  preter and compl
08a0: 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65  etely initialize
08b0: 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54   it. */.static T
08c0: 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73  cl_Interp *appfs
08d0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
08e0: 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72 5f 73  p(char **error_s
08f0: 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f 49 6e  tring) {..Tcl_In
0900: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69  terp *interp;..i
0910: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50  nt tcl_ret;...AP
0920: 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74  PFS_DEBUG("Creat
0930: 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65  ing new Tcl inte
0940: 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 20  rpreter for TID 
0950: 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69  = 0x%llx", (unsi
0960: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
0970: 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b  pthread_self());
0980: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f  ...interp = Tcl_
0990: 43 72 65 61 74 65 49 6e 74 65 72 70 28 29 3b 0a  CreateInterp();.
09a0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
09b0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
09c0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
09d0: 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 49   to create Tcl I
09e0: 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f  nterpreter.  Abo
09f0: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69  rting.\n");....i
0a00: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
0a10: 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72   {....*error_str
0a20: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22 55 6e  ing = strdup("Un
0a30: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54  able to create T
0a40: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
0a50: 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e  );...}....return
0a60: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (NULL);..}...Tcl
0a70: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
0a80: 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54  );...tcl_ret = T
0a90: 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b  cl_Init(interp);
0aa0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
0ab0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
0ac0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
0ad0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
0ae0: 7a 65 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e  ze Tcl.  Abortin
0af0: 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74  g.\n");...fprint
0b00: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
0b10: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
0b20: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0b30: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
0b40: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
0b50: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
0b60: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
0b70: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
0b80: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d  lt(interp));...}
0b90: 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ....Tcl_Release(
0ba0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 41 50 50 46  interp);....APPF
0bb0: 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61  S_DEBUG("Termina
0bc0: 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72  ting Tcl interpr
0bd0: 65 74 65 72 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f  eter.");....Tcl_
0be0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
0bf0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
0c00: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  NULL);..}...tcl_
0c10: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
0c20: 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20  nterp, "package 
0c30: 69 66 6e 65 65 64 65 64 20 73 68 61 31 20 31 2e  ifneeded sha1 1.
0c40: 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20  0 [list load {} 
0c50: 73 68 61 31 5d 22 29 3b 0a 09 69 66 20 28 74 63  sha1]");..if (tc
0c60: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
0c70: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
0c80: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
0c90: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 53  initialize Tcl S
0ca0: 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  HA1.  Aborting.\
0cb0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
0cc0: 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f  tderr, "Tcl Erro
0cd0: 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  r is: %s\n", Tcl
0ce0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
0cf0: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66  (interp));....if
0d00: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
0d10: 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  {....*error_stri
0d20: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
0d30: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
0d40: 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09  interp));...}...
0d50: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
0d60: 65 72 70 29 3b 0a 0a 09 09 41 50 50 46 53 5f 44  erp);....APPFS_D
0d70: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
0d80: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
0d90: 72 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c  r.");....Tcl_Del
0da0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
0db0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
0dc0: 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  L);..}...tcl_ret
0dd0: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
0de0: 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e  rp, "package ifn
0df0: 65 65 64 65 64 20 61 70 70 66 73 64 20 31 2e 30  eeded appfsd 1.0
0e00: 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 61   [list load {} a
0e10: 70 70 66 73 64 5d 22 29 3b 0a 09 69 66 20 28 74  ppfsd]");..if (t
0e20: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
0e30: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
0e40: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
0e50: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
0e60: 41 70 70 46 53 20 50 61 63 6b 61 67 65 2e 20 20  AppFS Package.  
0e70: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
0e80: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0e90: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
0ea0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
0eb0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0ec0: 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  p));....if (erro
0ed0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
0ee0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
0ef0: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
0f00: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0f10: 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52  ));...}....Tcl_R
0f20: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
0f30: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
0f40: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
0f50: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
0f60: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
0f70: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  erp(interp);....
0f80: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
0f90: 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 22  .../*.. * Load "
0fa0: 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68 65 20  pki.tcl" in the 
0fb0: 73 61 6d 65 20 77 61 79 20 61 73 20 61 70 70 66  same way as appf
0fc0: 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65 6c 6f  sd.tcl (see belo
0fd0: 77 29 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74  w).. */..tcl_ret
0fe0: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
0ff0: 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20  rp, "".#include 
1000: 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 22 22 29  "pki.tcl.h".."")
1010: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
1020: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
1030: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1040: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1050: 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20 41 62  ize Tcl PKI.  Ab
1060: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
1070: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1080: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1090: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
10a0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
10b0: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
10c0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
10d0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
10e0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
10f0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1100: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c  ;...}....Tcl_Rel
1110: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09  ease(interp);...
1120: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
1130: 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e  rminating Tcl in
1140: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
1150: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
1160: 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  p(interp);....re
1170: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1180: 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 74 68 65  ./*.. * Load the
1190: 20 22 61 70 70 66 73 64 2e 74 63 6c 22 20 73 63   "appfsd.tcl" sc
11a0: 72 69 70 74 2c 20 77 68 69 63 68 20 69 73 20 22  ript, which is "
11b0: 63 6f 6d 70 69 6c 65 64 22 20 69 6e 74 6f 20 61  compiled" into a
11c0: 20 43 20 68 65 61 64 65 72 0a 09 20 2a 20 73 6f   C header.. * so
11d0: 20 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f   that it does no
11e0: 74 20 6e 65 65 64 20 74 6f 20 65 78 69 73 74 20  t need to exist 
11f0: 6f 6e 20 74 68 65 20 66 69 6c 65 73 79 73 74 65  on the filesyste
1200: 6d 20 61 6e 64 20 63 61 6e 20 62 65 0a 09 20 2a  m and can be.. *
1210: 20 64 69 72 65 63 74 6c 79 20 65 76 61 6c 75 61   directly evalua
1220: 74 65 64 2e 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72  ted... */..tcl_r
1230: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
1240: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
1250: 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 22  e "appfsd.tcl.h"
1260: 0a 09 22 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f  .."");..if (tcl_
1270: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
1280: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1290: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  r, "Unable to in
12a0: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70  itialize Tcl App
12b0: 46 53 20 73 63 72 69 70 74 2e 20 20 41 62 6f 72  FS script.  Abor
12c0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72  ting.\n");...fpr
12d0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
12e0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
12f0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1300: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1310: 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74  ....if (error_st
1320: 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f  ring) {....*erro
1330: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
1340: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
1350: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1360: 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61  ..}....Tcl_Relea
1370: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 41  se(interp);....A
1380: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
1390: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
13a0: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 54  rpreter.");....T
13b0: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
13c0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
13d0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
13e0: 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c  *.. * Set global
13f0: 20 76 61 72 69 61 62 6c 65 73 20 66 72 6f 6d 20   variables from 
1400: 43 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09 69  C to Tcl.. */..i
1410: 66 20 28 54 63 6c 5f 53 65 74 56 61 72 28 69 6e  f (Tcl_SetVar(in
1420: 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  terp, "::appfs::
1430: 63 61 63 68 65 64 69 72 22 2c 20 61 70 70 66 73  cachedir", appfs
1440: 5f 63 61 63 68 65 64 69 72 2c 20 54 43 4c 5f 47  _cachedir, TCL_G
1450: 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e  LOBAL_ONLY) == N
1460: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
1470: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
1480: 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69   to set cache di
1490: 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73  rectory.  This s
14a0: 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c  hould never fail
14b0: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72  .\n");....if (er
14c0: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
14d0: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
14e0: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
14f0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1500: 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c  rp));...}....Tcl
1510: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
1520: 3b 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  ;....APPFS_DEBUG
1530: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63  ("Terminating Tc
1540: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
1550: 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  ;....Tcl_DeleteI
1560: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
1570: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1580: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74  .}.../*.. * Init
1590: 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 70 66  ialize the "appf
15a0: 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d  sd.tcl" environm
15b0: 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 74 20  ent, which must 
15c0: 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a 09 20  be done after.. 
15d0: 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  * global variabl
15e0: 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f  es are set... */
15f0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
1600: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Eval(interp, "::
1610: 61 70 70 66 73 3a 3a 69 6e 69 74 22 29 3b 0a 09  appfs::init");..
1620: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
1630: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
1640: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1650: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
1660: 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69 70   Tcl AppFS scrip
1670: 74 20 28 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74  t (::appfs::init
1680: 29 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  ).  Aborting.\n"
1690: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
16a0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
16b0: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
16c0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
16d0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28  nterp));....if (
16e0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
16f0: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
1700: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
1710: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
1720: 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54  terp));...}....T
1730: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1740: 70 29 3b 0a 0a 09 09 41 50 50 46 53 5f 44 45 42  p);....APPFS_DEB
1750: 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20  UG("Terminating 
1760: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
1770: 22 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74  ");....Tcl_Delet
1780: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
1790: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
17a0: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69  ;..}.../*.. * Hi
17b0: 64 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d  de some Tcl comm
17c0: 61 6e 64 73 20 74 68 61 74 20 77 65 20 64 6f 20  ands that we do 
17d0: 6e 6f 74 20 63 61 72 65 20 74 6f 20 75 73 65 20  not care to use 
17e0: 61 6e 64 20 77 68 69 63 68 20 6d 61 79 0a 09 20  and which may.. 
17f0: 2a 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d  * slow down run-
1800: 74 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e  time operations.
1810: 0a 09 20 2a 2f 0a 09 54 63 6c 5f 48 69 64 65 43  .. */..Tcl_HideC
1820: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
1830: 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22  auto_load_index"
1840: 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64  , "auto_load_ind
1850: 65 78 22 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43  ex");..Tcl_HideC
1860: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
1870: 75 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f  unknown", "unkno
1880: 77 6e 22 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43  wn");..Tcl_HideC
1890: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
18a0: 65 78 69 74 22 2c 20 22 65 78 69 74 22 29 3b 0a  exit", "exit");.
18b0: 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65  ../*.. * Release
18c0: 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76   the hold we hav
18d0: 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72  e on the interpr
18e0: 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20  eter so that it 
18f0: 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74  may be.. * delet
1900: 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a  ed if needed.. *
1910: 2f 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  /..Tcl_Release(i
1920: 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nterp);.../*.. *
1930: 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d 70   Return the comp
1940: 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a  letely initializ
1950: 65 64 20 69 6e 74 65 72 70 72 65 74 65 72 0a 09  ed interpreter..
1960: 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e 74 65   */..return(inte
1970: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65  rp);.}../*. * Re
1980: 74 75 72 6e 20 74 68 65 20 74 68 72 65 61 64 2d  turn the thread-
1990: 73 70 65 63 69 66 69 63 20 54 63 6c 20 69 6e 74  specific Tcl int
19a0: 65 72 70 72 65 74 65 72 2c 20 63 72 65 61 74 69  erpreter, creati
19b0: 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65 64 0a  ng it if needed.
19c0: 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49   */.static Tcl_I
19d0: 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54 63 6c  nterp *appfs_Tcl
19e0: 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b 0a 09  Interp(void) {..
19f0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1a00: 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  rp;..int pthread
1a10: 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f  _ret;..static __
1a20: 74 68 72 65 61 64 20 69 6e 74 20 74 68 72 65 61  thread int threa
1a30: 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  d_interp_reset_k
1a40: 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 67 6c 6f  ey = 0;..int glo
1a50: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
1a60: 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69  _key;...global_i
1a70: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
1a80: 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61  = __sync_fetch_a
1a90: 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72  nd_add(&interp_r
1aa0: 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 0a 09  eset_key, 0);...
1ab0: 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65 61 64  interp = pthread
1ac0: 5f 67 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _getspecific(int
1ad0: 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28 69 6e  erpKey);..if (in
1ae0: 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 26 26 20  terp != NULL && 
1af0: 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65  thread_interp_re
1b00: 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c 6f 62 61  set_key != globa
1b10: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
1b20: 65 79 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  ey) {...APPFS_DE
1b30: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
1b40: 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 74 65 72   old interpreter
1b50: 20 61 6e 64 20 72 65 73 74 61 72 74 69 6e 67 20   and restarting 
1b60: 64 75 65 20 74 6f 20 72 65 73 65 74 20 72 65 71  due to reset req
1b70: 75 65 73 74 2e 22 29 3b 0a 0a 09 09 54 63 6c 5f  uest.");....Tcl_
1b80: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1b90: 65 72 70 29 3b 0a 0a 09 09 69 6e 74 65 72 70 20  erp);....interp 
1ba0: 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 70 74 68 72 65  = NULL;....pthre
1bb0: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
1bc0: 5f 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _setspecific(int
1bd0: 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b  erpKey, interp);
1be0: 0a 09 7d 0a 0a 09 74 68 72 65 61 64 5f 69 6e 74  ..}...thread_int
1bf0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20  erp_reset_key = 
1c00: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
1c10: 73 65 74 5f 6b 65 79 3b 0a 0a 09 69 66 20 28 69  set_key;...if (i
1c20: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
1c30: 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
1c40: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
1c50: 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69 66 20  rp(NULL);....if 
1c60: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
1c70: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c   {....return(NUL
1c80: 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68 72 65  L);...}....pthre
1c90: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
1ca0: 5f 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74  _setspecific(int
1cb0: 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b  erpKey, interp);
1cc0: 0a 09 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ...if (pthread_r
1cd0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41 50  et != 0) {....AP
1ce0: 50 46 53 5f 44 45 42 55 47 28 22 70 74 68 72 65  PFS_DEBUG("pthre
1cf0: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 29  ad_setspecific()
1d00: 20 66 61 69 6c 65 64 2e 20 20 54 65 72 6d 69 6e   failed.  Termin
1d10: 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70  ating Tcl interp
1d20: 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 09 54 63  reter.");.....Tc
1d30: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
1d40: 6e 74 65 72 70 29 3b 0a 0a 09 09 09 72 65 74 75  nterp);.....retu
1d50: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d  rn(NULL);...}..}
1d60: 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70  ...return(interp
1d70: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c  );.}../*. * Eval
1d80: 75 61 74 65 20 61 20 54 63 6c 20 73 63 72 69 70  uate a Tcl scrip
1d90: 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 62 79  t constructed by
1da0: 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67 20 61   concatenating a
1db0: 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74 72 69   bunch of C stri
1dc0: 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65 72 2e  ngs. * together.
1dd0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
1de0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54  appfs_Tcl_Eval(T
1df0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
1e00: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e  p, int objc, con
1e10: 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e  st char *cmd, ..
1e20: 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a  .) {..Tcl_Obj **
1e30: 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61  objv;..const cha
1e40: 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74  r *arg;..va_list
1e50: 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65 74 76   argp;..int retv
1e60: 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66  al;..int i;...if
1e70: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
1e80: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c  ) {...return(TCL
1e90: 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62  _ERROR);..}...ob
1ea0: 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b  jv = (void *) ck
1eb0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62  alloc(sizeof(*ob
1ec0: 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 09 6f 62  jv) * objc);..ob
1ed0: 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65 77 53  jv[0] = Tcl_NewS
1ee0: 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20 2d 31  tringObj(cmd, -1
1ef0: 29 3b 0a 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  );..Tcl_IncrRefC
1f00: 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a  ount(objv[0]);..
1f10: 09 76 61 5f 73 74 61 72 74 28 61 72 67 70 2c 20  .va_start(argp, 
1f20: 63 6d 64 29 3b 0a 09 66 6f 72 20 28 69 20 3d 20  cmd);..for (i = 
1f30: 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  1; i < objc; i++
1f40: 29 20 7b 0a 09 09 61 72 67 20 3d 20 76 61 5f 61  ) {...arg = va_a
1f50: 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63  rg(argp, const c
1f60: 68 61 72 20 2a 29 3b 0a 09 09 6f 62 6a 76 5b 69  har *);...objv[i
1f70: 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  ] = Tcl_NewStrin
1f80: 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a 09  gObj(arg, -1);..
1f90: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
1fa0: 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 09  t(objv[i]);..}..
1fb0: 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a 0a 09  va_end(argp);...
1fc0: 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61  retval = Tcl_Eva
1fd0: 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62  lObjv(interp, ob
1fe0: 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a 0a 09  jc, objv, 0);...
1ff0: 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20  for (i = 0; i < 
2000: 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 54  objc; i++) {...T
2010: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
2020: 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 0a 09 63  objv[i]);..}...c
2030: 6b 66 72 65 65 28 28 76 6f 69 64 20 2a 29 20 6f  kfree((void *) o
2040: 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65 74 76  bjv);...if (retv
2050: 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  al != TCL_OK) {.
2060: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
2070: 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65  cl command faile
2080: 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63  d, ::errorInfo c
2090: 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20  ontains: %s\n", 
20a0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
20b0: 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22  p, "::errorInfo"
20c0: 2c 20 30 29 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  , 0));..}...retu
20d0: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f  rn(retval);.}../
20e0: 2a 0a 20 2a 20 52 65 71 75 65 73 74 20 61 6c 6c  *. * Request all
20f0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
2100: 73 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74  s restart. */.st
2110: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
2120: 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73  tcl_ResetInterps
2130: 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f  (void) {..APPFS_
2140: 44 45 42 55 47 28 22 52 65 71 75 65 73 74 69 6e  DEBUG("Requestin
2150: 67 20 72 65 73 65 74 20 6f 66 20 61 6c 6c 20 69  g reset of all i
2160: 6e 74 65 72 70 72 65 74 65 72 73 2e 22 29 3b 0a  nterpreters.");.
2170: 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 5f 61 6e 64  ..__sync_add_and
2180: 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72  _fetch(&interp_r
2190: 65 73 65 74 5f 6b 65 79 2c 20 31 29 3b 0a 0a 09  eset_key, 1);...
21a0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
21b0: 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 55   Determine the U
21c0: 49 44 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ID for the user 
21d0: 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65  making the curre
21e0: 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79 73 74  nt FUSE filesyst
21f0: 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54  em request.. * T
2200: 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64  his will be used
2210: 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75   to lookup the u
2220: 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63  ser's home direc
2230: 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73  tory so we can s
2240: 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63  earch for. * loc
2250: 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69  ally modified fi
2260: 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20  les.. */.static 
2270: 75 69 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f  uid_t appfs_get_
2280: 66 73 75 69 64 28 76 6f 69 64 29 20 7b 0a 09 73  fsuid(void) {..s
2290: 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65  truct fuse_conte
22a0: 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21  xt *ctx;...if (!
22b0: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
22c0: 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67  ed) {...return(g
22d0: 65 74 75 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63  etuid());..}...c
22e0: 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f  tx = fuse_get_co
22f0: 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74  ntext();..if (ct
2300: 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f  x == NULL) {.../
2310: 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b  * Unable to look
2320: 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65  up user for some
2330: 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20   reason */.../* 
2340: 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76  Return an unpriv
2350: 69 6c 65 67 65 64 20 75 73 65 72 20 49 44 20 2a  ileged user ID *
2360: 2f 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  /...return(1);..
2370: 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e  }...return(ctx->
2380: 75 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44  uid);.}../*. * D
2390: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 47 49 44  etermine the GID
23a0: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
23b0: 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  king the current
23c0: 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d   FUSE filesystem
23d0: 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69   request.. * Thi
23e0: 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74  s will be used t
23f0: 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65  o lookup the use
2400: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
2410: 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61  ry so we can sea
2420: 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c  rch for. * local
2430: 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65  ly modified file
2440: 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69  s.. */.static gi
2450: 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73  d_t appfs_get_fs
2460: 67 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72  gid(void) {..str
2470: 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74  uct fuse_context
2480: 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70   *ctx;...if (!ap
2490: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
24a0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74  ) {...return(get
24b0: 67 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78  gid());..}...ctx
24c0: 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74   = fuse_get_cont
24d0: 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20  ext();..if (ctx 
24e0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20  == NULL) {.../* 
24f0: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70  Unable to lookup
2500: 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72   user for some r
2510: 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65  eason */.../* Re
2520: 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c  turn an unprivil
2530: 65 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a  eged user ID */.
2540: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
2550: 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67 69  ..return(ctx->gi
2560: 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  d);.}..static vo
2570: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
2580: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
2590: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
25a0: 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  d(appfs_get_fsui
25b0: 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d());..setfsgid(
25c0: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
25d0: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  ));.}..static vo
25e0: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
25f0: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
2600: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
2610: 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d(0);..setfsgid(
2620: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f  0);.}../*. * Loo
2630: 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69  k up the home di
2640: 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69  rectory for a gi
2650: 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20  ven UID. *      
2660: 20 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74    Returns a C st
2670: 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ring containing 
2680: 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20  the user's home 
2690: 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c  directory or NUL
26a0: 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74  L if. *        t
26b0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
26c0: 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f  irectory does no
26d0: 74 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f  t exist or is no
26e0: 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20  t correctly. *  
26f0: 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64        configured
2700: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  . */.static char
2710: 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65   *appfs_get_home
2720: 64 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29  dir(uid_t fsuid)
2730: 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77   {..struct passw
2740: 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74  d entry, *result
2750: 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73  ;..struct stat s
2760: 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b  tbuf;..char buf[
2770: 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a  1024], *retval;.
2780: 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74  .int gpu_ret, st
2790: 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65  at_ret;...gpu_re
27a0: 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66  t = getpwuid_r(f
27b0: 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75  suid, &entry, bu
27c0: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20  f, sizeof(buf), 
27d0: 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67  &result);..if (g
27e0: 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  pu_ret != 0) {..
27f0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
2800: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
2810: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20  ..) returned in 
2820: 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67  failure", (unsig
2830: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
2840: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
2850: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
2860: 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29  (result == NULL)
2870: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2880: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
2890: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
28a0: 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28   NULL result", (
28b0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
28c0: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
28d0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
28e0: 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77  ..if (result->pw
28f0: 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  _dir == NULL) {.
2900: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
2910: 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20  etpwuid_r(%llu, 
2920: 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55  ...) returned NU
2930: 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  LL home director
2940: 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  y", (unsigned lo
2950: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
2960: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
2970: 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20  ;..}...stat_ret 
2980: 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70  = stat(result->p
2990: 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a  w_dir, &stbuf);.
29a0: 09 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d  .if (stat_ret !=
29b0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
29c0: 42 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65  BUG("stat(%s) re
29d0: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
29e0: 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64  e", result->pw_d
29f0: 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ir);....return(N
2a00: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  ULL);..}...if (s
2a10: 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66  tbuf.st_uid != f
2a20: 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f  suid) {...APPFS_
2a30: 44 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d  DEBUG("UID mis-m
2a40: 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c  atch on user %ll
2a50: 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  u's home directo
2a60: 72 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f  ry (%s).  It's o
2a70: 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a  wned by %llu.",.
2a80: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
2a90: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
2aa0: 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e  ,...    result->
2ab0: 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75  pw_dir,...    (u
2ac0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
2ad0: 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a  g) stbuf.st_uid.
2ae0: 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ..);....return(N
2af0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61  ULL);..}...retva
2b00: 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c  l = strdup(resul
2b10: 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65  t->pw_dir);...re
2b20: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
2b30: 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20  ./*. * Generate 
2b40: 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67  an inode for a g
2b50: 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20  iven path.  The 
2b60: 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20  inode should be 
2b70: 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68  computed in such
2b80: 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69  . * a way that i
2b90: 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f  t is unlikely to
2ba0: 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61   be duplicated a
2bb0: 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73  nd remains the s
2bc0: 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a  ame for a given.
2bd0: 20 2a 20 66 69 6c 65 0a 20 2a 2f 0a 23 69 66 20   * file. */.#if 
2be0: 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34 39  UINT_MAX < 42949
2bf0: 36 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e 74  67295.#error Int
2c00: 65 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f 6f  eger size is too
2c10: 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a 73   small .#endif.s
2c20: 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 6c  tatic unsigned l
2c30: 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f 67  ong long appfs_g
2c40: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63 6f  et_path_inode(co
2c50: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
2c60: 7b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09  {..int retval;..
2c70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a  const char *p;..
2c80: 09 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09  .retval = 10;...
2c90: 66 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a  for (p = path; *
2ca0: 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76  p; p++) {...retv
2cb0: 61 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30  al %= 4290960290
2cc0: 55 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d  ULL;...retval +=
2cd0: 20 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c   *p;...retval <<
2ce0: 3d 20 36 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  = 6;..}...retval
2cf0: 20 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20   += 10;..retval 
2d00: 25 3d 20 34 32 39 34 39 36 37 32 38 36 55 4c 4c  %= 4294967286ULL
2d10: 3b 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31 30 3b  ;..retval += 10;
2d20: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
2d30: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68  );.}../*. * Cach
2d40: 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20  e Get Path Info 
2d50: 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65  lookups for spee
2d60: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
2d70: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
2d80: 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63  info_cache_get(c
2d90: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
2da0: 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75   uid_t uid, stru
2db0: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
2dc0: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
2dd0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73  unsigned int has
2de0: 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72  h_idx;..int pthr
2df0: 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  ead_ret;..int re
2e00: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
2e10: 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65   1;...pthread_re
2e20: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
2e30: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
2e40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
2e50: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
2e60: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
2e70: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
2e80: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
2e90: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
2ea0: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
2eb0: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  n(-1);..}...if (
2ec0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2ed0: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
2ee0: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61  ...hash_idx = (a
2ef0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
2f00: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29  ode(path) + uid)
2f10: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
2f20: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
2f30: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
2f40: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
2f50: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
2f60: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  h != NULL) {....
2f70: 69 66 20 28 73 74 72 63 6d 70 28 61 70 70 66 73  if (strcmp(appfs
2f80: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
2f90: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
2fa0: 65 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d 3d  e_path, path) ==
2fb0: 20 30 20 26 26 20 61 70 70 66 73 5f 70 61 74 68   0 && appfs_path
2fc0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
2fd0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64  _idx]._cache_uid
2fe0: 20 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 72   == uid) {.....r
2ff0: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09  etval = 0;......
3000: 6d 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2c  memcpy(pathinfo,
3010: 20 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   &appfs_path_inf
3020: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3030: 5d 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69  ], sizeof(*pathi
3040: 6e 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 69  nfo));.....pathi
3050: 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68  nfo->_cache_path
3060: 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09   = NULL;....}...
3070: 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72  }..}...pthread_r
3080: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
3090: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
30a0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
30b0: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
30c0: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
30d0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
30e0: 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63  "Unable to unloc
30f0: 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68  k path_info cach
3100: 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09  e mutex !");....
3110: 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a  return(-1);..}..
3120: 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30  .if (retval == 0
3130: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
3140: 47 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e 20  G("Cache hit on 
3150: 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65  %s", path);..} e
3160: 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  lse {...APPFS_DE
3170: 42 55 47 28 22 43 61 63 68 65 20 6d 69 73 73 20  BUG("Cache miss 
3180: 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09  on %s", path);..
3190: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
31a0: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  l);.}..static vo
31b0: 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  id appfs_get_pat
31c0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64  h_info_cache_add
31d0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
31e0: 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74  h, uid_t uid, st
31f0: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
3200: 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b  nfo *pathinfo) {
3210: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  ..unsigned int h
3220: 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74  ash_idx;..int pt
3230: 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68  hread_ret;...pth
3240: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
3250: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
3260: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3270: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
3280: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
3290: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
32a0: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
32b0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
32c0: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
32d0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
32e0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
32f0: 66 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c  fo_cache == NULL
3300: 29 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 68  ) {...appfs_path
3310: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 61  _info_cache = ca
3320: 6c 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68 5f  lloc(appfs_path_
3330: 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c  info_cache_size,
3340: 20 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70   sizeof(*appfs_p
3350: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29  ath_info_cache))
3360: 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20  ;..}...hash_idx 
3370: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
3380: 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20  h_inode(path) + 
3390: 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74  uid) % appfs_pat
33a0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
33b0: 65 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  e;...if (appfs_p
33c0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
33d0: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
33e0: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
33f0: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
3400: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
3410: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
3420: 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  th);..}...memcpy
3430: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
3440: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3450: 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a  ], pathinfo, siz
3460: 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b  eof(*pathinfo));
3470: 0a 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
3480: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3490: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
34a0: 20 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a 09   strdup(path);..
34b0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
34c0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
34d0: 5f 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75 69  _cache_uid  = ui
34e0: 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  d;...pthread_ret
34f0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
3500: 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  _unlock(&appfs_p
3510: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
3520: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
3530: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
3540: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
3550: 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20  nable to unlock 
3560: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
3570: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
3580: 74 75 72 6e 3b 0a 09 7d 0a 09 72 65 74 75 72 6e  turn;..}..return
3590: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
35a0: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
35b0: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f  info_cache_rm(co
35c0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
35d0: 75 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e  uid_t uid) {..un
35e0: 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f  signed int hash_
35f0: 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61  idx;..int pthrea
3600: 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64  d_ret;...pthread
3610: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
3620: 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73  utex_lock(&appfs
3630: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3640: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
3650: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
3660: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3670: 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20  "Unable to lock 
3680: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
3690: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
36a0: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61  turn;..}...if (a
36b0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
36c0: 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  ache != NULL) {.
36d0: 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
36e0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
36f0: 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20  de(path) + uid) 
3700: 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  % appfs_path_inf
3710: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09  o_cache_size;...
3720: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
3730: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3740: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3750: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 66   != NULL) {....f
3760: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
3770: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3780: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29  dx]._cache_path)
3790: 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68  ;.....appfs_path
37a0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
37b0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
37c0: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d  h = NULL;...}..}
37d0: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
37e0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75   pthread_mutex_u
37f0: 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  nlock(&appfs_pat
3800: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
3810: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
3820: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
3830: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3840: 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61  ble to unlock pa
3850: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
3860: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
3870: 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b  rn;..}...return;
3880: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
3890: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
38a0: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
38b0: 75 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20 6e  uid_t uid, int n
38c0: 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69  ew_size) {..unsi
38d0: 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69  gned int idx;..i
38e0: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a  nt pthread_ret;.
38f0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 46  ..APPFS_DEBUG("F
3900: 6c 75 73 68 69 6e 67 20 41 70 70 46 53 20 63 61  lushing AppFS ca
3910: 63 68 65 20 28 75 69 64 20 3d 20 25 6c 6c 69 2c  che (uid = %lli,
3920: 20 6e 65 77 5f 73 69 7a 65 20 3d 20 25 69 29 22   new_size = %i)"
3930: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69  , (long long) ui
3940: 64 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09  d, new_size);...
3950: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
3960: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
3970: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
3980: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
3990: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
39a0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
39b0: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
39c0: 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  o lock path_info
39d0: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
39e0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
39f0: 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
3a00: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e  _info_cache != N
3a10: 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20 28 69 64  ULL) {...for (id
3a20: 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 61 70 70  x = 0; idx < app
3a30: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3a40: 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20  he_size; idx++) 
3a50: 7b 0a 09 09 09 69 66 20 28 61 70 70 66 73 5f 70  {....if (appfs_p
3a60: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69  ath_info_cache[i
3a70: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
3a80: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 69  != NULL) {.....i
3a90: 66 20 28 75 69 64 20 21 3d 20 28 28 75 69 64 5f  f (uid != ((uid_
3aa0: 74 29 20 2d 31 29 29 20 7b 0a 09 09 09 09 09 69  t) -1)) {......i
3ab0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3ac0: 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63  fo_cache[idx]._c
3ad0: 61 63 68 65 5f 75 69 64 20 21 3d 20 75 69 64 29  ache_uid != uid)
3ae0: 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74 69 6e 75   {.......continu
3af0: 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a  e;......}.....}.
3b00: 0a 09 09 09 09 66 72 65 65 28 61 70 70 66 73 5f  .....free(appfs_
3b10: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3b20: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3b30: 29 3b 0a 0a 09 09 09 09 61 70 70 66 73 5f 70 61  );......appfs_pa
3b40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64  th_info_cache[id
3b50: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
3b60: 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a   NULL;....}...}.
3b70: 09 7d 0a 0a 09 69 66 20 28 75 69 64 20 3d 3d 20  .}...if (uid == 
3b80: 28 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a  ((uid_t) -1)) {.
3b90: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
3ba0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 3b 0a 0a  h_info_cache);..
3bb0: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
3bc0: 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a  o_cache = NULL;.
3bd0: 0a 09 09 69 66 20 28 6e 65 77 5f 73 69 7a 65 20  ...if (new_size 
3be0: 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61 70 70 66  != -1) {....appf
3bf0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3c00: 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f 73 69 7a  e_size = new_siz
3c10: 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72  e;...}..}...pthr
3c20: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
3c30: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
3c40: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3c50: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
3c60: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
3c70: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
3c80: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
3c90: 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  unlock path_info
3ca0: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
3cb0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
3cc0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20  ..return;.}../* 
3cd0: 47 65 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  Get information 
3ce0: 61 62 6f 75 74 20 61 20 70 61 74 68 2c 20 61 6e  about a path, an
3cf0: 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73  d optionally lis
3d00: 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74  t children */.st
3d10: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 67  atic int appfs_g
3d20: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e  et_path_info(con
3d30: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
3d40: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
3d50: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20  info *pathinfo) 
3d60: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
3d70: 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20  nterp;..Tcl_Obj 
3d80: 2a 61 74 74 72 73 5f 64 69 63 74 2c 20 2a 61 74  *attrs_dict, *at
3d90: 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f 6e 73 74  tr_value;..const
3da0: 20 63 68 61 72 20 2a 61 74 74 72 5f 76 61 6c 75   char *attr_valu
3db0: 65 5f 73 74 72 3b 0a 09 54 63 6c 5f 57 69 64 65  e_str;..Tcl_Wide
3dc0: 49 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 77  Int attr_value_w
3dd0: 69 64 65 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76  ide;..int attr_v
3de0: 61 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69  alue_int;..stati
3df0: 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f  c __thread Tcl_O
3e00: 62 6a 20 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70  bj *attr_key_typ
3e10: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
3e20: 6b 65 79 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c  key_perms = NULL
3e30: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65  , *attr_key_size
3e40: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
3e50: 65 79 5f 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20  ey_time = NULL, 
3e60: 2a 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65  *attr_key_source
3e70: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
3e80: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ey_childcount = 
3e90: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
3ea0: 70 61 63 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b  packaged = NULL;
3eb0: 0a 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74 3b  ..int cache_ret;
3ec0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09  ..int tcl_ret;..
3ed0: 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09 66  uid_t fsuid;...f
3ee0: 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74  suid = appfs_get
3ef0: 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63 61 63 68  _fsuid();...cach
3f00: 65 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65  e_ret = appfs_ge
3f10: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
3f20: 65 5f 67 65 74 28 70 61 74 68 2c 20 66 73 75 69  e_get(path, fsui
3f30: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69  d, pathinfo);..i
3f40: 66 20 28 63 61 63 68 65 5f 72 65 74 20 3d 3d 20  f (cache_ret == 
3f50: 30 29 20 7b 0a 09 09 69 66 20 28 70 61 74 68 69  0) {...if (pathi
3f60: 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50  nfo->type == APP
3f70: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53  FS_PATHTYPE_DOES
3f80: 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b 0a 09 09  _NOT_EXIST) {...
3f90: 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29  .return(-ENOENT)
3fa0: 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 70 61 74  ;...}....if (pat
3fb0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41  hinfo->type == A
3fc0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
3fd0: 56 41 4c 49 44 29 20 7b 0a 09 09 09 72 65 74 75  VALID) {....retu
3fe0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09  rn(-EIO);...}...
3ff0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
4000: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
4010: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
4020: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
4030: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
4040: 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65  O);..}...Tcl_Pre
4050: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a  serve(interp);..
4060: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
4070: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
4080: 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67  , 2, "::appfs::g
4090: 65 74 61 74 74 72 22 2c 20 70 61 74 68 29 3b 0a  etattr", path);.
40a0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
40b0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
40c0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
40d0: 3a 3a 67 65 74 61 74 74 72 28 25 73 29 20 66 61  ::getattr(%s) fa
40e0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
40f0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
4100: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
4110: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
4120: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
4130: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
4140: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
4150: 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54  E_DOES_NOT_EXIST
4160: 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70  ;....appfs_get_p
4170: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61  ath_info_cache_a
4180: 64 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20  dd(path, fsuid, 
4190: 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 09 54 63  pathinfo);....Tc
41a0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
41b0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e  );....return(-EN
41c0: 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  OENT);..}...if (
41d0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d  attr_key_type ==
41e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 74 74 72 5f   NULL) {...attr_
41f0: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d  key_type       =
4200: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
4210: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09  j("type", -1);..
4220: 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20  .attr_key_perms 
4230: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
4240: 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c  ringObj("perms",
4250: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
4260: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63  _size       = Tc
4270: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4280: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  size", -1);...at
4290: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20  tr_key_time     
42a0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
42b0: 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29  gObj("time", -1)
42c0: 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ;...attr_key_sou
42d0: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  rce     = Tcl_Ne
42e0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72  wStringObj("sour
42f0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72  ce", -1);...attr
4300: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20  _key_childcount 
4310: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
4320: 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c  bj("childcount",
4330: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
4340: 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63  _packaged   = Tc
4350: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4360: 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a  packaged", -1);.
4370: 09 7d 0a 0a 09 61 74 74 72 73 5f 64 69 63 74 20  .}...attrs_dict 
4380: 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  = Tcl_GetObjResu
4390: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 74 63 6c  lt(interp);..tcl
43a0: 5f 72 65 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f  _ret = Tcl_DictO
43b0: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
43c0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
43d0: 65 79 5f 74 79 70 65 2c 20 26 61 74 74 72 5f 76  ey_type, &attr_v
43e0: 61 6c 75 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f  alue);..if (tcl_
43f0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
4400: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4410: 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70 65  [dict get \"type
4420: 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09  \"] failed");...
4430: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
4440: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
4450: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
4460: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
4470: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
4480: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
4490: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  -EIO);..}...if (
44a0: 61 74 74 72 5f 76 61 6c 75 65 20 3d 3d 20 4e 55  attr_value == NU
44b0: 4c 4c 29 20 7b 0a 09 09 54 63 6c 5f 52 65 6c 65  LL) {...Tcl_Rele
44c0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
44d0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
44e0: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
44f0: 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61 74 68  kaged = 0;..path
4500: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70  info->inode = ap
4510: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
4520: 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 74 74 72  de(path);...attr
4530: 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c  _value_str = Tcl
4540: 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f  _GetString(attr_
4550: 76 61 6c 75 65 29 3b 0a 09 73 77 69 74 63 68 20  value);..switch 
4560: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  (attr_value_str[
4570: 30 5d 29 20 7b 0a 09 09 63 61 73 65 20 27 64 27  0]) {...case 'd'
4580: 3a 20 2f 2a 20 64 69 72 65 63 74 6f 72 79 20 2a  : /* directory *
4590: 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  /....pathinfo->t
45a0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
45b0: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a  TYPE_DIRECTORY;.
45c0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
45d0: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63  einfo.dir.childc
45e0: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 54 63  ount = 0;.....Tc
45f0: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
4600: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
4610: 20 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63   attr_key_childc
4620: 6f 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75  ount, &attr_valu
4630: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
4640: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
4650: 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  .....tcl_ret = T
4660: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
4670: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
4680: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
4690: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69 66  ue_wide);.....if
46a0: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
46b0: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74 68  _OK) {......path
46c0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
46d0: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
46e0: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
46f0: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09  .....}....}.....
4700: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 66  break;...case 'f
4710: 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09  ': /* file */...
4720: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
4730: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
4740: 5f 46 49 4c 45 3b 0a 09 09 09 70 61 74 68 69 6e  _FILE;....pathin
4750: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
4760: 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 70  e.size = 0;....p
4770: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
4780: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c  o.file.executabl
4790: 65 20 3d 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44  e = 0;.....Tcl_D
47a0: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
47b0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
47c0: 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26 61 74  tr_key_size, &at
47d0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66  tr_value);....if
47e0: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20   (attr_value != 
47f0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74 63 6c 5f  NULL) {.....tcl_
4800: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64  ret = Tcl_GetWid
4810: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c  eIntFromObj(NULL
4820: 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61  , attr_value, &a
4830: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b  ttr_value_wide);
4840: 0a 09 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74  .....if (tcl_ret
4850: 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   == TCL_OK) {...
4860: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
4870: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20  einfo.file.size 
4880: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64  = attr_value_wid
4890: 65 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09  e;.....}....}...
48a0: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
48b0: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
48c0: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65  ict, attr_key_pe
48d0: 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rms, &attr_value
48e0: 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76  );....if (attr_v
48f0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
4900: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
4910: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
4920: 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  ng(attr_value);.
4930: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
4940: 75 65 5f 73 74 72 5b 30 5d 20 3d 3d 20 27 78 27  ue_str[0] == 'x'
4950: 29 20 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66  ) {......pathinf
4960: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
4970: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b  .executable = 1;
4980: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62  .....}....}....b
4990: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 73 27  reak;...case 's'
49a0: 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a  : /* symlink */.
49b0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
49c0: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
49d0: 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09 70  PE_SYMLINK;....p
49e0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
49f0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d  o.symlink.size =
4a00: 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d   0;....pathinfo-
4a10: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  >typeinfo.symlin
4a20: 6b 2e 73 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c  k.source[0] = '\
4a30: 30 27 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74  0';.....Tcl_Dict
4a40: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
4a50: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
4a60: 6b 65 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74  key_source, &att
4a70: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 20  r_value);....if 
4a80: 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e  (attr_value != N
4a90: 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74 72 5f  ULL) {.....attr_
4aa0: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f  value_str = Tcl_
4ab0: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
4ac0: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74  (attr_value, &at
4ad0: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a  tr_value_int); .
4ae0: 0a 09 09 09 09 69 66 20 28 28 61 74 74 72 5f 76  .....if ((attr_v
4af0: 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d  alue_int + 1) <=
4b00: 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f   sizeof(pathinfo
4b10: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
4b20: 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 09  nk.source)) {...
4b30: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
4b40: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69  einfo.symlink.si
4b50: 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f  ze = attr_value_
4b60: 69 6e 74 3b 0a 09 09 09 09 09 70 61 74 68 69 6e  int;......pathin
4b70: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
4b80: 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72  link.source[attr
4b90: 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c  _value_int] = '\
4ba0: 30 27 3b 0a 0a 09 09 09 09 09 6d 65 6d 63 70 79  0';.......memcpy
4bb0: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  (pathinfo->typei
4bc0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
4bd0: 63 65 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 73  ce, attr_value_s
4be0: 74 72 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  tr, attr_value_i
4bf0: 6e 74 29 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a  nt);.....}....}.
4c00: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
4c10: 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69   'F': /* pipe/fi
4c20: 66 6f 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66  fo */....pathinf
4c30: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
4c40: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09  PATHTYPE_FIFO;..
4c50: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
4c60: 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d  'S': /* UNIX dom
4c70: 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09  ain socket */...
4c80: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
4c90: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
4ca0: 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 62 72 65 61  _SOCKET;....brea
4cb0: 6b 3b 0a 09 09 64 65 66 61 75 6c 74 3a 0a 09 09  k;...default:...
4cc0: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
4cd0: 65 72 70 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  erp);.....return
4ce0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (-EIO);..}...Tcl
4cf0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
4d00: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
4d10: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
4d20: 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  d, &attr_value);
4d30: 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
4d40: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 70 61   != NULL) {...pa
4d50: 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64  thinfo->packaged
4d60: 20 3d 20 31 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44   = 1;..}...Tcl_D
4d70: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
4d80: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
4d90: 74 72 5f 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74  tr_key_time, &at
4da0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66 20 28  tr_value);..if (
4db0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
4dc0: 4c 4c 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20  LL) {...tcl_ret 
4dd0: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
4de0: 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74  FromObj(NULL, at
4df0: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
4e00: 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 69  value_wide);...i
4e10: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
4e20: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 70 61 74 68 69  L_OK) {....pathi
4e30: 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 72  nfo->time = attr
4e40: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 7d  _value_wide;...}
4e50: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 70 61 74  ..} else {...pat
4e60: 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 30 3b  hinfo->time = 0;
4e70: 0a 09 7d 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73  ..}...Tcl_Releas
4e80: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 61 70 70  e(interp);...app
4e90: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4ea0: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c  _cache_add(path,
4eb0: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
4ec0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
4ed0: 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  }..static char *
4ee0: 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f  appfs_prepare_to
4ef0: 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68  _create(const ch
4f00: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c  ar *path) {..Tcl
4f10: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
4f20: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65  ..const char *re
4f30: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63  al_path;..int tc
4f40: 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67  l_ret;...appfs_g
4f50: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
4f60: 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67  he_flush(appfs_g
4f70: 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b  et_fsuid(), -1);
4f80: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
4f90: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
4fa0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
4fb0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
4fc0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50  ULL);..}...Tcl_P
4fd0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
4fe0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
4ff0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
5000: 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 2, "::appfs:
5010: 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  :prepare_to_crea
5020: 74 65 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  te", path);..if 
5030: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
5040: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
5050: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72  BUG("::appfs::pr
5060: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
5070: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
5080: 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42  th);...APPFS_DEB
5090: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
50a0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
50b0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
50c0: 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65  p));....Tcl_Rele
50d0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
50e0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
50f0: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
5100: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5110: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63  lt(interp);...Tc
5120: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
5130: 29 3b 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  );...if (real_pa
5140: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
5150: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
5160: 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70  ...return(strdup
5170: 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a  (real_path));.}.
5180: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70  .static char *ap
5190: 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63 6f  pfs_localpath(co
51a0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
51b0: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
51c0: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
51d0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
51e0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
51f0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
5200: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
5210: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
5220: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
5230: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65  ;..}...Tcl_Prese
5240: 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 74  rve(interp);...t
5250: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
5260: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
5270: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63  2, "::appfs::loc
5280: 61 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a  alpath", path);.
5290: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
52a0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
52b0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
52c0: 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29 20  ::localpath(%s) 
52d0: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
52e0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
52f0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
5300: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
5310: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
5320: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
5330: 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68  ;..}...real_path
5340: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
5350: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
5360: 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
5370: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72 65 61  terp);...if (rea
5380: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
5390: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
53a0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74  ;..}...return(st
53b0: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29  rdup(real_path))
53c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
53d0: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c  appfs_fuse_readl
53e0: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
53f0: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
5400: 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a   size_t size) {.
5410: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
5420: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
5430: 0a 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30  ..int retval = 0
5440: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5450: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
5460: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
5470: 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  ...pathinfo.type
5480: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
5490: 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74  E_INVALID;...ret
54a0: 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  val = appfs_get_
54b0: 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20  path_info(path, 
54c0: 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20  &pathinfo);..if 
54d0: 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a  (retval != 0) {.
54e0: 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
54f0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  ;..}...if (pathi
5500: 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46  nfo.type != APPF
5510: 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49  S_PATHTYPE_SYMLI
5520: 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  NK) {...return(-
5530: 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66  EINVAL);..}...if
5540: 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e   ((strlen(pathin
5550: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
5560: 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29  ink.source) + 1)
5570: 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74   > size) {...ret
5580: 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e  urn(-ENAMETOOLON
5590: 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28  G);..}...memcpy(
55a0: 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79  buf, pathinfo.ty
55b0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
55c0: 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61  ource, strlen(pa
55d0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
55e0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20  symlink.source) 
55f0: 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30  + 1);...return(0
5600: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
5610: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
5620: 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ttr(const char *
5630: 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74 61  path, struct sta
5640: 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72  t *stbuf) {..str
5650: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
5660: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e  fo pathinfo;..in
5670: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76  t retval;...retv
5680: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
5690: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
56a0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
56b0: 70 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66  path);...pathinf
56c0: 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  o.type = APPFS_P
56d0: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b  ATHTYPE_INVALID;
56e0: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66  ...retval = appf
56f0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
5700: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
5710: 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d  ;..if (retval !=
5720: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72   0) {...return(r
5730: 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  etval);..}...mem
5740: 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69  set(stbuf, 0, si
5750: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74  zeof(struct stat
5760: 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ));...stbuf->st_
5770: 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f  mtime = pathinfo
5780: 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73  .time;..stbuf->s
5790: 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e  t_ctime = pathin
57a0: 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d  fo.time;..stbuf-
57b0: 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68  >st_atime = path
57c0: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75  info.time;..stbu
57d0: 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61  f->st_ino   = pa
57e0: 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73  thinfo.inode;..s
57f0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d  tbuf->st_mode  =
5800: 20 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70 61   0;...switch (pa
5810: 74 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a 09  thinfo.type) {..
5820: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
5830: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a 0a  TYPE_DIRECTORY:.
5840: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
5850: 65 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30 35  e = S_IFDIR | 05
5860: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
5870: 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61 74  _nlink = 2 + pat
5880: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 64  hinfo.typeinfo.d
5890: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09  ir.childcount;..
58a0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
58b0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
58c0: 49 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74 68  ILE:....if (path
58d0: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69  info.typeinfo.fi
58e0: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b  le.executable) {
58f0: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
5900: 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20  ode = S_IFREG | 
5910: 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65 20  0555;....} else 
5920: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
5930: 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c  mode = S_IFREG |
5940: 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09 09   0444;....}.....
5950: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
5960: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
5970: 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66  t_size = pathinf
5980: 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  o.typeinfo.file.
5990: 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a  size;....break;.
59a0: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
59b0: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09  HTYPE_SYMLINK:..
59c0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
59d0: 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35   = S_IFLNK | 055
59e0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
59f0: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
5a00: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
5a10: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
5a20: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09  .symlink.size;..
5a30: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
5a40: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
5a50: 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d  OCKET:....stbuf-
5a60: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53  >st_mode = S_IFS
5a70: 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  OCK | 0555;....s
5a80: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
5a90: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
5aa0: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
5ab0: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
5ac0: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a  S_PATHTYPE_FIFO:
5ad0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
5ae0: 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30  de = S_IFIFO | 0
5af0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
5b00: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
5b10: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
5b20: 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09   0;....break;...
5b30: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
5b40: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
5b50: 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ST:....retval = 
5b60: 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65  -ENOENT;.....bre
5b70: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
5b80: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
5b90: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
5ba0: 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  EIO;.....break;.
5bb0: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
5bc0: 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09  o.packaged) {...
5bd0: 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20  stbuf->st_uid   
5be0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
5bf0: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
5c00: 5f 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67  _gid   = appfs_g
5c10: 65 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74  et_fsgid();...st
5c20: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20  buf->st_mode |= 
5c30: 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  0200;..}...retur
5c40: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
5c50: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
5c60: 75 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73  use_readdir(cons
5c70: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f  t char *path, vo
5c80: 69 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69  id *buf, fuse_fi
5c90: 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c  ll_dir_t filler,
5ca0: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
5cb0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
5cc0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
5cd0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
5ce0: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c  ..Tcl_Obj **chil
5cf0: 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64  dren;..int child
5d00: 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a  ren_count, idx;.
5d10: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
5d20: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
5d30: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
5d40: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
5d50: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
5d60: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
5d70: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
5d80: 7b 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  {...return(0);..
5d90: 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65  }...Tcl_Preserve
5da0: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 66 69 6c 6c  (interp);...fill
5db0: 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e 55 4c  er(buf, ".", NUL
5dc0: 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72 28 62  L, 0);..filler(b
5dd0: 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20  uf, "..", NULL, 
5de0: 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  0);...tcl_ret = 
5df0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
5e00: 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70  nterp, 2, "::app
5e10: 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 22  fs::getchildren"
5e20: 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63  , path);..if (tc
5e30: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
5e40: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5e50: 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68  ("::appfs::getch
5e60: 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69 6c 65  ildren(%s) faile
5e70: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
5e80: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
5e90: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
5ea0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
5eb0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54  t(interp));....T
5ec0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
5ed0: 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  p);....return(0)
5ee0: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
5ef0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45   Tcl_ListObjGetE
5f00: 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20  lements(interp, 
5f10: 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_GetObjResult
5f20: 28 69 6e 74 65 72 70 29 2c 20 26 63 68 69 6c 64  (interp), &child
5f30: 72 65 6e 5f 63 6f 75 6e 74 2c 20 26 63 68 69 6c  ren_count, &chil
5f40: 64 72 65 6e 29 3b 0a 09 69 66 20 28 74 63 6c 5f  dren);..if (tcl_
5f50: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
5f60: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5f70: 50 61 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20  Parsing list of 
5f80: 63 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68  children on path
5f90: 20 25 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61   %s failed.", pa
5fa0: 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42  th);...APPFS_DEB
5fb0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
5fc0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
5fd0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
5fe0: 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65  p));....Tcl_Rele
5ff0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
6000: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09  return(0);..}...
6010: 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64  for (idx = 0; id
6020: 78 20 3c 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75  x < children_cou
6030: 6e 74 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 66  nt; idx++) {...f
6040: 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f 47  iller(buf, Tcl_G
6050: 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64 72 65  etString(childre
6060: 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30  n[idx]), NULL, 0
6070: 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 52 65 6c 65  );..}...Tcl_Rele
6080: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 72  ase(interp);...r
6090: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
60a0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
60b0: 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68  se_open(const ch
60c0: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
60d0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
60e0: 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  *fi) {..Tcl_Inte
60f0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73 74 72  rp *interp;..str
6100: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
6110: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 63 6f  fo pathinfo;..co
6120: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
6130: 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69 6e 74  ath, *mode;..int
6140: 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f 72 65   gpi_ret, tcl_re
6150: 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09 41 50  t;..int fh;...AP
6160: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
6170: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
6180: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67 70 69  )", path);...gpi
6190: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65 74  _ret = appfs_get
61a0: 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c  _path_info(path,
61b0: 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 69   &pathinfo);...i
61c0: 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20  f ((fi->flags & 
61d0: 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45 41  (O_WRONLY|O_CREA
61e0: 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54 7c  T)) == (O_CREAT|
61f0: 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09 2f  O_WRONLY)) {.../
6200: 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c 6c 20  * The file will 
6210: 62 65 20 63 72 65 61 74 65 64 20 69 66 20 69 74  be created if it
6220: 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20   does not exist 
6230: 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74  */...if (gpi_ret
6240: 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72 65 74   != 0 && gpi_ret
6250: 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09   != -ENOENT) {..
6260: 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65 74  ..return(gpi_ret
6270: 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d  );...}....mode =
6280: 20 22 63 72 65 61 74 65 22 3b 0a 0a 09 09 2f 2a   "create";..../*
6290: 0a 09 09 20 2a 20 57 65 20 68 61 76 65 20 74 6f  ... * We have to
62a0: 20 63 6c 65 61 72 20 74 68 65 20 63 61 63 68 65   clear the cache
62b0: 20 68 65 72 65 20 73 6f 20 74 68 61 74 20 74 68   here so that th
62c0: 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09 20 2a  e number of... *
62d0: 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61 69 6e   links gets main
62e0: 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 70 61  tained on the pa
62f0: 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79 0a 09  rent directory..
6300: 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67 65 74  . */...appfs_get
6310: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
6320: 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74  _flush(appfs_get
6330: 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 09  _fsuid(), -1);..
6340: 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20 54 68  } else {.../* Th
6350: 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c 72 65  e file must alre
6360: 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09 09 69  ady exist */...i
6370: 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30 29  f (gpi_ret != 0)
6380: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69   {....return(gpi
6390: 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f  _ret);...}....mo
63a0: 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66 20 28  de = "";....if (
63b0: 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f 5f 57  (fi->flags & O_W
63c0: 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f 4e  RONLY) == O_WRON
63d0: 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20 3d 20  LY) {....mode = 
63e0: 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09 7d 0a  "write";...}..}.
63f0: 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74  ..if (pathinfo.t
6400: 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54  ype == APPFS_PAT
6410: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 29  HTYPE_DIRECTORY)
6420: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 53   {...return(-EIS
6430: 44 49 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72  DIR);..}...inter
6440: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
6450: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
6460: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
6470: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
6480: 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76 65 28  ...Tcl_Preserve(
6490: 69 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f 72  interp);...tcl_r
64a0: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
64b0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22  val(interp, 3, "
64c0: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
64d0: 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b  h", path, mode);
64e0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
64f0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
6500: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
6510: 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20  s::openpath(%s, 
6520: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
6530: 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 41 50 50  th, mode);...APP
6540: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
6550: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
6560: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
6570: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63  (interp));....Tc
6580: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
6590: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  );....return(-EI
65a0: 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  O);..}...real_pa
65b0: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
65c0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
65d0: 3b 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ;...Tcl_Release(
65e0: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72  interp);...if (r
65f0: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
6600: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
6610: 4f 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44  O);..}...APPFS_D
6620: 45 42 55 47 28 22 54 72 61 6e 73 6c 61 74 65 64  EBUG("Translated
6630: 20 72 65 71 75 65 73 74 20 74 6f 20 6f 70 65 6e   request to open
6640: 20 25 73 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25   %s to opening %
6650: 73 20 28 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22  s (mode = \"%s\"
6660: 29 22 2c 20 70 61 74 68 2c 20 72 65 61 6c 5f 70  )", path, real_p
6670: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68  ath, mode);...fh
6680: 20 3d 20 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74   = open(real_pat
6690: 68 2c 20 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36  h, fi->flags, 06
66a0: 30 30 29 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20  00);...if (fh < 
66b0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  0) {...return(-E
66c0: 49 4f 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68  IO);..}...fi->fh
66d0: 20 3d 20 66 68 3b 0a 0a 09 72 65 74 75 72 6e 28   = fh;...return(
66e0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
66f0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f  t appfs_fuse_clo
6700: 73 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  se(const char *p
6710: 61 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65  ath, struct fuse
6720: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
6730: 7b 0a 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74  {..int close_ret
6740: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
6750: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
6760: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
6770: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f  _fsuid());...clo
6780: 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66  se_ret = close(f
6790: 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f  i->fh);..if (clo
67a0: 73 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  se_ret != 0) {..
67b0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
67c0: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
67d0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
67e0: 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e  fs_fuse_read(con
67f0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
6800: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
6810: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66   size, off_t off
6820: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
6830: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
6840: 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72  {..off_t lseek_r
6850: 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61  et;..ssize_t rea
6860: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
6870: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
6880: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
6890: 61 74 68 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65  ath);...lseek_re
68a0: 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68  t = lseek(fi->fh
68b0: 2c 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53  , offset, SEEK_S
68c0: 45 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f  ET);..if (lseek_
68d0: 72 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b  ret != offset) {
68e0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
68f0: 0a 09 7d 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d  ..}...read_ret =
6900: 20 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75   read(fi->fh, bu
6910: 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75  f, size);...retu
6920: 72 6e 28 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a  rn(read_ret);.}.
6930: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6940: 73 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f 6e  s_fuse_write(con
6950: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
6960: 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c 20  onst char *buf, 
6970: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
6980: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
6990: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
69a0: 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c   *fi) {..off_t l
69b0: 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65  seek_ret;..ssize
69c0: 5f 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 0a 09  _t write_ret;...
69d0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
69e0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
69f0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
6a00: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6a10: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
6a20: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
6a30: 64 28 29 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65  d());...lseek_re
6a40: 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68  t = lseek(fi->fh
6a50: 2c 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53  , offset, SEEK_S
6a60: 45 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f  ET);..if (lseek_
6a70: 72 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b  ret != offset) {
6a80: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
6a90: 0a 09 7d 0a 0a 09 77 72 69 74 65 5f 72 65 74 20  ..}...write_ret 
6aa0: 3d 20 77 72 69 74 65 28 66 69 2d 3e 66 68 2c 20  = write(fi->fh, 
6ab0: 62 75 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65  buf, size);...re
6ac0: 74 75 72 6e 28 77 72 69 74 65 5f 72 65 74 29 3b  turn(write_ret);
6ad0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
6ae0: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28  ppfs_fuse_mknod(
6af0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6b00: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64  , mode_t mode, d
6b10: 65 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09  ev_t device) {..
6b20: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
6b30: 0a 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b  ..int mknod_ret;
6b40: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6b50: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
6b60: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
6b70: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
6b80: 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48  IFCHR) == S_IFCH
6b90: 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  R) {...return(-E
6ba0: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  PERM);..}...if (
6bb0: 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29  (mode & S_IFBLK)
6bc0: 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09   == S_IFBLK) {..
6bd0: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
6be0: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
6bf0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
6c00: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
6c10: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
6c20: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
6c30: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
6c40: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
6c50: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
6c60: 0a 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b  ..mknod_ret = mk
6c70: 6e 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  nod(real_path, m
6c80: 6f 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09  ode, device);...
6c90: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
6ca0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
6cb0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
6cc0: 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72  );...if (mknod_r
6cd0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
6ce0: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
6cf0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
6d00: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
6d10: 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65  ppfs_fuse_create
6d20: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
6d30: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20  h, mode_t mode, 
6d40: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
6d50: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68  _info *fi) {..ch
6d60: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
6d70: 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f  int fd;...APPFS_
6d80: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
6d90: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
6da0: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
6db0: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
6dc0: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
6dd0: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
6de0: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
6df0: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
6e00: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
6e10: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
6e20: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
6e30: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
6e40: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
6e50: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
6e60: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
6e70: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
6e80: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
6e90: 74 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72  ter();...fd = cr
6ea0: 65 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  eat(real_path, m
6eb0: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
6ec0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
6ed0: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
6ee0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
6ef0: 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74  (fd < 0) {...ret
6f00: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
6f10: 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66  ..}...fi->fh = f
6f20: 64 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  d;...return(0);.
6f30: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
6f40: 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74  pfs_fuse_truncat
6f50: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
6f60: 74 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20  th, off_t size) 
6f70: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
6f80: 74 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74  th;..int truncat
6f90: 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  e_ret;...APPFS_D
6fa0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
6fb0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
6fc0: 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74  ath);...real_pat
6fd0: 68 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70  h = appfs_localp
6fe0: 61 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ath(path);..if (
6ff0: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
7000: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
7010: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
7020: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
7030: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
7040: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
7050: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
7060: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
7070: 29 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65  );...truncate_re
7080: 74 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61  t = truncate(rea
7090: 6c 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a  l_path, size);..
70a0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
70b0: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
70c0: 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74  ...free(real_pat
70d0: 68 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61  h);...if (trunca
70e0: 74 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  te_ret != 0) {..
70f0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
7100: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
7110: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
7120: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e  nt appfs_fuse_un
7130: 6c 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74  link_rmdir(const
7140: 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09   char *path) {..
7150: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7160: 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  rp;..int tcl_ret
7170: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
7180: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
7190: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
71a0: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
71b0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
71c0: 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75  sh(appfs_get_fsu
71d0: 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74  id(), -1);...int
71e0: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
71f0: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
7200: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
7210: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
7220: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  .}...tcl_ret = a
7230: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
7240: 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66  terp, 2, "::appf
7250: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20  s::unlinkpath", 
7260: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
7270: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
7280: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
7290: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
72a0: 61 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ath(%s) failed."
72b0: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
72c0: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
72d0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
72e0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
72f0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f  nterp));....Tcl_
7300: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
7310: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
7320: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 52 65 6c 65 61  ;..}...Tcl_Relea
7330: 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 72 65  se(interp);...re
7340: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
7350: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
7360: 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68  e_mkdir(const ch
7370: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
7380: 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a   mode) {..char *
7390: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
73a0: 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50  mkdir_ret;...APP
73b0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
73c0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
73d0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c  ", path);...real
73e0: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
73f0: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
7400: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
7410: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
7420: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
7430: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
7440: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
7450: 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65  er();...mkdir_re
7460: 74 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70  t = mkdir(real_p
7470: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
7480: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
7490: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
74a0: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b  free(real_path);
74b0: 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74  ...if (mkdir_ret
74c0: 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65   != 0) {...if (e
74d0: 72 72 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20  rrno != EEXIST) 
74e0: 7b 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e  {....return(errn
74f0: 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a  o * -1);...}..}.
7500: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7510: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7520: 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73  _fuse_chmod(cons
7530: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
7540: 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63  de_t mode) {..Tc
7550: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7560: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
7570: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
7580: 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65  cl_ret, chmod_re
7590: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
75a0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
75b0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
75c0: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
75d0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
75e0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
75f0: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74  _fsuid());...int
7600: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
7610: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
7620: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
7630: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
7640: 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65 72 76  .}...Tcl_Preserv
7650: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 74 63 6c  e(interp);...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 33 2c  _Eval(interp, 3,
7680: 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70   "::appfs::openp
7690: 61 74 68 22 2c 20 70 61 74 68 2c 20 22 77 72 69  ath", path, "wri
76a0: 74 65 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  te");..if (tcl_r
76b0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
76c0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
76d0: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
76e0: 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e  (%s, %s) failed.
76f0: 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22  ", path, "write"
7700: 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  );...APPFS_DEBUG
7710: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
7720: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
7730: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
7740: 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73  );....Tcl_Releas
7750: 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  e(interp);....re
7760: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
7770: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
7780: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
7790: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f  (interp);...Tcl_
77a0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
77b0: 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ...if (real_path
77c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
77d0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
77e0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
77f0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
7800: 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63  ...chmod_ret = c
7810: 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20  hmod(real_path, 
7820: 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  mode);...appfs_s
7830: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
7840: 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72  leave();...retur
7850: 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a  n(chmod_ret);.}.
7860: 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d  ./*. * SQLite3 m
7870: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
7880: 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e 20   SQL and return 
7890: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
78a0: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
78b0: 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28  t appfs_sqlite3(
78c0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 29  const char *sql)
78d0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
78e0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
78f0: 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69  har *sql_ret;..i
7900: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
7910: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
7920: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55  ate_TclInterp(NU
7930: 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  LL);..if (interp
7940: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70   == NULL) {...fp
7950: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
7960: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
7970: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
7980: 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  r.  Aborting.\n"
7990: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
79a0: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
79b0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
79c0: 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70 70  nterp, 5, "::app
79d0: 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22 2c  fs::db", "eval",
79e0: 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75 6e   sql, "row", "un
79f0: 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  set -nocomplain 
7a00: 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20 72  row(*); parray r
7a10: 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c  ow; puts \"----\
7a20: 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d 20  "");..sql_ret = 
7a30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
7a40: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ult(interp);...i
7a50: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
7a60: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
7a70: 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f  f(stderr, "[erro
7a80: 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65  r] %s\n", sql_re
7a90: 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  t);....return(1)
7aa0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f 72  ;..}...if (sql_r
7ab0: 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30 5d  et && sql_ret[0]
7ac0: 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 72   != '\0') {...pr
7ad0: 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71 6c  intf("%s\n", sql
7ae0: 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  _ret);..}...retu
7af0: 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  rn(0);.}../*. * 
7b00: 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75 74  Tcl mode: Execut
7b10: 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72 65  e raw Tcl and re
7b20: 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72 20  turn success or 
7b30: 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74  failure. */.stat
7b40: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63 6c  ic int appfs_tcl
7b50: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  (const char *tcl
7b60: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
7b70: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
7b80: 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74  char *tcl_result
7b90: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
7ba0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
7bb0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
7bc0: 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e  p(NULL);..if (in
7bd0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
7be0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
7bf0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65  , "Unable to cre
7c00: 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70  ate a Tcl interp
7c10: 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67  reter.  Aborting
7c20: 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  .\n");....return
7c30: 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  (1);..}...tcl_re
7c40: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
7c50: 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f  erp, tcl);..tcl_
7c60: 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74  result = Tcl_Get
7c70: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
7c80: 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f  erp);...if (tcl_
7c90: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
7ca0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
7cb0: 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e  r, "[error] %s\n
7cc0: 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a  ", tcl_result);.
7cd0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
7ce0: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c  ...if (tcl_resul
7cf0: 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b  t && tcl_result[
7d00: 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09  0] != '\0') {...
7d10: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74  printf("%s\n", t
7d20: 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a  cl_result);..}..
7d30: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f  .return(0);.}../
7d40: 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b  *. * AppFSd Pack
7d50: 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20  age for Tcl:. * 
7d60: 20 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66          Bridge f
7d70: 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e  or I/O operation
7d80: 73 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66  s to request inf
7d90: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74  ormation about t
7da0: 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20  he current. *   
7db0: 20 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f        transactio
7dc0: 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20  n. */./*. * Tcl 
7dd0: 69 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65 74  interface to get
7de0: 20 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74   the home direct
7df0: 6f 72 79 20 66 6f 72 20 74 68 65 20 75 73 65 72  ory for the user
7e00: 20 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75 72   making the "cur
7e10: 72 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49 2f  rent". * FUSE I/
7e20: 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74  O request. */.st
7e30: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
7e40: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 43  fs_get_homedir(C
7e50: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
7e60: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7e70: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
7e80: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
7e90: 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65  ]) {..char *home
7ea0: 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68  dir;..Tcl_Obj *h
7eb0: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64  omedir_obj;..uid
7ec0: 5f 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74 69  _t fsuid;..stati
7ed0: 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f  c __thread Tcl_O
7ee0: 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72  bj *last_homedir
7ef0: 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74  _obj = NULL;..st
7f00: 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75 69  atic __thread ui
7f10: 64 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20 3d  d_t last_fsuid =
7f20: 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69 66   -1;..        if
7f30: 20 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20   (objc != 1) {. 
7f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
7f50: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
7f60: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
7f70: 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20   NULL);.        
7f80: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54          return(T
7f90: 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 20  CL_ERROR);.     
7fa0: 20 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61     }...fsuid = a
7fb0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
7fc0: 3b 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d 3d  ;...if (fsuid ==
7fd0: 20 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20 6c   last_fsuid && l
7fe0: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ast_homedir_obj 
7ff0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d  != NULL) {...hom
8000: 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f  edir_obj = last_
8010: 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 7d 20  homedir_obj;..} 
8020: 65 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64 69 72  else {...homedir
8030: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d   = appfs_get_hom
8040: 65 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f 66  edir(appfs_get_f
8050: 73 75 69 64 28 29 29 3b 0a 0a 09 09 69 66 20 28  suid());....if (
8060: 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c 29  homedir == NULL)
8070: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 54 43 4c   {....return(TCL
8080: 5f 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a 09 09  _ERROR);...}....
8090: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 54 63  homedir_obj = Tc
80a0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 68  l_NewStringObj(h
80b0: 6f 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a 09 09  omedir, -1);....
80c0: 66 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a 0a  free(homedir);..
80d0: 09 09 69 66 20 28 6c 61 73 74 5f 68 6f 6d 65 64  ..if (last_homed
80e0: 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20  ir_obj != NULL) 
80f0: 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66  {....Tcl_DecrRef
8100: 43 6f 75 6e 74 28 6c 61 73 74 5f 68 6f 6d 65 64  Count(last_homed
8110: 69 72 5f 6f 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09  ir_obj);...}....
8120: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
8130: 20 3d 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a   = homedir_obj;.
8140: 09 09 6c 61 73 74 5f 66 73 75 69 64 20 3d 20 66  ..last_fsuid = f
8150: 73 75 69 64 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63  suid;....Tcl_Inc
8160: 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68  rRefCount(last_h
8170: 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a  omedir_obj);..}.
8180: 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74  .       .Tcl_Set
8190: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
81a0: 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  , homedir_obj);.
81b0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28  .        return(
81c0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
81d0: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
81e0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
81f0: 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44 61  s_enter(ClientDa
8200: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
8210: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
8220: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
8230: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61  NST objv[]) {..a
8240: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
8250: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
8260: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
8270: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
8280: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
8290: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
82a0: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
82b0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
82c0: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
82d0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
82e0: 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d  []) {..appfs_sim
82f0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
8300: 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ave();...return(
8310: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
8320: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
8330: 5f 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65 6e  _get_fsuid(Clien
8340: 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e  tData cd, Tcl_In
8350: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
8360: 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20  t objc, Tcl_Obj 
8370: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b  *CONST objv[]) {
8380: 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a  ..uid_t fsuid;..
8390: 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67  .fsuid = appfs_g
83a0: 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20 20  et_fsuid();..   
83b0: 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52      .Tcl_SetObjR
83c0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63  esult(interp, Tc
83d0: 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28  l_NewWideIntObj(
83e0: 66 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75 72  fsuid));...retur
83f0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
8400: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
8410: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c 69  fs_get_fsgid(Cli
8420: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
8430: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
8440: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
8450: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
8460: 20 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64 3b   {..gid_t fsgid;
8470: 0a 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66 73  ...fsgid = appfs
8480: 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20  _get_fsgid();.. 
8490: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
84a0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
84b0: 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62  Tcl_NewWideIntOb
84c0: 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65 74  j(fsgid));...ret
84d0: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
84e0: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
84f0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
8500: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 43  fo_cache_flush(C
8510: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
8520: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
8530: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
8540: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
8550: 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ]) {..int tcl_re
8560: 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65  t;..int new_size
8570: 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d  ;...new_size = -
8580: 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d  1;...if (objc ==
8590: 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20   2) {...tcl_ret 
85a0: 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d  = Tcl_GetIntFrom
85b0: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
85c0: 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b  [1], &new_size);
85d0: 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ...if (tcl_ret !
85e0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72  = TCL_OK) {....r
85f0: 65 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a  eturn(tcl_ret);.
8600: 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20 28  ..}..} else if (
8610: 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63  objc > 2 || objc
8620: 20 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20   < 1) {.        
8630: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
8640: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
8650: 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f   1, objv, "?new_
8660: 63 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09  cache_size?");..
8670: 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f  .return(TCL_ERRO
8680: 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67  R);..}...appfs_g
8690: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
86a0: 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77  he_flush(-1, new
86b0: 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e  _size);...return
86c0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
86d0: 74 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f 49  tic int Appfsd_I
86e0: 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  nit(Tcl_Interp *
86f0: 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65 66  interp) {.#ifdef
8700: 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09   USE_TCL_STUBS..
8710: 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75 62  if (Tcl_InitStub
8720: 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45  s(interp, TCL_VE
8730: 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29  RSION, 0) == 0L)
8740: 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f   {...return(TCL_
8750: 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69  ERROR);..}.#endi
8760: 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  f...Tcl_CreateOb
8770: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
8780: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f   "appfsd::get_ho
8790: 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70 66  medir", tcl_appf
87a0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e  s_get_homedir, N
87b0: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
87c0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
87d0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
87e0: 64 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c 20 74  d::get_fsuid", t
87f0: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75  cl_appfs_get_fsu
8800: 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  id, NULL, NULL);
8810: 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43  ..Tcl_CreateObjC
8820: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
8830: 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67 69  appfsd::get_fsgi
8840: 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  d", tcl_appfs_ge
8850: 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e  t_fsgid, NULL, N
8860: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
8870: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
8880: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d  rp, "appfsd::sim
8890: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
88a0: 74 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ter", tcl_appfs_
88b0: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
88c0: 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55  _enter, NULL, NU
88d0: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
88e0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
88f0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75  p, "appfsd::simu
8900: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
8910: 76 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73  ve", tcl_appfs_s
8920: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
8930: 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  leave, NULL, NUL
8940: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
8950: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
8960: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 70  , "appfsd::get_p
8970: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
8980: 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66 73  lush", tcl_appfs
8990: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
89a0: 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c  ache_flush, NULL
89b0: 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50  , NULL);...Tcl_P
89c0: 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70  kgProvide(interp
89d0: 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30  , "appfsd", "1.0
89e0: 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c  ");...return(TCL
89f0: 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 48  _OK);.}../*. * H
8a00: 6f 74 2d 72 65 73 74 61 72 74 20 73 75 70 70 6f  ot-restart suppo
8a10: 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61  rt. */./* Initia
8a20: 74 65 20 61 20 68 6f 74 2d 72 65 73 74 61 72 74  te a hot-restart
8a30: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
8a40: 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72  appfs_hot_restar
8a50: 74 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53  t(void) {..APPFS
8a60: 5f 44 45 42 55 47 28 22 41 73 6b 65 64 20 74 6f  _DEBUG("Asked to
8a70: 20 69 6e 69 74 69 61 74 65 20 68 6f 74 20 72 65   initiate hot re
8a80: 73 74 61 72 74 22 29 3b 0a 0a 09 61 70 70 66 73  start");...appfs
8a90: 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70  _tcl_ResetInterp
8aa0: 73 28 29 3b 0a 09 61 70 70 66 73 5f 67 65 74 5f  s();..appfs_get_
8ab0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
8ac0: 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a  flush(-1, -1);..
8ad0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
8ae0: 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72  * Signal handler
8af0: 0a 20 2a 20 20 20 20 20 20 20 20 20 53 49 47 48  . *         SIGH
8b00: 55 50 20 69 6e 69 74 69 61 74 65 73 20 61 20 68  UP initiates a h
8b10: 6f 74 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73  ot restart. */.s
8b20: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
8b30: 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 28  _signal_handler(
8b40: 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a 20 44  int sig) {../* D
8b50: 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73 69 67  o not handle sig
8b60: 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55 53 45 20  nals until FUSE 
8b70: 68 61 73 20 62 65 65 6e 20 73 74 61 72 74 65 64  has been started
8b80: 20 2a 2f 0a 09 69 66 20 28 21 61 70 70 66 73 5f   */..if (!appfs_
8b90: 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a  fuse_started) {.
8ba0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f  ..return;..}.../
8bb0: 2a 20 52 65 71 75 65 73 74 20 74 6f 20 70 65 72  * Request to per
8bc0: 66 6f 72 6d 20 61 20 22 68 6f 74 22 20 72 65 73  form a "hot" res
8bd0: 74 61 72 74 20 2a 2f 0a 09 69 66 20 28 73 69 67  tart */..if (sig
8be0: 20 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a 09 09   == SIGHUP) {...
8bf0: 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72  appfs_hot_restar
8c00: 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  t();..}...return
8c10: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72 6d 69  ;.}../*. * Termi
8c20: 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a 20 2a  nate a thread. *
8c30: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
8c40: 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e  pfs_terminate_in
8c50: 74 65 72 70 28 76 6f 69 64 20 2a 5f 69 6e 74 65  terp(void *_inte
8c60: 72 70 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  rp) {..Tcl_Inter
8c70: 70 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50  p *interp;...APP
8c80: 46 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 65 64  FS_DEBUG("Called
8c90: 3a 20 5f 69 6e 74 65 72 70 20 3d 20 25 70 22 2c  : _interp = %p",
8ca0: 20 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20   _interp);...if 
8cb0: 28 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c  (_interp == NULL
8cc0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
8cd0: 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 74  G("Terminating t
8ce0: 68 72 65 61 64 20 77 69 74 68 20 6e 6f 20 69 6e  hread with no in
8cf0: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09  terpreter");....
8d00: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74  return;..}...int
8d10: 65 72 70 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a  erp = _interp;..
8d20: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
8d30: 72 6d 69 6e 61 74 69 6e 67 20 69 6e 74 65 72 70  rminating interp
8d40: 72 65 74 65 72 20 64 75 65 20 74 6f 20 74 68 72  reter due to thr
8d50: 65 61 64 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22  ead termination"
8d60: 29 3b 0a 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49  );...Tcl_DeleteI
8d70: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
8d80: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
8d90: 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e  * FUSE operation
8da0: 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a  s structure. */.
8db0: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75  static struct fu
8dc0: 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70  se_operations ap
8dd0: 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d  pfs_operations =
8de0: 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d   {...getattr   =
8df0: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
8e00: 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20  ttr,...readdir  
8e10: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65   = appfs_fuse_re
8e20: 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e  addir,...readlin
8e30: 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f  k  = appfs_fuse_
8e40: 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e  readlink,...open
8e50: 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75        = appfs_fu
8e60: 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61  se_open,...relea
8e70: 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  se   = appfs_fus
8e80: 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20  e_close,...read 
8e90: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
8ea0: 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20  e_read,...write 
8eb0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
8ec0: 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20  _write,...mknod 
8ed0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
8ee0: 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65  _mknod,...create
8ef0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
8f00: 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63  _create,...trunc
8f10: 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ate  = appfs_fus
8f20: 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e  e_truncate,...un
8f30: 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f  link    = appfs_
8f40: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
8f50: 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d  r,...rmdir     =
8f60: 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69   appfs_fuse_unli
8f70: 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69  nk_rmdir,...mkdi
8f80: 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  r     = appfs_fu
8f90: 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f  se_mkdir,...chmo
8fa0: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
8fb0: 73 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a 2f 2a  se_chmod,.};../*
8fc0: 0a 20 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20  . * FUSE option 
8fd0: 70 61 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b  parsing callback
8fe0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
8ff0: 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63  appfs_fuse_opt_c
9000: 62 28 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f  b(void *data, co
9010: 6e 73 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69  nst char *arg, i
9020: 6e 74 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66  nt key, struct f
9030: 75 73 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67  use_args *outarg
9040: 73 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e 74  s) {..static int
9050: 20 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d   seen_cachedir =
9060: 20 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20 3d 3d   0;...if (key ==
9070: 20 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f 4e 4f   FUSE_OPT_KEY_NO
9080: 4e 4f 50 54 20 26 26 20 73 65 65 6e 5f 63 61 63  NOPT && seen_cac
9090: 68 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a 09 09  hedir == 0) {...
90a0: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20  seen_cachedir = 
90b0: 31 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 63 68  1;....appfs_cach
90c0: 65 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72  edir = strdup(ar
90d0: 67 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  g);....return(0)
90e0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 31 29  ;..}...return(1)
90f0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79  ;.}../*. * Entry
9100: 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68 69 73   point into this
9110: 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e   program.. */.in
9120: 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c  t main(int argc,
9130: 20 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a   char **argv) {.
9140: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73  .Tcl_Interp *tes
9150: 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20  t_interp;..char 
9160: 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72  *test_interp_err
9170: 6f 72 3b 0a 09 73 74 72 75 63 74 20 66 75 73 65  or;..struct fuse
9180: 5f 61 72 67 73 20 61 72 67 73 20 3d 20 46 55 53  _args args = FUS
9190: 45 5f 41 52 47 53 5f 49 4e 49 54 28 61 72 67 63  E_ARGS_INIT(argc
91a0: 2c 20 61 72 67 76 29 3b 0a 09 69 6e 74 20 70 74  , argv);..int pt
91b0: 68 72 65 61 64 5f 72 65 74 3b 0a 09 76 6f 69 64  hread_ret;..void
91c0: 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09   *signal_ret;...
91d0: 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73  /*.. * Skip pass
91e0: 65 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a  ed program name.
91f0: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
9200: 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e  = 0 || argv == N
9210: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
9220: 31 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a  1);..}..argc--;.
9230: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20  .argv++;.../*.. 
9240: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
9250: 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68  iables, these sh
9260: 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72  ould be configur
9270: 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09  ation options...
9280: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65   */..appfs_cache
9290: 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48  dir = APPFS_CACH
92a0: 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  EDIR;.../*.. * S
92b0: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  et global variab
92c0: 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d  le for "boot tim
92d0: 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65  e" to set a time
92e0: 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a   on directories.
92f0: 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65  . * that we fake
9300: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f  ... */..appfs_bo
9310: 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55  ottime = time(NU
9320: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65  LL);.../*.. * Re
9330: 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e  gister "sha1" an
9340: 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61  d "appfsd" packa
9350: 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73  ge with libtcl s
9360: 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09  o that any new..
9370: 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20   * interpreters 
9380: 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61  created (which a
9390: 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61  re done dynamica
93a0: 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e  lly by FUSE) can
93b0: 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70   have.. * the ap
93c0: 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67  propriate config
93d0: 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74  uration done aut
93e0: 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f  omatically... */
93f0: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b  ..Tcl_StaticPack
9400: 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22  age(NULL, "sha1"
9410: 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c  , Sha1_Init, NUL
9420: 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50  L);..Tcl_StaticP
9430: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70  ackage(NULL, "ap
9440: 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e  pfsd", Appfsd_In
9450: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a  it, NULL);.../*.
9460: 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72  . * Create a thr
9470: 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74  ead-specific-dat
9480: 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20  a (TSD) key for 
9490: 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72  each thread to r
94a0: 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20  efer.. * to its 
94b0: 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65  own Tcl interpre
94c0: 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70  ter.  Tcl interp
94d0: 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75  reters must be u
94e0: 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68  nique per.. * th
94f0: 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72  read and new thr
9500: 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63  eads are dynamic
9510: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20  ally created by 
9520: 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72  FUSE... */..pthr
9530: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
9540: 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e  d_key_create(&in
9550: 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74  terpKey, appfs_t
9560: 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 29  erminate_interp)
9570: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
9580: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72  et != 0) {...fpr
9590: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
95a0: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54  able to create T
95b0: 53 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20  SD key for Tcl. 
95c0: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
95d0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
95e0: 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c  .../*.. * Manual
95f0: 6c 79 20 73 70 65 63 69 66 79 20 63 61 63 68 65  ly specify cache
9600: 20 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68   directory, with
9610: 6f 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63  out FUSE callbac
9620: 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f  k.. * This optio
9630: 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65  n only works whe
9640: 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45  n not using FUSE
9650: 2c 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64  , since we.. * d
9660: 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74  o not process it
9670: 20 77 69 74 68 20 46 55 53 45 73 20 6f 70 74 69   with FUSEs opti
9680: 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09  on processing...
9690: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d   */..if (argc >=
96a0: 20 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63   2) {...if (strc
96b0: 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63  mp(argv[0], "--c
96c0: 61 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20  achedir") == 0) 
96d0: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68 65  {....appfs_cache
96e0: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
96f0: 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20  v[1]);.....argc 
9700: 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d  -= 2;....argv +=
9710: 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a   2;...}..}.../*.
9720: 09 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65  . * SQLite3 mode
9730: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
9740: 77 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68  w SQL against th
9750: 65 20 63 61 63 68 65 20 64 61 74 61 62 61 73 65  e cache database
9760: 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20  .. */..if (argc 
9770: 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61  == 2 && strcmp(a
9780: 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74  rgv[0], "--sqlit
9790: 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72  e3") == 0) {...r
97a0: 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69  eturn(appfs_sqli
97b0: 74 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  te3(argv[1]));..
97c0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d  }.../*.. * Tcl m
97d0: 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67  ode, for running
97e0: 20 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20   raw Tcl in the 
97f0: 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  same environment
9800: 20 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20   AppFSd would.. 
9810: 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f  * run code... */
9820: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20  ..if (argc == 2 
9830: 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30  && strcmp(argv[0
9840: 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30  ], "--tcl") == 0
9850: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70  ) {...return(app
9860: 66 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29  fs_tcl(argv[1]))
9870: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72  ;..}.../*.. * Cr
9880: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
9890: 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76  preter just to v
98a0: 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67  erify that thing
98b0: 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67  s are in working
98c0: 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f   .. * order befo
98d0: 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64  re we become a d
98e0: 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73  aemon... */..tes
98f0: 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  t_interp = appfs
9900: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
9910: 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  p(&test_interp_e
9920: 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74  rror);..if (test
9930: 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  _interp == NULL)
9940: 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e   {...if (test_in
9950: 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55  terp_error == NU
9960: 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e  LL) {....test_in
9970: 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e  terp_error = "Un
9980: 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09  known error";...
9990: 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  }....fprintf(std
99a0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
99b0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69  initialize Tcl i
99c0: 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41  nterpreter for A
99d0: 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70  ppFSd:\n");...fp
99e0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
99f0: 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72  s\n", test_inter
9a00: 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74  p_error);....ret
9a10: 75 72 6e 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f  urn(1);..}..Tcl_
9a20: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73  DeleteInterp(tes
9a30: 74 5f 69 6e 74 65 72 70 29 3b 0a 09 54 63 6c 5f  t_interp);..Tcl_
9a40: 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72  FinalizeNotifier
9a50: 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  (NULL);.../*.. *
9a60: 20 52 65 67 69 73 74 65 72 20 61 20 73 69 67 6e   Register a sign
9a70: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
9a80: 6f 74 2d 72 65 73 74 61 72 74 20 72 65 71 75 65  ot-restart reque
9a90: 73 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c  sts.. */..signal
9aa0: 5f 72 65 74 20 3d 20 73 69 67 6e 61 6c 28 53 49  _ret = signal(SI
9ab0: 47 48 55 50 2c 20 61 70 70 66 73 5f 73 69 67 6e  GHUP, appfs_sign
9ac0: 61 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66  al_handler);..if
9ad0: 20 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20   (signal_ret == 
9ae0: 53 49 47 5f 45 52 52 29 20 7b 0a 09 09 66 70 72  SIG_ERR) {...fpr
9af0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
9b00: 61 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c 6c 20  able to install 
9b10: 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66  signal handler f
9b20: 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74 5c 6e  or hot-restart\n
9b30: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ");...fprintf(st
9b40: 64 65 72 72 2c 20 22 48 6f 74 2d 72 65 73 74 61  derr, "Hot-resta
9b50: 72 74 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20 61  rt will not be a
9b60: 76 61 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09  vailable.\n");..
9b70: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 41 64 64 20 46  }.../*.. * Add F
9b80: 55 53 45 20 61 72 67 75 6d 65 6e 74 73 20 77 68  USE arguments wh
9b90: 69 63 68 20 77 65 20 61 6c 77 61 79 73 20 73 75  ich we always su
9ba0: 70 70 6c 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f  pply.. */..fuse_
9bb0: 6f 70 74 5f 70 61 72 73 65 28 26 61 72 67 73 2c  opt_parse(&args,
9bc0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 61 70 70   NULL, NULL, app
9bd0: 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62 29 3b  fs_fuse_opt_cb);
9be0: 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
9bf0: 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 64 65 66  rg(&args, "-odef
9c00: 61 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73  ault_permissions
9c10: 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75  ,fsname=appfs,su
9c20: 62 74 79 70 65 3d 61 70 70 66 73 64 2c 75 73 65  btype=appfsd,use
9c30: 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63 68  _ino,kernel_cach
9c40: 65 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d  e,entry_timeout=
9c50: 30 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30  0,attr_timeout=0
9c60: 2c 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72  ,big_writes,intr
9c70: 2c 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a  ,hard_remove");.
9c80: 0a 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d  ..if (getuid() =
9c90: 3d 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70  = 0) {...fuse_op
9ca0: 74 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e  t_parse(&args, N
9cb0: 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  ULL, NULL, NULL)
9cc0: 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ;...fuse_opt_add
9cd0: 5f 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 61  _arg(&args, "-oa
9ce0: 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 7d  llow_other");..}
9cf0: 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20  .../*.. * Enter 
9d00: 74 68 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f  the FUSE main lo
9d10: 6f 70 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20  op -- this will 
9d20: 70 72 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75  process any argu
9d30: 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74  ments.. * and st
9d40: 61 72 74 20 73 65 72 76 69 63 69 6e 67 20 72 65  art servicing re
9d50: 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70  quests... */..ap
9d60: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
9d70: 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75   = 1;..return(fu
9d80: 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67  se_main(args.arg
9d90: 63 2c 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61  c, args.argv, &a
9da0: 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c  ppfs_operations,
9db0: 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a            NULL));.}. .