Hex Artifact Content

Artifact 1768754e265c27bc51c18255ad9b2e0c0b488b62:


0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45  #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e  _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69 64  clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a  ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 69 67 6e 61 6c  #include <signal
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6c 69  .h>.#include <li
0080: 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  mits.h>.#include
0090: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
00a0: 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e 0a  lude <stdarg.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
00c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75 6e  .h>.#include <un
00d0: 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  istd.h>.#include
00e0: 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63 6c   <errno.h>.#incl
00f0: 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69  ude <fcntl.h>.#i
0100: 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e  nclude <stdio.h>
0110: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65 2e  .#include <fuse.
0120: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77 64  h>.#include <pwd
0130: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63  .h>.#include <tc
0140: 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44 65 66 61  l.h>../*. * Defa
0150: 75 6c 74 20 63 61 63 68 65 20 64 69 72 65 63 74  ult cache direct
0160: 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64 65 66 20  ory. */.#ifndef 
0170: 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 0a 23  APPFS_CACHEDIR.#
0180: 64 65 66 69 6e 65 20 41 50 50 46 53 5f 43 41 43  define APPFS_CAC
0190: 48 45 44 49 52 20 22 2f 76 61 72 2f 63 61 63 68  HEDIR "/var/cach
01a0: 65 2f 61 70 70 66 73 22 0a 23 65 6e 64 69 66 0a  e/appfs".#endif.
01b0: 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67 20 6d 61  ./* Debugging ma
01c0: 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65 66 20 44  cros */.#ifdef D
01d0: 45 42 55 47 0a 23 64 65 66 69 6e 65 20 41 50 50  EBUG.#define APP
01e0: 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b  FS_DEBUG(x...) {
01f0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
0200: 20 22 5b 64 65 62 75 67 5d 20 25 73 3a 25 69 3a   "[debug] %s:%i:
0210: 25 73 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f 2c  %s: ", __FILE__,
0220: 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e   __LINE__, __fun
0230: 63 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73 74  c__); fprintf(st
0240: 64 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e 74  derr, x); fprint
0250: 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b  f(stderr, "\n");
0260: 20 7d 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65   }.#else.#define
0270: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e   APPFS_DEBUG(x..
0280: 2e 29 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a  .) /**/.#endif..
0290: 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c 20 50  /*. * SHA1 Tcl P
02a0: 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c 69 7a  ackage initializ
02b0: 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a  er, from sha1.o.
02c0: 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69   */.int Sha1_Ini
02d0: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
02e0: 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68  terp);../*. * Th
02f0: 72 65 61 64 20 53 70 65 63 69 66 69 63 20 44 61  read Specific Da
0300: 74 61 20 28 54 53 44 29 20 66 6f 72 20 54 63 6c  ta (TSD) for Tcl
0310: 20 49 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72   Interpreter for
0320: 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
0330: 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70  ead. */.static p
0340: 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74  thread_key_t int
0350: 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47  erpKey;../*. * G
0360: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c  lobal variables,
0370: 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c 6c 20   needed for all 
0380: 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e 6c 79  threads but only
0390: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 65 66   initialized bef
03a0: 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53 45 20  ore any. * FUSE 
03b0: 74 68 72 65 61 64 73 20 61 72 65 20 63 72 65 61  threads are crea
03c0: 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68  ted. */.const ch
03d0: 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68 65 64  ar *appfs_cached
03e0: 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66 73  ir;.time_t appfs
03f0: 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61  _boottime;.int a
0400: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
0410: 64 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c  d = 0;../*. * Gl
0420: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
0430: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67  or AppFS caching
0440: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0450: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f  ex_t appfs_path_
0460: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
0470: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0480: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e  _INITIALIZER;.in
0490: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
04a0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38  o_cache_size = 8
04b0: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66  209;.struct appf
04c0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66  s_pathinfo *appf
04d0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
04e0: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 23 69 66 6e 64  e = NULL;..#ifnd
04f0: 65 66 20 54 43 4c 5f 54 48 52 45 41 44 53 0a 2f  ef TCL_THREADS./
0500: 2a 0a 20 2a 20 48 61 6e 64 6c 65 20 75 6e 74 68  *. * Handle unth
0510: 72 65 61 64 65 64 20 54 63 6c 0a 20 2a 2f 0a 70  readed Tcl. */.p
0520: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61  thread_mutex_t a
0530: 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f  ppfs_tcl_big_glo
0540: 62 61 6c 5f 6c 6f 63 6b 20 3d 20 50 54 48 52 45  bal_lock = PTHRE
0550: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c  AD_MUTEX_INITIAL
0560: 49 5a 45 52 3b 0a 23 64 65 66 69 6e 65 20 61 70  IZER;.#define ap
0570: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f  pfs_call_libtcl_
0580: 65 6e 74 65 72 20 70 74 68 72 65 61 64 5f 6d 75  enter pthread_mu
0590: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
05a0: 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c  tcl_big_global_l
05b0: 6f 63 6b 29 3b 0a 23 64 65 66 69 6e 65 20 61 70  ock);.#define ap
05c0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f  pfs_call_libtcl_
05d0: 65 78 69 74 20 70 74 68 72 65 61 64 5f 6d 75 74  exit pthread_mut
05e0: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
05f0: 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f  _tcl_big_global_
0600: 6c 6f 63 6b 29 3b 0a 23 65 6c 73 65 0a 23 64 65  lock);.#else.#de
0610: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f  fine appfs_call_
0620: 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 2f 2a 2a  libtcl_enter /**
0630: 2f 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f  /.#define appfs_
0640: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74  call_libtcl_exit
0650: 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 23 64 65   /**/.#endif.#de
0660: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f  fine appfs_call_
0670: 6c 69 62 74 63 6c 28 78 2e 2e 2e 29 20 61 70 70  libtcl(x...) app
0680: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65  fs_call_libtcl_e
0690: 6e 74 65 72 20 78 20 61 70 70 66 73 5f 63 61 6c  nter x appfs_cal
06a0: 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 0a 2f  l_libtcl_exit../
06b0: 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69  *. * Global vari
06c0: 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53 20  ables for AppFS 
06d0: 54 63 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20  Tcl Interpreter 
06e0: 72 65 73 74 61 72 74 69 6e 67 0a 20 2a 2f 0a 69  restarting. */.i
06f0: 6e 74 20 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  nt interp_reset_
0700: 6b 65 79 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20  key = 0;../*. * 
0710: 41 70 70 46 53 20 50 61 74 68 20 54 79 70 65 3a  AppFS Path Type:
0720: 20 20 44 65 73 63 72 69 62 65 73 20 74 68 65 20    Describes the 
0730: 74 79 70 65 20 6f 66 20 70 61 74 68 20 61 20 67  type of path a g
0740: 69 76 65 6e 20 66 69 6c 65 20 69 73 0a 20 2a 2f  iven file is. */
0750: 0a 74 79 70 65 64 65 66 20 65 6e 75 6d 20 7b 0a  .typedef enum {.
0760: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f  .APPFS_PATHTYPE_
0770: 49 4e 56 41 4c 49 44 2c 0a 09 41 50 50 46 53 5f  INVALID,..APPFS_
0780: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f  PATHTYPE_DOES_NO
0790: 54 5f 45 58 49 53 54 2c 0a 09 41 50 50 46 53 5f  T_EXIST,..APPFS_
07a0: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 2c 0a 09  PATHTYPE_FILE,..
07b0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
07c0: 49 52 45 43 54 4f 52 59 2c 0a 09 41 50 50 46 53  IRECTORY,..APPFS
07d0: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e  _PATHTYPE_SYMLIN
07e0: 4b 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  K,..APPFS_PATHTY
07f0: 50 45 5f 53 4f 43 4b 45 54 2c 0a 09 41 50 50 46  PE_SOCKET,..APPF
0800: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 2c  S_PATHTYPE_FIFO,
0810: 0a 7d 20 61 70 70 66 73 5f 70 61 74 68 74 79 70  .} appfs_pathtyp
0820: 65 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  e_t;../*. * AppF
0830: 53 20 50 61 74 68 20 49 6e 66 6f 72 6d 61 74 69  S Path Informati
0840: 6f 6e 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 43  on:. *         C
0850: 6f 6d 70 6c 65 74 65 6c 79 20 64 65 73 63 72 69  ompletely descri
0860: 62 65 73 20 61 20 73 70 65 63 69 66 69 63 20 70  bes a specific p
0870: 61 74 68 2c 20 68 6f 77 20 69 74 20 73 68 6f 75  ath, how it shou
0880: 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64 20 74  ld be returned t
0890: 6f 0a 20 2a 20 20 20 20 20 20 20 20 20 74 6f 20  o. *         to 
08a0: 74 68 65 20 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73  the kernel. */.s
08b0: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
08c0: 69 6e 66 6f 20 7b 0a 09 61 70 70 66 73 5f 70 61  info {..appfs_pa
08d0: 74 68 74 79 70 65 5f 74 20 74 79 70 65 3b 0a 09  thtype_t type;..
08e0: 74 69 6d 65 5f 74 20 74 69 6d 65 3b 0a 09 63 68  time_t time;..ch
08f0: 61 72 20 68 6f 73 74 6e 61 6d 65 5b 32 35 36 5d  ar hostname[256]
0900: 3b 0a 09 69 6e 74 20 70 61 63 6b 61 67 65 64 3b  ;..int packaged;
0910: 0a 09 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20  ..unsigned long 
0920: 6c 6f 6e 67 20 69 6e 6f 64 65 3b 0a 09 75 6e 69  long inode;..uni
0930: 6f 6e 20 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a  on {...struct {.
0940: 09 09 09 69 6e 74 20 63 68 69 6c 64 63 6f 75 6e  ...int childcoun
0950: 74 3b 0a 09 09 7d 20 64 69 72 3b 0a 09 09 73 74  t;...} dir;...st
0960: 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 65 78  ruct {....int ex
0970: 65 63 75 74 61 62 6c 65 3b 0a 09 09 09 6f 66 66  ecutable;....off
0980: 5f 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c  _t size;...} fil
0990: 65 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09  e;...struct {...
09a0: 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09  .off_t size;....
09b0: 63 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d  char source[256]
09c0: 3b 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09  ;...} symlink;..
09d0: 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a  } typeinfo;.../*
09e0: 20 41 74 74 72 69 62 75 74 65 73 20 75 73 65 64   Attributes used
09f0: 20 6f 6e 6c 79 20 66 6f 72 20 63 61 63 68 69 6e   only for cachin
0a00: 67 20 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68  g entries */..ch
0a10: 61 72 20 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b  ar *_cache_path;
0a20: 0a 09 75 69 64 5f 74 20 5f 63 61 63 68 65 5f 75  ..uid_t _cache_u
0a30: 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72  id;.};../*. * Cr
0a40: 65 61 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69  eate a new Tcl i
0a50: 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64 20 63  nterpreter and c
0a60: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
0a70: 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74  lize it. */.stat
0a80: 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61  ic Tcl_Interp *a
0a90: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
0aa0: 6e 74 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72  nterp(char **err
0ab0: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63  or_string) {..Tc
0ac0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
0ad0: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
0ae0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  .const char *tcl
0af0: 5f 73 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41  _setvar_ret;...A
0b00: 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61  PPFS_DEBUG("Crea
0b10: 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74  ting new Tcl int
0b20: 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44  erpreter for TID
0b30: 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73   = 0x%llx", (uns
0b40: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
0b50: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29   pthread_self())
0b60: 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
0b70: 69 62 74 63 6c 28 0a 09 09 69 6e 74 65 72 70 20  ibtcl(...interp 
0b80: 3d 20 54 63 6c 5f 43 72 65 61 74 65 49 6e 74 65  = Tcl_CreateInte
0b90: 72 70 28 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e  rp();..)..if (in
0ba0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
0bb0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0bc0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65  , "Unable to cre
0bd0: 61 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65  ate Tcl Interpre
0be0: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ter.  Aborting.\
0bf0: 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  n");....if (erro
0c00: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
0c10: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
0c20: 74 72 64 75 70 28 22 55 6e 61 62 6c 65 20 74 6f  trdup("Unable to
0c30: 20 63 72 65 61 74 65 20 54 63 6c 20 69 6e 74 65   create Tcl inte
0c40: 72 70 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a  rpreter.");...}.
0c50: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
0c60: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
0c70: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73  _libtcl(Tcl_Pres
0c80: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  erve(interp);)..
0c90: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
0ca0: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20  cl(...tcl_ret = 
0cb0: 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29  Tcl_Init(interp)
0cc0: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
0cd0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
0ce0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0cf0: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74   "Unable to init
0d00: 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f  ialize Tcl.  Abo
0d10: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70  rting.\n");...ap
0d20: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
0d30: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
0d40: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
0d50: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
0d60: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0d70: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
0d80: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
0d90: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
0da0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
0db0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
0dc0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
0dd0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
0de0: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
0df0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
0e00: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
0e10: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
0e20: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
0e30: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
0e40: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
0e50: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
0e60: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
0e70: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
0e80: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
0e90: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
0ea0: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
0eb0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63  val(interp, "pac
0ec0: 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 73 68  kage ifneeded sh
0ed0: 61 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61  a1 1.0 [list loa
0ee0: 64 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09 29  d {} sha1]");..)
0ef0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
0f00: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
0f10: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
0f20: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
0f30: 7a 65 20 54 63 6c 20 53 48 41 31 2e 20 20 41 62  ze Tcl SHA1.  Ab
0f40: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
0f50: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
0f60: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
0f70: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
0f80: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
0f90: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
0fa0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
0fb0: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
0fc0: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
0fd0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
0fe0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
0ff0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
1000: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1010: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
1020: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1030: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
1040: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
1050: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
1060: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
1070: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1080: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1090: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
10a0: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
10b0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
10c0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
10d0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
10e0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61  Eval(interp, "pa
10f0: 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 61  ckage ifneeded a
1100: 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20  ppfsd 1.0 [list 
1110: 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22  load {} appfsd]"
1120: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
1130: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
1140: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1150: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
1160: 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46  tialize Tcl AppF
1170: 53 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72  S Package.  Abor
1180: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70  ting.\n");...app
1190: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
11a0: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
11b0: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
11c0: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
11d0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
11e0: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66  erp));...)....if
11f0: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1200: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  {....appfs_call_
1210: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72  libtcl(.....*err
1220: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
1230: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
1240: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1250: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70  ....)...}....app
1260: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
1270: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1280: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45  p);)....APPFS_DE
1290: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
12a0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
12b0: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
12c0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
12d0: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
12e0: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e  p);)....return(N
12f0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
1300: 2a 20 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c 22  * Load "pki.tcl"
1310: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 77 61 79   in the same way
1320: 20 61 73 20 61 70 70 66 73 64 2e 74 63 6c 20 28   as appfsd.tcl (
1330: 73 65 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f 0a  see below).. */.
1340: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1350: 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72  cl_enter...tcl_r
1360: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
1370: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
1380: 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 09  e "pki.tcl.h"...
1390: 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c  "");..appfs_call
13a0: 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69 66  _libtcl_exit..if
13b0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
13c0: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
13d0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
13e0: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
13f0: 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e  cl PKI.  Abortin
1400: 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f  g.\n");...appfs_
1410: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
1420: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
1430: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
1440: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  s\n", Tcl_GetStr
1450: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
1460: 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65  ));...)....if (e
1470: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
1480: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1490: 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f  tcl(.....*error_
14a0: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
14b0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
14c0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
14d0: 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f  .)...}....appfs_
14e0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
14f0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
1500: 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  )....APPFS_DEBUG
1510: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63  ("Terminating Tc
1520: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
1530: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
1540: 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74  libtcl(Tcl_Delet
1550: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
1560: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  )....return(NULL
1570: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c  );..}.../*.. * L
1580: 6f 61 64 20 74 68 65 20 22 61 70 70 66 73 64 2e  oad the "appfsd.
1590: 74 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69  tcl" script, whi
15a0: 63 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22  ch is "compiled"
15b0: 20 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72   into a C header
15c0: 0a 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20  .. * so that it 
15d0: 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f  does not need to
15e0: 20 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69   exist on the fi
15f0: 6c 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e  lesystem and can
1600: 20 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79   be.. * directly
1610: 20 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f   evaluated... */
1620: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1630: 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f  tcl_enter...tcl_
1640: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1650: 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75  nterp, "".#inclu
1660: 64 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68  de "appfsd.tcl.h
1670: 22 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f  "..."");..appfs_
1680: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74  call_libtcl_exit
1690: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
16a0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
16b0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
16c0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
16d0: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72  ze Tcl AppFS scr
16e0: 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ipt.  Aborting.\
16f0: 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  n");...appfs_cal
1700: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72  l_libtcl(....fpr
1710: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
1720: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
1730: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1740: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1750: 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f  ...)....if (erro
1760: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61  r_string) {....a
1770: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1780: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72  (.....*error_str
1790: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
17a0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
17b0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a  (interp));....).
17c0: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..}....appfs_cal
17d0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
17e0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
17f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
1800: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69  erminating Tcl i
1810: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a  nterpreter.");..
1820: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1830: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e  tcl(Tcl_DeleteIn
1840: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a  terp(interp);)..
1850: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1860: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20  .}.../*.. * Set 
1870: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  global variables
1880: 20 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09   from C to Tcl..
1890: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f   */..appfs_call_
18a0: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73 65  libtcl(...tcl_se
18b0: 74 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f 53  tvar_ret = Tcl_S
18c0: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a  etVar(interp, ":
18d0: 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72  :appfs::cachedir
18e0: 22 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64 69  ", appfs_cachedi
18f0: 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e  r, TCL_GLOBAL_ON
1900: 4c 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c  LY);..)..if (tcl
1910: 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20 4e  _setvar_ret == N
1920: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
1930: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
1940: 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69   to set cache di
1950: 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73  rectory.  This s
1960: 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c  hould never fail
1970: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72  .\n");....if (er
1980: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
1990: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
19a0: 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73  cl(.....*error_s
19b0: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
19c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
19d0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09  lt(interp));....
19e0: 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63  )...}....appfs_c
19f0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
1a00: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
1a10: 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
1a20: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c  "Terminating Tcl
1a30: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
1a40: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
1a50: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65  ibtcl(Tcl_Delete
1a60: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29  Interp(interp);)
1a70: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
1a80: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e  ;..}.../*.. * In
1a90: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70  itialize the "ap
1aa0: 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f  pfsd.tcl" enviro
1ab0: 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73  nment, which mus
1ac0: 74 20 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a  t be done after.
1ad0: 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  . * global varia
1ae0: 62 6c 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20  bles are set... 
1af0: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  */..appfs_call_l
1b00: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
1b10: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
1b20: 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e  rp, "::appfs::in
1b30: 69 74 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  it");..)..if (tc
1b40: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
1b50: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
1b60: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
1b70: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
1b80: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61  ppFS script (::a
1b90: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62  ppfs::init).  Ab
1ba0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
1bb0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1bc0: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
1bd0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
1be0: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
1bf0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1c00: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
1c10: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
1c20: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
1c30: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
1c40: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
1c50: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
1c60: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1c70: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
1c80: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1c90: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
1ca0: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
1cb0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
1cc0: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
1cd0: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1ce0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1cf0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1d00: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
1d10: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  (NULL);..}.../*.
1d20: 09 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63  . * Hide some Tc
1d30: 6c 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20  l commands that 
1d40: 77 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74  we do not care t
1d50: 6f 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20  o use and which 
1d60: 6d 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77  may.. * slow dow
1d70: 6e 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61  n run-time opera
1d80: 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  tions... */..app
1d90: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1da0: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e  ..Tcl_HideComman
1db0: 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f  d(interp, "auto_
1dc0: 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75  load_index", "au
1dd0: 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b  to_load_index");
1de0: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ...Tcl_HideComma
1df0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e  nd(interp, "unkn
1e00: 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29  own", "unknown")
1e10: 3b 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d  ;...Tcl_HideComm
1e20: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69  and(interp, "exi
1e30: 74 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a  t", "exit");..).
1e40: 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65  ../*.. * Release
1e50: 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76   the hold we hav
1e60: 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72  e on the interpr
1e70: 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20  eter so that it 
1e80: 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74  may be.. * delet
1e90: 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a  ed if needed.. *
1ea0: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  /..appfs_call_li
1eb0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
1ec0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a  (interp);).../*.
1ed0: 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63  . * Return the c
1ee0: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
1ef0: 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65  lized interprete
1f00: 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69  r.. */..return(i
1f10: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  nterp);.}../*. *
1f20: 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65   Return the thre
1f30: 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20  ad-specific Tcl 
1f40: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65  interpreter, cre
1f50: 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64  ating it if need
1f60: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63  ed. */.static Tc
1f70: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f  l_Interp *appfs_
1f80: 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20  TclInterp(void) 
1f90: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
1fa0: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72  nterp;..int pthr
1fb0: 65 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63  ead_ret;..static
1fc0: 20 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68   __thread int th
1fd0: 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65  read_interp_rese
1fe0: 74 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20  t_key = 0;..int 
1ff0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
2000: 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61  set_key;...globa
2010: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
2020: 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63  ey = __sync_fetc
2030: 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72  h_and_add(&inter
2040: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b  p_reset_key, 0);
2050: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72  ...interp = pthr
2060: 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28  ead_getspecific(
2070: 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20  interpKey);..if 
2080: 28 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20  (interp != NULL 
2090: 26 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70  && thread_interp
20a0: 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c  _reset_key != gl
20b0: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
20c0: 74 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53  t_key) {...APPFS
20d0: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
20e0: 69 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65  ing old interpre
20f0: 74 65 72 20 61 6e 64 20 72 65 73 74 61 72 74 69  ter and restarti
2100: 6e 67 20 64 75 65 20 74 6f 20 72 65 73 65 74 20  ng due to reset 
2110: 72 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61  request.");....a
2120: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2130: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
2140: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69  p(interp);)....i
2150: 6e 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09  nterp = NULL;...
2160: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
2170: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66  thread_setspecif
2180: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e  ic(interpKey, in
2190: 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  terp);..}...if (
21a0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
21b0: 73 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b  set_key == -1) {
21c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
21d0: 4e 6f 74 20 63 72 65 61 74 69 6e 67 20 61 20 6e  Not creating a n
21e0: 65 77 20 69 6e 74 65 72 70 72 65 74 65 72 20 73  ew interpreter s
21f0: 69 6e 63 65 20 77 65 20 61 72 65 20 74 65 72 6d  ince we are term
2200: 69 6e 61 74 69 6e 67 2e 22 29 3b 0a 0a 09 09 72  inating.");....r
2210: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2220: 0a 09 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f  ..thread_interp_
2230: 72 65 73 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62  reset_key = glob
2240: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
2250: 6b 65 79 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72  key;...if (inter
2260: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69  p == NULL) {...i
2270: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
2280: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e  eate_TclInterp(N
2290: 55 4c 4c 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74  ULL);....if (int
22a0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
22b0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
22c0: 09 09 7d 0a 0a 09 09 70 74 68 72 65 61 64 5f 72  ..}....pthread_r
22d0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 73 65 74  et = pthread_set
22e0: 73 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b  specific(interpK
22f0: 65 79 2c 20 69 6e 74 65 72 70 29 3b 0a 09 09 69  ey, interp);...i
2300: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
2310: 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  = 0) {....APPFS_
2320: 44 45 42 55 47 28 22 70 74 68 72 65 61 64 5f 73  DEBUG("pthread_s
2330: 65 74 73 70 65 63 69 66 69 63 28 29 20 66 61 69  etspecific() fai
2340: 6c 65 64 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e  led.  Terminatin
2350: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
2360: 72 2e 22 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f  r.");.....appfs_
2370: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
2380: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
2390: 65 72 70 29 3b 29 0a 0a 09 09 09 72 65 74 75 72  erp);).....retur
23a0: 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a  n(NULL);...}..}.
23b0: 0a 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29  ..return(interp)
23c0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75  ;.}../*. * Evalu
23d0: 61 74 65 20 61 20 54 63 6c 20 73 63 72 69 70 74  ate a Tcl script
23e0: 20 63 6f 6e 73 74 72 75 63 74 65 64 20 62 79 20   constructed by 
23f0: 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67 20 61 20  concatenating a 
2400: 62 75 6e 63 68 20 6f 66 20 43 20 73 74 72 69 6e  bunch of C strin
2410: 67 73 0a 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a  gs. * together..
2420: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
2430: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63  ppfs_Tcl_Eval(Tc
2440: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
2450: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73  , int objc, cons
2460: 74 20 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e  t char *cmd, ...
2470: 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f  ) {..Tcl_Obj **o
2480: 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  bjv;..const char
2490: 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20   *arg;..va_list 
24a0: 61 72 67 70 3b 0a 09 69 6e 74 20 72 65 74 76 61  argp;..int retva
24b0: 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20  l;..int i;...if 
24c0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
24d0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f   {...return(TCL_
24e0: 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62 6a  ERROR);..}...obj
24f0: 76 20 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b 61  v = (void *) cka
2500: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62 6a  lloc(sizeof(*obj
2510: 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 0a 09 61 70  v) * objc);...ap
2520: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2530: 0a 09 09 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c  ...objv[0] = Tcl
2540: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d  _NewStringObj(cm
2550: 64 2c 20 2d 31 29 3b 0a 0a 09 09 54 63 6c 5f 49  d, -1);....Tcl_I
2560: 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76  ncrRefCount(objv
2570: 5b 30 5d 29 3b 0a 0a 09 09 76 61 5f 73 74 61 72  [0]);....va_star
2580: 74 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 09  t(argp, cmd);...
2590: 66 6f 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20  for (i = 1; i < 
25a0: 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09  objc; i++) {....
25b0: 61 72 67 20 3d 20 76 61 5f 61 72 67 28 61 72 67  arg = va_arg(arg
25c0: 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29  p, const char *)
25d0: 3b 0a 0a 09 09 09 6f 62 6a 76 5b 69 5d 20 3d 20  ;.....objv[i] = 
25e0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
25f0: 28 61 72 67 2c 20 2d 31 29 3b 0a 0a 09 09 09 54  (arg, -1);.....T
2600: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
2610: 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09 09  objv[i]);...}...
2620: 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a 09 29  va_end(argp);..)
2630: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2640: 62 74 63 6c 28 0a 09 09 72 65 74 76 61 6c 20 3d  btcl(...retval =
2650: 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e   Tcl_EvalObjv(in
2660: 74 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76  terp, objc, objv
2670: 2c 20 30 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73  , 0);..)...appfs
2680: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
2690: 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20  for (i = 0; i < 
26a0: 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09  objc; i++) {....
26b0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
26c0: 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09  (objv[i]);...}..
26d0: 29 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f 69 64  )...ckfree((void
26e0: 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20   *) objv);...if 
26f0: 28 72 65 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f  (retval != TCL_O
2700: 4b 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c  K) {...appfs_cal
2710: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
2720: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 63 6f  FS_DEBUG("Tcl co
2730: 6d 6d 61 6e 64 20 66 61 69 6c 65 64 2c 20 3a 3a  mmand failed, ::
2740: 65 72 72 6f 72 49 6e 66 6f 20 63 6f 6e 74 61 69  errorInfo contai
2750: 6e 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  ns: %s\n", Tcl_G
2760: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a  etVar(interp, ":
2770: 3a 65 72 72 6f 72 49 6e 66 6f 22 2c 20 30 29 29  :errorInfo", 0))
2780: 3b 0a 09 09 29 0a 09 7d 0a 0a 09 72 65 74 75 72  ;...)..}...retur
2790: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a  n(retval);.}../*
27a0: 0a 20 2a 20 52 65 71 75 65 73 74 20 61 6c 6c 20  . * Request all 
27b0: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73  Tcl interpreters
27c0: 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74 61   restart. */.sta
27d0: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 74  tic void appfs_t
27e0: 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73 28  cl_ResetInterps(
27f0: 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f 44  void) {..APPFS_D
2800: 45 42 55 47 28 22 52 65 71 75 65 73 74 69 6e 67  EBUG("Requesting
2810: 20 72 65 73 65 74 20 6f 66 20 61 6c 6c 20 69 6e   reset of all in
2820: 74 65 72 70 72 65 74 65 72 73 2e 22 29 3b 0a 0a  terpreters.");..
2830: 09 5f 5f 73 79 6e 63 5f 61 64 64 5f 61 6e 64 5f  .__sync_add_and_
2840: 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72 65  fetch(&interp_re
2850: 73 65 74 5f 6b 65 79 2c 20 31 29 3b 0a 0a 09 72  set_key, 1);...r
2860: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  eturn;.}../*. * 
2870: 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 55 49  Determine the UI
2880: 44 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d  D for the user m
2890: 61 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e  aking the curren
28a0: 74 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65  t FUSE filesyste
28b0: 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68  m request.. * Th
28c0: 69 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20  is will be used 
28d0: 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73  to lookup the us
28e0: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74  er's home direct
28f0: 6f 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65  ory so we can se
2900: 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61  arch for. * loca
2910: 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c  lly modified fil
2920: 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 75  es.. */.static u
2930: 69 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66  id_t appfs_get_f
2940: 73 75 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74  suid(void) {..st
2950: 72 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78  ruct fuse_contex
2960: 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61  t *ctx;...if (!a
2970: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
2980: 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65  d) {...return(ge
2990: 74 75 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74  tuid());..}...ct
29a0: 78 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e  x = fuse_get_con
29b0: 74 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78  text();..if (ctx
29c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a   == NULL) {.../*
29d0: 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75   Unable to looku
29e0: 70 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20  p user for some 
29f0: 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52  reason */.../* R
2a00: 65 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69  eturn an unprivi
2a10: 6c 65 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f  leged user ID */
2a20: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
2a30: 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 75  ...return(ctx->u
2a40: 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65  id);.}../*. * De
2a50: 74 65 72 6d 69 6e 65 20 74 68 65 20 47 49 44 20  termine the GID 
2a60: 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b  for the user mak
2a70: 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74 20  ing the current 
2a80: 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d 20  FUSE filesystem 
2a90: 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69 73  request.. * This
2aa0: 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74 6f   will be used to
2ab0: 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65 72   lookup the user
2ac0: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
2ad0: 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61 72  y so we can sear
2ae0: 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c  ch for. * locall
2af0: 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65 73  y modified files
2b00: 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69 64  .. */.static gid
2b10: 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67  _t appfs_get_fsg
2b20: 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75  id(void) {..stru
2b30: 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20  ct fuse_context 
2b40: 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70  *ctx;...if (!app
2b50: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29  fs_fuse_started)
2b60: 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74 67   {...return(getg
2b70: 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20  id());..}...ctx 
2b80: 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  = fuse_get_conte
2b90: 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d  xt();..if (ctx =
2ba0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55  = NULL) {.../* U
2bb0: 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20  nable to lookup 
2bc0: 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65  user for some re
2bd0: 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74  ason */.../* Ret
2be0: 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65  urn an unprivile
2bf0: 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09  ged user ID */..
2c00: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
2c10: 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67 69 64  .return(ctx->gid
2c20: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
2c30: 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  d appfs_simulate
2c40: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 76  _user_fs_enter(v
2c50: 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69 64  oid) {..setfsuid
2c60: 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  (appfs_get_fsuid
2c70: 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64 28 61  ());..setfsgid(a
2c80: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29  ppfs_get_fsgid()
2c90: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
2ca0: 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  d appfs_simulate
2cb0: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 76  _user_fs_leave(v
2cc0: 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69 64  oid) {..setfsuid
2cd0: 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64 28 30  (0);..setfsgid(0
2ce0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b  );.}../*. * Look
2cf0: 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69 72   up the home dir
2d00: 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69 76  ectory for a giv
2d10: 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20 20  en UID. *       
2d20: 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74 72   Returns a C str
2d30: 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ing containing t
2d40: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
2d50: 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c 4c  irectory or NULL
2d60: 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74 68   if. *        th
2d70: 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69  e user's home di
2d80: 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f 74  rectory does not
2d90: 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f 74   exist or is not
2da0: 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20 20   correctly. *   
2db0: 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64 0a       configured.
2dc0: 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20   */.static char 
2dd0: 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64  *appfs_get_homed
2de0: 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29 20  ir(uid_t fsuid) 
2df0: 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77 64  {..struct passwd
2e00: 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74 3b   entry, *result;
2e10: 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73 74  ..struct stat st
2e20: 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b 31  buf;..char buf[1
2e30: 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a 09  024], *retval;..
2e40: 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74 61  int gpu_ret, sta
2e50: 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65 74  t_ret;...gpu_ret
2e60: 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66 73   = getpwuid_r(fs
2e70: 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75 66  uid, &entry, buf
2e80: 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20 26  , sizeof(buf), &
2e90: 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67 70  result);..if (gp
2ea0: 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  u_ret != 0) {...
2eb0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74  APPFS_DEBUG("get
2ec0: 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e  pwuid_r(%llu, ..
2ed0: 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20 66  .) returned in f
2ee0: 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67 6e  ailure", (unsign
2ef0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
2f00: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  uid);....return(
2f10: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
2f20: 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29 20  result == NULL) 
2f30: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
2f40: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
2f50: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
2f60: 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28 75  NULL result", (u
2f70: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
2f80: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65  g) fsuid);....re
2f90: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
2fa0: 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77 5f  .if (result->pw_
2fb0: 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  dir == NULL) {..
2fc0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
2fd0: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
2fe0: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c  ..) returned NUL
2ff0: 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  L home directory
3000: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
3010: 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a  g long) fsuid);.
3020: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3030: 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20 3d  ..}...stat_ret =
3040: 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70 77   stat(result->pw
3050: 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a 09  _dir, &stbuf);..
3060: 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d 20  if (stat_ret != 
3070: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
3080: 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65 74  UG("stat(%s) ret
3090: 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65  urned in failure
30a0: 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69  ", result->pw_di
30b0: 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  r);....return(NU
30c0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 74  LL);..}...if (st
30d0: 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66 73  buf.st_uid != fs
30e0: 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  uid) {...APPFS_D
30f0: 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d 61  EBUG("UID mis-ma
3100: 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c 75  tch on user %llu
3110: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
3120: 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f 77  y (%s).  It's ow
3130: 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a 09  ned by %llu.",..
3140: 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20 6c  .    (unsigned l
3150: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 2c  ong long) fsuid,
3160: 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e 70  ...    result->p
3170: 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75 6e  w_dir,...    (un
3180: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
3190: 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a 09  ) stbuf.st_uid..
31a0: 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  .);....return(NU
31b0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  LL);..}...retval
31c0: 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c 74   = strdup(result
31d0: 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65 74  ->pw_dir);...ret
31e0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
31f0: 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20 61  /*. * Generate a
3200: 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67 69  n inode for a gi
3210: 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20 69  ven path.  The i
3220: 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20 63  node should be c
3230: 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68 0a  omputed in such.
3240: 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69 74   * a way that it
3250: 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f 20   is unlikely to 
3260: 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61 6e  be duplicated an
3270: 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73 61  d remains the sa
3280: 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a 20  me for a given. 
3290: 2a 20 66 69 6c 65 0a 20 2a 2f 0a 23 69 66 20 55  * file. */.#if U
32a0: 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34 39 36  INT_MAX < 429496
32b0: 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e 74 65  7295.#error Inte
32c0: 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f 6f 20  ger size is too 
32d0: 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a 73 74  small .#endif.st
32e0: 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 6c 6f  atic unsigned lo
32f0: 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f 67 65  ng long appfs_ge
3300: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63 6f 6e  t_path_inode(con
3310: 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b  st char *path) {
3320: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09 63  ..int retval;..c
3330: 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a 09  onst char *p;...
3340: 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09 66  retval = 10;...f
3350: 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a 70  or (p = path; *p
3360: 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76 61  ; p++) {...retva
3370: 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30 55  l %= 4290960290U
3380: 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20  LL;...retval += 
3390: 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c 3d  *p;...retval <<=
33a0: 20 36 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20   6;..}...retval 
33b0: 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20 25  += 10;..retval %
33c0: 3d 20 34 32 39 34 39 36 37 32 38 36 55 4c 4c 3b  = 4294967286ULL;
33d0: 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31 30 3b 0a  ..retval += 10;.
33e0: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
33f0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68 65  ;.}../*. * Cache
3400: 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20 6c   Get Path Info l
3410: 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65 64  ookups for speed
3420: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
3430: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3440: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63 6f  nfo_cache_get(co
3450: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
3460: 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63  uid_t uid, struc
3470: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
3480: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75   *pathinfo) {..u
3490: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
34a0: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
34b0: 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74  ad_ret;..int ret
34c0: 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  val;...retval = 
34d0: 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  1;...pthread_ret
34e0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
34f0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
3500: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
3510: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
3520: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
3530: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3540: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
3550: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
3560: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
3570: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61  (-1);..}...if (a
3580: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3590: 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  ache != NULL) {.
35a0: 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
35b0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
35c0: 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20  de(path) + uid) 
35d0: 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  % appfs_path_inf
35e0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09  o_cache_size;...
35f0: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
3600: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3610: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3620: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 69   != NULL) {....i
3630: 66 20 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f  f (strcmp(appfs_
3640: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3650: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
3660: 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d 3d 20  _path, path) == 
3670: 30 20 26 26 20 61 70 70 66 73 5f 70 61 74 68 5f  0 && appfs_path_
3680: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3690: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20  idx]._cache_uid 
36a0: 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 72 65  == uid) {.....re
36b0: 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09 6d  tval = 0;......m
36c0: 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2c 20  emcpy(pathinfo, 
36d0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
36e0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
36f0: 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e  , sizeof(*pathin
3700: 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 69 6e  fo));.....pathin
3710: 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68 20  fo->_cache_path 
3720: 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d  = NULL;....}...}
3730: 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  ..}...pthread_re
3740: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3750: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
3760: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
3770: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
3780: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3790: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
37a0: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
37b0: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
37c0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
37d0: 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09  eturn(-1);..}...
37e0: 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29  if (retval == 0)
37f0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
3800: 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e 20 25  ("Cache hit on %
3810: 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65 6c  s", path);..} el
3820: 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  se {...APPFS_DEB
3830: 55 47 28 22 43 61 63 68 65 20 6d 69 73 73 20 6f  UG("Cache miss o
3840: 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d  n %s", path);..}
3850: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
3860: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
3870: 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  d appfs_get_path
3880: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28  _info_cache_add(
3890: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
38a0: 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72  , uid_t uid, str
38b0: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
38c0: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a  fo *pathinfo) {.
38d0: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61  .unsigned int ha
38e0: 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  sh_idx;..int pth
38f0: 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72  read_ret;...pthr
3900: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
3910: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70  d_mutex_lock(&ap
3920: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3930: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
3940: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
3950: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
3960: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  UG("Unable to lo
3970: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
3980: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
3990: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66  .return;..}...if
39a0: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
39b0: 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29  o_cache == NULL)
39c0: 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f   {...appfs_path_
39d0: 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 61 6c  info_cache = cal
39e0: 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68 5f 69  loc(appfs_path_i
39f0: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c 20  nfo_cache_size, 
3a00: 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70 61  sizeof(*appfs_pa
3a10: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29 3b  th_info_cache));
3a20: 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20 3d  ..}...hash_idx =
3a30: 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68   (appfs_get_path
3a40: 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20 75  _inode(path) + u
3a50: 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74 68  id) % appfs_path
3a60: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
3a70: 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61  ;...if (appfs_pa
3a80: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
3a90: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
3aa0: 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath != NULL) {..
3ab0: 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68  .free(appfs_path
3ac0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3ad0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
3ae0: 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28  h);..}...memcpy(
3af0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
3b00: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
3b10: 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a 65  , pathinfo, size
3b20: 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a  of(*pathinfo));.
3b30: 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
3b40: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3b50: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ]._cache_path = 
3b60: 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a 09 61  strdup(path);..a
3b70: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3b80: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
3b90: 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75 69 64  cache_uid  = uid
3ba0: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
3bb0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
3bc0: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
3bd0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
3be0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
3bf0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
3c00: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
3c10: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
3c20: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
3c30: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
3c40: 75 72 6e 3b 0a 09 7d 0a 09 72 65 74 75 72 6e 3b  urn;..}..return;
3c50: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
3c60: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3c70: 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e  nfo_cache_rm(con
3c80: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75  st char *path, u
3c90: 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e 73  id_t uid) {..uns
3ca0: 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69  igned int hash_i
3cb0: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  dx;..int pthread
3cc0: 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f  _ret;...pthread_
3cd0: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
3ce0: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
3cf0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
3d00: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
3d10: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3d20: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3d30: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70  Unable to lock p
3d40: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
3d50: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
3d60: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70  urn;..}...if (ap
3d70: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3d80: 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che != NULL) {..
3d90: 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70  .hash_idx = (app
3da0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
3db0: 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20 25  e(path) + uid) %
3dc0: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
3dd0: 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09  _cache_size;....
3de0: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
3df0: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3e00: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
3e10: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72  != NULL) {....fr
3e20: 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ee(appfs_path_in
3e30: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3e40: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b  x]._cache_path);
3e50: 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f  .....appfs_path_
3e60: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3e70: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3e80: 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a   = NULL;...}..}.
3e90: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
3ea0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
3eb0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
3ec0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
3ed0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
3ee0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
3ef0: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
3f00: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74  le to unlock pat
3f10: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
3f20: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
3f30: 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a  n;..}...return;.
3f40: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  }..static void a
3f50: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
3f60: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 75  fo_cache_flush(u
3f70: 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20 6e 65  id_t uid, int ne
3f80: 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67  w_size) {..unsig
3f90: 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e  ned int idx;..in
3fa0: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a  t pthread_ret;..
3fb0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 46 6c  .APPFS_DEBUG("Fl
3fc0: 75 73 68 69 6e 67 20 41 70 70 46 53 20 63 61 63  ushing AppFS cac
3fd0: 68 65 20 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20  he (uid = %lli, 
3fe0: 6e 65 77 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c  new_size = %i)",
3ff0: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64   (long long) uid
4000: 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70  , new_size);...p
4010: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
4020: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
4030: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
4040: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
4050: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
4060: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
4070: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
4080: 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20   lock path_info 
4090: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
40a0: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
40b0: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
40c0: 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55  info_cache != NU
40d0: 4c 4c 29 20 7b 0a 09 09 66 6f 72 20 28 69 64 78  LL) {...for (idx
40e0: 20 3d 20 30 3b 20 69 64 78 20 3c 20 61 70 70 66   = 0; idx < appf
40f0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4100: 65 5f 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b  e_size; idx++) {
4110: 0a 09 09 09 69 66 20 28 61 70 70 66 73 5f 70 61  ....if (appfs_pa
4120: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64  th_info_cache[id
4130: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
4140: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66  = NULL) {.....if
4150: 20 28 75 69 64 20 21 3d 20 28 28 75 69 64 5f 74   (uid != ((uid_t
4160: 29 20 2d 31 29 29 20 7b 0a 09 09 09 09 09 69 66  ) -1)) {......if
4170: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
4180: 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61  o_cache[idx]._ca
4190: 63 68 65 5f 75 69 64 20 21 3d 20 75 69 64 29 20  che_uid != uid) 
41a0: 7b 0a 09 09 09 09 09 09 63 6f 6e 74 69 6e 75 65  {.......continue
41b0: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
41c0: 09 09 09 09 66 72 65 65 28 61 70 70 66 73 5f 70  ....free(appfs_p
41d0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69  ath_info_cache[i
41e0: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29  dx]._cache_path)
41f0: 3b 0a 0a 09 09 09 09 61 70 70 66 73 5f 70 61 74  ;......appfs_pat
4200: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78  h_info_cache[idx
4210: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ]._cache_path = 
4220: 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09  NULL;....}...}..
4230: 7d 0a 0a 09 69 66 20 28 75 69 64 20 3d 3d 20 28  }...if (uid == (
4240: 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09  (uid_t) -1)) {..
4250: 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68  .free(appfs_path
4260: 5f 69 6e 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09  _info_cache);...
4270: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
4280: 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a  _cache = NULL;..
4290: 09 09 69 66 20 28 6e 65 77 5f 73 69 7a 65 20 21  ..if (new_size !
42a0: 3d 20 2d 31 29 20 7b 0a 09 09 09 61 70 70 66 73  = -1) {....appfs
42b0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
42c0: 5f 73 69 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65  _size = new_size
42d0: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65  ;...}..}...pthre
42e0: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
42f0: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61  _mutex_unlock(&a
4300: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4310: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
4320: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
4330: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
4340: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75  BUG("Unable to u
4350: 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20  nlock path_info 
4360: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
4370: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
4380: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47  .return;.}../* G
4390: 65 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61  et information a
43a0: 62 6f 75 74 20 61 20 70 61 74 68 2c 20 61 6e 64  bout a path, and
43b0: 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74   optionally list
43c0: 20 63 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61   children */.sta
43d0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65  tic int appfs_ge
43e0: 74 5f 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73  t_path_info(cons
43f0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
4400: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
4410: 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b  nfo *pathinfo) {
4420: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
4430: 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a  terp;..Tcl_Obj *
4440: 61 74 74 72 73 5f 64 69 63 74 2c 20 2a 61 74 74  attrs_dict, *att
4450: 72 5f 76 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20  r_value;..const 
4460: 63 68 61 72 20 2a 61 74 74 72 5f 76 61 6c 75 65  char *attr_value
4470: 5f 73 74 72 3b 0a 09 54 63 6c 5f 57 69 64 65 49  _str;..Tcl_WideI
4480: 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  nt attr_value_wi
4490: 64 65 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76 61  de;..int attr_va
44a0: 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63  lue_int;..static
44b0: 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62   __thread Tcl_Ob
44c0: 6a 20 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  j *attr_key_type
44d0: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
44e0: 65 79 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c  ey_perms = NULL,
44f0: 20 2a 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20   *attr_key_size 
4500: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4510: 79 5f 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a  y_time = NULL, *
4520: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20  attr_key_source 
4530: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4540: 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e  y_childcount = N
4550: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70  ULL, *attr_key_p
4560: 61 63 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a  ackaged = NULL;.
4570: 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a  .int cache_ret;.
4580: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69  .int tcl_ret;..i
4590: 6e 74 20 72 65 74 76 61 6c 3b 0a 09 75 69 64 5f  nt retval;..uid_
45a0: 74 20 66 73 75 69 64 3b 0a 0a 09 72 65 74 76 61  t fsuid;...retva
45b0: 6c 20 3d 20 30 3b 0a 0a 09 66 73 75 69 64 20 3d  l = 0;...fsuid =
45c0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
45d0: 28 29 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20  ();...cache_ret 
45e0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
45f0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28  _info_cache_get(
4600: 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74  path, fsuid, pat
4610: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 63 61 63  hinfo);..if (cac
4620: 68 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09  he_ret == 0) {..
4630: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74  .if (pathinfo->t
4640: 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54  ype == APPFS_PAT
4650: 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45  HTYPE_DOES_NOT_E
4660: 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72  XIST) {....retur
4670: 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a  n(-ENOENT);...}.
4680: 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d  ...if (pathinfo-
4690: 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  >type == APPFS_P
46a0: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29  ATHTYPE_INVALID)
46b0: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 49   {....return(-EI
46c0: 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72  O);...}....retur
46d0: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72  n(0);..}...inter
46e0: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
46f0: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
4700: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
4710: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
4720: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
4730: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
4740: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63  e(interp);)...tc
4750: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
4760: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
4770: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  , "::appfs::geta
4780: 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ttr", path);..if
4790: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
47a0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
47b0: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67  EBUG("::appfs::g
47c0: 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65  etattr(%s) faile
47d0: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
47e0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
47f0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
4800: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
4810: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
4820: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
4830: 3b 0a 09 09 29 0a 0a 09 09 70 61 74 68 69 6e 66  ;...)....pathinf
4840: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
4850: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f  PATHTYPE_DOES_NO
4860: 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61 70 70 66  T_EXIST;....appf
4870: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
4880: 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20  cache_add(path, 
4890: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29  fsuid, pathinfo)
48a0: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
48b0: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
48c0: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
48d0: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b  return(-ENOENT);
48e0: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b  ..}...if (attr_k
48f0: 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29  ey_type == NULL)
4900: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f   {...appfs_call_
4910: 6c 69 62 74 63 6c 28 0a 09 09 09 61 74 74 72 5f  libtcl(....attr_
4920: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d  key_type       =
4930: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
4940: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09  j("type", -1);..
4950: 09 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73  ..attr_key_perms
4960: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
4970: 74 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22  tringObj("perms"
4980: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b  , -1);....attr_k
4990: 65 79 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20  ey_size       = 
49a0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
49b0: 28 22 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09  ("size", -1);...
49c0: 09 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20  .attr_key_time  
49d0: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
49e0: 72 69 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20  ringObj("time", 
49f0: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79  -1);....attr_key
4a00: 5f 73 6f 75 72 63 65 20 20 20 20 20 3d 20 54 63  _source     = Tc
4a10: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
4a20: 73 6f 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09  source", -1);...
4a30: 09 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63  .attr_key_childc
4a40: 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74  ount = Tcl_NewSt
4a50: 72 69 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f  ringObj("childco
4a60: 75 6e 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  unt", -1);....at
4a70: 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20  tr_key_packaged 
4a80: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
4a90: 67 4f 62 6a 28 22 70 61 63 6b 61 67 65 64 22 2c  gObj("packaged",
4aa0: 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e   -1);.....Tcl_In
4ab0: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
4ac0: 6b 65 79 5f 74 79 70 65 29 3b 0a 09 09 09 54 63  key_type);....Tc
4ad0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
4ae0: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a  ttr_key_perms);.
4af0: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
4b00: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a  unt(attr_key_siz
4b10: 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  e);....Tcl_IncrR
4b20: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
4b30: 5f 74 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49  _time);....Tcl_I
4b40: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
4b50: 5f 6b 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09  _key_source);...
4b60: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
4b70: 74 28 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64  t(attr_key_child
4b80: 63 6f 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49  count);....Tcl_I
4b90: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
4ba0: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a  _key_packaged);.
4bb0: 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  ..)..}...appfs_c
4bc0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74  all_libtcl(...at
4bd0: 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47  trs_dict = Tcl_G
4be0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
4bf0: 72 70 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d  rp);...tcl_ret =
4c00: 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28   Tcl_DictObjGet(
4c10: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
4c20: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70  ct, attr_key_typ
4c30: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
4c40: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
4c50: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
4c60: 41 50 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69  APPFS_DEBUG("[di
4c70: 63 74 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d  ct get \"type\"]
4c80: 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 61 70 70   failed");...app
4c90: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
4ca0: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4cb0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
4cc0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
4cd0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
4ce0: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...)....appfs_ca
4cf0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
4d00: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
4d10: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
4d20: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76  ..}...if (attr_v
4d30: 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  alue == NULL) {.
4d40: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
4d50: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
4d60: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
4d70: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
4d80: 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67  pathinfo->packag
4d90: 65 64 20 3d 20 30 3b 0a 09 70 61 74 68 69 6e 66  ed = 0;..pathinf
4da0: 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73  o->inode = appfs
4db0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
4dc0: 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 63  path);...appfs_c
4dd0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74  all_libtcl(...at
4de0: 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54  tr_value_str = T
4df0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74  cl_GetString(att
4e00: 72 5f 76 61 6c 75 65 29 3b 0a 0a 09 09 73 77 69  r_value);....swi
4e10: 74 63 68 20 28 61 74 74 72 5f 76 61 6c 75 65 5f  tch (attr_value_
4e20: 73 74 72 5b 30 5d 29 20 7b 0a 09 09 09 63 61 73  str[0]) {....cas
4e30: 65 20 27 64 27 3a 20 2f 2a 20 64 69 72 65 63 74  e 'd': /* direct
4e40: 6f 72 79 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ory */.....pathi
4e50: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
4e60: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
4e70: 54 4f 52 59 3b 0a 09 09 09 09 70 61 74 68 69 6e  TORY;.....pathin
4e80: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72  fo->typeinfo.dir
4e90: 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 30 3b  .childcount = 0;
4ea0: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ......Tcl_DictOb
4eb0: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
4ec0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
4ed0: 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20 26 61  y_childcount, &a
4ee0: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09  ttr_value);.....
4ef0: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
4f00: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 74  = NULL) {......t
4f10: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
4f20: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e  WideIntFromObj(N
4f30: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c  ULL, attr_value,
4f40: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64   &attr_value_wid
4f50: 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63 6c  e);......if (tcl
4f60: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
4f70: 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  {.......pathinfo
4f80: 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63  ->typeinfo.dir.c
4f90: 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74 72  hildcount = attr
4fa0: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09  _value_wide;....
4fb0: 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 62  ..}.....}......b
4fc0: 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 66  reak;....case 'f
4fd0: 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09  ': /* file */...
4fe0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
4ff0: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
5000: 45 5f 46 49 4c 45 3b 0a 09 09 09 09 70 61 74 68  E_FILE;.....path
5010: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5020: 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09  ile.size = 0;...
5030: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5040: 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74  info.file.execut
5050: 61 62 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54  able = 0;......T
5060: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5070: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5080: 2c 20 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c  , attr_key_size,
5090: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
50a0: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
50b0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
50c0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
50d0: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
50e0: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
50f0: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
5100: 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28  wide);......if (
5110: 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f  tcl_ret == TCL_O
5120: 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69  K) {.......pathi
5130: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5140: 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f 76  le.size = attr_v
5150: 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09  alue_wide;......
5160: 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c  }.....}......Tcl
5170: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5180: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5190: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20  attr_key_perms, 
51a0: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
51b0: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
51c0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
51d0: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
51e0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
51f0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5200: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
5210: 5f 73 74 72 5b 30 5d 20 3d 3d 20 27 78 27 29 20  _str[0] == 'x') 
5220: 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  {.......pathinfo
5230: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5240: 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b 0a  executable = 1;.
5250: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09  .....}.....}....
5260: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
5270: 27 73 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20  's': /* symlink 
5280: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
5290: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
52a0: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a  THTYPE_SYMLINK;.
52b0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
52c0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
52d0: 69 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74  ize = 0;.....pat
52e0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
52f0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30  symlink.source[0
5300: 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54  ] = '\0';......T
5310: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5320: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5330: 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63  , attr_key_sourc
5340: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
5350: 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61  .....if (attr_va
5360: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
5370: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
5380: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
5390: 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76  ngFromObj(attr_v
53a0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
53b0: 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69  e_int); .......i
53c0: 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69  f ((attr_value_i
53d0: 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f  nt + 1) <= sizeo
53e0: 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  f(pathinfo->type
53f0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
5400: 72 63 65 29 29 20 7b 0a 09 09 09 09 09 09 70 61  rce)) {.......pa
5410: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5420: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20  .symlink.size = 
5430: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a  attr_value_int;.
5440: 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ......pathinfo->
5450: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
5460: 2e 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c  .source[attr_val
5470: 75 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a  ue_int] = '\0';.
5480: 0a 09 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61  .......memcpy(pa
5490: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
54a0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
54b0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c   attr_value_str,
54c0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29   attr_value_int)
54d0: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09  ;......}.....}..
54e0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
54f0: 65 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66  e 'F': /* pipe/f
5500: 69 66 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ifo */.....pathi
5510: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
5520: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b  S_PATHTYPE_FIFO;
5530: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
5540: 61 73 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58  ase 'S': /* UNIX
5550: 20 64 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a   domain socket *
5560: 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  /.....pathinfo->
5570: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
5580: 48 54 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09  HTYPE_SOCKET;...
5590: 09 09 62 72 65 61 6b 3b 0a 09 09 09 64 65 66 61  ..break;....defa
55a0: 75 6c 74 3a 0a 09 09 09 09 72 65 74 76 61 6c 20  ult:.....retval 
55b0: 3d 20 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54  = -EIO;...}....T
55c0: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
55d0: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
55e0: 2c 20 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61  , attr_key_packa
55f0: 67 65 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  ged, &attr_value
5600: 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61  );...if (attr_va
5610: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
5620: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b  ..pathinfo->pack
5630: 61 67 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09  aged = 1;...}...
5640: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
5650: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
5660: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d  ct, attr_key_tim
5670: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
5680: 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
5690: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
56a0: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
56b0: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
56c0: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
56d0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
56e0: 64 65 29 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f  de);....if (tcl_
56f0: 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret == TCL_OK) {
5700: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5710: 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65  ime = attr_value
5720: 5f 77 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20  _wide;....}...} 
5730: 65 6c 73 65 20 7b 0a 09 09 09 70 61 74 68 69 6e  else {....pathin
5740: 66 6f 2d 3e 74 69 6d 65 20 3d 20 30 3b 0a 09 09  fo->time = 0;...
5750: 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65  }....Tcl_Release
5760: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 69  (interp);..)...i
5770: 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20  f (retval == 0) 
5780: 7b 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70 61  {...appfs_get_pa
5790: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64  th_info_cache_ad
57a0: 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70  d(path, fsuid, p
57b0: 61 74 68 69 6e 66 6f 29 3b 0a 09 7d 0a 0a 09 72  athinfo);..}...r
57c0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
57d0: 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61  ..static char *a
57e0: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
57f0: 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61  create(const cha
5800: 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f  r *path) {..Tcl_
5810: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
5820: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61  .const char *rea
5830: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c  l_path;..int tcl
5840: 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65  _ret;...appfs_ge
5850: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
5860: 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65  e_flush(appfs_ge
5870: 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a  t_fsuid(), -1);.
5880: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
5890: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
58a0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
58b0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
58c0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  LL);..}...appfs_
58d0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
58e0: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
58f0: 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;)...appfs_call_
5900: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65  libtcl(...tcl_re
5910: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
5920: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
5930: 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f  :appfs::prepare_
5940: 74 6f 5f 63 72 65 61 74 65 22 2c 20 70 61 74 68  to_create", path
5950: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
5960: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
5970: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
5980: 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f  :appfs::prepare_
5990: 74 6f 5f 63 72 65 61 74 65 28 25 73 29 20 66 61  to_create(%s) fa
59a0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
59b0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
59c0: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
59d0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
59e0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
59f0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
5a00: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
5a10: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
5a20: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
5a30: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  );)....return(NU
5a40: 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  LL);..}...appfs_
5a50: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72  call_libtcl(...r
5a60: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
5a70: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
5a80: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70  nterp);..)...app
5a90: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
5aa0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
5ab0: 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f  p);)...if (real_
5ac0: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
5ad0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
5ae0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64  .}...return(strd
5af0: 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a  up(real_path));.
5b00: 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  }..static char *
5b10: 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28  appfs_localpath(
5b20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
5b30: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
5b40: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
5b50: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
5b60: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
5b70: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
5b80: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
5b90: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
5ba0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ) {...return(NUL
5bb0: 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  L);..}...appfs_c
5bc0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50  all_libtcl(Tcl_P
5bd0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
5be0: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
5bf0: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
5c00: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
5c10: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
5c20: 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68  appfs::localpath
5c30: 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66  ", path);..)..if
5c40: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
5c50: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
5c60: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c  EBUG("::appfs::l
5c70: 6f 63 61 6c 70 61 74 68 28 25 73 29 20 66 61 69  ocalpath(%s) fai
5c80: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
5c90: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5ca0: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
5cb0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
5cc0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
5cd0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
5ce0: 29 29 3b 0a 09 09 29 0a 0a 09 09 72 65 74 75 72  ));...)....retur
5cf0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
5d00: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5d10: 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
5d20: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5d30: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a  lt(interp);..)..
5d40: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5d50: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
5d60: 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72  nterp);)...if (r
5d70: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
5d80: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ) {...return(NUL
5d90: 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  L);..}...return(
5da0: 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68  strdup(real_path
5db0: 29 29 3b 0a 7d 0a 0a 23 69 66 20 28 64 65 66 69  ));.}..#if (defi
5dc0: 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65  ned(DEBUG) && de
5dd0: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54  fined(APPFS_EXIT
5de0: 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e  _PATH)) || defin
5df0: 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41  ed(APPFS_EXIT_PA
5e00: 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f  TH_ENABLE_MAJOR_
5e10: 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73  SECURITY_HOLE).s
5e20: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
5e30: 5f 65 78 69 74 28 76 6f 69 64 29 20 7b 0a 09 69  _exit(void) {..i
5e40: 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  nt global_interp
5e50: 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c  _reset_key;...gl
5e60: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
5e70: 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66  t_key = __sync_f
5e80: 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e  etch_and_add(&in
5e90: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
5ea0: 30 29 3b 0a 09 5f 5f 73 79 6e 63 5f 66 65 74 63  0);..__sync_fetc
5eb0: 68 5f 61 6e 64 5f 73 75 62 28 26 69 6e 74 65 72  h_and_sub(&inter
5ec0: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 67 6c 6f  p_reset_key, glo
5ed0: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
5ee0: 5f 6b 65 79 29 3b 0a 0a 09 77 68 69 6c 65 20 28  _key);...while (
5ef0: 5f 5f 73 79 6e 63 5f 73 75 62 5f 61 6e 64 5f 66  __sync_sub_and_f
5f00: 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73  etch(&interp_res
5f10: 65 74 5f 6b 65 79 2c 20 31 29 20 3e 3d 20 30 29  et_key, 1) >= 0)
5f20: 20 7b 0a 09 09 2f 2a 20 42 75 73 79 20 4c 6f 6f   {.../* Busy Loo
5f30: 70 20 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f 62 61 6c  p */..}...global
5f40: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
5f50: 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68  y = __sync_fetch
5f60: 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70  _and_add(&interp
5f70: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a  _reset_key, 0);.
5f80: 09 69 66 20 28 67 6c 6f 62 61 6c 5f 69 6e 74 65  .if (global_inte
5f90: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20  rp_reset_key != 
5fa0: 2d 31 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  -1) {...APPFS_DE
5fb0: 42 55 47 28 22 45 72 72 6f 72 20 73 65 6e 64 69  BUG("Error sendi
5fc0: 6e 67 20 6b 69 6c 6c 20 73 69 67 6e 61 6c 20 74  ng kill signal t
5fd0: 6f 20 61 6c 6c 20 74 68 72 65 61 64 73 2c 20 61  o all threads, a
5fe0: 62 6f 72 74 69 6e 67 20 61 6e 79 77 61 79 2e 22  borting anyway."
5ff0: 29 3b 0a 09 7d 0a 0a 09 66 75 73 65 5f 65 78 69  );..}...fuse_exi
6000: 74 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  t(fuse_get_conte
6010: 78 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 61  xt()->fuse);...a
6020: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6030: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d  fo_cache_flush(-
6040: 31 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e  1, -1);...return
6050: 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74  ;.}.#endif..stat
6060: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
6070: 65 5f 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74  e_readlink(const
6080: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61   char *path, cha
6090: 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73  r *buf, size_t s
60a0: 69 7a 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61  ize) {..struct a
60b0: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61  ppfs_pathinfo pa
60c0: 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74  thinfo;..int ret
60d0: 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53  val = 0;...APPFS
60e0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
60f0: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
6100: 20 70 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e   path);...pathin
6110: 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  fo.type = APPFS_
6120: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
6130: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70  ;...retval = app
6140: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6150: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
6160: 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21  );..if (retval !
6170: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
6180: 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66  retval);..}...if
6190: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20   (pathinfo.type 
61a0: 21 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  != APPFS_PATHTYP
61b0: 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72  E_SYMLINK) {...r
61c0: 65 74 75 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a  eturn(-EINVAL);.
61d0: 09 7d 0a 0a 09 69 66 20 28 28 73 74 72 6c 65 6e  .}...if ((strlen
61e0: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e  (pathinfo.typein
61f0: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
6200: 65 29 20 2b 20 31 29 20 3e 20 73 69 7a 65 29 20  e) + 1) > size) 
6210: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d  {...return(-ENAM
6220: 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09  ETOOLONG);..}...
6230: 6d 65 6d 63 70 79 28 62 75 66 2c 20 70 61 74 68  memcpy(buf, path
6240: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79  info.typeinfo.sy
6250: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74  mlink.source, st
6260: 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79  rlen(pathinfo.ty
6270: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
6280: 6f 75 72 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72  ource) + 1);...r
6290: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
62a0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
62b0: 73 65 5f 67 65 74 61 74 74 72 28 63 6f 6e 73 74  se_getattr(const
62c0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72   char *path, str
62d0: 75 63 74 20 73 74 61 74 20 2a 73 74 62 75 66 29  uct stat *stbuf)
62e0: 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73   {..struct appfs
62f0: 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e  _pathinfo pathin
6300: 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  fo;..int retval;
6310: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a  ...retval = 0;..
6320: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
6330: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
6340: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23  ...)", path);..#
6350: 69 66 20 28 64 65 66 69 6e 65 64 28 44 45 42 55  if (defined(DEBU
6360: 47 29 20 26 26 20 64 65 66 69 6e 65 64 28 41 50  G) && defined(AP
6370: 50 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20  PFS_EXIT_PATH)) 
6380: 7c 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46 53  || defined(APPFS
6390: 5f 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c  _EXIT_PATH_ENABL
63a0: 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59  E_MAJOR_SECURITY
63b0: 5f 48 4f 4c 45 29 0a 09 2f 2a 0a 09 20 2a 20 54  _HOLE)../*.. * T
63c0: 68 69 73 20 69 73 20 61 20 6d 61 6a 6f 72 20 73  his is a major s
63d0: 65 63 75 72 69 74 79 20 69 73 73 75 65 20 73 6f  ecurity issue so
63e0: 20 77 65 20 63 61 6e 6e 6f 74 20 6c 65 74 20 69   we cannot let i
63f0: 74 20 62 65 20 63 6f 6d 70 69 6c 65 64 20 69 6e  t be compiled in
6400: 74 6f 0a 09 20 2a 20 61 6e 79 20 72 65 6c 65 61  to.. * any relea
6410: 73 65 0a 09 20 2a 2f 0a 0a 09 69 66 20 28 73 74  se.. */...if (st
6420: 72 63 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 69  rcmp(path, "/exi
6430: 74 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70  t") == 0) {...ap
6440: 70 66 73 5f 65 78 69 74 28 29 3b 0a 09 7d 0a 23  pfs_exit();..}.#
6450: 65 6e 64 69 66 0a 0a 09 70 61 74 68 69 6e 66 6f  endif...pathinfo
6460: 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  .type = APPFS_PA
6470: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a  THTYPE_INVALID;.
6480: 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73  ..retval = appfs
6490: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
64a0: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b  ath, &pathinfo);
64b0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
64c0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65  0) {...return(re
64d0: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 73  tval);..}...mems
64e0: 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69 7a  et(stbuf, 0, siz
64f0: 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74 29  eof(struct stat)
6500: 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  );...stbuf->st_m
6510: 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e  time = pathinfo.
6520: 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  time;..stbuf->st
6530: 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66  _ctime = pathinf
6540: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e  o.time;..stbuf->
6550: 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68 69  st_atime = pathi
6560: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
6570: 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61 74  ->st_ino   = pat
6580: 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74  hinfo.inode;..st
6590: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20  buf->st_mode  = 
65a0: 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70 61 74  0;...switch (pat
65b0: 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a 09 09  hinfo.type) {...
65c0: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
65d0: 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a 0a 09  YPE_DIRECTORY:..
65e0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
65f0: 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30 35 35   = S_IFDIR | 055
6600: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
6610: 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68  nlink = 2 + path
6620: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69  info.typeinfo.di
6630: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09  r.childcount;...
6640: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
6650: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
6660: 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74 68 69  LE:....if (pathi
6670: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
6680: 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a  e.executable) {.
6690: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
66a0: 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30  de = S_IFREG | 0
66b0: 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65 20 7b  555;....} else {
66c0: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
66d0: 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20  ode = S_IFREG | 
66e0: 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09 09 73  0444;....}.....s
66f0: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
6700: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
6710: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f  _size = pathinfo
6720: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
6730: 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  ize;....break;..
6740: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
6750: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09  TYPE_SYMLINK:...
6760: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
6770: 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35  = S_IFLNK | 0555
6780: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e  ;....stbuf->st_n
6790: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62  link = 1;....stb
67a0: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61  uf->st_size = pa
67b0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
67c0: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09  symlink.size;...
67d0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
67e0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f  PPFS_PATHTYPE_SO
67f0: 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d 3e  CKET:....stbuf->
6800: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53 4f  st_mode = S_IFSO
6810: 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74  CK | 0555;....st
6820: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20  buf->st_nlink = 
6830: 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  1;....stbuf->st_
6840: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65  size = 0;....bre
6850: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
6860: 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a 0a  _PATHTYPE_FIFO:.
6870: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
6880: 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30 35  e = S_IFIFO | 05
6890: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
68a0: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
68b0: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
68c0: 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  0;....break;...c
68d0: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
68e0: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53  PE_DOES_NOT_EXIS
68f0: 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  T:....retval = -
6900: 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61  ENOENT;.....brea
6910: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
6920: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
6930: 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45  :....retval = -E
6940: 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09  IO;.....break;..
6950: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
6960: 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 73  .packaged) {...s
6970: 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20 3d  tbuf->st_uid   =
6980: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
6990: 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f  ();...stbuf->st_
69a0: 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65  gid   = appfs_ge
69b0: 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74 62  t_fsgid();...stb
69c0: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30  uf->st_mode |= 0
69d0: 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  200;..}...return
69e0: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61  (retval);.}..sta
69f0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
6a00: 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73 74  se_readdir(const
6a10: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f 69   char *path, voi
6a20: 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69 6c  d *buf, fuse_fil
6a30: 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20  l_dir_t filler, 
6a40: 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74  off_t offset, st
6a50: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
6a60: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f  nfo *fi) {..Tcl_
6a70: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
6a80: 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64  .Tcl_Obj **child
6a90: 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72  ren;..int childr
6aa0: 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09  en_count, idx;..
6ab0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41  int tcl_ret;...A
6ac0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
6ad0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
6ae0: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e  .)", path);...in
6af0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
6b00: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
6b10: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
6b20: 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d  ...return(0);..}
6b30: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6b40: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
6b50: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 66 69  e(interp);)...fi
6b60: 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e  ller(buf, ".", N
6b70: 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72  ULL, 0);..filler
6b80: 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c  (buf, "..", NULL
6b90: 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20  , 0);...tcl_ret 
6ba0: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
6bb0: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
6bc0: 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65  ppfs::getchildre
6bd0: 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  n", path);..if (
6be0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
6bf0: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
6c00: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  UG("::appfs::get
6c10: 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69  children(%s) fai
6c20: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
6c30: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6c40: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
6c50: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
6c60: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
6c70: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
6c80: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
6c90: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
6ca0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
6cb0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  ;)....return(0);
6cc0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
6cd0: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72  _libtcl(...tcl_r
6ce0: 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  et = Tcl_ListObj
6cf0: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65  GetElements(inte
6d00: 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  rp, Tcl_GetObjRe
6d10: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26 63  sult(interp), &c
6d20: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 26  hildren_count, &
6d30: 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29 0a 09 69  children);..)..i
6d40: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
6d50: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
6d60: 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20 6c  DEBUG("Parsing l
6d70: 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e 20  ist of children 
6d80: 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c 65  on path %s faile
6d90: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
6da0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6db0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
6dc0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
6dd0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
6de0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
6df0: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
6e00: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
6e10: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
6e20: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
6e30: 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d 20 30  }...for (idx = 0
6e40: 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72 65 6e  ; idx < children
6e50: 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20 7b  _count; idx++) {
6e60: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6e70: 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c 65 72 28  btcl(....filler(
6e80: 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  buf, Tcl_GetStri
6e90: 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64 78 5d  ng(children[idx]
6ea0: 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 09 29  ), NULL, 0);...)
6eb0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
6ec0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
6ed0: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
6ee0: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
6ef0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
6f00: 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63  use_open(const c
6f10: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
6f20: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
6f30: 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74   *fi) {..Tcl_Int
6f40: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73 74  erp *interp;..st
6f50: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
6f60: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 63  nfo pathinfo;..c
6f70: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
6f80: 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69 6e  path, *mode;..in
6f90: 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f 72  t gpi_ret, tcl_r
6fa0: 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09 41  et;..int fh;...A
6fb0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
6fc0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
6fd0: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67 70  .)", path);...gp
6fe0: 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65  i_ret = appfs_ge
6ff0: 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68  t_path_info(path
7000: 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  , &pathinfo);...
7010: 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26  if ((fi->flags &
7020: 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45   (O_WRONLY|O_CRE
7030: 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54  AT)) == (O_CREAT
7040: 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09  |O_WRONLY)) {...
7050: 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c 6c  /* The file will
7060: 20 62 65 20 63 72 65 61 74 65 64 20 69 66 20 69   be created if i
7070: 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  t does not exist
7080: 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65   */...if (gpi_re
7090: 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72 65  t != 0 && gpi_re
70a0: 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a  t != -ENOENT) {.
70b0: 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65  ...return(gpi_re
70c0: 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20  t);...}....mode 
70d0: 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a 09 09 2f  = "create";..../
70e0: 2a 0a 09 09 20 2a 20 57 65 20 68 61 76 65 20 74  *... * We have t
70f0: 6f 20 63 6c 65 61 72 20 74 68 65 20 63 61 63 68  o clear the cach
7100: 65 20 68 65 72 65 20 73 6f 20 74 68 61 74 20 74  e here so that t
7110: 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09 20  he number of... 
7120: 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61 69  * links gets mai
7130: 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 70  ntained on the p
7140: 61 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79 0a  arent directory.
7150: 09 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67 65  .. */...appfs_ge
7160: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
7170: 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65  e_flush(appfs_ge
7180: 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a  t_fsuid(), -1);.
7190: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20 54  .} else {.../* T
71a0: 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c 72  he file must alr
71b0: 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09 09  eady exist */...
71c0: 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30  if (gpi_ret != 0
71d0: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67 70  ) {....return(gp
71e0: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d  i_ret);...}....m
71f0: 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66 20  ode = "";....if 
7200: 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f 5f  ((fi->flags & O_
7210: 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f  WRONLY) == O_WRO
7220: 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20 3d  NLY) {....mode =
7230: 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09 7d   "write";...}..}
7240: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
7250: 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41  type == APPFS_PA
7260: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
7270: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
7280: 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65  SDIR);..}...inte
7290: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
72a0: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
72b0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
72c0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
72d0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
72e0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
72f0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
7300: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
7310: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
7320: 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65  3, "::appfs::ope
7330: 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f  npath", path, mo
7340: 64 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  de);..if (tcl_re
7350: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
7360: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
7370: 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28  appfs::openpath(
7380: 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22  %s, %s) failed."
7390: 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09  , path, mode);..
73a0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
73b0: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
73c0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
73d0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
73e0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
73f0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
7400: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
7410: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7420: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
7430: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
7440: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72  call_libtcl(...r
7450: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
7460: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
7470: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70  nterp);..)...app
7480: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
7490: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
74a0: 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f  p);)...if (real_
74b0: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
74c0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
74d0: 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  .}...APPFS_DEBUG
74e0: 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65 71  ("Translated req
74f0: 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73 20  uest to open %s 
7500: 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d  to opening %s (m
7510: 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20  ode = \"%s\")", 
7520: 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c  path, real_path,
7530: 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f   mode);...fh = o
7540: 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 66  pen(real_path, f
7550: 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29 3b  i->flags, 0600);
7560: 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20 7b  ...if (fh < 0) {
7570: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
7580: 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66  ..}...fi->fh = f
7590: 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  h;...return(0);.
75a0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
75b0: 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63  pfs_fuse_close(c
75c0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
75d0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
75e0: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69  e_info *fi) {..i
75f0: 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09  nt close_ret;...
7600: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7610: 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74  nfo_cache_rm(pat
7620: 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75  h, appfs_get_fsu
7630: 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72  id());...close_r
7640: 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66  et = close(fi->f
7650: 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72  h);..if (close_r
7660: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
7670: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
7680: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
7690: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
76a0: 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63  use_read(const c
76b0: 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20  har *path, char 
76c0: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
76d0: 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c  e, off_t offset,
76e0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
76f0: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 6f  e_info *fi) {..o
7700: 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b 0a  ff_t lseek_ret;.
7710: 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 65  .ssize_t read_re
7720: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
7730: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
7740: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
7750: 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d 20  ;...lseek_ret = 
7760: 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f 66  lseek(fi->fh, of
7770: 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b  fset, SEEK_SET);
7780: 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 20  ..if (lseek_ret 
7790: 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 72  != offset) {...r
77a0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
77b0: 0a 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65 61  ..read_ret = rea
77c0: 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73  d(fi->fh, buf, s
77d0: 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72  ize);...return(r
77e0: 65 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61  ead_ret);.}..sta
77f0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
7800: 73 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63  se_write(const c
7810: 68 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74  har *path, const
7820: 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65   char *buf, size
7830: 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f  _t size, off_t o
7840: 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75  ffset, struct fu
7850: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
7860: 29 20 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b  ) {..off_t lseek
7870: 5f 72 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 77  _ret;..ssize_t w
7880: 72 69 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46  rite_ret;...APPF
7890: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
78a0: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
78b0: 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73  , path);...appfs
78c0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
78d0: 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70  ache_rm(path, ap
78e0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
78f0: 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d 20  ;...lseek_ret = 
7900: 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f 66  lseek(fi->fh, of
7910: 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b  fset, SEEK_SET);
7920: 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 20  ..if (lseek_ret 
7930: 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 72  != offset) {...r
7940: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
7950: 0a 09 77 72 69 74 65 5f 72 65 74 20 3d 20 77 72  ..write_ret = wr
7960: 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c  ite(fi->fh, buf,
7970: 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e   size);...return
7980: 28 77 72 69 74 65 5f 72 65 74 29 3b 0a 7d 0a 0a  (write_ret);.}..
7990: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
79a0: 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73  _fuse_mknod(cons
79b0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
79c0: 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f 74  de_t mode, dev_t
79d0: 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61 72   device) {..char
79e0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
79f0: 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41  t mknod_ret;...A
7a00: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
7a10: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
7a20: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66  .)", path);...if
7a30: 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48   ((mode & S_IFCH
7a40: 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b  R) == S_IFCHR) {
7a50: 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d  ...return(-EPERM
7a60: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64  );..}...if ((mod
7a70: 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20  e & S_IFBLK) == 
7a80: 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74  S_IFBLK) {...ret
7a90: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
7aa0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
7ab0: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
7ac0: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
7ad0: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
7ae0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
7af0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
7b00: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
7b10: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b  fs_enter();...mk
7b20: 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 28  nod_ret = mknod(
7b30: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 2c  real_path, mode,
7b40: 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70 66   device);...appf
7b50: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
7b60: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
7b70: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
7b80: 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 21  .if (mknod_ret !
7b90: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
7ba0: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
7bb0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7bc0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7bd0: 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f 6e  _fuse_create(con
7be0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
7bf0: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72 75  ode_t mode, stru
7c00: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
7c10: 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20 2a  o *fi) {..char *
7c20: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
7c30: 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  fd;...APPFS_DEBU
7c40: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
7c50: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
7c60: 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  );...if ((mode &
7c70: 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49   S_IFCHR) == S_I
7c80: 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e  FCHR) {...return
7c90: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69  (-EPERM);..}...i
7ca0: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42  f ((mode & S_IFB
7cb0: 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20  LK) == S_IFBLK) 
7cc0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
7cd0: 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  M);..}...real_pa
7ce0: 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61  th = appfs_prepa
7cf0: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74  re_to_create(pat
7d00: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
7d10: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
7d20: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
7d30: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
7d40: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
7d50: 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74 28  );...fd = creat(
7d60: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
7d70: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
7d80: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
7d90: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
7da0: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64 20  path);...if (fd 
7db0: 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  < 0) {...return(
7dc0: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
7dd0: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a  ..fi->fh = fd;..
7de0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
7df0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7e00: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63 6f  fuse_truncate(co
7e10: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
7e20: 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09 63  off_t size) {..c
7e30: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
7e40: 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72 65  .int truncate_re
7e50: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
7e60: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
7e70: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
7e80: 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  ;...real_path = 
7e90: 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28  appfs_localpath(
7ea0: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
7eb0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
7ec0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
7ed0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  ..}...appfs_get_
7ee0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
7ef0: 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67  rm(path, appfs_g
7f00: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 61  et_fsuid());...a
7f10: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
7f20: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
7f30: 09 74 72 75 6e 63 61 74 65 5f 72 65 74 20 3d 20  .truncate_ret = 
7f40: 74 72 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 61  truncate(real_pa
7f50: 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70  th, size);...app
7f60: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
7f70: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
7f80: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
7f90: 0a 09 69 66 20 28 74 72 75 6e 63 61 74 65 5f 72  ..if (truncate_r
7fa0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
7fb0: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
7fc0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
7fd0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
7fe0: 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b  ppfs_fuse_unlink
7ff0: 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 61  _rmdir(const cha
8000: 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f  r *path) {..Tcl_
8010: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
8020: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
8030: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
8040: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
8050: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
8060: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
8070: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
8080: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
8090: 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20  , -1);...interp 
80a0: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
80b0: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
80c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
80d0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
80e0: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
80f0: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
8100: 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75  , 2, "::appfs::u
8110: 6e 6c 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68  nlinkpath", path
8120: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
8130: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
8140: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
8150: 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28  pfs::unlinkpath(
8160: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
8170: 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  th);...appfs_cal
8180: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
8190: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
81a0: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
81b0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
81c0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
81d0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
81e0: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
81f0: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
8200: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8210: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8220: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
8230: 74 65 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e  terp);)...return
8240: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
8250: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b  nt appfs_fuse_mk
8260: 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  dir(const char *
8270: 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64  path, mode_t mod
8280: 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  e) {..char *real
8290: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69  _path;..int mkdi
82a0: 72 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  r_ret;...APPFS_D
82b0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
82c0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
82d0: 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74  ath);...real_pat
82e0: 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72  h = appfs_prepar
82f0: 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68  e_to_create(path
8300: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
8310: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
8320: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
8330: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
8340: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
8350: 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20  ;...mkdir_ret = 
8360: 6d 6b 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c  mkdir(real_path,
8370: 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f   mode);...appfs_
8380: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
8390: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65  _leave();...free
83a0: 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69  (real_path);...i
83b0: 66 20 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20  f (mkdir_ret != 
83c0: 30 29 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f  0) {...if (errno
83d0: 20 21 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09   != EEXIST) {...
83e0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
83f0: 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65  -1);...}..}...re
8400: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
8410: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8420: 65 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68  e_chmod(const ch
8430: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
8440: 20 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e   mode) {..Tcl_In
8450: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
8460: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
8470: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
8480: 65 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a  et, chmod_ret;..
8490: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
84a0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
84b0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
84c0: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
84d0: 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74  nfo_cache_rm(pat
84e0: 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75  h, appfs_get_fsu
84f0: 69 64 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20  id());...interp 
8500: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
8510: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
8520: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
8530: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
8540: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8550: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
8560: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
8570: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
8580: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20  Eval(interp, 3, 
8590: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
85a0: 74 68 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74  th", path, "writ
85b0: 65 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  e");..if (tcl_re
85c0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
85d0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
85e0: 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28  appfs::openpath(
85f0: 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22  %s, %s) failed."
8600: 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 29  , path, "write")
8610: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
8620: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
8630: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
8640: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
8650: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
8660: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
8670: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
8680: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
8690: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
86a0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
86b0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
86c0: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
86d0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
86e0: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  t(interp);..)...
86f0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8700: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
8710: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65  terp);)...if (re
8720: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
8730: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
8740: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
8750: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
8760: 6e 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f  nter();...chmod_
8770: 72 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c  ret = chmod(real
8780: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
8790: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
87a0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
87b0: 0a 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72  ..return(chmod_r
87c0: 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51  et);.}../*. * SQ
87d0: 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63  Lite3 mode: Exec
87e0: 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20  ute raw SQL and 
87f0: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
8800: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
8810: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73  atic int appfs_s
8820: 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61  qlite3(const cha
8830: 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *sql) {..Tcl_I
8840: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
8850: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f  const char *sql_
8860: 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ret;..int tcl_re
8870: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
8880: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
8890: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20  terp(NULL);..if 
88a0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
88b0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
88c0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
88d0: 63 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74  create a Tcl int
88e0: 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74  erpreter.  Abort
88f0: 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74  ing.\n");....ret
8900: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c  urn(1);..}...tcl
8910: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
8920: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c  _Eval(interp, 5,
8930: 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20   "::appfs::db", 
8940: 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f  "eval", sql, "ro
8950: 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f  w", "unset -noco
8960: 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70  mplain row(*); p
8970: 61 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20  array row; puts 
8980: 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c  \"----\"");..sql
8990: 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74  _ret = Tcl_GetSt
89a0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
89b0: 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65  p);...if (tcl_re
89c0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
89d0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
89e0: 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c   "[error] %s\n",
89f0: 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65   sql_ret);....re
8a00: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66  turn(1);..}...if
8a10: 20 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c   (sql_ret && sql
8a20: 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29  _ret[0] != '\0')
8a30: 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c   {...printf("%s\
8a40: 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d  n", sql_ret);..}
8a50: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
8a60: 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a  ./*. * Tcl mode:
8a70: 20 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c   Execute raw Tcl
8a80: 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63   and return succ
8a90: 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20  ess or failure. 
8aa0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
8ab0: 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68  pfs_tcl(const ch
8ac0: 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f  ar *tcl) {..Tcl_
8ad0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
8ae0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  .const char *tcl
8af0: 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63  _result;..int tc
8b00: 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20  l_ret;...interp 
8b10: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
8b20: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
8b30: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
8b40: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
8b50: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
8b60: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
8b70: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
8b80: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
8b90: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
8ba0: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
8bb0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29  val(interp, tcl)
8bc0: 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20  ;..tcl_result = 
8bd0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
8be0: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ult(interp);...i
8bf0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
8c00: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
8c10: 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f  f(stderr, "[erro
8c20: 72 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65  r] %s\n", tcl_re
8c30: 73 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e  sult);....return
8c40: 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63  (1);..}...if (tc
8c50: 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f  l_result && tcl_
8c60: 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30  result[0] != '\0
8c70: 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25  ') {...printf("%
8c80: 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74  s\n", tcl_result
8c90: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
8ca0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  );.}../*. * AppF
8cb0: 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54  Sd Package for T
8cc0: 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42  cl:. *         B
8cd0: 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70  ridge for I/O op
8ce0: 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75  erations to requ
8cf0: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  est information 
8d00: 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e  about the curren
8d10: 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61  t. *         tra
8d20: 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a  nsaction. */./*.
8d30: 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65   * Tcl interface
8d40: 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65   to get the home
8d50: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74   directory for t
8d60: 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74  he user making t
8d70: 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20  he "current". * 
8d80: 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74  FUSE I/O request
8d90: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
8da0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
8db0: 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61  medir(ClientData
8dc0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
8dd0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
8de0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
8df0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61  T objv[]) {..cha
8e00: 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c  r *homedir;..Tcl
8e10: 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62  _Obj *homedir_ob
8e20: 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b  j;..uid_t fsuid;
8e30: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61  ..static __threa
8e40: 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f  d Tcl_Obj *last_
8e50: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55  homedir_obj = NU
8e60: 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  LL;..static __th
8e70: 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f  read uid_t last_
8e80: 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20  fsuid = -1;..   
8e90: 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d       if (objc !=
8ea0: 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20   1) {.          
8eb0: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e        Tcl_WrongN
8ec0: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
8ed0: 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20  , objv, NULL);. 
8ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
8ef0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
8f00: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73  ;.        }...fs
8f10: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  uid = appfs_get_
8f20: 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66  fsuid();...if (f
8f30: 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75  suid == last_fsu
8f40: 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64  id && last_homed
8f50: 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20  ir_obj != NULL) 
8f60: 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  {...homedir_obj 
8f70: 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  = last_homedir_o
8f80: 62 6a 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52  bj;....Tcl_IncrR
8f90: 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f  efCount(homedir_
8fa0: 6f 62 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  obj);..} else {.
8fb0: 09 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66  ..homedir = appf
8fc0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70  s_get_homedir(ap
8fd0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
8fe0: 3b 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72  ;....if (homedir
8ff0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72   == NULL) {....r
9000: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
9010: 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72  ;...}....homedir
9020: 5f 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74  _obj = Tcl_NewSt
9030: 72 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c  ringObj(homedir,
9040: 20 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f   -1);....free(ho
9050: 6d 65 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f 49  medir);....Tcl_I
9060: 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65  ncrRefCount(home
9070: 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66 20  dir_obj);....if 
9080: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  (last_homedir_ob
9090: 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  j != NULL) {....
90a0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
90b0: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  (last_homedir_ob
90c0: 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f  j);...}....last_
90d0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f  homedir_obj = ho
90e0: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73  medir_obj;...las
90f0: 74 5f 66 73 75 69 64 20 3d 20 66 73 75 69 64 3b  t_fsuid = fsuid;
9100: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
9110: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a  ount(homedir_obj
9120: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
9130: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
9140: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
9150: 6f 62 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63 72  obj);...Tcl_Decr
9160: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72  RefCount(homedir
9170: 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20  _obj);..        
9180: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
9190: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
91a0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
91b0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43  _user_fs_enter(C
91c0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
91d0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
91e0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
91f0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
9200: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
9210: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
9220: 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  er();...return(T
9230: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
9240: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
9250: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
9260: 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74  _leave(ClientDat
9270: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
9280: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
9290: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
92a0: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
92b0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
92c0: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
92d0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
92e0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
92f0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
9300: 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  d(ClientData cd,
9310: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
9320: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
9330: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
9340: 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66  jv[]) {..uid_t f
9350: 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20  suid;...fsuid = 
9360: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
9370: 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f  );..       .Tcl_
9380: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
9390: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65  erp, Tcl_NewWide
93a0: 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a  IntObj(fsuid));.
93b0: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
93c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
93d0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73  tcl_appfs_get_fs
93e0: 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63  gid(ClientData c
93f0: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
9400: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
9410: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
9420: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74  objv[]) {..gid_t
9430: 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20   fsgid;...fsgid 
9440: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
9450: 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63  d();..       .Tc
9460: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
9470: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69  nterp, Tcl_NewWi
9480: 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29  deIntObj(fsgid))
9490: 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f  ;...return(TCL_O
94a0: 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  K);.}..static in
94b0: 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f  t tcl_appfs_get_
94c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
94d0: 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61  flush(ClientData
94e0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
94f0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
9500: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
9510: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74  T objv[]) {..int
9520: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e   tcl_ret;..int n
9530: 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73  ew_size;...new_s
9540: 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28  ize = -1;...if (
9550: 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74  objc == 2) {...t
9560: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
9570: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
9580: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77  p, objv[1], &new
9590: 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63  _size);...if (tc
95a0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
95b0: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c   {....return(tcl
95c0: 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c  _ret);...}..} el
95d0: 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20  se if (objc > 2 
95e0: 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20  || objc < 1) {. 
95f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
9600: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
9610: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
9620: 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a   "?new_cache_siz
9630: 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54  e?");...return(T
9640: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
9650: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
9660: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
9670: 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a  -1, new_size);..
9680: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
9690: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41  .}..static int A
96a0: 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49  ppfsd_Init(Tcl_I
96b0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b  nterp *interp) {
96c0: 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f  .#ifdef USE_TCL_
96d0: 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49  STUBS..if (Tcl_I
96e0: 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c  nitStubs(interp,
96f0: 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29   TCL_VERSION, 0)
9700: 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75   == 0L) {...retu
9710: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
9720: 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43  }.#endif...Tcl_C
9730: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
9740: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
9750: 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74  :get_homedir", t
9760: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
9770: 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  edir, NULL, NULL
9780: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
9790: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
97a0: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73   "appfsd::get_fs
97b0: 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  uid", tcl_appfs_
97c0: 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c  get_fsuid, NULL,
97d0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
97e0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
97f0: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67  terp, "appfsd::g
9800: 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61  et_fsgid", tcl_a
9810: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20  ppfs_get_fsgid, 
9820: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
9830: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
9840: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
9850: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
9860: 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c  r_fs_enter", tcl
9870: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
9880: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e  user_fs_enter, N
9890: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
98a0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
98b0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
98c0: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  d::simulate_user
98d0: 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f  _fs_leave", tcl_
98e0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
98f0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55  ser_fs_leave, NU
9900: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
9910: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
9920: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
9930: 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  ::get_path_info_
9940: 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63  cache_flush", tc
9950: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  l_appfs_get_path
9960: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
9970: 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  h, NULL, NULL);.
9980: 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65  ..Tcl_PkgProvide
9990: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
99a0: 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74  ", "1.0");...ret
99b0: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
99c0: 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72  /*. * Hot-restar
99d0: 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a  t support. */./*
99e0: 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d   Initiate a hot-
99f0: 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69  restart */.stati
9a00: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74  c void appfs_hot
9a10: 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b  _restart(void) {
9a20: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41  ..APPFS_DEBUG("A
9a30: 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65  sked to initiate
9a40: 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a   hot restart");.
9a50: 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65  ..appfs_tcl_Rese
9a60: 74 49 6e 74 65 72 70 73 28 29 3b 0a 09 61 70 70  tInterps();..app
9a70: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
9a80: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
9a90: 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a   -1);...return;.
9aa0: 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20  }../*. * Signal 
9ab0: 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 20  handler. *      
9ac0: 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69 61     SIGHUP initia
9ad0: 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61 72  tes a hot restar
9ae0: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t. */.static voi
9af0: 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68  d appfs_signal_h
9b00: 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29 20  andler(int sig) 
9b10: 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e  {../* Do not han
9b20: 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 69  dle signals unti
9b30: 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e 20  l FUSE has been 
9b40: 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 28  started */..if (
9b50: 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  !appfs_fuse_star
9b60: 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b  ted) {...return;
9b70: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74  ..}.../* Request
9b80: 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 68   to perform a "h
9b90: 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a 09  ot" restart */..
9ba0: 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48 55  if (sig == SIGHU
9bb0: 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74  P) {...appfs_hot
9bc0: 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a  _restart();..}..
9bd0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
9be0: 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74 68  * Terminate a th
9bf0: 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20  read. */.static 
9c00: 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d 69  void appfs_termi
9c10: 6e 61 74 65 5f 69 6e 74 65 72 70 28 76 6f 69 64  nate_interp(void
9c20: 20 2a 5f 69 6e 74 65 72 70 29 20 7b 0a 09 54 63   *_interp) {..Tc
9c30: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
9c40: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
9c50: 22 43 61 6c 6c 65 64 3a 20 5f 69 6e 74 65 72 70  "Called: _interp
9c60: 20 3d 20 25 70 22 2c 20 5f 69 6e 74 65 72 70 29   = %p", _interp)
9c70: 3b 0a 0a 09 69 66 20 28 5f 69 6e 74 65 72 70 20  ;...if (_interp 
9c80: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
9c90: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
9ca0: 61 74 69 6e 67 20 74 68 72 65 61 64 20 77 69 74  ating thread wit
9cb0: 68 20 6e 6f 20 69 6e 74 65 72 70 72 65 74 65 72  h no interpreter
9cc0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09  ");....return;..
9cd0: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 5f 69 6e  }...interp = _in
9ce0: 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45  terp;...APPFS_DE
9cf0: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
9d00: 20 69 6e 74 65 72 70 72 65 74 65 72 20 64 75 65   interpreter due
9d10: 20 74 6f 20 74 68 72 65 61 64 20 74 65 72 6d 69   to thread termi
9d20: 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09 61 70 70 66  nation");...appf
9d30: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
9d40: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
9d50: 70 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  p(interp);..)...
9d60: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
9d70: 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73   FUSE operations
9d80: 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73   structure. */.s
9d90: 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75 73  tatic struct fus
9da0: 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70  e_operations app
9db0: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20  fs_operations = 
9dc0: 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20  {...getattr   = 
9dd0: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
9de0: 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20  tr,...readdir   
9df0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
9e00: 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b  ddir,...readlink
9e10: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
9e20: 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20  eadlink,...open 
9e30: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
9e40: 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73  e_open,...releas
9e50: 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  e   = appfs_fuse
9e60: 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20  _close,...read  
9e70: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
9e80: 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20  _read,...write  
9e90: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
9ea0: 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20  write,...mknod  
9eb0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
9ec0: 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20  mknod,...create 
9ed0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
9ee0: 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61  create,...trunca
9ef0: 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  te  = appfs_fuse
9f00: 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c  _truncate,...unl
9f10: 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ink    = appfs_f
9f20: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
9f30: 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20  ,...rmdir     = 
9f40: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e  appfs_fuse_unlin
9f50: 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72  k_rmdir,...mkdir
9f60: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
9f70: 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64  e_mkdir,...chmod
9f80: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
9f90: 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a 2f 2a 0a  e_chmod,.};../*.
9fa0: 20 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20 70   * FUSE option p
9fb0: 61 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b 0a  arsing callback.
9fc0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
9fd0: 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62  ppfs_fuse_opt_cb
9fe0: 28 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f 6e  (void *data, con
9ff0: 73 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69 6e  st char *arg, in
a000: 74 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66 75  t key, struct fu
a010: 73 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67 73  se_args *outargs
a020: 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e 74 20  ) {..static int 
a030: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20  seen_cachedir = 
a040: 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20 3d 3d 20  0;...if (key == 
a050: 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f 4e 4f 4e  FUSE_OPT_KEY_NON
a060: 4f 50 54 20 26 26 20 73 65 65 6e 5f 63 61 63 68  OPT && seen_cach
a070: 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a 09 09 73  edir == 0) {...s
a080: 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20 31  een_cachedir = 1
a090: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 63 68 65  ;....appfs_cache
a0a0: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
a0b0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
a0c0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 31 29 3b  ..}...return(1);
a0d0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20  .}../*. * Entry 
a0e0: 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68 69 73 20  point into this 
a0f0: 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74  program.. */.int
a100: 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20   main(int argc, 
a110: 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09  char **argv) {..
a120: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73 74  Tcl_Interp *test
a130: 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a  _interp;..char *
a140: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
a150: 72 3b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f  r;..struct fuse_
a160: 61 72 67 73 20 61 72 67 73 20 3d 20 46 55 53 45  args args = FUSE
a170: 5f 41 52 47 53 5f 49 4e 49 54 28 61 72 67 63 2c  _ARGS_INIT(argc,
a180: 20 61 72 67 76 29 3b 0a 09 69 6e 74 20 70 74 68   argv);..int pth
a190: 72 65 61 64 5f 72 65 74 3b 0a 09 76 6f 69 64 20  read_ret;..void 
a1a0: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09 2f  *signal_ret;.../
a1b0: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
a1c0: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
a1d0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
a1e0: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
a1f0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
a200: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
a210: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
a220: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
a230: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
a240: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
a250: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
a260: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
a270: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
a280: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
a290: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
a2a0: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
a2b0: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
a2c0: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
a2d0: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
a2e0: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
a2f0: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
a300: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
a310: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
a320: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
a330: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
a340: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
a350: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
a360: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
a370: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
a380: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
a390: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
a3a0: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
a3b0: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
a3c0: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
a3d0: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
a3e0: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
a3f0: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
a400: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
a410: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
a420: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
a430: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
a440: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
a450: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
a460: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
a470: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
a480: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
a490: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
a4a0: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
a4b0: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
a4c0: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
a4d0: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
a4e0: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
a4f0: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
a500: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
a510: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
a520: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
a530: 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 65  erpKey, appfs_te
a540: 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 29 3b  rminate_interp);
a550: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
a560: 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69  t != 0) {...fpri
a570: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
a580: 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53  ble to create TS
a590: 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20  D key for Tcl.  
a5a0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
a5b0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
a5c0: 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c  ../*.. * Manuall
a5d0: 79 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20  y specify cache 
a5e0: 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f  directory, witho
a5f0: 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b  ut FUSE callback
a600: 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e  .. * This option
a610: 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e   only works when
a620: 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c   not using FUSE,
a630: 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f   since we.. * do
a640: 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20   not process it 
a650: 77 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f  with FUSEs optio
a660: 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20  n processing... 
a670: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20  */..if (argc >= 
a680: 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d  2) {...if (strcm
a690: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61  p(argv[0], "--ca
a6a0: 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b  chedir") == 0) {
a6b0: 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64  ....appfs_cached
a6c0: 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76  ir = strdup(argv
a6d0: 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d  [1]);.....argc -
a6e0: 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20  = 2;....argv += 
a6f0: 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09  2;...}..}.../*..
a700: 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c   * SQLite3 mode,
a710: 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77   for running raw
a720: 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65   SQL against the
a730: 20 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a   cache database.
a740: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
a750: 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72  = 2 && strcmp(ar
a760: 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65  gv[0], "--sqlite
a770: 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  3") == 0) {...re
a780: 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74  turn(appfs_sqlit
a790: 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d  e3(argv[1]));..}
a7a0: 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f  .../*.. * Tcl mo
a7b0: 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20  de, for running 
a7c0: 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73  raw Tcl in the s
a7d0: 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  ame environment 
a7e0: 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a  AppFSd would.. *
a7f0: 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a   run code... */.
a800: 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26  .if (argc == 2 &
a810: 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d  & strcmp(argv[0]
a820: 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29  , "--tcl") == 0)
a830: 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66   {...return(appf
a840: 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b  s_tcl(argv[1]));
a850: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65  ..}.../*.. * Cre
a860: 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70  ate a Tcl interp
a870: 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65  reter just to ve
a880: 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67 73  rify that things
a890: 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20   are in working 
a8a0: 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72  .. * order befor
a8b0: 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61  e we become a da
a8c0: 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74  emon... */..test
a8d0: 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  _interp = appfs_
a8e0: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
a8f0: 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72  (&test_interp_er
a900: 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f  ror);..if (test_
a910: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
a920: 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74  {...if (test_int
a930: 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c  erp_error == NUL
a940: 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74  L) {....test_int
a950: 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b  erp_error = "Unk
a960: 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d  nown error";...}
a970: 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
a980: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
a990: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e  nitialize Tcl in
a9a0: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41 70  terpreter for Ap
a9b0: 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72  pFSd:\n");...fpr
a9c0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73  intf(stderr, "%s
a9d0: 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70  \n", test_interp
a9e0: 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75  _error);....retu
a9f0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  rn(1);..}...Tcl_
aa00: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73  DeleteInterp(tes
aa10: 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c  t_interp);...Tcl
aa20: 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65  _FinalizeNotifie
aa30: 72 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20  r(NULL);.../*.. 
aa40: 2a 20 52 65 67 69 73 74 65 72 20 61 20 73 69 67  * Register a sig
aa50: 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20  nal handler for 
aa60: 68 6f 74 2d 72 65 73 74 61 72 74 20 72 65 71 75  hot-restart requ
aa70: 65 73 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61  ests.. */..signa
aa80: 6c 5f 72 65 74 20 3d 20 73 69 67 6e 61 6c 28 53  l_ret = signal(S
aa90: 49 47 48 55 50 2c 20 61 70 70 66 73 5f 73 69 67  IGHUP, appfs_sig
aaa0: 6e 61 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69  nal_handler);..i
aab0: 66 20 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d  f (signal_ret ==
aac0: 20 53 49 47 5f 45 52 52 29 20 7b 0a 09 09 66 70   SIG_ERR) {...fp
aad0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
aae0: 6e 61 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c 6c  nable to install
aaf0: 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20   signal handler 
ab00: 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74 5c  for hot-restart\
ab10: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
ab20: 74 64 65 72 72 2c 20 22 48 6f 74 2d 72 65 73 74  tderr, "Hot-rest
ab30: 61 72 74 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20  art will not be 
ab40: 61 76 61 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a  available.\n");.
ab50: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 41 64 64 20  .}.../*.. * Add 
ab60: 46 55 53 45 20 61 72 67 75 6d 65 6e 74 73 20 77  FUSE arguments w
ab70: 68 69 63 68 20 77 65 20 61 6c 77 61 79 73 20 73  hich we always s
ab80: 75 70 70 6c 79 0a 09 20 2a 2f 0a 09 66 75 73 65  upply.. */..fuse
ab90: 5f 6f 70 74 5f 70 61 72 73 65 28 26 61 72 67 73  _opt_parse(&args
aba0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 61 70  , NULL, NULL, ap
abb0: 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62 29  pfs_fuse_opt_cb)
abc0: 3b 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ;..fuse_opt_add_
abd0: 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 64 65  arg(&args, "-ode
abe0: 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e  fault_permission
abf0: 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73  s,fsname=appfs,s
ac00: 75 62 74 79 70 65 3d 61 70 70 66 73 64 2c 75 73  ubtype=appfsd,us
ac10: 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63  e_ino,kernel_cac
ac20: 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74  he,entry_timeout
ac30: 3d 30 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d  =0,attr_timeout=
ac40: 30 2c 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74  0,big_writes,int
ac50: 72 2c 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b  r,hard_remove");
ac60: 0a 0a 09 69 66 20 28 67 65 74 75 69 64 28 29 20  ...if (getuid() 
ac70: 3d 3d 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f  == 0) {...fuse_o
ac80: 70 74 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20  pt_parse(&args, 
ac90: 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  NULL, NULL, NULL
aca0: 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64  );...fuse_opt_ad
acb0: 64 5f 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f  d_arg(&args, "-o
acc0: 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09  allow_other");..
acd0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72  }.../*.. * Enter
ace0: 20 74 68 65 20 46 55 53 45 20 6d 61 69 6e 20 6c   the FUSE main l
acf0: 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c  oop -- this will
ad00: 20 70 72 6f 63 65 73 73 20 61 6e 79 20 61 72 67   process any arg
ad10: 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73  uments.. * and s
ad20: 74 61 72 74 20 73 65 72 76 69 63 69 6e 67 20 72  tart servicing r
ad30: 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61  equests... */..a
ad40: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
ad50: 64 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e 28 66  d = 1;..return(f
ad60: 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72  use_main(args.ar
ad70: 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c 20 26  gc, args.argv, &
ad80: 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73  appfs_operations
ad90: 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a        , NULL));.}. .