Hex Artifact Content

Artifact 1dcdd9bb28bbdca1a253f5e34c42179abbc75d25:


0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45  #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e  _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69 64  clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a  ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67  #include <string
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0080: 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  darg.h>.#include
0090: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
00a0: 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a  lude <unistd.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e  #include <errno.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e  h>.#include <fcn
00d0: 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  tl.h>.#include <
00e0: 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64  stdio.h>.#includ
00f0: 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69 6e 63 6c  e <fuse.h>.#incl
0100: 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23 69 6e 63  ude <pwd.h>.#inc
0110: 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a  lude <tcl.h>../*
0120: 0a 20 2a 20 44 65 66 61 75 6c 74 20 63 61 63 68  . * Default cach
0130: 65 20 64 69 72 65 63 74 6f 72 79 0a 20 2a 2f 0a  e directory. */.
0140: 23 69 66 6e 64 65 66 20 41 50 50 46 53 5f 43 41  #ifndef APPFS_CA
0150: 43 48 45 44 49 52 0a 23 64 65 66 69 6e 65 20 41  CHEDIR.#define A
0160: 50 50 46 53 5f 43 41 43 48 45 44 49 52 20 22 2f  PPFS_CACHEDIR "/
0170: 76 61 72 2f 63 61 63 68 65 2f 61 70 70 66 73 22  var/cache/appfs"
0180: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44 65 62 75  .#endif../* Debu
0190: 67 67 69 6e 67 20 6d 61 63 72 6f 73 20 2a 2f 0a  gging macros */.
01a0: 23 69 66 64 65 66 20 44 45 42 55 47 0a 23 64 65  #ifdef DEBUG.#de
01b0: 66 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47  fine APPFS_DEBUG
01c0: 28 78 2e 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66  (x...) { fprintf
01d0: 28 73 74 64 65 72 72 2c 20 22 5b 64 65 62 75 67  (stderr, "[debug
01e0: 5d 20 25 73 3a 25 69 3a 25 73 3a 20 22 2c 20 5f  ] %s:%i:%s: ", _
01f0: 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f  _FILE__, __LINE_
0200: 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 66 70  _, __func__); fp
0210: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 29  rintf(stderr, x)
0220: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ; fprintf(stderr
0230: 2c 20 22 5c 6e 22 29 3b 20 7d 0a 23 65 6c 73 65  , "\n"); }.#else
0240: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
0250: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a  EBUG(x...) /**/.
0260: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48  #endif../*. * SH
0270: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69  A1 Tcl Package i
0280: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d  nitializer, from
0290: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20   sha1.o. */.int 
02a0: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  Sha1_Init(Tcl_In
02b0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a  terp *interp);..
02c0: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65  /*. * Thread Spe
02d0: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29  cific Data (TSD)
02e0: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72   for Tcl Interpr
02f0: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72  eter for the cur
0300: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a  rent thread. */.
0310: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b  static pthread_k
0320: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a  ey_t interpKey;.
0330: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61  ./*. * Global va
0340: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20  riables, needed 
0350: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20  for all threads 
0360: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c  but only initial
0370: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a  ized before any.
0380: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20   * FUSE threads 
0390: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a  are created. */.
03a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
03b0: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65  s_cachedir;.time
03c0: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d  _t appfs_boottim
03d0: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73  e;.int appfs_fus
03e0: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 0a  e_started = 0;..
03f0: 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68  /*. * AppFS Path
0400: 20 54 79 70 65 3a 20 20 44 65 73 63 72 69 62 65   Type:  Describe
0410: 73 20 74 68 65 20 74 79 70 65 20 6f 66 20 70 61  s the type of pa
0420: 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c 65 20  th a given file 
0430: 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20 65  is. */.typedef e
0440: 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f 50 41 54  num {..APPFS_PAT
0450: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09  HTYPE_INVALID,..
0460: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
0470: 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  ILE,..APPFS_PATH
0480: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a  TYPE_DIRECTORY,.
0490: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f  .APPFS_PATHTYPE_
04a0: 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46 53 5f  SYMLINK,..APPFS_
04b0: 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 2c  PATHTYPE_SOCKET,
04c0: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
04d0: 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 73 5f 70  _FIFO,.} appfs_p
04e0: 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a 0a 20  athtype_t;../*. 
04f0: 2a 20 41 70 70 46 53 20 50 61 74 68 20 49 6e 66  * AppFS Path Inf
0500: 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20 20 20  ormation:. *    
0510: 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 6c 79 20       Completely 
0520: 64 65 73 63 72 69 62 65 73 20 61 20 73 70 65 63  describes a spec
0530: 69 66 69 63 20 70 61 74 68 2c 20 68 6f 77 20 69  ific path, how i
0540: 74 20 73 68 6f 75 6c 64 20 62 65 20 72 65 74 75  t should be retu
0550: 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 20 20 20  rned to. *      
0560: 20 20 20 74 6f 20 74 68 65 20 6b 65 72 6e 65 6c     to the kernel
0570: 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70 70 66  . */.struct appf
0580: 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61 70  s_pathinfo {..ap
0590: 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 20 74  pfs_pathtype_t t
05a0: 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69 6d  ype;..time_t tim
05b0: 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e 61 6d  e;..char hostnam
05c0: 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70 61 63  e[256];..int pac
05d0: 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e 65 64  kaged;..unsigned
05e0: 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f 64 65   long long inode
05f0: 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73 74 72  ;..union {...str
0600: 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63 68 69  uct {....int chi
0610: 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64 69 72  ldcount;...} dir
0620: 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  ;...struct {....
0630: 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65 3b 0a  int executable;.
0640: 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09  ...off_t size;..
0650: 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74 72 75 63  .} file;...struc
0660: 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a  t {....off_t siz
0670: 65 3b 0a 09 09 09 63 68 61 72 20 73 6f 75 72 63  e;....char sourc
0680: 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 79 6d 6c  e[256];...} syml
0690: 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 6e 66 6f  ink;..} typeinfo
06a0: 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61  ;.};../*. * Crea
06b0: 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74  te a new Tcl int
06c0: 65 72 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d  erpreter and com
06d0: 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69  pletely initiali
06e0: 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63  ze it. */.static
06f0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70   Tcl_Interp *app
0700: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
0710: 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72  erp(char **error
0720: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f  _string) {..Tcl_
0730: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
0740: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
0750: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65  APPFS_DEBUG("Cre
0760: 61 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e  ating new Tcl in
0770: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49  terpreter for TI
0780: 44 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e  D = 0x%llx", (un
0790: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
07a0: 29 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29  ) pthread_self()
07b0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 54 63  );...interp = Tc
07c0: 6c 5f 43 72 65 61 74 65 49 6e 74 65 72 70 28 29  l_CreateInterp()
07d0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
07e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
07f0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0800: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c  le to create Tcl
0810: 20 49 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   Interpreter.  A
0820: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
0830: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
0840: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
0850: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22  tring = strdup("
0860: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
0870: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
0880: 2e 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  .");...}....retu
0890: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74  rn(NULL);..}...t
08a0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 49 6e 69  cl_ret = Tcl_Ini
08b0: 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28  t(interp);..if (
08c0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
08d0: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
08e0: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
08f0: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
0900: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
0910: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
0920: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
0930: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
0940: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0950: 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65  terp));....if (e
0960: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
0970: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
0980: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(Tcl_Get
0990: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
09a0: 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63  erp));...}....Tc
09b0: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
09c0: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
09d0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
09e0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
09f0: 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67  (interp, "packag
0a00: 65 20 69 66 6e 65 65 64 65 64 20 73 68 61 31 20  e ifneeded sha1 
0a10: 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b  1.0 [list load {
0a20: 7d 20 73 68 61 31 5d 22 29 3b 0a 09 69 66 20 28  } sha1]");..if (
0a30: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
0a40: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
0a50: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
0a60: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
0a70: 20 53 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67   SHA1.  Aborting
0a80: 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  .\n");...fprintf
0a90: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
0aa0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
0ab0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
0ac0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
0ad0: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
0ae0: 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74  ) {....*error_st
0af0: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
0b00: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
0b10: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a  t(interp));...}.
0b20: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
0b30: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  erp(interp);....
0b40: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
0b50: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
0b60: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70  _Eval(interp, "p
0b70: 61 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20  ackage ifneeded 
0b80: 61 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74  appfsd 1.0 [list
0b90: 20 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d   load {} appfsd]
0ba0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0bb0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0bc0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0bd0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0be0: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
0bf0: 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72 74 69  Package.  Aborti
0c00: 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  ng.\n");...fprin
0c10: 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20  tf(stderr, "Tcl 
0c20: 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c  Error is: %s\n",
0c30: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
0c40: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
0c50: 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69  ..if (error_stri
0c60: 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f  ng) {....*error_
0c70: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
0c80: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0c90: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
0ca0: 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  }....Tcl_DeleteI
0cb0: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
0cc0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
0cd0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64  .}.../*.. * Load
0ce0: 20 22 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68   "pki.tcl" in th
0cf0: 65 20 73 61 6d 65 20 77 61 79 20 61 73 20 61 70  e same way as ap
0d00: 70 66 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65  pfsd.tcl (see be
0d10: 6c 6f 77 29 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72  low).. */..tcl_r
0d20: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
0d30: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
0d40: 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 22  e "pki.tcl.h".."
0d50: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0d60: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0d70: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0d80: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0d90: 61 6c 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20  alize Tcl PKI.  
0da0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
0db0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0dc0: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
0dd0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
0de0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0df0: 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  p));....if (erro
0e00: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
0e10: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
0e20: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
0e30: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0e40: 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44  ));...}....Tcl_D
0e50: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
0e60: 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  rp);....return(N
0e70: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
0e80: 2a 20 4c 6f 61 64 20 74 68 65 20 22 61 70 70 66  * Load the "appf
0e90: 73 64 2e 74 63 6c 22 20 73 63 72 69 70 74 2c 20  sd.tcl" script, 
0ea0: 77 68 69 63 68 20 69 73 20 22 63 6f 6d 70 69 6c  which is "compil
0eb0: 65 64 22 20 69 6e 74 6f 20 61 20 43 20 68 65 61  ed" into a C hea
0ec0: 64 65 72 0a 09 20 2a 20 73 6f 20 74 68 61 74 20  der.. * so that 
0ed0: 69 74 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64  it does not need
0ee0: 20 74 6f 20 65 78 69 73 74 20 6f 6e 20 74 68 65   to exist on the
0ef0: 20 66 69 6c 65 73 79 73 74 65 6d 20 61 6e 64 20   filesystem and 
0f00: 63 61 6e 20 62 65 0a 09 20 2a 20 64 69 72 65 63  can be.. * direc
0f10: 74 6c 79 20 65 76 61 6c 75 61 74 65 64 2e 0a 09  tly evaluated...
0f20: 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54   */..tcl_ret = T
0f30: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
0f40: 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 61 70 70  "".#include "app
0f50: 66 73 64 2e 74 63 6c 2e 68 22 0a 09 22 22 29 3b  fsd.tcl.h".."");
0f60: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
0f70: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
0f80: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
0f90: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
0fa0: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72  ze Tcl AppFS scr
0fb0: 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ipt.  Aborting.\
0fc0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73  n");...fprintf(s
0fd0: 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f  tderr, "Tcl Erro
0fe0: 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c  r is: %s\n", Tcl
0ff0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1000: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66  (interp));....if
1010: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1020: 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  {....*error_stri
1030: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
1040: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1050: 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09  interp));...}...
1060: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
1070: 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65  p(interp);....re
1080: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1090: 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62  ./*.. * Set glob
10a0: 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66 72 6f  al variables fro
10b0: 6d 20 43 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a  m C to Tcl.. */.
10c0: 09 69 66 20 28 54 63 6c 5f 53 65 74 56 61 72 28  .if (Tcl_SetVar(
10d0: 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73  interp, "::appfs
10e0: 3a 3a 63 61 63 68 65 64 69 72 22 2c 20 61 70 70  ::cachedir", app
10f0: 66 73 5f 63 61 63 68 65 64 69 72 2c 20 54 43 4c  fs_cachedir, TCL
1100: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 3d 3d  _GLOBAL_ONLY) ==
1110: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
1120: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1130: 6c 65 20 74 6f 20 73 65 74 20 63 61 63 68 65 20  le to set cache 
1140: 64 69 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73  directory.  This
1150: 20 73 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61   should never fa
1160: 69 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28  il.\n");....if (
1170: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
1180: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
1190: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
11a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
11b0: 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54  terp));...}....T
11c0: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
11d0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
11e0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
11f0: 2a 0a 09 20 2a 20 49 6e 69 74 69 61 6c 69 7a 65  *.. * Initialize
1200: 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63 6c   the "appfsd.tcl
1210: 22 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20 77  " environment, w
1220: 68 69 63 68 20 6d 75 73 74 20 62 65 20 64 6f 6e  hich must be don
1230: 65 20 61 66 74 65 72 0a 09 20 2a 20 67 6c 6f 62  e after.. * glob
1240: 61 6c 20 76 61 72 69 61 62 6c 65 73 20 61 72 65  al variables are
1250: 20 73 65 74 2e 0a 09 20 2a 2f 0a 09 74 63 6c 5f   set... */..tcl_
1260: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1270: 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a  nterp, "::appfs:
1280: 3a 69 6e 69 74 22 29 3b 0a 09 69 66 20 28 74 63  :init");..if (tc
1290: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
12a0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
12b0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
12c0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
12d0: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61  ppFS script (::a
12e0: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62  ppfs::init).  Ab
12f0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
1300: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1310: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1320: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
1330: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1340: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
1350: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
1360: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1370: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1380: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1390: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c  ;...}....Tcl_Del
13a0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
13b0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
13c0: 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  L);..}.../*.. * 
13d0: 48 69 64 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f  Hide some Tcl co
13e0: 6d 6d 61 6e 64 73 20 74 68 61 74 20 77 65 20 64  mmands that we d
13f0: 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f 20 75 73  o not care to us
1400: 65 20 61 6e 64 20 77 68 69 63 68 20 6d 61 79 0a  e and which may.
1410: 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75  . * slow down ru
1420: 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e  n-time operation
1430: 73 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 48 69 64  s... */..Tcl_Hid
1440: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
1450: 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65   "auto_load_inde
1460: 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69  x", "auto_load_i
1470: 6e 64 65 78 22 29 3b 0a 09 54 63 6c 5f 48 69 64  ndex");..Tcl_Hid
1480: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
1490: 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b   "unknown", "unk
14a0: 6e 6f 77 6e 22 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nown");.../*.. *
14b0: 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f 6d 70   Return the comp
14c0: 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a  letely initializ
14d0: 65 64 20 69 6e 74 65 72 70 72 65 74 65 72 0a 09  ed interpreter..
14e0: 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e 74 65   */..return(inte
14f0: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65  rp);.}../*. * Re
1500: 74 75 72 6e 20 74 68 65 20 74 68 72 65 61 64 2d  turn the thread-
1510: 73 70 65 63 69 66 69 63 20 54 63 6c 20 69 6e 74  specific Tcl int
1520: 65 72 70 72 65 74 65 72 2c 20 63 72 65 61 74 69  erpreter, creati
1530: 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65 64 0a  ng it if needed.
1540: 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49   */.static Tcl_I
1550: 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54 63 6c  nterp *appfs_Tcl
1560: 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b 0a 09  Interp(void) {..
1570: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
1580: 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  rp;..int pthread
1590: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
15a0: 20 70 74 68 72 65 61 64 5f 67 65 74 73 70 65 63   pthread_getspec
15b0: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 29 3b  ific(interpKey);
15c0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
15d0: 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72 70  NULL) {...interp
15e0: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
15f0: 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b  TclInterp(NULL);
1600: 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ....if (interp =
1610: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74  = NULL) {....ret
1620: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a  urn(NULL);...}..
1630: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
1640: 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69  pthread_setspeci
1650: 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69  fic(interpKey, i
1660: 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70 74  nterp);...if (pt
1670: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
1680: 7b 0a 09 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  {....Tcl_DeleteI
1690: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
16a0: 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
16b0: 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  ...}..}...return
16c0: 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a  (interp);.}../*.
16d0: 20 2a 20 45 76 61 6c 75 61 74 65 20 61 20 54 63   * Evaluate a Tc
16e0: 6c 20 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75  l script constru
16f0: 63 74 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e  cted by concaten
1700: 61 74 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66  ating a bunch of
1710: 20 43 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f   C strings. * to
1720: 67 65 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74  gether.. */.stat
1730: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c  ic int appfs_Tcl
1740: 5f 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70  _Eval(Tcl_Interp
1750: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
1760: 6a 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  jc, const char *
1770: 63 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c  cmd, ...) {..Tcl
1780: 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f  _Obj **objv;..co
1790: 6e 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09  nst char *arg;..
17a0: 76 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69  va_list argp;..i
17b0: 6e 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20  nt retval;..int 
17c0: 69 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20  i;...if (interp 
17d0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
17e0: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
17f0: 09 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69  .}...objv = (voi
1800: 64 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a  d *) ckalloc(siz
1810: 65 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a  eof(*objv) * obj
1820: 63 29 3b 0a 09 6f 62 6a 76 5b 30 5d 20 3d 20 54  c);..objv[0] = T
1830: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
1840: 63 6d 64 2c 20 2d 31 29 3b 0a 09 54 63 6c 5f 49  cmd, -1);..Tcl_I
1850: 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76  ncrRefCount(objv
1860: 5b 30 5d 29 3b 0a 0a 09 76 61 5f 73 74 61 72 74  [0]);...va_start
1870: 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 66 6f  (argp, cmd);..fo
1880: 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f 62  r (i = 1; i < ob
1890: 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 67  jc; i++) {...arg
18a0: 20 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c 20   = va_arg(argp, 
18b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a 09  const char *);..
18c0: 09 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e  .objv[i] = Tcl_N
18d0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 72 67 2c  ewStringObj(arg,
18e0: 20 2d 31 29 3b 0a 09 09 54 63 6c 5f 49 6e 63 72   -1);...Tcl_Incr
18f0: 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d  RefCount(objv[i]
1900: 29 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64 28 61 72  );..}..va_end(ar
1910: 67 70 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  gp);...retval = 
1920: 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74  Tcl_EvalObjv(int
1930: 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c  erp, objc, objv,
1940: 20 30 29 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20   0);...for (i = 
1950: 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  0; i < objc; i++
1960: 29 20 7b 0a 09 09 54 63 6c 5f 44 65 63 72 52 65  ) {...Tcl_DecrRe
1970: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b  fCount(objv[i]);
1980: 0a 09 7d 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f  ..}...ckfree((vo
1990: 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69  id *) objv);...i
19a0: 66 20 28 72 65 74 76 61 6c 20 21 3d 20 54 43 4c  f (retval != TCL
19b0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
19c0: 45 42 55 47 28 22 54 63 6c 20 63 6f 6d 6d 61 6e  EBUG("Tcl comman
19d0: 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65 72 72 6f  d failed, ::erro
19e0: 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e 73 3a 20  rInfo contains: 
19f0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61  %s\n", Tcl_GetVa
1a00: 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65 72 72  r(interp, "::err
1a10: 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b 0a 09 7d  orInfo", 0));..}
1a20: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
1a30: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65  );.}../*. * Dete
1a40: 72 6d 69 6e 65 20 74 68 65 20 55 49 44 20 66 6f  rmine the UID fo
1a50: 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e  r the user makin
1a60: 67 20 74 68 65 20 63 75 72 72 65 6e 74 20 46 55  g the current FU
1a70: 53 45 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65  SE filesystem re
1a80: 71 75 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77  quest.. * This w
1a90: 69 6c 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c  ill be used to l
1aa0: 6f 6f 6b 75 70 20 74 68 65 20 75 73 65 72 27 73  ookup the user's
1ab0: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20   home directory 
1ac0: 73 6f 20 77 65 20 63 61 6e 20 73 65 61 72 63 68  so we can search
1ad0: 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20   for. * locally 
1ae0: 6d 6f 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a  modified files..
1af0: 20 2a 2f 0a 73 74 61 74 69 63 20 75 69 64 5f 74   */.static uid_t
1b00: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
1b10: 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74  (void) {..struct
1b20: 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63   fuse_context *c
1b30: 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73  tx;...if (!appfs
1b40: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b  _fuse_started) {
1b50: 0a 09 09 72 65 74 75 72 6e 28 67 65 74 75 69 64  ...return(getuid
1b60: 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20  ());..}...ctx = 
1b70: 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74  fuse_get_context
1b80: 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20  ();..if (ctx == 
1b90: 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61  NULL) {.../* Una
1ba0: 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73  ble to lookup us
1bb0: 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73  er for some reas
1bc0: 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72  on */.../* Retur
1bd0: 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65  n an unprivilege
1be0: 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 72  d user ID */...r
1bf0: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72  eturn(1);..}...r
1c00: 65 74 75 72 6e 28 63 74 78 2d 3e 75 69 64 29 3b  eturn(ctx->uid);
1c10: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d  .}../*. * Determ
1c20: 69 6e 65 20 74 68 65 20 47 49 44 20 66 6f 72 20  ine the GID for 
1c30: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
1c40: 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53 45  the current FUSE
1c50: 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71 75   filesystem requ
1c60: 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c  est.. * This wil
1c70: 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  l be used to loo
1c80: 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20 68  kup the user's h
1c90: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73 6f  ome directory so
1ca0: 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20 66   we can search f
1cb0: 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f  or. * locally mo
1cc0: 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a  dified files.. *
1cd0: 2f 0a 73 74 61 74 69 63 20 67 69 64 5f 74 20 61  /.static gid_t a
1ce0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 76  ppfs_get_fsgid(v
1cf0: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66  oid) {..struct f
1d00: 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  use_context *ctx
1d10: 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66  ;...if (!appfs_f
1d20: 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09  use_started) {..
1d30: 09 72 65 74 75 72 6e 28 67 65 74 67 69 64 28 29  .return(getgid()
1d40: 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75  );..}...ctx = fu
1d50: 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29  se_get_context()
1d60: 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e 55  ;..if (ctx == NU
1d70: 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c  LL) {.../* Unabl
1d80: 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72  e to lookup user
1d90: 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e   for some reason
1da0: 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20   */.../* Return 
1db0: 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64 20  an unprivileged 
1dc0: 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 72 65 74  user ID */...ret
1dd0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74  urn(1);..}...ret
1de0: 75 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d  urn(ctx->gid);.}
1df0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
1e00: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
1e10: 72 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29  r_fs_enter(void)
1e20: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70   {..setfsuid(app
1e30: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
1e40: 0a 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73  ..setfsgid(appfs
1e50: 5f 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d  _get_fsgid());.}
1e60: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
1e70: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
1e80: 72 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29  r_fs_leave(void)
1e90: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b   {..setfsuid(0);
1ea0: 0a 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d  ..setfsgid(0);.}
1eb0: 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20  ../*. * Look up 
1ec0: 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  the home directo
1ed0: 72 79 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55  ry for a given U
1ee0: 49 44 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74  ID. *        Ret
1ef0: 75 72 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20  urns a C string 
1f00: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75  containing the u
1f10: 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63  ser's home direc
1f20: 74 6f 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a  tory or NULL if.
1f30: 20 2a 20 20 20 20 20 20 20 20 74 68 65 20 75 73   *        the us
1f40: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74  er's home direct
1f50: 6f 72 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69  ory does not exi
1f60: 73 74 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72  st or is not cor
1f70: 72 65 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20  rectly. *       
1f80: 20 63 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a   configured. */.
1f90: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70  static char *app
1fa0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75  fs_get_homedir(u
1fb0: 69 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73  id_t fsuid) {..s
1fc0: 74 72 75 63 74 20 70 61 73 73 77 64 20 65 6e 74  truct passwd ent
1fd0: 72 79 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74  ry, *result;..st
1fe0: 72 75 63 74 20 73 74 61 74 20 73 74 62 75 66 3b  ruct stat stbuf;
1ff0: 0a 09 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d  ..char buf[1024]
2000: 2c 20 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20  , *retval;..int 
2010: 67 70 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65  gpu_ret, stat_re
2020: 74 3b 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67  t;...gpu_ret = g
2030: 65 74 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c  etpwuid_r(fsuid,
2040: 20 26 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69   &entry, buf, si
2050: 7a 65 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75  zeof(buf), &resu
2060: 6c 74 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65  lt);..if (gpu_re
2070: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
2080: 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69  S_DEBUG("getpwui
2090: 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72  d_r(%llu, ...) r
20a0: 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75  eturned in failu
20b0: 72 65 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c  re", (unsigned l
20c0: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29  ong long) fsuid)
20d0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
20e0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75  );..}...if (resu
20f0: 6c 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  lt == NULL) {...
2100: 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74  APPFS_DEBUG("get
2110: 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e  pwuid_r(%llu, ..
2120: 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c  .) returned NULL
2130: 20 72 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67   result", (unsig
2140: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
2150: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
2160: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
2170: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20  (result->pw_dir 
2180: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
2190: 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75  FS_DEBUG("getpwu
21a0: 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20  id_r(%llu, ...) 
21b0: 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f  returned NULL ho
21c0: 6d 65 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28  me directory", (
21d0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
21e0: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
21f0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2200: 0a 09 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61  ..stat_ret = sta
2210: 74 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72  t(result->pw_dir
2220: 2c 20 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28  , &stbuf);..if (
2230: 73 74 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b  stat_ret != 0) {
2240: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2250: 73 74 61 74 28 25 73 29 20 72 65 74 75 72 6e 65  stat(%s) returne
2260: 64 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72  d in failure", r
2270: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a  esult->pw_dir);.
2280: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2290: 0a 09 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e  ..}...if (stbuf.
22a0: 73 74 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29  st_uid != fsuid)
22b0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
22c0: 28 22 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20  ("UID mis-match 
22d0: 6f 6e 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68  on user %llu's h
22e0: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 28 25  ome directory (%
22f0: 73 29 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20  s).  It's owned 
2300: 62 79 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20  by %llu.",...   
2310: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
2320: 6c 6f 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20  long) fsuid,... 
2330: 20 20 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69     result->pw_di
2340: 72 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e  r,...    (unsign
2350: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74  ed long long) st
2360: 62 75 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a  buf.st_uid...);.
2370: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2380: 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73  ..}...retval = s
2390: 74 72 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77  trdup(result->pw
23a0: 5f 64 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28  _dir);...return(
23b0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20  retval);.}../*. 
23c0: 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20  * Tcl interface 
23d0: 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20  to get the home 
23e0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68  directory for th
23f0: 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68  e user making th
2400: 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46  e "current". * F
2410: 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a  USE I/O request.
2420: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74   */.static int t
2430: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
2440: 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20  edir(ClientData 
2450: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
2460: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
2470: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
2480: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72   objv[]) {..char
2490: 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f   *homedir;..Tcl_
24a0: 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a  Obj *homedir_obj
24b0: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  ;..uid_t fsuid;.
24c0: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
24d0: 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68   Tcl_Obj *last_h
24e0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c  omedir_obj = NUL
24f0: 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  L;..static __thr
2500: 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66  ead uid_t last_f
2510: 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20  suid = -1;..    
2520: 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20      if (objc != 
2530: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1) {.           
2540: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
2550: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
2560: 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20   objv, NULL);.  
2570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
2580: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
2590: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75  .        }...fsu
25a0: 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66  id = appfs_get_f
25b0: 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73  suid();...if (fs
25c0: 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69  uid == last_fsui
25d0: 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69  d && last_homedi
25e0: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b  r_obj != NULL) {
25f0: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d  ...homedir_obj =
2600: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
2610: 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 69  j;..} else {...i
2620: 66 20 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  f (last_homedir_
2630: 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  obj != NULL) {..
2640: 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75  ..Tcl_DecrRefCou
2650: 6e 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  nt(last_homedir_
2660: 6f 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d  obj);...}....hom
2670: 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74  edir = appfs_get
2680: 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67  _homedir(appfs_g
2690: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09  et_fsuid());....
26a0: 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e  if (homedir == N
26b0: 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  ULL) {....return
26c0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d  (TCL_ERROR);...}
26d0: 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ....homedir_obj 
26e0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
26f0: 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b  bj(homedir, -1);
2700: 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72  ....free(homedir
2710: 29 3b 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  );....last_homed
2720: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
2730: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
2740: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
2750: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
2760: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
2770: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
2780: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
2790: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
27a0: 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72  obj);..        r
27b0: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
27c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
27d0: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
27e0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c  user_fs_enter(Cl
27f0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
2800: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
2810: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
2820: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
2830: 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  ) {..appfs_simul
2840: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
2850: 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  r();...return(TC
2860: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  L_OK);.}..static
2870: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73   int tcl_appfs_s
2880: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
2890: 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61  leave(ClientData
28a0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
28b0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
28c0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
28d0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70  T objv[]) {..app
28e0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
28f0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72  _fs_leave();...r
2900: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
2910: 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65  ../*. * Generate
2920: 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20   an inode for a 
2930: 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65  given path.  The
2940: 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65   inode should be
2950: 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63   computed in suc
2960: 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20  h. * a way that 
2970: 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74  it is unlikely t
2980: 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20  o be duplicated 
2990: 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20  and remains the 
29a0: 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e  same for a given
29b0: 0a 20 2a 20 66 69 6c 65 0a 20 2a 2f 0a 73 74 61  . * file. */.sta
29c0: 74 69 63 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70  tic long long ap
29d0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
29e0: 64 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  de(const char *p
29f0: 61 74 68 29 20 7b 0a 09 6c 6f 6e 67 20 6c 6f 6e  ath) {..long lon
2a00: 67 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74  g retval;..const
2a10: 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74 76   char *p;...retv
2a20: 61 6c 20 3d 20 31 30 3b 0a 0a 09 66 6f 72 20 28  al = 10;...for (
2a30: 70 20 3d 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b  p = path; *p; p+
2a40: 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 25 3d  +) {...retval %=
2a50: 20 34 32 39 30 39 36 30 32 39 30 55 4c 4c 3b 0a   4290960290ULL;.
2a60: 09 09 72 65 74 76 61 6c 20 2b 3d 20 2a 70 3b 0a  ..retval += *p;.
2a70: 09 09 72 65 74 76 61 6c 20 3c 3c 3d 20 37 3b 0a  ..retval <<= 7;.
2a80: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31  .}...retval += 1
2a90: 30 3b 0a 09 72 65 74 76 61 6c 20 25 3d 20 34 32  0;..retval %= 42
2aa0: 39 34 39 36 37 32 39 36 55 4c 4c 3b 0a 0a 09 72  94967296ULL;...r
2ab0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
2ac0: 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61  ../* Get informa
2ad0: 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74  tion about a pat
2ae0: 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c  h, and optionall
2af0: 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20  y list children 
2b00: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
2b10: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
2b20: 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  o(const char *pa
2b30: 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  th, struct appfs
2b40: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
2b50: 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  nfo) {..Tcl_Inte
2b60: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c  rp *interp;..Tcl
2b70: 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74  _Obj *attrs_dict
2b80: 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09  , *attr_value;..
2b90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72  const char *attr
2ba0: 5f 76 61 6c 75 65 5f 73 74 72 3b 0a 09 54 63 6c  _value_str;..Tcl
2bb0: 5f 57 69 64 65 49 6e 74 20 61 74 74 72 5f 76 61  _WideInt attr_va
2bc0: 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20 61  lue_wide;..int a
2bd0: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09  ttr_value_int;..
2be0: 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20  static __thread 
2bf0: 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b 65  Tcl_Obj *attr_ke
2c00: 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20 2a  y_type = NULL, *
2c10: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 3d  attr_key_perms =
2c20: 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79   NULL, *attr_key
2c30: 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61  _size = NULL, *a
2c40: 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20 4e  ttr_key_time = N
2c50: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73  ULL, *attr_key_s
2c60: 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61  ource = NULL, *a
2c70: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
2c80: 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72  nt = NULL, *attr
2c90: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 3d 20  _key_packaged = 
2ca0: 4e 55 4c 4c 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  NULL;..int tcl_r
2cb0: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
2cc0: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
2cd0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
2ce0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
2cf0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63  n(-EIO);..}...tc
2d00: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
2d10: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
2d20: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  , "::appfs::geta
2d30: 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ttr", path);..if
2d40: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
2d50: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
2d60: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67  EBUG("::appfs::g
2d70: 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65  etattr(%s) faile
2d80: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
2d90: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
2da0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
2db0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
2dc0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72  t(interp));....r
2dd0: 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a  eturn(-ENOENT);.
2de0: 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b 65  .}...if (attr_ke
2df0: 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20  y_type == NULL) 
2e00: 7b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 74 79 70  {...attr_key_typ
2e10: 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  e       = Tcl_Ne
2e20: 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70 65  wStringObj("type
2e30: 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b  ", -1);...attr_k
2e40: 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20 3d 20  ey_perms      = 
2e50: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
2e60: 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b 0a 09  ("perms", -1);..
2e70: 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 20  .attr_key_size  
2e80: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
2e90: 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65 22 2c 20  ringObj("size", 
2ea0: 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f  -1);...attr_key_
2eb0: 74 69 6d 65 20 20 20 20 20 20 20 3d 20 54 63 6c  time       = Tcl
2ec0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74  _NewStringObj("t
2ed0: 69 6d 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74  ime", -1);...att
2ee0: 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 20 20 20  r_key_source    
2ef0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
2f00: 4f 62 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d 31  Obj("source", -1
2f10: 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 63 68  );...attr_key_ch
2f20: 69 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e  ildcount = Tcl_N
2f30: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68 69  ewStringObj("chi
2f40: 6c 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a 09  ldcount", -1);..
2f50: 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  .attr_key_packag
2f60: 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74  ed   = Tcl_NewSt
2f70: 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67 65  ringObj("package
2f80: 64 22 2c 20 2d 31 29 3b 0a 09 7d 0a 0a 09 61 74  d", -1);..}...at
2f90: 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47  trs_dict = Tcl_G
2fa0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
2fb0: 72 70 29 3b 0a 09 74 63 6c 5f 72 65 74 20 3d 20  rp);..tcl_ret = 
2fc0: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
2fd0: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
2fe0: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  t, attr_key_type
2ff0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
3000: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
3010: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
3020: 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20 67  S_DEBUG("[dict g
3030: 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69  et \"type\"] fai
3040: 6c 65 64 22 29 3b 0a 09 09 41 50 50 46 53 5f 44  led");...APPFS_D
3050: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
3060: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
3070: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
3080: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
3090: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20  (-EIO);..}...if 
30a0: 28 61 74 74 72 5f 76 61 6c 75 65 20 3d 3d 20 4e  (attr_value == N
30b0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
30c0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74 68  -EIO);..}...path
30d0: 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d  info->packaged =
30e0: 20 30 3b 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 69   0;..pathinfo->i
30f0: 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74  node = appfs_get
3100: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
3110: 29 3b 0a 0a 09 61 74 74 72 5f 76 61 6c 75 65 5f  );...attr_value_
3120: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
3130: 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b  ing(attr_value);
3140: 0a 09 73 77 69 74 63 68 20 28 61 74 74 72 5f 76  ..switch (attr_v
3150: 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09  alue_str[0]) {..
3160: 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69  .case 'd': /* di
3170: 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 70 61  rectory */....pa
3180: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
3190: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
31a0: 52 45 43 54 4f 52 59 3b 0a 09 09 09 70 61 74 68  RECTORY;....path
31b0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
31c0: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
31d0: 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f  0;.....Tcl_DictO
31e0: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
31f0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
3200: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20 26  ey_childcount, &
3210: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
3220: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
3230: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74 63  = NULL) {.....tc
3240: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
3250: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
3260: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
3270: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
3280: 29 3b 0a 09 09 09 09 69 66 20 28 74 63 6c 5f 72  );.....if (tcl_r
3290: 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et == TCL_OK) {.
32a0: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
32b0: 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c  ypeinfo.dir.chil
32c0: 64 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f 76 61  dcount = attr_va
32d0: 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 7d 0a  lue_wide;.....}.
32e0: 09 09 09 7d 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ...}.....break;.
32f0: 09 09 63 61 73 65 20 27 66 27 3a 20 2f 2a 20 66  ..case 'f': /* f
3300: 69 6c 65 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e  ile */....pathin
3310: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
3320: 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a  _PATHTYPE_FILE;.
3330: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
3340: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20  einfo.file.size 
3350: 3d 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f  = 0;....pathinfo
3360: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
3370: 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a  executable = 0;.
3380: 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
3390: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
33a0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
33b0: 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  size, &attr_valu
33c0: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
33d0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
33e0: 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  .....tcl_ret = T
33f0: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
3400: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
3410: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
3420: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69 66  ue_wide);.....if
3430: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
3440: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74 68  _OK) {......path
3450: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
3460: 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f  ile.size = attr_
3470: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09  value_wide;.....
3480: 7d 0a 09 09 09 7d 0a 0a 09 09 09 54 63 6c 5f 44  }....}.....Tcl_D
3490: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
34a0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
34b0: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61  tr_key_perms, &a
34c0: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69  ttr_value);....i
34d0: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
34e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74   NULL) {.....att
34f0: 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63  r_value_str = Tc
3500: 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72  l_GetString(attr
3510: 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20  _value);.....if 
3520: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  (attr_value_str[
3530: 30 5d 20 3d 3d 20 27 78 27 29 20 7b 0a 09 09 09  0] == 'x') {....
3540: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
3550: 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74  info.file.execut
3560: 61 62 6c 65 20 3d 20 31 3b 0a 09 09 09 09 7d 0a  able = 1;.....}.
3570: 09 09 09 7d 0a 09 09 09 62 72 65 61 6b 3b 0a 09  ...}....break;..
3580: 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73 79  .case 's': /* sy
3590: 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 70 61 74 68  mlink */....path
35a0: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
35b0: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
35c0: 49 4e 4b 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f  INK;....pathinfo
35d0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
35e0: 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09  nk.size = 0;....
35f0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
3600: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
3610: 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09  e[0] = '\0';....
3620: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
3630: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
3640: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ct, attr_key_sou
3650: 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rce, &attr_value
3660: 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76  );....if (attr_v
3670: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
3680: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
3690: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
36a0: 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76  ngFromObj(attr_v
36b0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
36c0: 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 69 66  e_int); ......if
36d0: 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e   ((attr_value_in
36e0: 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66  t + 1) <= sizeof
36f0: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  (pathinfo->typei
3700: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
3710: 63 65 29 29 20 7b 0a 09 09 09 09 09 70 61 74 68  ce)) {......path
3720: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
3730: 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74  ymlink.size = at
3740: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09  tr_value_int;...
3750: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
3760: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
3770: 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65 5f  urce[attr_value_
3780: 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09  int] = '\0';....
3790: 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69 6e  ...memcpy(pathin
37a0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
37b0: 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74 74  link.source, att
37c0: 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74 74  r_value_str, att
37d0: 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09 09  r_value_int);...
37e0: 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 72 65 61  ..}....}....brea
37f0: 6b 3b 0a 09 09 63 61 73 65 20 27 46 27 3a 20 2f  k;...case 'F': /
3800: 2a 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09  * pipe/fifo */..
3810: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
3820: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
3830: 45 5f 46 49 46 4f 3b 0a 09 09 09 62 72 65 61 6b  E_FIFO;....break
3840: 3b 0a 09 09 63 61 73 65 20 27 53 27 3a 20 2f 2a  ;...case 'S': /*
3850: 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73 6f 63   UNIX domain soc
3860: 6b 65 74 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e  ket */....pathin
3870: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
3880: 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54  _PATHTYPE_SOCKET
3890: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 64 65  ;....break;...de
38a0: 66 61 75 6c 74 3a 0a 09 09 09 72 65 74 75 72 6e  fault:....return
38b0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (-EIO);..}...Tcl
38c0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
38d0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
38e0: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
38f0: 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  d, &attr_value);
3900: 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
3910: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 70 61   != NULL) {...pa
3920: 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64  thinfo->packaged
3930: 20 3d 20 31 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44   = 1;..}...Tcl_D
3940: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
3950: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
3960: 74 72 5f 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74  tr_key_time, &at
3970: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66 20 28  tr_value);..if (
3980: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
3990: 4c 4c 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20  LL) {...tcl_ret 
39a0: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
39b0: 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74  FromObj(NULL, at
39c0: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
39d0: 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 69  value_wide);...i
39e0: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
39f0: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 70 61 74 68 69  L_OK) {....pathi
3a00: 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 72  nfo->time = attr
3a10: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 7d  _value_wide;...}
3a20: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 70 61 74  ..} else {...pat
3a30: 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 30 3b  hinfo->time = 0;
3a40: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
3a50: 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20  .}..static char 
3a60: 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74  *appfs_prepare_t
3a70: 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  o_create(const c
3a80: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
3a90: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
3aa0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
3ab0: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
3ac0: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
3ad0: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
3ae0: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
3af0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
3b00: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
3b10: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
3b20: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
3b30: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
3b40: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
3b50: 65 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  e", path);..if (
3b60: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
3b70: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
3b80: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65  UG("::appfs::pre
3b90: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25  pare_to_create(%
3ba0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
3bb0: 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  h);...APPFS_DEBU
3bc0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
3bd0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
3be0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
3bf0: 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  ));....return(NU
3c00: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70  LL);..}...real_p
3c10: 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ath = Tcl_GetStr
3c20: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
3c30: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
3c40: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
3c50: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
3c60: 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70 28  ..return(strdup(
3c70: 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a  real_path));.}..
3c80: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70  static char *app
3c90: 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63 6f 6e  fs_localpath(con
3ca0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b  st char *path) {
3cb0: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
3cc0: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
3cd0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
3ce0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
3cf0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
3d00: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
3d10: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
3d20: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3d30: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
3d40: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
3d50: 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70  nterp, 2, "::app
3d60: 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 22 2c 20  fs::localpath", 
3d70: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
3d80: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
3d90: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3da0: 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61  ::appfs::localpa
3db0: 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  th(%s) failed.",
3dc0: 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f   path);...APPFS_
3dd0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
3de0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
3df0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
3e00: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72  terp));....retur
3e10: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
3e20: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
3e30: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
3e40: 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 6c  terp);..if (real
3e50: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
3e60: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3e70: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 72  ..}...return(str
3e80: 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29 3b  dup(real_path));
3e90: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
3ea0: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69  ppfs_fuse_readli
3eb0: 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  nk(const char *p
3ec0: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
3ed0: 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09  size_t size) {..
3ee0: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
3ef0: 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a  hinfo pathinfo;.
3f00: 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30 3b  .int retval = 0;
3f10: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3f20: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
3f30: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
3f40: 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20  ..pathinfo.type 
3f50: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
3f60: 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76  _INVALID;...retv
3f70: 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70  al = appfs_get_p
3f80: 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26  ath_info(path, &
3f90: 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28  pathinfo);..if (
3fa0: 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09  retval != 0) {..
3fb0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
3fc0: 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e  ..}...if (pathin
3fd0: 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46 53  fo.type != APPFS
3fe0: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e  _PATHTYPE_SYMLIN
3ff0: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  K) {...return(-E
4000: 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  INVAL);..}...if 
4010: 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66  ((strlen(pathinf
4020: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
4030: 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 20  nk.source) + 1) 
4040: 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74 75  > size) {...retu
4050: 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47  rn(-ENAMETOOLONG
4060: 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62  );..}...memcpy(b
4070: 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79 70  uf, pathinfo.typ
4080: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
4090: 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61 74  urce, strlen(pat
40a0: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73  hinfo.typeinfo.s
40b0: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b  ymlink.source) +
40c0: 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29   1);...return(0)
40d0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
40e0: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
40f0: 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  tr(const char *p
4100: 61 74 68 2c 20 73 74 72 75 63 74 20 73 74 61 74  ath, struct stat
4110: 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72 75   *stbuf) {..stru
4120: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
4130: 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74  o pathinfo;..int
4140: 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61   retval;...retva
4150: 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44  l = 0;...APPFS_D
4160: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
4170: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
4180: 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f  ath);...pathinfo
4190: 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  .type = APPFS_PA
41a0: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a  THTYPE_INVALID;.
41b0: 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73  ..retval = appfs
41c0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
41d0: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b  ath, &pathinfo);
41e0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
41f0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65  0) {...return(re
4200: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 73  tval);..}...mems
4210: 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69 7a  et(stbuf, 0, siz
4220: 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74 29  eof(struct stat)
4230: 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  );...stbuf->st_m
4240: 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e  time = pathinfo.
4250: 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  time;..stbuf->st
4260: 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66  _ctime = pathinf
4270: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e  o.time;..stbuf->
4280: 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68 69  st_atime = pathi
4290: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
42a0: 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61 74  ->st_ino   = pat
42b0: 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74  hinfo.inode;..st
42c0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20  buf->st_mode  = 
42d0: 30 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 75 69  0;..stbuf->st_ui
42e0: 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  d   = appfs_get_
42f0: 66 73 75 69 64 28 29 3b 0a 09 73 74 62 75 66 2d  fsuid();..stbuf-
4300: 3e 73 74 5f 67 69 64 20 20 20 3d 20 61 70 70 66  >st_gid   = appf
4310: 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a  s_get_fsgid();..
4320: 09 73 77 69 74 63 68 20 28 70 61 74 68 69 6e 66  .switch (pathinf
4330: 6f 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65  o.type) {...case
4340: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
4350: 44 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74  DIRECTORY:....st
4360: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
4370: 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09  _IFDIR | 0555;..
4380: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
4390: 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f  k = 2 + pathinfo
43a0: 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  .typeinfo.dir.ch
43b0: 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65  ildcount;....bre
43c0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
43d0: 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a  _PATHTYPE_FILE:.
43e0: 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
43f0: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78  typeinfo.file.ex
4400: 65 63 75 74 61 62 6c 65 29 20 7b 0a 09 09 09 09  ecutable) {.....
4410: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d  stbuf->st_mode =
4420: 20 53 5f 49 46 52 45 47 20 7c 20 30 35 35 35 3b   S_IFREG | 0555;
4430: 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
4440: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
4450: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34  = S_IFREG | 0444
4460: 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 74 62 75 66  ;....}.....stbuf
4470: 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a  ->st_nlink = 1;.
4480: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a  ...stbuf->st_siz
4490: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70  e = pathinfo.typ
44a0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b  einfo.file.size;
44b0: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
44c0: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
44d0: 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74 62  _SYMLINK:....stb
44e0: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
44f0: 49 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a 09 09  IFLNK | 0555;...
4500: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
4510: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
4520: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
4530: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
4540: 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65  ink.size;....bre
4550: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
4560: 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54  _PATHTYPE_SOCKET
4570: 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  :....stbuf->st_m
4580: 6f 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b 20 7c  ode = S_IFSOCK |
4590: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
45a0: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
45b0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65  ..stbuf->st_size
45c0: 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a   = 0;....break;.
45d0: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
45e0: 48 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09 09 73  HTYPE_FIFO:....s
45f0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
4600: 53 5f 49 46 49 46 4f 20 7c 20 30 35 35 35 3b 0a  S_IFIFO | 0555;.
4610: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
4620: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
4630: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09  ->st_size = 0;..
4640: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
4650: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
4660: 4e 56 41 4c 49 44 3a 0a 09 09 09 72 65 74 76 61  NVALID:....retva
4670: 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09  l = -ENOENT;....
4680: 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20  .break;..}...if 
4690: 28 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67  (pathinfo.packag
46a0: 65 64 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e 73  ed) {...stbuf->s
46b0: 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 32 32 3b 0a  t_mode |= 0222;.
46c0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  .}...return(retv
46d0: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  al);.}..static i
46e0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
46f0: 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72  addir(const char
4700: 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75   *path, void *bu
4710: 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72  f, fuse_fill_dir
4720: 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74  _t filler, off_t
4730: 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20   offset, struct 
4740: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
4750: 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  fi) {..Tcl_Inter
4760: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f  p *interp;..Tcl_
4770: 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a  Obj **children;.
4780: 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f  .int children_co
4790: 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74  unt, idx;..int t
47a0: 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  cl_ret;...APPFS_
47b0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
47c0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
47d0: 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20  path);...interp 
47e0: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
47f0: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
4800: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
4810: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 69  turn(0);..}...fi
4820: 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e  ller(buf, ".", N
4830: 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72  ULL, 0);..filler
4840: 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c  (buf, "..", NULL
4850: 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20  , 0);...tcl_ret 
4860: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
4870: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
4880: 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65  ppfs::getchildre
4890: 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  n", path);..if (
48a0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
48b0: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
48c0: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  UG("::appfs::get
48d0: 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69  children(%s) fai
48e0: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
48f0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
4900: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
4910: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
4920: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
4930: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
4940: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c  .tcl_ret = Tcl_L
4950: 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74  istObjGetElement
4960: 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  s(interp, Tcl_Ge
4970: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
4980: 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f  p), &children_co
4990: 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b  unt, &children);
49a0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
49b0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
49c0: 46 53 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e  FS_DEBUG("Parsin
49d0: 67 20 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72  g list of childr
49e0: 65 6e 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61  en on path %s fa
49f0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
4a00: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
4a10: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
4a20: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
4a30: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
4a40: 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a  ..return(0);..}.
4a50: 0a 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20  ..for (idx = 0; 
4a60: 69 64 78 20 3c 20 63 68 69 6c 64 72 65 6e 5f 63  idx < children_c
4a70: 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20 7b 0a 09  ount; idx++) {..
4a80: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c  .filler(buf, Tcl
4a90: 5f 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64  _GetString(child
4aa0: 72 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c  ren[idx]), NULL,
4ab0: 20 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e   0);..}...return
4ac0: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
4ad0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70  nt appfs_fuse_op
4ae0: 65 6e 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  en(const char *p
4af0: 61 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65  ath, struct fuse
4b00: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
4b10: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
4b20: 6e 74 65 72 70 3b 0a 09 73 74 72 75 63 74 20 61  nterp;..struct a
4b30: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61  ppfs_pathinfo pa
4b40: 74 68 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63  thinfo;..const c
4b50: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20  har *real_path, 
4b60: 2a 6d 6f 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f  *mode;..int gpi_
4b70: 72 65 74 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69  ret, tcl_ret;..i
4b80: 6e 74 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44  nt fh;...APPFS_D
4b90: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
4ba0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
4bb0: 61 74 68 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20  ath);...gpi_ret 
4bc0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
4bd0: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
4be0: 68 69 6e 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66  hinfo);...if ((f
4bf0: 69 2d 3e 66 6c 61 67 73 20 26 20 28 4f 5f 57 52  i->flags & (O_WR
4c00: 4f 4e 4c 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d  ONLY|O_CREAT)) =
4c10: 3d 20 28 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f  = (O_CREAT|O_WRO
4c20: 4e 4c 59 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65  NLY)) {.../* The
4c30: 20 66 69 6c 65 20 77 69 6c 6c 20 62 65 20 63 72   file will be cr
4c40: 65 61 74 65 64 20 69 66 20 69 74 20 64 6f 65 73  eated if it does
4c50: 20 6e 6f 74 20 65 78 69 73 74 20 2a 2f 0a 09 09   not exist */...
4c60: 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30  if (gpi_ret != 0
4c70: 20 26 26 20 67 70 69 5f 72 65 74 20 21 3d 20 2d   && gpi_ret != -
4c80: 45 4e 4f 45 4e 54 29 20 7b 0a 09 09 09 72 65 74  ENOENT) {....ret
4c90: 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09  urn(gpi_ret);...
4ca0: 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 63 72 65  }....mode = "cre
4cb0: 61 74 65 22 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  ate";..} else {.
4cc0: 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75  ../* The file mu
4cd0: 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73 74  st already exist
4ce0: 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65   */...if (gpi_re
4cf0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74  t != 0) {....ret
4d00: 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09  urn(gpi_ret);...
4d10: 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a  }....mode = "";.
4d20: 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67  ...if ((fi->flag
4d30: 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d  s & O_WRONLY) ==
4d40: 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09   O_WRONLY) {....
4d50: 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a  mode = "write";.
4d60: 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74  ..}..}...if (pat
4d70: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50  hinfo.type == AP
4d80: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
4d90: 45 43 54 4f 52 59 29 20 7b 0a 09 09 72 65 74 75  ECTORY) {...retu
4da0: 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a  rn(-EISDIR);..}.
4db0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
4dc0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
4dd0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
4de0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
4df0: 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  IO);..}...tcl_re
4e00: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
4e10: 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a  al(interp, 3, ":
4e20: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
4e30: 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a  ", path, mode);.
4e40: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
4e50: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
4e60: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
4e70: 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25  ::openpath(%s, %
4e80: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
4e90: 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 41 50 50 46  h, mode);...APPF
4ea0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
4eb0: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
4ec0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
4ed0: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74  interp));....ret
4ee0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
4ef0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f  real_path = Tcl_
4f00: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
4f10: 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65  interp);..if (re
4f20: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
4f30: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
4f40: 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45  );..}...APPFS_DE
4f50: 42 55 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20  BUG("Translated 
4f60: 72 65 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20  request to open 
4f70: 25 73 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73  %s to opening %s
4f80: 20 28 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29   (mode = \"%s\")
4f90: 22 2c 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61  ", path, real_pa
4fa0: 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20  th, mode);...fh 
4fb0: 3d 20 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68  = open(real_path
4fc0: 2c 20 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30  , fi->flags, 060
4fd0: 30 29 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30  0);...if (fh < 0
4fe0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
4ff0: 4f 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20  O);..}...fi->fh 
5000: 3d 20 66 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30  = fh;...return(0
5010: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
5020: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73   appfs_fuse_clos
5030: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
5040: 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  th, struct fuse_
5050: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
5060: 0a 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b  ..int close_ret;
5070: 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d 20 63  ...close_ret = c
5080: 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a 09 69  lose(fi->fh);..i
5090: 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21 3d 20  f (close_ret != 
50a0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  0) {...return(-E
50b0: 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  IO);..}...return
50c0: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
50d0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
50e0: 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ad(const char *p
50f0: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
5100: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
5110: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
5120: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
5130: 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c   *fi) {..off_t l
5140: 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65  seek_ret;..ssize
5150: 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41  _t read_ret;...A
5160: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
5170: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
5180: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 6c 73  .)", path);...ls
5190: 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b 28  eek_ret = lseek(
51a0: 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c 20  fi->fh, offset, 
51b0: 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20 28  SEEK_SET);..if (
51c0: 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66 66  lseek_ret != off
51d0: 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  set) {...return(
51e0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 64  -EIO);..}...read
51f0: 5f 72 65 74 20 3d 20 72 65 61 64 28 66 69 2d 3e  _ret = read(fi->
5200: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29 3b 0a  fh, buf, size);.
5210: 0a 09 72 65 74 75 72 6e 28 72 65 61 64 5f 72 65  ..return(read_re
5220: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
5230: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69  t appfs_fuse_wri
5240: 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  te(const char *p
5250: 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ath, const char 
5260: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
5270: 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c  e, off_t offset,
5280: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
5290: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 6f  e_info *fi) {..o
52a0: 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b 0a  ff_t lseek_ret;.
52b0: 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65 5f 72  .ssize_t write_r
52c0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
52d0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
52e0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
52f0: 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d  );...lseek_ret =
5300: 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f   lseek(fi->fh, o
5310: 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29  ffset, SEEK_SET)
5320: 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74  ;..if (lseek_ret
5330: 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09   != offset) {...
5340: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
5350: 0a 0a 09 77 72 69 74 65 5f 72 65 74 20 3d 20 77  ...write_ret = w
5360: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66  rite(fi->fh, buf
5370: 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72  , size);...retur
5380: 6e 28 77 72 69 74 65 5f 72 65 74 29 3b 0a 7d 0a  n(write_ret);.}.
5390: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
53a0: 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e  s_fuse_mknod(con
53b0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
53c0: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f  ode_t mode, dev_
53d0: 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61  t device) {..cha
53e0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
53f0: 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09  nt mknod_ret;...
5400: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
5410: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
5420: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
5430: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43  f ((mode & S_IFC
5440: 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20  HR) == S_IFCHR) 
5450: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
5460: 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f  M);..}...if ((mo
5470: 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d  de & S_IFBLK) ==
5480: 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65   S_IFBLK) {...re
5490: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
54a0: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
54b0: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
54c0: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69  create(path);..i
54d0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
54e0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
54f0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
5500: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
5510: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d  _fs_enter();...m
5520: 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64  knod_ret = mknod
5530: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
5540: 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70  , device);...app
5550: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
5560: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
5570: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
5580: 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20  ..if (mknod_ret 
5590: 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  != 0) {...return
55a0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
55b0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
55c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
55d0: 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f  s_fuse_create(co
55e0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
55f0: 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72  mode_t mode, str
5600: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
5610: 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20  fo *fi) {..char 
5620: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
5630: 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42   fd;...APPFS_DEB
5640: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
5650: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
5660: 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20  h);...if ((mode 
5670: 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f  & S_IFCHR) == S_
5680: 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72  IFCHR) {...retur
5690: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09  n(-EPERM);..}...
56a0: 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46  if ((mode & S_IF
56b0: 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29  BLK) == S_IFBLK)
56c0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45   {...return(-EPE
56d0: 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70  RM);..}...real_p
56e0: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70  ath = appfs_prep
56f0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61  are_to_create(pa
5700: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70  th);..if (real_p
5710: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
5720: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
5730: 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  }...appfs_simula
5740: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
5750: 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74  ();...fd = creat
5760: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
5770: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
5780: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
5790: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
57a0: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64  _path);...if (fd
57b0: 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e   < 0) {...return
57c0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
57d0: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a  ...fi->fh = fd;.
57e0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
57f0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
5800: 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63  _fuse_truncate(c
5810: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
5820: 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09   off_t size) {..
5830: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
5840: 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72  ..int truncate_r
5850: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
5860: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
5870: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
5880: 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  );...real_path =
5890: 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68   appfs_localpath
58a0: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
58b0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
58c0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
58d0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
58e0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
58f0: 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e 63 61 74  ter();...truncat
5900: 65 5f 72 65 74 20 3d 20 74 72 75 6e 63 61 74 65  e_ret = truncate
5910: 28 72 65 61 6c 5f 70 61 74 68 2c 20 73 69 7a 65  (real_path, size
5920: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
5930: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
5940: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
5950: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 74 72  _path);...if (tr
5960: 75 6e 63 61 74 65 5f 72 65 74 20 21 3d 20 30 29  uncate_ret != 0)
5970: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
5980: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
5990: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
59a0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
59b0: 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 28 63  e_unlink_rmdir(c
59c0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29  onst char *path)
59d0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
59e0: 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c  interp;..int tcl
59f0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
5a00: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
5a10: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
5a20: 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  th);...interp = 
5a30: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
5a40: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
5a50: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
5a60: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74  rn(-EIO);..}...t
5a70: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
5a80: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
5a90: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c  2, "::appfs::unl
5aa0: 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b  inkpath", path);
5ab0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
5ac0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
5ad0: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
5ae0: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73  s::unlinkpath(%s
5af0: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
5b00: 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  );...APPFS_DEBUG
5b10: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
5b20: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
5b30: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
5b40: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  );....return(-EI
5b50: 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  O);..}...return(
5b60: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
5b70: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64  t appfs_fuse_mkd
5b80: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
5b90: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
5ba0: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
5bb0: 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72  path;..int mkdir
5bc0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
5bd0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
5be0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
5bf0: 74 68 29 3b 0a 0a 0a 09 72 65 61 6c 5f 70 61 74  th);....real_pat
5c00: 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72  h = appfs_prepar
5c10: 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68  e_to_create(path
5c20: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
5c30: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
5c40: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
5c50: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
5c60: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
5c70: 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20  ;...mkdir_ret = 
5c80: 6d 6b 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c  mkdir(real_path,
5c90: 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f   mode);...appfs_
5ca0: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
5cb0: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65  _leave();...free
5cc0: 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69  (real_path);...i
5cd0: 66 20 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20  f (mkdir_ret != 
5ce0: 30 29 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f  0) {...if (errno
5cf0: 20 21 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09   != EEXIST) {...
5d00: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
5d10: 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65  -1);...}..}...re
5d20: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
5d30: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
5d40: 65 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68  e_chmod(const ch
5d50: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
5d60: 20 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e   mode) {..Tcl_In
5d70: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
5d80: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
5d90: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
5da0: 65 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a  et, chmod_ret;..
5db0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
5dc0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
5dd0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
5de0: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5df0: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5e00: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5e10: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
5e20: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
5e30: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
5e40: 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61  (interp, 3, "::a
5e50: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c  ppfs::openpath",
5e60: 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b   path, "write");
5e70: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
5e80: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
5e90: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
5ea0: 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20  s::openpath(%s, 
5eb0: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
5ec0: 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 09  th, "write");...
5ed0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
5ee0: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
5ef0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
5f00: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
5f10: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
5f20: 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  }...real_path = 
5f30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
5f40: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66  ult(interp);..if
5f50: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
5f60: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
5f70: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
5f80: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
5f90: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 63 68  fs_enter();...ch
5fa0: 6d 6f 64 5f 72 65 74 20 3d 20 63 68 6d 6f 64 28  mod_ret = chmod(
5fb0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
5fc0: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
5fd0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
5fe0: 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 63 68 6d  ();...return(chm
5ff0: 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20  od_ret);.}../*. 
6000: 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 3a 20  * SQLite3 mode: 
6010: 45 78 65 63 75 74 65 20 72 61 77 20 53 51 4c 20  Execute raw SQL 
6020: 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65  and return succe
6030: 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a  ss or failure. *
6040: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
6050: 66 73 5f 73 71 6c 69 74 65 33 28 63 6f 6e 73 74  fs_sqlite3(const
6060: 20 63 68 61 72 20 2a 73 71 6c 29 20 7b 0a 09 54   char *sql) {..T
6070: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
6080: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
6090: 73 71 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63  sql_ret;..int tc
60a0: 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20  l_ret;...interp 
60b0: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
60c0: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
60d0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
60e0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
60f0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
6100: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
6110: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
6120: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
6130: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
6140: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
6150: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
6160: 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64  , 5, "::appfs::d
6170: 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c  b", "eval", sql,
6180: 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d   "row", "unset -
6190: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a  nocomplain row(*
61a0: 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20 70  ); parray row; p
61b0: 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a  uts \"----\"");.
61c0: 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .sql_ret = Tcl_G
61d0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
61e0: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63  nterp);...if (tc
61f0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
6200: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
6210: 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73  err, "[error] %s
6220: 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a  \n", sql_ret);..
6230: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
6240: 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26 26  ..if (sql_ret &&
6250: 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27   sql_ret[0] != '
6260: 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28  \0') {...printf(
6270: 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29  "%s\n", sql_ret)
6280: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
6290: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d  ;.}../*. * Tcl m
62a0: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
62b0: 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e 20   Tcl and return 
62c0: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
62d0: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
62e0: 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73  t appfs_tcl(cons
62f0: 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09  t char *tcl) {..
6300: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6310: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
6320: 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e  *tcl_result;..in
6330: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74  t tcl_ret;...int
6340: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
6350: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
6360: 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  L);..if (interp 
6370: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72  == NULL) {...fpr
6380: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
6390: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61  able to create a
63a0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
63b0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
63c0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
63d0: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54  .}...tcl_ret = T
63e0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
63f0: 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c  tcl);..tcl_resul
6400: 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  t = Tcl_GetStrin
6410: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
6420: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ...if (tcl_ret !
6430: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
6440: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b  rintf(stderr, "[
6450: 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 74 63  error] %s\n", tc
6460: 6c 5f 72 65 73 75 6c 74 29 3b 0a 0a 09 09 72 65  l_result);....re
6470: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66  turn(1);..}...if
6480: 20 28 74 63 6c 5f 72 65 73 75 6c 74 20 26 26 20   (tcl_result && 
6490: 74 63 6c 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d  tcl_result[0] !=
64a0: 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74   '\0') {...print
64b0: 66 28 22 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65  f("%s\n", tcl_re
64c0: 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  sult);..}...retu
64d0: 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  rn(0);.}../*. * 
64e0: 41 70 70 46 53 64 20 50 61 63 6b 61 67 65 20 66  AppFSd Package f
64f0: 6f 72 20 54 63 6c 3a 0a 20 2a 20 20 20 20 20 20  or Tcl:. *      
6500: 20 20 20 42 72 69 64 67 65 20 66 6f 72 20 49 2f     Bridge for I/
6510: 4f 20 6f 70 65 72 61 74 69 6f 6e 73 20 74 6f 20  O operations to 
6520: 72 65 71 75 65 73 74 20 69 6e 66 6f 72 6d 61 74  request informat
6530: 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20 63 75  ion about the cu
6540: 72 72 65 6e 74 0a 20 2a 20 20 20 20 20 20 20 20  rrent. *        
6550: 20 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f   transaction. */
6560: 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70 70 66  .static int Appf
6570: 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  sd_Init(Tcl_Inte
6580: 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69  rp *interp) {.#i
6590: 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53 54 55  fdef USE_TCL_STU
65a0: 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69 74  BS..if (Tcl_Init
65b0: 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20 54 43  Stubs(interp, TC
65c0: 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d  L_VERSION, 0) ==
65d0: 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28   0L) {...return(
65e0: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23  TCL_ERROR);..}.#
65f0: 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61  endif...Tcl_Crea
6600: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
6610: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65  erp, "appfsd::ge
6620: 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f  t_homedir", tcl_
6630: 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69  appfs_get_homedi
6640: 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  r, NULL, NULL);.
6650: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
6660: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
6670: 70 70 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f  ppfsd::simulate_
6680: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20  user_fs_enter", 
6690: 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61  tcl_appfs_simula
66a0: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
66b0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
66c0: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
66d0: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70  mand(interp, "ap
66e0: 70 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75  pfsd::simulate_u
66f0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74  ser_fs_leave", t
6700: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
6710: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c  e_user_fs_leave,
6720: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09   NULL, NULL);...
6730: 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69  Tcl_PkgProvide(i
6740: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c  nterp, "appfsd",
6750: 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72   "1.0");...retur
6760: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a  n(TCL_OK);.}../*
6770: 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69  . * FUSE operati
6780: 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a  ons structure. *
6790: 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20  /.static struct 
67a0: 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20  fuse_operations 
67b0: 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73  appfs_operations
67c0: 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20   = {...getattr  
67d0: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65   = appfs_fuse_ge
67e0: 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72  tattr,...readdir
67f0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
6800: 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c  readdir,...readl
6810: 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ink  = appfs_fus
6820: 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70  e_readlink,...op
6830: 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  en      = appfs_
6840: 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c  fuse_open,...rel
6850: 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66  ease   = appfs_f
6860: 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61  use_close,...rea
6870: 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  d      = appfs_f
6880: 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74  use_read,...writ
6890: 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  e     = appfs_fu
68a0: 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f  se_write,...mkno
68b0: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
68c0: 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61  se_mknod,...crea
68d0: 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  te    = appfs_fu
68e0: 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75  se_create,...tru
68f0: 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66  ncate  = appfs_f
6900: 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e  use_truncate,...
6910: 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66  unlink    = appf
6920: 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d  s_fuse_unlink_rm
6930: 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20  dir,...rmdir    
6940: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e   = appfs_fuse_un
6950: 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b  link_rmdir,...mk
6960: 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f  dir     = appfs_
6970: 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68  fuse_mkdir,...ch
6980: 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f  mod     = appfs_
6990: 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a  fuse_chmod,.};..
69a0: 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70 74 69 6f  /*. * FUSE optio
69b0: 6e 20 70 61 72 73 69 6e 67 20 63 61 6c 6c 62 61  n parsing callba
69c0: 63 6b 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ck. */.static in
69d0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 74  t appfs_fuse_opt
69e0: 5f 63 62 28 76 6f 69 64 20 2a 64 61 74 61 2c 20  _cb(void *data, 
69f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67 2c  const char *arg,
6a00: 20 69 6e 74 20 6b 65 79 2c 20 73 74 72 75 63 74   int key, struct
6a10: 20 66 75 73 65 5f 61 72 67 73 20 2a 6f 75 74 61   fuse_args *outa
6a20: 72 67 73 29 20 7b 0a 09 73 74 61 74 69 63 20 69  rgs) {..static i
6a30: 6e 74 20 73 65 65 6e 5f 63 61 63 68 65 64 69 72  nt seen_cachedir
6a40: 20 3d 20 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20   = 0;...if (key 
6a50: 3d 3d 20 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f  == FUSE_OPT_KEY_
6a60: 4e 4f 4e 4f 50 54 20 26 26 20 73 65 65 6e 5f 63  NONOPT && seen_c
6a70: 61 63 68 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a  achedir == 0) {.
6a80: 09 09 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20  ..seen_cachedir 
6a90: 3d 20 31 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  = 1;....appfs_ca
6aa0: 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70 28  chedir = strdup(
6ab0: 61 72 67 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  arg);....return(
6ac0: 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  0);..}...return(
6ad0: 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74  1);.}../*. * Ent
6ae0: 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68  ry point into th
6af0: 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a  is program.. */.
6b00: 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67  int main(int arg
6b10: 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29 20  c, char **argv) 
6b20: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74  {..Tcl_Interp *t
6b30: 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61  est_interp;..cha
6b40: 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  r *test_interp_e
6b50: 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66 75  rror;..struct fu
6b60: 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20 46  se_args args = F
6b70: 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 61 72  USE_ARGS_INIT(ar
6b80: 67 63 2c 20 61 72 67 76 29 3b 0a 09 69 6e 74 20  gc, argv);..int 
6b90: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 2f  pthread_ret;.../
6ba0: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
6bb0: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
6bc0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
6bd0: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
6be0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
6bf0: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
6c00: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
6c10: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
6c20: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
6c30: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
6c40: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
6c50: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
6c60: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
6c70: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
6c80: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
6c90: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
6ca0: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
6cb0: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
6cc0: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
6cd0: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
6ce0: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
6cf0: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
6d00: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
6d10: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
6d20: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
6d30: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
6d40: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
6d50: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
6d60: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
6d70: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
6d80: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
6d90: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
6da0: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
6db0: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
6dc0: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
6dd0: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
6de0: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
6df0: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
6e00: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
6e10: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
6e20: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
6e30: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
6e40: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
6e50: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
6e60: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
6e70: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
6e80: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
6e90: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
6ea0: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
6eb0: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
6ec0: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
6ed0: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
6ee0: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
6ef0: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
6f00: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
6f10: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
6f20: 65 72 70 4b 65 79 2c 20 4e 55 4c 4c 29 3b 0a 09  erpKey, NULL);..
6f30: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
6f40: 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74  != 0) {...fprint
6f50: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
6f60: 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20  e to create TSD 
6f70: 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62  key for Tcl.  Ab
6f80: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
6f90: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
6fa0: 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20  /*.. * Manually 
6fb0: 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69  specify cache di
6fc0: 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74  rectory, without
6fd0: 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09   FUSE callback..
6fe0: 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f   * This option o
6ff0: 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e  nly works when n
7000: 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73  ot using FUSE, s
7010: 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e  ince we.. * do n
7020: 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69  ot process it wi
7030: 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20  th FUSEs option 
7040: 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f  processing... */
7050: 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29  ..if (argc >= 2)
7060: 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28   {...if (strcmp(
7070: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68  argv[0], "--cach
7080: 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  edir") == 0) {..
7090: 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
70a0: 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31   = strdup(argv[1
70b0: 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20  ]);.....argc -= 
70c0: 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b  2;....argv += 2;
70d0: 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ...}..}.../*.. *
70e0: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66   SQLite3 mode, f
70f0: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53  or running raw S
7100: 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63  QL against the c
7110: 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20  ache database.. 
7120: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
7130: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
7140: 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22  [0], "--sqlite3"
7150: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
7160: 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33  rn(appfs_sqlite3
7170: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
7180: 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65  ./*.. * Tcl mode
7190: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
71a0: 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d  w Tcl in the sam
71b0: 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70  e environment Ap
71c0: 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72  pFSd would.. * r
71d0: 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69  un code... */..i
71e0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
71f0: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
7200: 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b  "--tcl") == 0) {
7210: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
7220: 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  tcl(argv[1]));..
7230: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74  }.../*.. * Creat
7240: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
7250: 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69  ter just to veri
7260: 66 79 20 74 68 61 74 20 74 68 69 6e 67 73 20 61  fy that things a
7270: 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09  re in working ..
7280: 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20   * order before 
7290: 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d  we become a daem
72a0: 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69  on... */..test_i
72b0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
72c0: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26  eate_TclInterp(&
72d0: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
72e0: 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e  r);..if (test_in
72f0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
7300: 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72  ..if (test_inter
7310: 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29  p_error == NULL)
7320: 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72   {....test_inter
7330: 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f  p_error = "Unkno
7340: 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a  wn error";...}..
7350: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
7360: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
7370: 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65  tialize Tcl inte
7380: 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70 46  rpreter for AppF
7390: 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  Sd:\n");...fprin
73a0: 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c 6e  tf(stderr, "%s\n
73b0: 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  ", test_interp_e
73c0: 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  rror);....return
73d0: 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 65 6c  (1);..}..Tcl_Del
73e0: 65 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f 69  eteInterp(test_i
73f0: 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  nterp);.../*.. *
7400: 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d 65   Add FUSE argume
7410: 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c 77  nts which we alw
7420: 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f 0a  ays supply.. */.
7430: 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28  .fuse_opt_parse(
7440: 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  &args, NULL, NUL
7450: 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70  L, appfs_fuse_op
7460: 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70 74  t_cb);..fuse_opt
7470: 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c 20  _add_arg(&args, 
7480: 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69  "-odefault_permi
7490: 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70  ssions,fsname=ap
74a0: 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66  pfs,subtype=appf
74b0: 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65  sd,use_ino,kerne
74c0: 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69  l_cache,entry_ti
74d0: 6d 65 6f 75 74 3d 36 30 2c 61 74 74 72 5f 74 69  meout=60,attr_ti
74e0: 6d 65 6f 75 74 3d 33 36 30 30 2c 69 6e 74 72 2c  meout=3600,intr,
74f0: 62 69 67 5f 77 72 69 74 65 73 22 29 3b 0a 0a 09  big_writes");...
7500: 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20  if (getuid() == 
7510: 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f  0) {...fuse_opt_
7520: 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55 4c  parse(&args, NUL
7530: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
7540: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
7550: 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c 6c  rg(&args, "-oall
7560: 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a 0a  ow_other");..}..
7570: 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68  ./*.. * Enter th
7580: 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70  e FUSE main loop
7590: 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72   -- this will pr
75a0: 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65  ocess any argume
75b0: 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72  nts.. * and star
75c0: 74 20 73 65 72 76 69 63 69 6e 67 20 72 65 71 75  t servicing requ
75d0: 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  ests... */..appf
75e0: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d  s_fuse_started =
75f0: 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65   1;..return(fuse
7600: 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c  _main(args.argc,
7610: 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70   args.argv, &app
7620: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e  fs_operations, N
7630: 55 4c 4c 29 29 3b 0a 7d 0a 20 0a                 ULL));.}. .