Hex Artifact Content

Artifact 5e5056a24c2bbdc6a636edff0f541a5ee73fb9cc:


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 74 72 69 6e 67  #include <string
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0080: 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  darg.h>.#include
0090: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
00a0: 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a  lude <unistd.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e  #include <errno.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e  h>.#include <fcn
00d0: 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  tl.h>.#include <
00e0: 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64  stdio.h>.#includ
00f0: 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69 6e 63 6c  e <fuse.h>.#incl
0100: 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23 69 6e 63  ude <pwd.h>.#inc
0110: 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a  lude <tcl.h>../*
0120: 0a 20 2a 20 44 65 66 61 75 6c 74 20 63 61 63 68  . * Default cach
0130: 65 20 64 69 72 65 63 74 6f 72 79 0a 20 2a 2f 0a  e directory. */.
0140: 23 69 66 6e 64 65 66 20 41 50 50 46 53 5f 43 41  #ifndef APPFS_CA
0150: 43 48 45 44 49 52 0a 23 64 65 66 69 6e 65 20 41  CHEDIR.#define A
0160: 50 50 46 53 5f 43 41 43 48 45 44 49 52 20 22 2f  PPFS_CACHEDIR "/
0170: 76 61 72 2f 63 61 63 68 65 2f 61 70 70 66 73 22  var/cache/appfs"
0180: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44 65 62 75  .#endif../* Debu
0190: 67 67 69 6e 67 20 6d 61 63 72 6f 73 20 2a 2f 0a  gging macros */.
01a0: 23 69 66 64 65 66 20 44 45 42 55 47 0a 23 64 65  #ifdef DEBUG.#de
01b0: 66 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47  fine APPFS_DEBUG
01c0: 28 78 2e 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66  (x...) { fprintf
01d0: 28 73 74 64 65 72 72 2c 20 22 5b 64 65 62 75 67  (stderr, "[debug
01e0: 5d 20 25 73 3a 25 69 3a 25 73 3a 20 22 2c 20 5f  ] %s:%i:%s: ", _
01f0: 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f  _FILE__, __LINE_
0200: 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 66 70  _, __func__); fp
0210: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 29  rintf(stderr, x)
0220: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ; fprintf(stderr
0230: 2c 20 22 5c 6e 22 29 3b 20 7d 0a 23 65 6c 73 65  , "\n"); }.#else
0240: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
0250: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a  EBUG(x...) /**/.
0260: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48  #endif../*. * SH
0270: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69  A1 Tcl Package i
0280: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d  nitializer, from
0290: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20   sha1.o. */.int 
02a0: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  Sha1_Init(Tcl_In
02b0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a  terp *interp);..
02c0: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65  /*. * Thread Spe
02d0: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29  cific Data (TSD)
02e0: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72   for Tcl Interpr
02f0: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72  eter for the cur
0300: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a  rent thread. */.
0310: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b  static pthread_k
0320: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a  ey_t interpKey;.
0330: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61  ./*. * Global va
0340: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20  riables, needed 
0350: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20  for all threads 
0360: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c  but only initial
0370: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a  ized before any.
0380: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20   * FUSE threads 
0390: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a  are created. */.
03a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
03b0: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65  s_cachedir;.time
03c0: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d  _t appfs_boottim
03d0: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73  e;.int appfs_fus
03e0: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 0a  e_started = 0;..
03f0: 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72  /*. * Global var
0400: 69 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53  iables for AppFS
0410: 20 63 61 63 68 69 6e 67 0a 20 2a 2f 0a 70 74 68   caching. */.pth
0420: 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 70 70  read_mutex_t app
0430: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
0440: 68 65 5f 6d 75 74 65 78 20 3d 20 50 54 48 52 45  he_mutex = PTHRE
0450: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c  AD_MUTEX_INITIAL
0460: 49 5a 45 52 3b 0a 69 6e 74 20 61 70 70 66 73 5f  IZER;.int appfs_
0470: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
0480: 73 69 7a 65 20 3d 20 38 32 30 39 3b 0a 73 74 72  size = 8209;.str
0490: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
04a0: 66 6f 20 2a 61 70 70 66 73 5f 70 61 74 68 5f 69  fo *appfs_path_i
04b0: 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c  nfo_cache = NULL
04c0: 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50  ;../*. * AppFS P
04d0: 61 74 68 20 54 79 70 65 3a 20 20 44 65 73 63 72  ath Type:  Descr
04e0: 69 62 65 73 20 74 68 65 20 74 79 70 65 20 6f 66  ibes the type of
04f0: 20 70 61 74 68 20 61 20 67 69 76 65 6e 20 66 69   path a given fi
0500: 6c 65 20 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65  le is. */.typede
0510: 66 20 65 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f  f enum {..APPFS_
0520: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
0530: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
0540: 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54  E_DOES_NOT_EXIST
0550: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
0560: 45 5f 46 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50  E_FILE,..APPFS_P
0570: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
0580: 59 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  Y,..APPFS_PATHTY
0590: 50 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50  PE_SYMLINK,..APP
05a0: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b  FS_PATHTYPE_SOCK
05b0: 45 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54  ET,..APPFS_PATHT
05c0: 59 50 45 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66  YPE_FIFO,.} appf
05d0: 73 5f 70 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f  s_pathtype_t;../
05e0: 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68 20  *. * AppFS Path 
05f0: 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20  Information:. * 
0600: 20 20 20 20 20 20 20 20 43 6f 6d 70 6c 65 74 65          Complete
0610: 6c 79 20 64 65 73 63 72 69 62 65 73 20 61 20 73  ly describes a s
0620: 70 65 63 69 66 69 63 20 70 61 74 68 2c 20 68 6f  pecific path, ho
0630: 77 20 69 74 20 73 68 6f 75 6c 64 20 62 65 20 72  w it should be r
0640: 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20  eturned to. *   
0650: 20 20 20 20 20 20 74 6f 20 74 68 65 20 6b 65 72        to the ker
0660: 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61  nel. */.struct a
0670: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a  ppfs_pathinfo {.
0680: 09 61 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f  .appfs_pathtype_
0690: 74 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20  t type;..time_t 
06a0: 74 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73 74  time;..char host
06b0: 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20  name[256];..int 
06c0: 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67  packaged;..unsig
06d0: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e  ned long long in
06e0: 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09  ode;..union {...
06f0: 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20  struct {....int 
0700: 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20  childcount;...} 
0710: 64 69 72 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a  dir;...struct {.
0720: 09 09 09 69 6e 74 20 65 78 65 63 75 74 61 62 6c  ...int executabl
0730: 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65  e;....off_t size
0740: 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74  ;...} file;...st
0750: 72 75 63 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20  ruct {....off_t 
0760: 73 69 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 6f  size;....char so
0770: 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73  urce[256];...} s
0780: 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69  ymlink;..} typei
0790: 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74 72 69 62  nfo;.../* Attrib
07a0: 75 74 65 73 20 75 73 65 64 20 6f 6e 6c 79 20 66  utes used only f
07b0: 6f 72 20 63 61 63 68 69 6e 67 20 65 6e 74 72 69  or caching entri
07c0: 65 73 20 2a 2f 0a 09 63 68 61 72 20 2a 5f 63 61  es */..char *_ca
07d0: 63 68 65 5f 70 61 74 68 3b 0a 09 75 69 64 5f 74  che_path;..uid_t
07e0: 20 5f 63 61 63 68 65 5f 75 69 64 3b 0a 7d 3b 0a   _cache_uid;.};.
07f0: 0a 2f 2a 0a 20 2a 20 43 72 65 61 74 65 20 61 20  ./*. * Create a 
0800: 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65  new Tcl interpre
0810: 74 65 72 20 61 6e 64 20 63 6f 6d 70 6c 65 74 65  ter and complete
0820: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 74  ly initialize it
0830: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f  . */.static Tcl_
0840: 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 63 72  Interp *appfs_cr
0850: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 63  eate_TclInterp(c
0860: 68 61 72 20 2a 2a 65 72 72 6f 72 5f 73 74 72 69  har **error_stri
0870: 6e 67 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  ng) {..Tcl_Inter
0880: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20  p *interp;..int 
0890: 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  tcl_ret;...APPFS
08a0: 5f 44 45 42 55 47 28 22 43 72 65 61 74 69 6e 67  _DEBUG("Creating
08b0: 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72   new Tcl interpr
08c0: 65 74 65 72 20 66 6f 72 20 54 49 44 20 3d 20 30  eter for TID = 0
08d0: 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67 6e 65  x%llx", (unsigne
08e0: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74 68  d long long) pth
08f0: 72 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a 0a 09  read_self());...
0900: 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65  interp = Tcl_Cre
0910: 61 74 65 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  ateInterp();..if
0920: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
0930: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
0940: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
0950: 20 63 72 65 61 74 65 20 54 63 6c 20 49 6e 74 65   create Tcl Inte
0960: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69  rpreter.  Aborti
0970: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28  ng.\n");....if (
0980: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
0990: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
09a0: 20 3d 20 73 74 72 64 75 70 28 22 55 6e 61 62 6c   = strdup("Unabl
09b0: 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20  e to create Tcl 
09c0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
09d0: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  ..}....return(NU
09e0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  LL);..}...tcl_re
09f0: 74 20 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74  t = Tcl_Init(int
0a00: 65 72 70 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  erp);..if (tcl_r
0a10: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
0a20: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0a30: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
0a40: 74 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62  tialize Tcl.  Ab
0a50: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
0a60: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
0a70: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
0a80: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
0a90: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
0aa0: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
0ab0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
0ac0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
0ad0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
0ae0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
0af0: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c  ;...}....Tcl_Del
0b00: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
0b10: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
0b20: 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  L);..}...tcl_ret
0b30: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
0b40: 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e  rp, "package ifn
0b50: 65 65 64 65 64 20 73 68 61 31 20 31 2e 30 20 5b  eeded sha1 1.0 [
0b60: 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61  list load {} sha
0b70: 31 5d 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  1]");..if (tcl_r
0b80: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
0b90: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0ba0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
0bb0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 53 48 41 31  tialize Tcl SHA1
0bc0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
0bd0: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
0be0: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
0bf0: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
0c00: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0c10: 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65  terp));....if (e
0c20: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
0c30: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
0c40: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(Tcl_Get
0c50: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
0c60: 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63  erp));...}....Tc
0c70: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
0c80: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
0c90: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
0ca0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
0cb0: 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67  (interp, "packag
0cc0: 65 20 69 66 6e 65 65 64 65 64 20 61 70 70 66 73  e ifneeded appfs
0cd0: 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64  d 1.0 [list load
0ce0: 20 7b 7d 20 61 70 70 66 73 64 5d 22 29 3b 0a 09   {} appfsd]");..
0cf0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
0d00: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
0d10: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0d20: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
0d30: 20 54 63 6c 20 41 70 70 46 53 20 50 61 63 6b 61   Tcl AppFS Packa
0d40: 67 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  ge.  Aborting.\n
0d50: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ");...fprintf(st
0d60: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72  derr, "Tcl Error
0d70: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f   is: %s\n", Tcl_
0d80: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
0d90: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20  interp));....if 
0da0: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b  (error_string) {
0db0: 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e  ....*error_strin
0dc0: 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47  g = strdup(Tcl_G
0dd0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
0de0: 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09  nterp));...}....
0df0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
0e00: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74  (interp);....ret
0e10: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
0e20: 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 22 70 6b 69  /*.. * Load "pki
0e30: 2e 74 63 6c 22 20 69 6e 20 74 68 65 20 73 61 6d  .tcl" in the sam
0e40: 65 20 77 61 79 20 61 73 20 61 70 70 66 73 64 2e  e way as appfsd.
0e50: 74 63 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a  tcl (see below).
0e60: 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20  . */..tcl_ret = 
0e70: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
0e80: 20 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 6b   "".#include "pk
0e90: 69 2e 74 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09  i.tcl.h".."");..
0ea0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
0eb0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
0ec0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0ed0: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
0ee0: 20 54 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74   Tcl PKI.  Abort
0ef0: 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69  ing.\n");...fpri
0f00: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c  ntf(stderr, "Tcl
0f10: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22   Error is: %s\n"
0f20: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
0f30: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
0f40: 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72  ...if (error_str
0f50: 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72  ing) {....*error
0f60: 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70  _string = strdup
0f70: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65  (Tcl_GetStringRe
0f80: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
0f90: 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65  .}....Tcl_Delete
0fa0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a  Interp(interp);.
0fb0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
0fc0: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61  ..}.../*.. * Loa
0fd0: 64 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63  d the "appfsd.tc
0fe0: 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 63 68  l" script, which
0ff0: 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20 69   is "compiled" i
1000: 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a 09  nto a C header..
1010: 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64 6f   * so that it do
1020: 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 65  es not need to e
1030: 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c 65  xist on the file
1040: 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20 62  system and can b
1050: 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20 65  e.. * directly e
1060: 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a 09  valuated... */..
1070: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
1080: 61 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69  al(interp, "".#i
1090: 6e 63 6c 75 64 65 20 22 61 70 70 66 73 64 2e 74  nclude "appfsd.t
10a0: 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 69 66 20  cl.h".."");..if 
10b0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
10c0: 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  OK) {...fprintf(
10d0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
10e0: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63  to initialize Tc
10f0: 6c 20 41 70 70 46 53 20 73 63 72 69 70 74 2e 20  l AppFS script. 
1100: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
1110: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1120: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
1130: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
1140: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1150: 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72  rp));....if (err
1160: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
1170: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20  *error_string = 
1180: 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74  strdup(Tcl_GetSt
1190: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
11a0: 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f  p));...}....Tcl_
11b0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
11c0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
11d0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
11e0: 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61   * Set global va
11f0: 72 69 61 62 6c 65 73 20 66 72 6f 6d 20 43 20 74  riables from C t
1200: 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09 69 66 20 28  o Tcl.. */..if (
1210: 54 63 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72  Tcl_SetVar(inter
1220: 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 63 61 63  p, "::appfs::cac
1230: 68 65 64 69 72 22 2c 20 61 70 70 66 73 5f 63 61  hedir", appfs_ca
1240: 63 68 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f 42  chedir, TCL_GLOB
1250: 41 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e 55 4c 4c  AL_ONLY) == NULL
1260: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
1270: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
1280: 20 73 65 74 20 63 61 63 68 65 20 64 69 72 65 63   set cache direc
1290: 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f 75  tory.  This shou
12a0: 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c 6e  ld never fail.\n
12b0: 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72  ");....if (error
12c0: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65  _string) {....*e
12d0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
12e0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
12f0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1300: 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65  );...}....Tcl_De
1310: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
1320: 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  p);....return(NU
1330: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  LL);..}.../*.. *
1340: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
1350: 22 61 70 70 66 73 64 2e 74 63 6c 22 20 65 6e 76  "appfsd.tcl" env
1360: 69 72 6f 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20  ironment, which 
1370: 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 61 66 74  must be done aft
1380: 65 72 0a 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61  er.. * global va
1390: 72 69 61 62 6c 65 73 20 61 72 65 20 73 65 74 2e  riables are set.
13a0: 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d  .. */..tcl_ret =
13b0: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
13c0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74  , "::appfs::init
13d0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
13e0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
13f0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
1400: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
1410: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
1420: 73 63 72 69 70 74 20 28 3a 3a 61 70 70 66 73 3a  script (::appfs:
1430: 3a 69 6e 69 74 29 2e 20 20 41 62 6f 72 74 69 6e  :init).  Abortin
1440: 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74  g.\n");...fprint
1450: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
1460: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
1470: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
1480: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
1490: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
14a0: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
14b0: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
14c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
14d0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d  lt(interp));...}
14e0: 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  ....Tcl_DeleteIn
14f0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09  terp(interp);...
1500: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1510: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69 64 65 20  }.../*.. * Hide 
1520: 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d 61 6e 64  some Tcl command
1530: 73 20 74 68 61 74 20 77 65 20 64 6f 20 6e 6f 74  s that we do not
1540: 20 63 61 72 65 20 74 6f 20 75 73 65 20 61 6e 64   care to use and
1550: 20 77 68 69 63 68 20 6d 61 79 0a 09 20 2a 20 73   which may.. * s
1560: 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d 74 69 6d  low down run-tim
1570: 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 09 20  e operations... 
1580: 2a 2f 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d  */..Tcl_HideComm
1590: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74  and(interp, "aut
15a0: 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22  o_load_index", "
15b0: 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22  auto_load_index"
15c0: 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d  );..Tcl_HideComm
15d0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b  and(interp, "unk
15e0: 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22  nown", "unknown"
15f0: 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 74 75  );.../*.. * Retu
1600: 72 6e 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 6c  rn the completel
1610: 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 69 6e  y initialized in
1620: 74 65 72 70 72 65 74 65 72 0a 09 20 2a 2f 0a 09  terpreter.. */..
1630: 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a  return(interp);.
1640: 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 74 75 72 6e 20  }../*. * Return 
1650: 74 68 65 20 74 68 72 65 61 64 2d 73 70 65 63 69  the thread-speci
1660: 66 69 63 20 54 63 6c 20 69 6e 74 65 72 70 72 65  fic Tcl interpre
1670: 74 65 72 2c 20 63 72 65 61 74 69 6e 67 20 69 74  ter, creating it
1680: 20 69 66 20 6e 65 65 64 65 64 0a 20 2a 2f 0a 73   if needed. */.s
1690: 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70  tatic Tcl_Interp
16a0: 20 2a 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72   *appfs_TclInter
16b0: 70 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f 49  p(void) {..Tcl_I
16c0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
16d0: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
16e0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72  ...interp = pthr
16f0: 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28  ead_getspecific(
1700: 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20  interpKey);..if 
1710: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
1720: 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70   {...interp = ap
1730: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
1740: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69  terp(NULL);....i
1750: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
1760: 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e  L) {....return(N
1770: 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68  ULL);...}....pth
1780: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
1790: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 69  ad_setspecific(i
17a0: 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70  nterpKey, interp
17b0: 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61 64  );...if (pthread
17c0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09  _ret != 0) {....
17d0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
17e0: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 09 72 65  (interp);.....re
17f0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a  turn(NULL);...}.
1800: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65  .}...return(inte
1810: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76  rp);.}../*. * Ev
1820: 61 6c 75 61 74 65 20 61 20 54 63 6c 20 73 63 72  aluate a Tcl scr
1830: 69 70 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20  ipt constructed 
1840: 62 79 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67  by concatenating
1850: 20 61 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74   a bunch of C st
1860: 72 69 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65  rings. * togethe
1870: 72 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  r.. */.static in
1880: 74 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  t appfs_Tcl_Eval
1890: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
18a0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63  erp, int objc, c
18b0: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20  onst char *cmd, 
18c0: 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20  ...) {..Tcl_Obj 
18d0: 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63  **objv;..const c
18e0: 68 61 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69  har *arg;..va_li
18f0: 73 74 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65  st argp;..int re
1900: 74 76 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09  tval;..int i;...
1910: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
1920: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54  LL) {...return(T
1930: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
1940: 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20  objv = (void *) 
1950: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a  ckalloc(sizeof(*
1960: 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 09  objv) * objc);..
1970: 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65  objv[0] = Tcl_Ne
1980: 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20  wStringObj(cmd, 
1990: 2d 31 29 3b 0a 09 54 63 6c 5f 49 6e 63 72 52 65  -1);..Tcl_IncrRe
19a0: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b  fCount(objv[0]);
19b0: 0a 0a 09 76 61 5f 73 74 61 72 74 28 61 72 67 70  ...va_start(argp
19c0: 2c 20 63 6d 64 29 3b 0a 09 66 6f 72 20 28 69 20  , cmd);..for (i 
19d0: 3d 20 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69  = 1; i < objc; i
19e0: 2b 2b 29 20 7b 0a 09 09 61 72 67 20 3d 20 76 61  ++) {...arg = va
19f0: 5f 61 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74  _arg(argp, const
1a00: 20 63 68 61 72 20 2a 29 3b 0a 09 09 6f 62 6a 76   char *);...objv
1a10: 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72  [i] = Tcl_NewStr
1a20: 69 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b  ingObj(arg, -1);
1a30: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
1a40: 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d  unt(objv[i]);..}
1a50: 0a 09 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a  ..va_end(argp);.
1a60: 0a 09 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45  ..retval = Tcl_E
1a70: 76 61 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20  valObjv(interp, 
1a80: 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a  objc, objv, 0);.
1a90: 0a 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20  ..for (i = 0; i 
1aa0: 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09  < objc; i++) {..
1ab0: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e  .Tcl_DecrRefCoun
1ac0: 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 0a  t(objv[i]);..}..
1ad0: 09 63 6b 66 72 65 65 28 28 76 6f 69 64 20 2a 29  .ckfree((void *)
1ae0: 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65   objv);...if (re
1af0: 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  tval != TCL_OK) 
1b00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
1b10: 22 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69  "Tcl command fai
1b20: 6c 65 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f  led, ::errorInfo
1b30: 20 63 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22   contains: %s\n"
1b40: 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  , Tcl_GetVar(int
1b50: 65 72 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66  erp, "::errorInf
1b60: 6f 22 2c 20 30 29 29 3b 0a 09 7d 0a 0a 09 72 65  o", 0));..}...re
1b70: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
1b80: 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65  ./*. * Determine
1b90: 20 74 68 65 20 55 49 44 20 66 6f 72 20 74 68 65   the UID for the
1ba0: 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65   user making the
1bb0: 20 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69   current FUSE fi
1bc0: 6c 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74  lesystem request
1bd0: 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62  .. * This will b
1be0: 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70  e used to lookup
1bf0: 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65   the user's home
1c00: 20 64 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65   directory so we
1c10: 20 63 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a   can search for.
1c20: 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66   * locally modif
1c30: 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73  ied files.. */.s
1c40: 74 61 74 69 63 20 75 69 64 5f 74 20 61 70 70 66  tatic uid_t appf
1c50: 73 5f 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64  s_get_fsuid(void
1c60: 29 20 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65  ) {..struct fuse
1c70: 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a  _context *ctx;..
1c80: 09 69 66 20 28 21 61 70 70 66 73 5f 66 75 73 65  .if (!appfs_fuse
1c90: 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65  _started) {...re
1ca0: 74 75 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a  turn(getuid());.
1cb0: 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f  .}...ctx = fuse_
1cc0: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09  get_context();..
1cd0: 69 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29  if (ctx == NULL)
1ce0: 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74   {.../* Unable t
1cf0: 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f  o lookup user fo
1d00: 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f  r some reason */
1d10: 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20  .../* Return an 
1d20: 75 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65  unprivileged use
1d30: 72 20 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e  r ID */...return
1d40: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (1);..}...return
1d50: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f  (ctx->uid);.}../
1d60: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74  *. * Determine t
1d70: 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75  he GID for the u
1d80: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63  ser making the c
1d90: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65  urrent FUSE file
1da0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a  system request..
1db0: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20   * This will be 
1dc0: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74  used to lookup t
1dd0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
1de0: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63  irectory so we c
1df0: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a  an search for. *
1e00: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65   locally modifie
1e10: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61  d files.. */.sta
1e20: 74 69 63 20 67 69 64 5f 74 20 61 70 70 66 73 5f  tic gid_t appfs_
1e30: 67 65 74 5f 66 73 67 69 64 28 76 6f 69 64 29 20  get_fsgid(void) 
1e40: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63  {..struct fuse_c
1e50: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69  ontext *ctx;...i
1e60: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73  f (!appfs_fuse_s
1e70: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75  tarted) {...retu
1e80: 72 6e 28 67 65 74 67 69 64 28 29 29 3b 0a 09 7d  rn(getgid());..}
1e90: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65  ...ctx = fuse_ge
1ea0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66  t_context();..if
1eb0: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (ctx == NULL) {
1ec0: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20  .../* Unable to 
1ed0: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20  lookup user for 
1ee0: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09  some reason */..
1ef0: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e  ./* Return an un
1f00: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20  privileged user 
1f10: 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e 28 31  ID */...return(1
1f20: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63  );..}...return(c
1f30: 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a 0a 73 74 61  tx->gid);.}..sta
1f40: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73  tic void appfs_s
1f50: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
1f60: 65 6e 74 65 72 28 76 6f 69 64 29 20 7b 0a 09 73  enter(void) {..s
1f70: 65 74 66 73 75 69 64 28 61 70 70 66 73 5f 67 65  etfsuid(appfs_ge
1f80: 74 5f 66 73 75 69 64 28 29 29 3b 0a 09 73 65 74  t_fsuid());..set
1f90: 66 73 67 69 64 28 61 70 70 66 73 5f 67 65 74 5f  fsgid(appfs_get_
1fa0: 66 73 67 69 64 28 29 29 3b 0a 7d 0a 0a 73 74 61  fsgid());.}..sta
1fb0: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73  tic void appfs_s
1fc0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
1fd0: 6c 65 61 76 65 28 76 6f 69 64 29 20 7b 0a 09 73  leave(void) {..s
1fe0: 65 74 66 73 75 69 64 28 30 29 3b 0a 09 73 65 74  etfsuid(0);..set
1ff0: 66 73 67 69 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a  fsgid(0);.}../*.
2000: 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 68 65 20 68   * Look up the h
2010: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 66 6f  ome directory fo
2020: 72 20 61 20 67 69 76 65 6e 20 55 49 44 0a 20 2a  r a given UID. *
2030: 20 20 20 20 20 20 20 20 52 65 74 75 72 6e 73 20          Returns 
2040: 61 20 43 20 73 74 72 69 6e 67 20 63 6f 6e 74 61  a C string conta
2050: 69 6e 69 6e 67 20 74 68 65 20 75 73 65 72 27 73  ining the user's
2060: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20   home directory 
2070: 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 2a 20 20 20  or NULL if. *   
2080: 20 20 20 20 20 74 68 65 20 75 73 65 72 27 73 20       the user's 
2090: 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 64  home directory d
20a0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 6f 72  oes not exist or
20b0: 20 69 73 20 6e 6f 74 20 63 6f 72 72 65 63 74 6c   is not correctl
20c0: 79 0a 20 2a 20 20 20 20 20 20 20 20 63 6f 6e 66  y. *        conf
20d0: 69 67 75 72 65 64 0a 20 2a 2f 0a 73 74 61 74 69  igured. */.stati
20e0: 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 67 65  c char *appfs_ge
20f0: 74 5f 68 6f 6d 65 64 69 72 28 75 69 64 5f 74 20  t_homedir(uid_t 
2100: 66 73 75 69 64 29 20 7b 0a 09 73 74 72 75 63 74  fsuid) {..struct
2110: 20 70 61 73 73 77 64 20 65 6e 74 72 79 2c 20 2a   passwd entry, *
2120: 72 65 73 75 6c 74 3b 0a 09 73 74 72 75 63 74 20  result;..struct 
2130: 73 74 61 74 20 73 74 62 75 66 3b 0a 09 63 68 61  stat stbuf;..cha
2140: 72 20 62 75 66 5b 31 30 32 34 5d 2c 20 2a 72 65  r buf[1024], *re
2150: 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70 75 5f 72  tval;..int gpu_r
2160: 65 74 2c 20 73 74 61 74 5f 72 65 74 3b 0a 0a 09  et, stat_ret;...
2170: 67 70 75 5f 72 65 74 20 3d 20 67 65 74 70 77 75  gpu_ret = getpwu
2180: 69 64 5f 72 28 66 73 75 69 64 2c 20 26 65 6e 74  id_r(fsuid, &ent
2190: 72 79 2c 20 62 75 66 2c 20 73 69 7a 65 6f 66 28  ry, buf, sizeof(
21a0: 62 75 66 29 2c 20 26 72 65 73 75 6c 74 29 3b 0a  buf), &result);.
21b0: 09 69 66 20 28 67 70 75 5f 72 65 74 20 21 3d 20  .if (gpu_ret != 
21c0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
21d0: 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28 25  UG("getpwuid_r(%
21e0: 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e  llu, ...) return
21f0: 65 64 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20  ed in failure", 
2200: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
2210: 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09  ong) fsuid);....
2220: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
2230: 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 20 3d 3d  ...if (result ==
2240: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
2250: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64  _DEBUG("getpwuid
2260: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65  _r(%llu, ...) re
2270: 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72 65 73 75  turned NULL resu
2280: 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c  lt", (unsigned l
2290: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29  ong long) fsuid)
22a0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
22b0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75  );..}...if (resu
22c0: 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d 20 4e 55  lt->pw_dir == NU
22d0: 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  LL) {...APPFS_DE
22e0: 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28  BUG("getpwuid_r(
22f0: 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72  %llu, ...) retur
2300: 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65 20 64 69  ned NULL home di
2310: 72 65 63 74 6f 72 79 22 2c 20 28 75 6e 73 69 67  rectory", (unsig
2320: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
2330: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
2340: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61  (NULL);..}...sta
2350: 74 5f 72 65 74 20 3d 20 73 74 61 74 28 72 65 73  t_ret = stat(res
2360: 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20 26 73 74  ult->pw_dir, &st
2370: 62 75 66 29 3b 0a 09 69 66 20 28 73 74 61 74 5f  buf);..if (stat_
2380: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
2390: 50 46 53 5f 44 45 42 55 47 28 22 73 74 61 74 28  PFS_DEBUG("stat(
23a0: 25 73 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20  %s) returned in 
23b0: 66 61 69 6c 75 72 65 22 2c 20 72 65 73 75 6c 74  failure", result
23c0: 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 09 72 65  ->pw_dir);....re
23d0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
23e0: 09 69 66 20 28 73 74 62 75 66 2e 73 74 5f 75 69  .if (stbuf.st_ui
23f0: 64 20 21 3d 20 66 73 75 69 64 29 20 7b 0a 09 09  d != fsuid) {...
2400: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 49 44  APPFS_DEBUG("UID
2410: 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e 20 75 73   mis-match on us
2420: 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d 65 20 64  er %llu's home d
2430: 69 72 65 63 74 6f 72 79 20 28 25 73 29 2e 20 20  irectory (%s).  
2440: 49 74 27 73 20 6f 77 6e 65 64 20 62 79 20 25 6c  It's owned by %l
2450: 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28 75 6e 73  lu.",...    (uns
2460: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
2470: 20 66 73 75 69 64 2c 0a 09 09 20 20 20 20 72 65   fsuid,...    re
2480: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 0a 09 09  sult->pw_dir,...
2490: 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f      (unsigned lo
24a0: 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75 66 2e 73  ng long) stbuf.s
24b0: 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09 09 72 65  t_uid...);....re
24c0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
24d0: 09 72 65 74 76 61 6c 20 3d 20 73 74 72 64 75 70  .retval = strdup
24e0: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29  (result->pw_dir)
24f0: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  ;...return(retva
2500: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e  l);.}../*. * Gen
2510: 65 72 61 74 65 20 61 6e 20 69 6e 6f 64 65 20 66  erate an inode f
2520: 6f 72 20 61 20 67 69 76 65 6e 20 70 61 74 68 2e  or a given path.
2530: 20 20 54 68 65 20 69 6e 6f 64 65 20 73 68 6f 75    The inode shou
2540: 6c 64 20 62 65 20 63 6f 6d 70 75 74 65 64 20 69  ld be computed i
2550: 6e 20 73 75 63 68 0a 20 2a 20 61 20 77 61 79 20  n such. * a way 
2560: 74 68 61 74 20 69 74 20 69 73 20 75 6e 6c 69 6b  that it is unlik
2570: 65 6c 79 20 74 6f 20 62 65 20 64 75 70 6c 69 63  ely to be duplic
2580: 61 74 65 64 20 61 6e 64 20 72 65 6d 61 69 6e 73  ated and remains
2590: 20 74 68 65 20 73 61 6d 65 20 66 6f 72 20 61 20   the same for a 
25a0: 67 69 76 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a  given. * file. *
25b0: 2f 0a 73 74 61 74 69 63 20 6c 6f 6e 67 20 6c 6f  /.static long lo
25c0: 6e 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ng appfs_get_pat
25d0: 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68  h_inode(const ch
25e0: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 6c 6f 6e  ar *path) {..lon
25f0: 67 20 6c 6f 6e 67 20 72 65 74 76 61 6c 3b 0a 09  g long retval;..
2600: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a  const char *p;..
2610: 09 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09  .retval = 10;...
2620: 66 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a  for (p = path; *
2630: 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76  p; p++) {...retv
2640: 61 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30  al %= 4290960290
2650: 55 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d  ULL;...retval +=
2660: 20 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c   *p;...retval <<
2670: 3d 20 37 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  = 7;..}...retval
2680: 20 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20   += 10;..retval 
2690: 25 3d 20 34 32 39 34 39 36 37 32 39 36 55 4c 4c  %= 4294967296ULL
26a0: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  ;...return(retva
26b0: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63  l);.}../*. * Cac
26c0: 68 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f  he Get Path Info
26d0: 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65   lookups for spe
26e0: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed. */.static in
26f0: 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  t appfs_get_path
2700: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28  _info_cache_get(
2710: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
2720: 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72  , uid_t uid, str
2730: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
2740: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a  fo *pathinfo) {.
2750: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61  .unsigned int ha
2760: 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  sh_idx;..int pth
2770: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72  read_ret;..int r
2780: 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20  etval;...retval 
2790: 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72  = 1;...pthread_r
27a0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
27b0: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  ex_lock(&appfs_p
27c0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
27d0: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
27e0: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
27f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
2800: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61  nable to lock pa
2810: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
2820: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
2830: 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20  rn(-1);..}...if 
2840: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
2850: 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20  _cache != NULL) 
2860: 7b 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28  {...hash_idx = (
2870: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
2880: 6e 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64  node(path) + uid
2890: 29 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69  ) % appfs_path_i
28a0: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a  nfo_cache_size;.
28b0: 0a 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
28c0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
28d0: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
28e0: 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th != NULL) {...
28f0: 09 69 66 20 28 73 74 72 63 6d 70 28 61 70 70 66  .if (strcmp(appf
2900: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
2910: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
2920: 68 65 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d  he_path, path) =
2930: 3d 20 30 20 26 26 20 61 70 70 66 73 5f 70 61 74  = 0 && appfs_pat
2940: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
2950: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69  h_idx]._cache_ui
2960: 64 20 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09  d == uid) {.....
2970: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09  retval = 0;.....
2980: 09 6d 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f  .memcpy(pathinfo
2990: 2c 20 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  , &appfs_path_in
29a0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
29b0: 78 5d 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68  x], sizeof(*path
29c0: 69 6e 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68  info));.....path
29d0: 69 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74  info->_cache_pat
29e0: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09  h = NULL;....}..
29f0: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f  .}..}...pthread_
2a00: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
2a10: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
2a20: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
2a30: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
2a40: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
2a50: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2a60: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
2a70: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
2a80: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
2a90: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a  .return(-1);..}.
2aa0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20  ..if (retval == 
2ab0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
2ac0: 55 47 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e  UG("Cache hit on
2ad0: 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20   %s", path);..} 
2ae0: 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44  else {...APPFS_D
2af0: 45 42 55 47 28 22 43 61 63 68 65 20 6d 69 73 73  EBUG("Cache miss
2b00: 20 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a   on %s", path);.
2b10: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  .}...return(retv
2b20: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  al);.}..static v
2b30: 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61  oid appfs_get_pa
2b40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64  th_info_cache_ad
2b50: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  d(const char *pa
2b60: 74 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73  th, uid_t uid, s
2b70: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
2b80: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20  info *pathinfo) 
2b90: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
2ba0: 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70  hash_idx;..int p
2bb0: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74  thread_ret;...pt
2bc0: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
2bd0: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
2be0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2bf0: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
2c00: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
2c10: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
2c20: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
2c30: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63  lock path_info c
2c40: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a  ache mutex !");.
2c50: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
2c60: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
2c70: 6e 66 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c  nfo_cache == NUL
2c80: 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74  L) {...appfs_pat
2c90: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63  h_info_cache = c
2ca0: 61 6c 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68  alloc(appfs_path
2cb0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
2cc0: 2c 20 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f  , sizeof(*appfs_
2cd0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29  path_info_cache)
2ce0: 29 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78  );..}...hash_idx
2cf0: 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61   = (appfs_get_pa
2d00: 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b  th_inode(path) +
2d10: 20 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61   uid) % appfs_pa
2d20: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69  th_info_cache_si
2d30: 7a 65 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  ze;...if (appfs_
2d40: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
2d50: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
2d60: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b  _path != NULL) {
2d70: 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61  ...free(appfs_pa
2d80: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
2d90: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
2da0: 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70  ath);..}...memcp
2db0: 79 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  y(&appfs_path_in
2dc0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
2dd0: 78 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69  x], pathinfo, si
2de0: 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29  zeof(*pathinfo))
2df0: 3b 0a 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69  ;...appfs_path_i
2e00: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
2e10: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
2e20: 3d 20 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a  = strdup(path);.
2e30: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
2e40: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
2e50: 2e 5f 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75  ._cache_uid  = u
2e60: 69 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  id;...pthread_re
2e70: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
2e80: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
2e90: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
2ea0: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
2eb0: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
2ec0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2ed0: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
2ee0: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
2ef0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
2f00: 65 74 75 72 6e 3b 0a 09 7d 0a 09 72 65 74 75 72  eturn;..}..retur
2f10: 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  n;.}..static voi
2f20: 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  d appfs_get_path
2f30: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63  _info_cache_rm(c
2f40: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
2f50: 20 75 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75   uid_t uid) {..u
2f60: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
2f70: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
2f80: 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61  ad_ret;...pthrea
2f90: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
2fa0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
2fb0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
2fc0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
2fd0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
2fe0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2ff0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
3000: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
3010: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
3020: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
3030: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3040: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
3050: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61  ...hash_idx = (a
3060: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
3070: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29  ode(path) + uid)
3080: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
3090: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
30a0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
30b0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
30c0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
30d0: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  h != NULL) {....
30e0: 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f  free(appfs_path_
30f0: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3100: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3110: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74  );.....appfs_pat
3120: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
3130: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
3140: 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09  th = NULL;...}..
3150: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  }...pthread_ret 
3160: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
3170: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
3180: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
3190: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
31a0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
31b0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
31c0: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
31d0: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
31e0: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
31f0: 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  urn;..}...return
3200: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
3210: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
3220: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
3230: 28 75 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20  (uid_t uid, int 
3240: 6e 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73  new_size) {..uns
3250: 69 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09  igned int idx;..
3260: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
3270: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
3280: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
3290: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
32a0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
32b0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
32c0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
32d0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
32e0: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
32f0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
3300: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
3310: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
3320: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
3330: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20  = NULL) {...for 
3340: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
3350: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3360: 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b  cache_size; idx+
3370: 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70 70 66  +) {....if (appf
3380: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3390: 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  e[idx]._cache_pa
33a0: 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th != NULL) {...
33b0: 09 09 69 66 20 28 75 69 64 20 21 3d 20 28 28 75  ..if (uid != ((u
33c0: 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 09  id_t) -1)) {....
33d0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
33e0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
33f0: 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d 20 75  ._cache_uid != u
3400: 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74  id) {.......cont
3410: 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09  inue;......}....
3420: 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61 70 70  .}......free(app
3430: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3440: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  he[idx]._cache_p
3450: 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70 66 73  ath);......appfs
3460: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3470: 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  [idx]._cache_pat
3480: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09  h = NULL;....}..
3490: 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69 64 20  .}..}...if (uid 
34a0: 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29 29  == ((uid_t) -1))
34b0: 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f   {...free(appfs_
34c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29  path_info_cache)
34d0: 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f  ;....appfs_path_
34e0: 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c  info_cache = NUL
34f0: 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f 73 69  L;....if (new_si
3500: 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61  ze != -1) {....a
3510: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3520: 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f  ache_size = new_
3530: 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70  size;...}..}...p
3540: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
3550: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
3560: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
3570: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
3580: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
3590: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
35a0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
35b0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
35c0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
35d0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
35e0: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .}...return;.}..
35f0: 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61 74 69  /* Get informati
3600: 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74 68 2c  on about a path,
3610: 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20   and optionally 
3620: 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f  list children */
3630: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
3640: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
3650: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
3660: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  , struct appfs_p
3670: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66  athinfo *pathinf
3680: 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  o) {..Tcl_Interp
3690: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f   *interp;..Tcl_O
36a0: 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74 2c 20  bj *attrs_dict, 
36b0: 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f  *attr_value;..co
36c0: 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72 5f 76  nst char *attr_v
36d0: 61 6c 75 65 5f 73 74 72 3b 0a 09 54 63 6c 5f 57  alue_str;..Tcl_W
36e0: 69 64 65 49 6e 74 20 61 74 74 72 5f 76 61 6c 75  ideInt attr_valu
36f0: 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20 61 74 74  e_wide;..int att
3700: 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 73 74  r_value_int;..st
3710: 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63  atic __thread Tc
3720: 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b 65 79 5f  l_Obj *attr_key_
3730: 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  type = NULL, *at
3740: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 3d 20 4e  tr_key_perms = N
3750: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73  ULL, *attr_key_s
3760: 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  ize = NULL, *att
3770: 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20 4e 55 4c  r_key_time = NUL
3780: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 6f 75  L, *attr_key_sou
3790: 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  rce = NULL, *att
37a0: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74  r_key_childcount
37b0: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
37c0: 65 79 5f 70 61 63 6b 61 67 65 64 20 3d 20 4e 55  ey_packaged = NU
37d0: 4c 4c 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f 72  LL;..int cache_r
37e0: 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  et;..int tcl_ret
37f0: 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20  ;...cache_ret = 
3800: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3810: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 70 61  nfo_cache_get(pa
3820: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
3830: 75 69 64 28 29 2c 20 70 61 74 68 69 6e 66 6f 29  uid(), pathinfo)
3840: 3b 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65 74  ;..if (cache_ret
3850: 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70   == 0) {...if (p
3860: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d  athinfo->type ==
3870: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
3880: 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20  DOES_NOT_EXIST) 
3890: 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f  {....return(-ENO
38a0: 45 4e 54 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20  ENT);...}....if 
38b0: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  (pathinfo->type 
38c0: 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  == APPFS_PATHTYP
38d0: 45 5f 49 4e 56 41 4c 49 44 29 20 7b 0a 09 09 09  E_INVALID) {....
38e0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09  return(-EIO);...
38f0: 7d 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  }....return(0);.
3900: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  .}...interp = ap
3910: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
3920: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
3930: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
3940: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c  (-EIO);..}...tcl
3950: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
3960: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
3970: 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74   "::appfs::getat
3980: 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  tr", path);..if 
3990: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
39a0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
39b0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65  BUG("::appfs::ge
39c0: 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65 64  tattr(%s) failed
39d0: 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50  .", path);...APP
39e0: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
39f0: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
3a00: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
3a10: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 70 61  (interp));....pa
3a20: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
3a30: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f  PPFS_PATHTYPE_DO
3a40: 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a 0a 09  ES_NOT_EXIST;...
3a50: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
3a60: 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70  info_cache_add(p
3a70: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66  ath, appfs_get_f
3a80: 73 75 69 64 28 29 2c 20 70 61 74 68 69 6e 66 6f  suid(), pathinfo
3a90: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e  );....return(-EN
3aa0: 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  OENT);..}...if (
3ab0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d  attr_key_type ==
3ac0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 74 74 72 5f   NULL) {...attr_
3ad0: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d  key_type       =
3ae0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3af0: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09  j("type", -1);..
3b00: 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20  .attr_key_perms 
3b10: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
3b20: 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c  ringObj("perms",
3b30: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
3b40: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63  _size       = Tc
3b50: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
3b60: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  size", -1);...at
3b70: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20  tr_key_time     
3b80: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
3b90: 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29  gObj("time", -1)
3ba0: 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ;...attr_key_sou
3bb0: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  rce     = Tcl_Ne
3bc0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72  wStringObj("sour
3bd0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72  ce", -1);...attr
3be0: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20  _key_childcount 
3bf0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
3c00: 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c  bj("childcount",
3c10: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
3c20: 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63  _packaged   = Tc
3c30: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
3c40: 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a  packaged", -1);.
3c50: 09 7d 0a 0a 09 61 74 74 72 73 5f 64 69 63 74 20  .}...attrs_dict 
3c60: 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  = Tcl_GetObjResu
3c70: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 74 63 6c  lt(interp);..tcl
3c80: 5f 72 65 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f  _ret = Tcl_DictO
3c90: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
3ca0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
3cb0: 65 79 5f 74 79 70 65 2c 20 26 61 74 74 72 5f 76  ey_type, &attr_v
3cc0: 61 6c 75 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f  alue);..if (tcl_
3cd0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
3ce0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3cf0: 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70 65  [dict get \"type
3d00: 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09  \"] failed");...
3d10: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
3d20: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
3d30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
3d40: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
3d50: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
3d60: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c  }...if (attr_val
3d70: 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue == NULL) {...
3d80: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
3d90: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
3da0: 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61 74 68  kaged = 0;..path
3db0: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70  info->inode = ap
3dc0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
3dd0: 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 74 74 72  de(path);...attr
3de0: 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c  _value_str = Tcl
3df0: 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f  _GetString(attr_
3e00: 76 61 6c 75 65 29 3b 0a 09 73 77 69 74 63 68 20  value);..switch 
3e10: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  (attr_value_str[
3e20: 30 5d 29 20 7b 0a 09 09 63 61 73 65 20 27 64 27  0]) {...case 'd'
3e30: 3a 20 2f 2a 20 64 69 72 65 63 74 6f 72 79 20 2a  : /* directory *
3e40: 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  /....pathinfo->t
3e50: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
3e60: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a  TYPE_DIRECTORY;.
3e70: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
3e80: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63  einfo.dir.childc
3e90: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 54 63  ount = 0;.....Tc
3ea0: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
3eb0: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
3ec0: 20 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63   attr_key_childc
3ed0: 6f 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75  ount, &attr_valu
3ee0: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
3ef0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
3f00: 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  .....tcl_ret = T
3f10: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
3f20: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
3f30: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
3f40: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69 66  ue_wide);.....if
3f50: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
3f60: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74 68  _OK) {......path
3f70: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
3f80: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
3f90: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
3fa0: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09  .....}....}.....
3fb0: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 66  break;...case 'f
3fc0: 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09  ': /* file */...
3fd0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
3fe0: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
3ff0: 5f 46 49 4c 45 3b 0a 09 09 09 70 61 74 68 69 6e  _FILE;....pathin
4000: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
4010: 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 70  e.size = 0;....p
4020: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
4030: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c  o.file.executabl
4040: 65 20 3d 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44  e = 0;.....Tcl_D
4050: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
4060: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
4070: 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26 61 74  tr_key_size, &at
4080: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66  tr_value);....if
4090: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20   (attr_value != 
40a0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74 63 6c 5f  NULL) {.....tcl_
40b0: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64  ret = Tcl_GetWid
40c0: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c  eIntFromObj(NULL
40d0: 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61  , attr_value, &a
40e0: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b  ttr_value_wide);
40f0: 0a 09 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74  .....if (tcl_ret
4100: 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   == TCL_OK) {...
4110: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
4120: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20  einfo.file.size 
4130: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64  = attr_value_wid
4140: 65 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09  e;.....}....}...
4150: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
4160: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
4170: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65  ict, attr_key_pe
4180: 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rms, &attr_value
4190: 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76  );....if (attr_v
41a0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
41b0: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
41c0: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
41d0: 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  ng(attr_value);.
41e0: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
41f0: 75 65 5f 73 74 72 5b 30 5d 20 3d 3d 20 27 78 27  ue_str[0] == 'x'
4200: 29 20 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66  ) {......pathinf
4210: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
4220: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b  .executable = 1;
4230: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62  .....}....}....b
4240: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 73 27  reak;...case 's'
4250: 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a  : /* symlink */.
4260: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
4270: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
4280: 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09 70  PE_SYMLINK;....p
4290: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
42a0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d  o.symlink.size =
42b0: 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d   0;....pathinfo-
42c0: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  >typeinfo.symlin
42d0: 6b 2e 73 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c  k.source[0] = '\
42e0: 30 27 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74  0';.....Tcl_Dict
42f0: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
4300: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
4310: 6b 65 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74  key_source, &att
4320: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 20  r_value);....if 
4330: 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e  (attr_value != N
4340: 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74 72 5f  ULL) {.....attr_
4350: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f  value_str = Tcl_
4360: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
4370: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74  (attr_value, &at
4380: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a  tr_value_int); .
4390: 0a 09 09 09 09 69 66 20 28 28 61 74 74 72 5f 76  .....if ((attr_v
43a0: 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d  alue_int + 1) <=
43b0: 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f   sizeof(pathinfo
43c0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
43d0: 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 09  nk.source)) {...
43e0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
43f0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69  einfo.symlink.si
4400: 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f  ze = attr_value_
4410: 69 6e 74 3b 0a 09 09 09 09 09 70 61 74 68 69 6e  int;......pathin
4420: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
4430: 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72  link.source[attr
4440: 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c  _value_int] = '\
4450: 30 27 3b 0a 0a 09 09 09 09 09 6d 65 6d 63 70 79  0';.......memcpy
4460: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  (pathinfo->typei
4470: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
4480: 63 65 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 73  ce, attr_value_s
4490: 74 72 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  tr, attr_value_i
44a0: 6e 74 29 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a  nt);.....}....}.
44b0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
44c0: 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69   'F': /* pipe/fi
44d0: 66 6f 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66  fo */....pathinf
44e0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
44f0: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09  PATHTYPE_FIFO;..
4500: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
4510: 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d  'S': /* UNIX dom
4520: 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09  ain socket */...
4530: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
4540: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
4550: 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 62 72 65 61  _SOCKET;....brea
4560: 6b 3b 0a 09 09 64 65 66 61 75 6c 74 3a 0a 09 09  k;...default:...
4570: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
4580: 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  }...Tcl_DictObjG
4590: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
45a0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
45b0: 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74 72 5f  packaged, &attr_
45c0: 76 61 6c 75 65 29 3b 0a 09 69 66 20 28 61 74 74  value);..if (att
45d0: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
45e0: 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70   {...pathinfo->p
45f0: 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 09 7d 0a  ackaged = 1;..}.
4600: 0a 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
4610: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
4620: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69  ict, attr_key_ti
4630: 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  me, &attr_value)
4640: 3b 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ;..if (attr_valu
4650: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 74  e != NULL) {...t
4660: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
4670: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e  WideIntFromObj(N
4680: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c  ULL, attr_value,
4690: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64   &attr_value_wid
46a0: 65 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65  e);...if (tcl_re
46b0: 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t == TCL_OK) {..
46c0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65  ..pathinfo->time
46d0: 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69   = attr_value_wi
46e0: 64 65 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20  de;...}..} else 
46f0: 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69  {...pathinfo->ti
4700: 6d 65 20 3d 20 30 3b 0a 09 7d 0a 0a 09 61 70 70  me = 0;..}...app
4710: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4720: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c  _cache_add(path,
4730: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
4740: 28 29 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a  (), pathinfo);..
4750: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
4760: 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66  tatic char *appf
4770: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
4780: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ate(const char *
4790: 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  path) {..Tcl_Int
47a0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
47b0: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
47c0: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ath;..int tcl_re
47d0: 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  t;...appfs_get_p
47e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
47f0: 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66  lush(appfs_get_f
4800: 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69  suid(), -1);...i
4810: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
4820: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
4830: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
4840: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
4850: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
4860: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
4870: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70  interp, 2, "::ap
4880: 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f  pfs::prepare_to_
4890: 63 72 65 61 74 65 22 2c 20 70 61 74 68 29 3b 0a  create", path);.
48a0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
48b0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
48c0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
48d0: 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  ::prepare_to_cre
48e0: 61 74 65 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ate(%s) failed."
48f0: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
4900: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
4910: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
4920: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
4930: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75  nterp));....retu
4940: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72  rn(NULL);..}...r
4950: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
4960: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
4970: 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61  nterp);..if (rea
4980: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
4990: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
49a0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74  ;..}...return(st
49b0: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29  rdup(real_path))
49c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72  ;.}..static char
49d0: 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74   *appfs_localpat
49e0: 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  h(const char *pa
49f0: 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  th) {..Tcl_Inter
4a00: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73  p *interp;..cons
4a10: 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  t char *real_pat
4a20: 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  h;..int tcl_ret;
4a30: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
4a40: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
4a50: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
4a60: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
4a70: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  ULL);..}...tcl_r
4a80: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
4a90: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
4aa0: 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61  ::appfs::localpa
4ab0: 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  th", path);..if 
4ac0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
4ad0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
4ae0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f  BUG("::appfs::lo
4af0: 63 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c  calpath(%s) fail
4b00: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41  ed.", path);...A
4b10: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
4b20: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
4b30: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
4b40: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
4b50: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
4b60: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
4b70: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
4b80: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20  lt(interp);..if 
4b90: 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55  (real_path == NU
4ba0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
4bb0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  ULL);..}...retur
4bc0: 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61  n(strdup(real_pa
4bd0: 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  th));.}..static 
4be0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72  int appfs_fuse_r
4bf0: 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68  eadlink(const ch
4c00: 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a  ar *path, char *
4c10: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
4c20: 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66  ) {..struct appf
4c30: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69  s_pathinfo pathi
4c40: 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c  nfo;..int retval
4c50: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45   = 0;...APPFS_DE
4c60: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
4c70: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
4c80: 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e  th);...pathinfo.
4c90: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
4ca0: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
4cb0: 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f  .retval = appfs_
4cc0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61  get_path_info(pa
4cd0: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a  th, &pathinfo);.
4ce0: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30  .if (retval != 0
4cf0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 74  ) {...return(ret
4d00: 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70  val);..}...if (p
4d10: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20  athinfo.type != 
4d20: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
4d30: 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75  YMLINK) {...retu
4d40: 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a  rn(-EINVAL);..}.
4d50: 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70 61  ..if ((strlen(pa
4d60: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
4d70: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20  symlink.source) 
4d80: 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09  + 1) > size) {..
4d90: 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f  .return(-ENAMETO
4da0: 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  OLONG);..}...mem
4db0: 63 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e 66  cpy(buf, pathinf
4dc0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
4dd0: 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c 65  nk.source, strle
4de0: 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  n(pathinfo.typei
4df0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
4e00: 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75  ce) + 1);...retu
4e10: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
4e20: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
4e30: 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63 68  getattr(const ch
4e40: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
4e50: 20 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b 0a   stat *stbuf) {.
4e60: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
4e70: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
4e80: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09  ..int retval;...
4e90: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50  retval = 0;...AP
4ea0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
4eb0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
4ec0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74  )", path);...pat
4ed0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
4ee0: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
4ef0: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
4f00: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
4f10: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
4f20: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
4f30: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  l != 0) {...retu
4f40: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a  rn(retval);..}..
4f50: 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20 30  .memset(stbuf, 0
4f60: 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20  , sizeof(struct 
4f70: 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d  stat));...stbuf-
4f80: 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68  >st_mtime = path
4f90: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75  info.time;..stbu
4fa0: 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 70 61  f->st_ctime = pa
4fb0: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74  thinfo.time;..st
4fc0: 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20  buf->st_atime = 
4fd0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
4fe0: 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20  stbuf->st_ino   
4ff0: 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65  = pathinfo.inode
5000: 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ;..stbuf->st_mod
5010: 65 20 20 3d 20 30 3b 0a 0a 09 73 77 69 74 63 68  e  = 0;...switch
5020: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 29   (pathinfo.type)
5030: 20 7b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f   {...case APPFS_
5040: 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f  PATHTYPE_DIRECTO
5050: 52 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  RY:....stbuf->st
5060: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49 52 20  _mode = S_IFDIR 
5070: 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66  | 0555;....stbuf
5080: 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b  ->st_nlink = 2 +
5090: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e   pathinfo.typein
50a0: 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e  fo.dir.childcoun
50b0: 74 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  t;....break;...c
50c0: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
50d0: 50 45 5f 46 49 4c 45 3a 0a 09 09 09 69 66 20 28  PE_FILE:....if (
50e0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
50f0: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c  o.file.executabl
5100: 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e  e) {.....stbuf->
5110: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45  st_mode = S_IFRE
5120: 47 20 7c 20 30 35 35 35 3b 0a 09 09 09 7d 20 65  G | 0555;....} e
5130: 6c 73 65 20 7b 0a 09 09 09 09 73 74 62 75 66 2d  lse {.....stbuf-
5140: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52  >st_mode = S_IFR
5150: 45 47 20 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a  EG | 0444;....}.
5160: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c  ....stbuf->st_nl
5170: 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75  ink = 1;....stbu
5180: 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74  f->st_size = pat
5190: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
51a0: 69 6c 65 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65  ile.size;....bre
51b0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
51c0: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e  _PATHTYPE_SYMLIN
51d0: 4b 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  K:....stbuf->st_
51e0: 6d 6f 64 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c  mode = S_IFLNK |
51f0: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
5200: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
5210: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65  ..stbuf->st_size
5220: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65   = pathinfo.type
5230: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a  info.symlink.siz
5240: 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  e;....break;...c
5250: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
5260: 50 45 5f 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74  PE_SOCKET:....st
5270: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
5280: 5f 49 46 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a  _IFSOCK | 0555;.
5290: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
52a0: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
52b0: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09  ->st_size = 0;..
52c0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
52d0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
52e0: 49 46 4f 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73  IFO:....stbuf->s
52f0: 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f  t_mode = S_IFIFO
5300: 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75   | 0555;....stbu
5310: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
5320: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
5330: 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b  ze = 0;....break
5340: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
5350: 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54  ATHTYPE_DOES_NOT
5360: 5f 45 58 49 53 54 3a 0a 09 09 09 72 65 74 76 61  _EXIST:....retva
5370: 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09  l = -ENOENT;....
5380: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
5390: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
53a0: 56 41 4c 49 44 3a 0a 09 09 09 72 65 74 76 61 6c  VALID:....retval
53b0: 20 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65   = -EIO;.....bre
53c0: 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74  ak;..}...if (pat
53d0: 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 20  hinfo.packaged) 
53e0: 7b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 75 69  {...stbuf->st_ui
53f0: 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  d   = appfs_get_
5400: 66 73 75 69 64 28 29 3b 0a 09 09 73 74 62 75 66  fsuid();...stbuf
5410: 2d 3e 73 74 5f 67 69 64 20 20 20 3d 20 61 70 70  ->st_gid   = app
5420: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a  fs_get_fsgid();.
5430: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
5440: 20 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a 0a 09 72   |= 0200;..}...r
5450: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
5460: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
5470: 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72 28  fs_fuse_readdir(
5480: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
5490: 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66 75 73  , void *buf, fus
54a0: 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66 69 6c  e_fill_dir_t fil
54b0: 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65  ler, off_t offse
54c0: 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  t, struct fuse_f
54d0: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
54e0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
54f0: 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a  erp;..Tcl_Obj **
5500: 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74 20 63  children;..int c
5510: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 69  hildren_count, i
5520: 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  dx;..int tcl_ret
5530: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5540: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
5550: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
5560: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
5570: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
5580: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
5590: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 30  LL) {...return(0
55a0: 29 3b 0a 09 7d 0a 0a 09 66 69 6c 6c 65 72 28 62  );..}...filler(b
55b0: 75 66 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30  uf, ".", NULL, 0
55c0: 29 3b 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20  );..filler(buf, 
55d0: 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a  "..", NULL, 0);.
55e0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
55f0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
5600: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
5610: 67 65 74 63 68 69 6c 64 72 65 6e 22 2c 20 70 61  getchildren", pa
5620: 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  th);..if (tcl_re
5630: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
5640: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
5650: 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72  appfs::getchildr
5660: 65 6e 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  en(%s) failed.",
5670: 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f   path);...APPFS_
5680: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
5690: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
56a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
56b0: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72  terp));....retur
56c0: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  n(0);..}...tcl_r
56d0: 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  et = Tcl_ListObj
56e0: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65  GetElements(inte
56f0: 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  rp, Tcl_GetObjRe
5700: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26 63  sult(interp), &c
5710: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 26  hildren_count, &
5720: 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69 66 20 28  children);..if (
5730: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
5740: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
5750: 55 47 28 22 50 61 72 73 69 6e 67 20 6c 69 73 74  UG("Parsing list
5760: 20 6f 66 20 63 68 69 6c 64 72 65 6e 20 6f 6e 20   of children on 
5770: 70 61 74 68 20 25 73 20 66 61 69 6c 65 64 2e 22  path %s failed."
5780: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
5790: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
57a0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
57b0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
57c0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75  nterp));....retu
57d0: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20  rn(0);..}...for 
57e0: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
57f0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20  children_count; 
5800: 69 64 78 2b 2b 29 20 7b 0a 09 09 66 69 6c 6c 65  idx++) {...fille
5810: 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74  r(buf, Tcl_GetSt
5820: 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64  ring(children[id
5830: 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09  x]), NULL, 0);..
5840: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
5850: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
5860: 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e  fs_fuse_open(con
5870: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
5880: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
5890: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
58a0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
58b0: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
58c0: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
58d0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
58e0: 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b  eal_path, *mode;
58f0: 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74  ..int gpi_ret, t
5900: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b  cl_ret;..int fh;
5910: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5920: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
5930: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
5940: 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66  ..gpi_ret = appf
5950: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
5960: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
5970: 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61  ;...if ((fi->fla
5980: 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f  gs & (O_WRONLY|O
5990: 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43  _CREAT)) == (O_C
59a0: 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20  REAT|O_WRONLY)) 
59b0: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20  {.../* The file 
59c0: 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20  will be created 
59d0: 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65  if it does not e
59e0: 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70  xist */...if (gp
59f0: 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70  i_ret != 0 && gp
5a00: 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54  i_ret != -ENOENT
5a10: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67 70  ) {....return(gp
5a20: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d  i_ret);...}....m
5a30: 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a  ode = "create";.
5a40: 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61  .../*... * We ha
5a50: 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20  ve to clear the 
5a60: 63 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68  cache here so th
5a70: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  at the number of
5a80: 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73  ... * links gets
5a90: 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74   maintained on t
5aa0: 68 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74  he parent direct
5ab0: 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66  ory... */...appf
5ac0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
5ad0: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66  cache_flush(appf
5ae0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d  s_get_fsuid(), -
5af0: 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  1);..} else {...
5b00: 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74  /* The file must
5b10: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a   already exist *
5b20: 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20  /...if (gpi_ret 
5b30: 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75 72  != 0) {....retur
5b40: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a  n(gpi_ret);...}.
5b50: 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09  ...mode = "";...
5b60: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20  .if ((fi->flags 
5b70: 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f  & O_WRONLY) == O
5b80: 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f  _WRONLY) {....mo
5b90: 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09  de = "write";...
5ba0: 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  }..}...if (pathi
5bb0: 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46  nfo.type == APPF
5bc0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
5bd0: 54 4f 52 59 29 20 7b 0a 09 09 72 65 74 75 72 6e  TORY) {...return
5be0: 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09  (-EISDIR);..}...
5bf0: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5c00: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5c10: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5c20: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
5c30: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
5c40: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
5c50: 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61  (interp, 3, "::a
5c60: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c  ppfs::openpath",
5c70: 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 69   path, mode);..i
5c80: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
5c90: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
5ca0: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
5cb0: 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29  openpath(%s, %s)
5cc0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c   failed.", path,
5cd0: 20 6d 6f 64 65 29 3b 0a 09 09 41 50 50 46 53 5f   mode);...APPFS_
5ce0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
5cf0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
5d00: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
5d10: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72  terp));....retur
5d20: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65  n(-EIO);..}...re
5d30: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
5d40: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
5d50: 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 6c  terp);..if (real
5d60: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
5d70: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
5d80: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  ..}...APPFS_DEBU
5d90: 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65  G("Translated re
5da0: 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73  quest to open %s
5db0: 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28   to opening %s (
5dc0: 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c  mode = \"%s\")",
5dd0: 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68   path, real_path
5de0: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20  , mode);...fh = 
5df0: 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20  open(real_path, 
5e00: 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29  fi->flags, 0600)
5e10: 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20  ;...if (fh < 0) 
5e20: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
5e30: 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20  ;..}...fi->fh = 
5e40: 66 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  fh;...return(0);
5e50: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
5e60: 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 28  ppfs_fuse_close(
5e70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
5e80: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
5e90: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
5ea0: 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a  int close_ret;..
5eb0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
5ec0: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
5ed0: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
5ee0: 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f  uid());...close_
5ef0: 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e  ret = close(fi->
5f00: 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f  fh);..if (close_
5f10: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  ret != 0) {...re
5f20: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
5f30: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
5f40: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
5f50: 66 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20  fuse_read(const 
5f60: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72  char *path, char
5f70: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
5f80: 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74  ze, off_t offset
5f90: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
5fa0: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
5fb0: 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b  off_t lseek_ret;
5fc0: 0a 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72  ..ssize_t read_r
5fd0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
5fe0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
5ff0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
6000: 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d  );...lseek_ret =
6010: 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f   lseek(fi->fh, o
6020: 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29  ffset, SEEK_SET)
6030: 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74  ;..if (lseek_ret
6040: 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09   != offset) {...
6050: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
6060: 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65  ...read_ret = re
6070: 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20  ad(fi->fh, buf, 
6080: 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28  size);...return(
6090: 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74  read_ret);.}..st
60a0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
60b0: 75 73 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20  use_write(const 
60c0: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73  char *path, cons
60d0: 74 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a  t char *buf, siz
60e0: 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20  e_t size, off_t 
60f0: 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66  offset, struct f
6100: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
6110: 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65  i) {..off_t lsee
6120: 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20  k_ret;..ssize_t 
6130: 77 72 69 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50  write_ret;...APP
6140: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
6150: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
6160: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  ", path);...appf
6170: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
6180: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61  cache_rm(path, a
6190: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
61a0: 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d  );...lseek_ret =
61b0: 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f   lseek(fi->fh, o
61c0: 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29  ffset, SEEK_SET)
61d0: 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74  ;..if (lseek_ret
61e0: 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09   != offset) {...
61f0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
6200: 0a 0a 09 77 72 69 74 65 5f 72 65 74 20 3d 20 77  ...write_ret = w
6210: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66  rite(fi->fh, buf
6220: 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72  , size);...retur
6230: 6e 28 77 72 69 74 65 5f 72 65 74 29 3b 0a 7d 0a  n(write_ret);.}.
6240: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6250: 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e  s_fuse_mknod(con
6260: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
6270: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f  ode_t mode, dev_
6280: 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61  t device) {..cha
6290: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
62a0: 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09  nt mknod_ret;...
62b0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
62c0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
62d0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
62e0: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43  f ((mode & S_IFC
62f0: 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20  HR) == S_IFCHR) 
6300: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
6310: 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f  M);..}...if ((mo
6320: 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d  de & S_IFBLK) ==
6330: 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65   S_IFBLK) {...re
6340: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
6350: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
6360: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
6370: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69  create(path);..i
6380: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
6390: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
63a0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
63b0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
63c0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d  _fs_enter();...m
63d0: 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64  knod_ret = mknod
63e0: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
63f0: 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70  , device);...app
6400: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
6410: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
6420: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
6430: 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20  ..if (mknod_ret 
6440: 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  != 0) {...return
6450: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
6460: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
6470: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6480: 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f  s_fuse_create(co
6490: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
64a0: 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72  mode_t mode, str
64b0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
64c0: 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20  fo *fi) {..char 
64d0: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
64e0: 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42   fd;...APPFS_DEB
64f0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
6500: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
6510: 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20  h);...if ((mode 
6520: 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f  & S_IFCHR) == S_
6530: 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72  IFCHR) {...retur
6540: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09  n(-EPERM);..}...
6550: 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46  if ((mode & S_IF
6560: 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29  BLK) == S_IFBLK)
6570: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45   {...return(-EPE
6580: 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70  RM);..}...real_p
6590: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70  ath = appfs_prep
65a0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61  are_to_create(pa
65b0: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70  th);..if (real_p
65c0: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
65d0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
65e0: 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  }...appfs_simula
65f0: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
6600: 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74  ();...fd = creat
6610: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
6620: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
6630: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
6640: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
6650: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64  _path);...if (fd
6660: 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e   < 0) {...return
6670: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
6680: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a  ...fi->fh = fd;.
6690: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
66a0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
66b0: 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63  _fuse_truncate(c
66c0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
66d0: 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09   off_t size) {..
66e0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
66f0: 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72  ..int truncate_r
6700: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
6710: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
6720: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
6730: 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  );...real_path =
6740: 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68   appfs_localpath
6750: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
6760: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
6770: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
6780: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74  ;..}...appfs_get
6790: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
67a0: 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f  _rm(path, appfs_
67b0: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09  get_fsuid());...
67c0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
67d0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
67e0: 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74 20 3d  ..truncate_ret =
67f0: 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c 5f 70   truncate(real_p
6800: 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70  ath, size);...ap
6810: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
6820: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
6830: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b  free(real_path);
6840: 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74 65 5f  ...if (truncate_
6850: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  ret != 0) {...re
6860: 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29  turn(errno * -1)
6870: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
6880: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
6890: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e  appfs_fuse_unlin
68a0: 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20 63 68  k_rmdir(const ch
68b0: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c  ar *path) {..Tcl
68c0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
68d0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
68e0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
68f0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
6900: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
6910: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
6920: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
6930: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
6940: 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70  ), -1);...interp
6950: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
6960: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
6970: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
6980: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
6990: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
69a0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
69b0: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
69c0: 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20 70 61 74  unlinkpath", pat
69d0: 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  h);..if (tcl_ret
69e0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
69f0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
6a00: 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68  ppfs::unlinkpath
6a10: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
6a20: 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45  ath);...APPFS_DE
6a30: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
6a40: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
6a50: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
6a60: 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  rp));....return(
6a70: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  -EIO);..}...retu
6a80: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
6a90: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
6aa0: 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72  mkdir(const char
6ab0: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d   *path, mode_t m
6ac0: 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  ode) {..char *re
6ad0: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b  al_path;..int mk
6ae0: 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  dir_ret;...APPFS
6af0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
6b00: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
6b10: 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70   path);...real_p
6b20: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70  ath = appfs_prep
6b30: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61  are_to_create(pa
6b40: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70  th);..if (real_p
6b50: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
6b60: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
6b70: 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  }...appfs_simula
6b80: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
6b90: 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20  ();...mkdir_ret 
6ba0: 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70 61 74  = mkdir(real_pat
6bb0: 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66  h, mode);...appf
6bc0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
6bd0: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
6be0: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
6bf0: 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74 20 21  .if (mkdir_ret !
6c00: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65 72 72  = 0) {...if (err
6c10: 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20 7b 0a  no != EEXIST) {.
6c20: 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
6c30: 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  * -1);...}..}...
6c40: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
6c50: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
6c60: 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20  use_chmod(const 
6c70: 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65  char *path, mode
6c80: 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f  _t mode) {..Tcl_
6c90: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
6ca0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61  .const char *rea
6cb0: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c  l_path;..int tcl
6cc0: 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b  _ret, chmod_ret;
6cd0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6ce0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
6cf0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
6d00: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
6d10: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70  _info_cache_rm(p
6d20: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66  ath, appfs_get_f
6d30: 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74 65 72  suid());...inter
6d40: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
6d50: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
6d60: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
6d70: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
6d80: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
6d90: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
6da0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
6db0: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
6dc0: 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20  , "write");..if 
6dd0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
6de0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
6df0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70  BUG("::appfs::op
6e00: 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66  enpath(%s, %s) f
6e10: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22  ailed.", path, "
6e20: 77 72 69 74 65 22 29 3b 0a 09 09 41 50 50 46 53  write");...APPFS
6e30: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
6e40: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
6e50: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
6e60: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75  nterp));....retu
6e70: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72  rn(-EIO);..}...r
6e80: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
6e90: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
6ea0: 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61  nterp);..if (rea
6eb0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
6ec0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
6ed0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
6ee0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
6ef0: 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72  ter();...chmod_r
6f00: 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f  et = chmod(real_
6f10: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
6f20: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
6f30: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
6f40: 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65  .return(chmod_re
6f50: 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51 4c  t);.}../*. * SQL
6f60: 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63 75  ite3 mode: Execu
6f70: 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20 72  te raw SQL and r
6f80: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72  eturn success or
6f90: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61   failure. */.sta
6fa0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73 71  tic int appfs_sq
6fb0: 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61 72  lite3(const char
6fc0: 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e   *sql) {..Tcl_In
6fd0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
6fe0: 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f 72  onst char *sql_r
6ff0: 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  et;..int tcl_ret
7000: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
7010: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
7020: 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28  erp(NULL);..if (
7030: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
7040: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
7050: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
7060: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
7070: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69  rpreter.  Aborti
7080: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75  ng.\n");....retu
7090: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  rn(1);..}...tcl_
70a0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
70b0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c 20  Eval(interp, 5, 
70c0: 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20 22  "::appfs::db", "
70d0: 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f 77  eval", sql, "row
70e0: 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d  ", "unset -nocom
70f0: 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70 61  plain row(*); pa
7100: 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20 5c  rray row; puts \
7110: 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c 5f  "----\"");..sql_
7120: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ret = Tcl_GetStr
7130: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
7140: 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  );...if (tcl_ret
7150: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
7160: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
7170: 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20  "[error] %s\n", 
7180: 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65 74  sql_ret);....ret
7190: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20  urn(1);..}...if 
71a0: 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c 5f  (sql_ret && sql_
71b0: 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20  ret[0] != '\0') 
71c0: 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e  {...printf("%s\n
71d0: 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a  ", sql_ret);..}.
71e0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
71f0: 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a 20  /*. * Tcl mode: 
7200: 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c 20  Execute raw Tcl 
7210: 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65  and return succe
7220: 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a  ss or failure. *
7230: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
7240: 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68 61  fs_tcl(const cha
7250: 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *tcl) {..Tcl_I
7260: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
7270: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f  const char *tcl_
7280: 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63 6c  result;..int tcl
7290: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
72a0: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63   appfs_create_Tc
72b0: 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09  lInterp(NULL);..
72c0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
72d0: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  LL) {...fprintf(
72e0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
72f0: 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c 20  to create a Tcl 
7300: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62  interpreter.  Ab
7310: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
7320: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
7330: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
7340: 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29 3b  al(interp, tcl);
7350: 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20 54  ..tcl_result = T
7360: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
7370: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66  lt(interp);...if
7380: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
7390: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
73a0: 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72  (stderr, "[error
73b0: 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73  ] %s\n", tcl_res
73c0: 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  ult);....return(
73d0: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c  1);..}...if (tcl
73e0: 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f 72  _result && tcl_r
73f0: 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27  esult[0] != '\0'
7400: 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73  ) {...printf("%s
7410: 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29  \n", tcl_result)
7420: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
7430: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53  ;.}../*. * AppFS
7440: 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54 63  d Package for Tc
7450: 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42 72  l:. *         Br
7460: 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65  idge for I/O ope
7470: 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 65  rations to reque
7480: 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61  st information a
7490: 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e 74  bout the current
74a0: 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61 6e  . *         tran
74b0: 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20  saction. */./*. 
74c0: 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20  * Tcl interface 
74d0: 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20  to get the home 
74e0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68  directory for th
74f0: 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68  e user making th
7500: 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46  e "current". * F
7510: 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a  USE I/O request.
7520: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74   */.static int t
7530: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
7540: 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20  edir(ClientData 
7550: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
7560: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
7570: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
7580: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72   objv[]) {..char
7590: 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f   *homedir;..Tcl_
75a0: 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a  Obj *homedir_obj
75b0: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  ;..uid_t fsuid;.
75c0: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
75d0: 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68   Tcl_Obj *last_h
75e0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c  omedir_obj = NUL
75f0: 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  L;..static __thr
7600: 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66  ead uid_t last_f
7610: 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20  suid = -1;..    
7620: 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20      if (objc != 
7630: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1) {.           
7640: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
7650: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
7660: 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20   objv, NULL);.  
7670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
7680: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
7690: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75  .        }...fsu
76a0: 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66  id = appfs_get_f
76b0: 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73  suid();...if (fs
76c0: 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69  uid == last_fsui
76d0: 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69  d && last_homedi
76e0: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b  r_obj != NULL) {
76f0: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d  ...homedir_obj =
7700: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
7710: 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68  j;..} else {...h
7720: 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67  omedir = appfs_g
7730: 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73  et_homedir(appfs
7740: 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a  _get_fsuid());..
7750: 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d  ..if (homedir ==
7760: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75   NULL) {....retu
7770: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
7780: 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62  .}....homedir_ob
7790: 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  j = Tcl_NewStrin
77a0: 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31  gObj(homedir, -1
77b0: 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64  );....free(homed
77c0: 69 72 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74  ir);....if (last
77d0: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20  _homedir_obj != 
77e0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44  NULL) {....Tcl_D
77f0: 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74  ecrRefCount(last
7800: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  _homedir_obj);..
7810: 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  .}....last_homed
7820: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
7830: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
7840: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
7850: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
7860: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
7870: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
7880: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
7890: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
78a0: 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72  obj);..        r
78b0: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
78c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
78d0: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
78e0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c  user_fs_enter(Cl
78f0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
7900: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
7910: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
7920: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
7930: 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  ) {..appfs_simul
7940: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
7950: 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  r();...return(TC
7960: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  L_OK);.}..static
7970: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73   int tcl_appfs_s
7980: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
7990: 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61  leave(ClientData
79a0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
79b0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
79c0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
79d0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70  T objv[]) {..app
79e0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
79f0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72  _fs_leave();...r
7a00: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
7a10: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
7a20: 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  _appfs_get_fsuid
7a30: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
7a40: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7a50: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
7a60: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
7a70: 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73  v[]) {..uid_t fs
7a80: 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61  uid;...fsuid = a
7a90: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
7aa0: 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53  ;..       .Tcl_S
7ab0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
7ac0: 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49  rp, Tcl_NewWideI
7ad0: 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a  ntObj(fsuid));..
7ae0: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
7af0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
7b00: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67  cl_appfs_get_fsg
7b10: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
7b20: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
7b30: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
7b40: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
7b50: 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20  bjv[]) {..gid_t 
7b60: 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d  fsgid;...fsgid =
7b70: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64   appfs_get_fsgid
7b80: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
7b90: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
7ba0: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
7bb0: 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b  eIntObj(fsgid));
7bc0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
7bd0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
7be0: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70   tcl_appfs_get_p
7bf0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
7c00: 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61 20  lush(ClientData 
7c10: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
7c20: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
7c30: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
7c40: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20   objv[]) {..int 
7c50: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65  tcl_ret;..int ne
7c60: 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69  w_size;...new_si
7c70: 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f  ze = -1;...if (o
7c80: 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63  bjc == 2) {...tc
7c90: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 49  l_ret = Tcl_GetI
7ca0: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  ntFromObj(interp
7cb0: 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f  , objv[1], &new_
7cc0: 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 6c  size);...if (tcl
7cd0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
7ce0: 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c 5f  {....return(tcl_
7cf0: 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73  ret);...}..} els
7d00: 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c  e if (objc > 2 |
7d10: 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20  | objc < 1) {.  
7d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
7d30: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
7d40: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
7d50: 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a 65  "?new_cache_size
7d60: 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 43  ?");...return(TC
7d70: 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61  L_ERROR);..}...a
7d80: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
7d90: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d  fo_cache_flush(-
7da0: 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09  1, new_size);...
7db0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
7dc0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70  }..static int Ap
7dd0: 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  pfsd_Init(Tcl_In
7de0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a  terp *interp) {.
7df0: 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53  #ifdef USE_TCL_S
7e00: 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e  TUBS..if (Tcl_In
7e10: 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20  itStubs(interp, 
7e20: 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20  TCL_VERSION, 0) 
7e30: 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72  == 0L) {...retur
7e40: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d  n(TCL_ERROR);..}
7e50: 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72  .#endif...Tcl_Cr
7e60: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
7e70: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
7e80: 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63  get_homedir", tc
7e90: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65  l_appfs_get_home
7ea0: 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  dir, NULL, NULL)
7eb0: 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ;..Tcl_CreateObj
7ec0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
7ed0: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 75  "appfsd::get_fsu
7ee0: 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67  id", tcl_appfs_g
7ef0: 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20  et_fsuid, NULL, 
7f00: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
7f10: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
7f20: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65  erp, "appfsd::ge
7f30: 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 70  t_fsgid", tcl_ap
7f40: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e  pfs_get_fsgid, N
7f50: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
7f60: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
7f70: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
7f80: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  d::simulate_user
7f90: 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f  _fs_enter", tcl_
7fa0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
7fb0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55  ser_fs_enter, NU
7fc0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
7fd0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
7fe0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
7ff0: 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  ::simulate_user_
8000: 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61  fs_leave", tcl_a
8010: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
8020: 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c  er_fs_leave, NUL
8030: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43  L, NULL);..Tcl_C
8040: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
8050: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
8060: 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  :get_path_info_c
8070: 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c  ache_flush", tcl
8080: 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  _appfs_get_path_
8090: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
80a0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a  , NULL, NULL);..
80b0: 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28  .Tcl_PkgProvide(
80c0: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22  interp, "appfsd"
80d0: 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75  , "1.0");...retu
80e0: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f  rn(TCL_OK);.}../
80f0: 2a 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74  *. * FUSE operat
8100: 69 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20  ions structure. 
8110: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  */.static struct
8120: 20 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73   fuse_operations
8130: 20 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e   appfs_operation
8140: 73 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20  s = {...getattr 
8150: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67    = appfs_fuse_g
8160: 65 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69  etattr,...readdi
8170: 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  r   = appfs_fuse
8180: 5f 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64  _readdir,...read
8190: 6c 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75  link  = appfs_fu
81a0: 73 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f  se_readlink,...o
81b0: 70 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73  pen      = appfs
81c0: 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65  _fuse_open,...re
81d0: 6c 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f  lease   = appfs_
81e0: 66 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65  fuse_close,...re
81f0: 61 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  ad      = appfs_
8200: 66 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69  fuse_read,...wri
8210: 74 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  te     = appfs_f
8220: 75 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e  use_write,...mkn
8230: 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  od     = appfs_f
8240: 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65  use_mknod,...cre
8250: 61 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ate    = appfs_f
8260: 75 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72  use_create,...tr
8270: 75 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f  uncate  = appfs_
8280: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09  fuse_truncate,..
8290: 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70  .unlink    = app
82a0: 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72  fs_fuse_unlink_r
82b0: 6d 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20  mdir,...rmdir   
82c0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75    = appfs_fuse_u
82d0: 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d  nlink_rmdir,...m
82e0: 6b 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73  kdir     = appfs
82f0: 5f 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63  _fuse_mkdir,...c
8300: 68 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73  hmod     = appfs
8310: 5f 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a  _fuse_chmod,.};.
8320: 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70 74 69  ./*. * FUSE opti
8330: 6f 6e 20 70 61 72 73 69 6e 67 20 63 61 6c 6c 62  on parsing callb
8340: 61 63 6b 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ack. */.static i
8350: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70  nt appfs_fuse_op
8360: 74 5f 63 62 28 76 6f 69 64 20 2a 64 61 74 61 2c  t_cb(void *data,
8370: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67   const char *arg
8380: 2c 20 69 6e 74 20 6b 65 79 2c 20 73 74 72 75 63  , int key, struc
8390: 74 20 66 75 73 65 5f 61 72 67 73 20 2a 6f 75 74  t fuse_args *out
83a0: 61 72 67 73 29 20 7b 0a 09 73 74 61 74 69 63 20  args) {..static 
83b0: 69 6e 74 20 73 65 65 6e 5f 63 61 63 68 65 64 69  int seen_cachedi
83c0: 72 20 3d 20 30 3b 0a 0a 09 69 66 20 28 6b 65 79  r = 0;...if (key
83d0: 20 3d 3d 20 46 55 53 45 5f 4f 50 54 5f 4b 45 59   == FUSE_OPT_KEY
83e0: 5f 4e 4f 4e 4f 50 54 20 26 26 20 73 65 65 6e 5f  _NONOPT && seen_
83f0: 63 61 63 68 65 64 69 72 20 3d 3d 20 30 29 20 7b  cachedir == 0) {
8400: 0a 09 09 73 65 65 6e 5f 63 61 63 68 65 64 69 72  ...seen_cachedir
8410: 20 3d 20 31 3b 0a 0a 09 09 61 70 70 66 73 5f 63   = 1;....appfs_c
8420: 61 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70  achedir = strdup
8430: 28 61 72 67 29 3b 0a 0a 09 09 72 65 74 75 72 6e  (arg);....return
8440: 28 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (0);..}...return
8450: 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e  (1);.}../*. * En
8460: 74 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74  try point into t
8470: 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f  his program.. */
8480: 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72  .int main(int ar
8490: 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29  gc, char **argv)
84a0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
84b0: 74 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68  test_interp;..ch
84c0: 61 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f  ar *test_interp_
84d0: 65 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66  error;..struct f
84e0: 75 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20  use_args args = 
84f0: 46 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 61  FUSE_ARGS_INIT(a
8500: 72 67 63 2c 20 61 72 67 76 29 3b 0a 09 69 6e 74  rgc, argv);..int
8510: 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09   pthread_ret;...
8520: 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73  /*.. * Skip pass
8530: 65 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a  ed program name.
8540: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
8550: 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e  = 0 || argv == N
8560: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
8570: 31 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a  1);..}..argc--;.
8580: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20  .argv++;.../*.. 
8590: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
85a0: 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68  iables, these sh
85b0: 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72  ould be configur
85c0: 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09  ation options...
85d0: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65   */..appfs_cache
85e0: 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48  dir = APPFS_CACH
85f0: 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  EDIR;.../*.. * S
8600: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  et global variab
8610: 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d  le for "boot tim
8620: 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65  e" to set a time
8630: 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a   on directories.
8640: 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65  . * that we fake
8650: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f  ... */..appfs_bo
8660: 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55  ottime = time(NU
8670: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65  LL);.../*.. * Re
8680: 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e  gister "sha1" an
8690: 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61  d "appfsd" packa
86a0: 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73  ge with libtcl s
86b0: 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09  o that any new..
86c0: 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20   * interpreters 
86d0: 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61  created (which a
86e0: 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61  re done dynamica
86f0: 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e  lly by FUSE) can
8700: 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70   have.. * the ap
8710: 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67  propriate config
8720: 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74  uration done aut
8730: 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f  omatically... */
8740: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b  ..Tcl_StaticPack
8750: 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22  age(NULL, "sha1"
8760: 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c  , Sha1_Init, NUL
8770: 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50  L);..Tcl_StaticP
8780: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70  ackage(NULL, "ap
8790: 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e  pfsd", Appfsd_In
87a0: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a  it, NULL);.../*.
87b0: 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72  . * Create a thr
87c0: 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74  ead-specific-dat
87d0: 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20  a (TSD) key for 
87e0: 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72  each thread to r
87f0: 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20  efer.. * to its 
8800: 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65  own Tcl interpre
8810: 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70  ter.  Tcl interp
8820: 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75  reters must be u
8830: 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68  nique per.. * th
8840: 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72  read and new thr
8850: 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63  eads are dynamic
8860: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20  ally created by 
8870: 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72  FUSE... */..pthr
8880: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
8890: 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e  d_key_create(&in
88a0: 74 65 72 70 4b 65 79 2c 20 4e 55 4c 4c 29 3b 0a  terpKey, NULL);.
88b0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
88c0: 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e   != 0) {...fprin
88d0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
88e0: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44  le to create TSD
88f0: 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41   key for Tcl.  A
8900: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
8910: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
8920: 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79  ./*.. * Manually
8930: 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64   specify cache d
8940: 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75  irectory, withou
8950: 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a  t FUSE callback.
8960: 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20  . * This option 
8970: 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20  only works when 
8980: 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20  not using FUSE, 
8990: 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20  since we.. * do 
89a0: 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77  not process it w
89b0: 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e  ith FUSEs option
89c0: 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a   processing... *
89d0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32  /..if (argc >= 2
89e0: 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70  ) {...if (strcmp
89f0: 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63  (argv[0], "--cac
8a00: 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a  hedir") == 0) {.
8a10: 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69  ...appfs_cachedi
8a20: 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b  r = strdup(argv[
8a30: 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d  1]);.....argc -=
8a40: 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32   2;....argv += 2
8a50: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ;...}..}.../*.. 
8a60: 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20  * SQLite3 mode, 
8a70: 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20  for running raw 
8a80: 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20  SQL against the 
8a90: 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09  cache database..
8aa0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
8ab0: 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67   2 && strcmp(arg
8ac0: 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33  v[0], "--sqlite3
8ad0: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74  ") == 0) {...ret
8ae0: 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65  urn(appfs_sqlite
8af0: 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a  3(argv[1]));..}.
8b00: 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64  ../*.. * Tcl mod
8b10: 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72  e, for running r
8b20: 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61  aw Tcl in the sa
8b30: 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41  me environment A
8b40: 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20  ppFSd would.. * 
8b50: 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09  run code... */..
8b60: 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26  if (argc == 2 &&
8b70: 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c   strcmp(argv[0],
8b80: 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20   "--tcl") == 0) 
8b90: 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73  {...return(appfs
8ba0: 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a  _tcl(argv[1]));.
8bb0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61  .}.../*.. * Crea
8bc0: 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72  te a Tcl interpr
8bd0: 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65 72  eter just to ver
8be0: 69 66 79 20 74 68 61 74 20 74 68 69 6e 67 73 20  ify that things 
8bf0: 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a  are in working .
8c00: 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72 65  . * order before
8c10: 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61 65   we become a dae
8c20: 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f  mon... */..test_
8c30: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63  interp = appfs_c
8c40: 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28  reate_TclInterp(
8c50: 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72  &test_interp_err
8c60: 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f 69  or);..if (test_i
8c70: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
8c80: 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65  ...if (test_inte
8c90: 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c  rp_error == NULL
8ca0: 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74 65  ) {....test_inte
8cb0: 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e  rp_error = "Unkn
8cc0: 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a  own error";...}.
8cd0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
8ce0: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  r, "Unable to in
8cf0: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74  itialize Tcl int
8d00: 65 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70  erpreter for App
8d10: 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69  FSd:\n");...fpri
8d20: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c  ntf(stderr, "%s\
8d30: 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70 5f  n", test_interp_
8d40: 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72  error);....retur
8d50: 6e 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 65  n(1);..}..Tcl_De
8d60: 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f  leteInterp(test_
8d70: 69 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20  interp);.../*.. 
8d80: 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d  * Add FUSE argum
8d90: 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c  ents which we al
8da0: 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f  ways supply.. */
8db0: 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
8dc0: 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  (&args, NULL, NU
8dd0: 4c 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f  LL, appfs_fuse_o
8de0: 70 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70  pt_cb);..fuse_op
8df0: 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c  t_add_arg(&args,
8e00: 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d   "-odefault_perm
8e10: 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61  issions,fsname=a
8e20: 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70  ppfs,subtype=app
8e30: 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e  fsd,use_ino,kern
8e40: 65 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74  el_cache,entry_t
8e50: 69 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69  imeout=0,attr_ti
8e60: 6d 65 6f 75 74 3d 30 2c 69 6e 74 72 2c 62 69 67  meout=0,intr,big
8e70: 5f 77 72 69 74 65 73 2c 68 61 72 64 5f 72 65 6d  _writes,hard_rem
8e80: 6f 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74  ove");...if (get
8e90: 75 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09  uid() == 0) {...
8ea0: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 26  fuse_opt_parse(&
8eb0: 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  args, NULL, NULL
8ec0: 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f  , NULL);...fuse_
8ed0: 6f 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67  opt_add_arg(&arg
8ee0: 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65  s, "-oallow_othe
8ef0: 72 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  r");..}.../*.. *
8f00: 20 45 6e 74 65 72 20 74 68 65 20 46 55 53 45 20   Enter the FUSE 
8f10: 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69  main loop -- thi
8f20: 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20 61  s will process a
8f30: 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a  ny arguments.. *
8f40: 20 61 6e 64 20 73 74 61 72 74 20 73 65 72 76 69   and start servi
8f50: 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a 09  cing requests...
8f60: 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65 5f   */..appfs_fuse_
8f70: 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72 65  started = 1;..re
8f80: 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61  turn(fuse_main(a
8f90: 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e 61  rgs.argc, args.a
8fa0: 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65 72  rgv, &appfs_oper
8fb0: 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a  ations, NULL));.
8fc0: 7d 0a 20 0a                                      }. .