Hex Artifact Content

Artifact bb0851401ce0cca1ae8d56d9542a21098e53a0e9:


0000: 2f 2a 0a 20 2a 20 43 6f 70 79 72 69 67 68 74 20  /*. * Copyright 
0010: 28 63 29 20 32 30 31 34 20 20 52 6f 79 20 4b 65  (c) 2014  Roy Ke
0020: 65 6e 65 0a 20 2a 0a 20 2a 20 50 65 72 6d 69 73  ene. *. * Permis
0030: 73 69 6f 6e 20 69 73 20 68 65 72 65 62 79 20 67  sion is hereby g
0040: 72 61 6e 74 65 64 2c 20 66 72 65 65 20 6f 66 20  ranted, free of 
0050: 63 68 61 72 67 65 2c 20 74 6f 20 61 6e 79 20 70  charge, to any p
0060: 65 72 73 6f 6e 20 6f 62 74 61 69 6e 69 6e 67 20  erson obtaining 
0070: 61 20 63 6f 70 79 0a 20 2a 20 6f 66 20 74 68 69  a copy. * of thi
0080: 73 20 73 6f 66 74 77 61 72 65 20 61 6e 64 20 61  s software and a
0090: 73 73 6f 63 69 61 74 65 64 20 64 6f 63 75 6d 65  ssociated docume
00a0: 6e 74 61 74 69 6f 6e 20 66 69 6c 65 73 20 28 74  ntation files (t
00b0: 68 65 20 22 53 6f 66 74 77 61 72 65 22 29 2c 20  he "Software"), 
00c0: 74 6f 20 64 65 61 6c 0a 20 2a 20 69 6e 20 74 68  to deal. * in th
00d0: 65 20 53 6f 66 74 77 61 72 65 20 77 69 74 68 6f  e Software witho
00e0: 75 74 20 72 65 73 74 72 69 63 74 69 6f 6e 2c 20  ut restriction, 
00f0: 69 6e 63 6c 75 64 69 6e 67 20 77 69 74 68 6f 75  including withou
0100: 74 20 6c 69 6d 69 74 61 74 69 6f 6e 20 74 68 65  t limitation the
0110: 20 72 69 67 68 74 73 0a 20 2a 20 74 6f 20 75 73   rights. * to us
0120: 65 2c 20 63 6f 70 79 2c 20 6d 6f 64 69 66 79 2c  e, copy, modify,
0130: 20 6d 65 72 67 65 2c 20 70 75 62 6c 69 73 68 2c   merge, publish,
0140: 20 64 69 73 74 72 69 62 75 74 65 2c 20 73 75 62   distribute, sub
0150: 6c 69 63 65 6e 73 65 2c 20 61 6e 64 2f 6f 72 20  license, and/or 
0160: 73 65 6c 6c 0a 20 2a 20 63 6f 70 69 65 73 20 6f  sell. * copies o
0170: 66 20 74 68 65 20 53 6f 66 74 77 61 72 65 2c 20  f the Software, 
0180: 61 6e 64 20 74 6f 20 70 65 72 6d 69 74 20 70 65  and to permit pe
0190: 72 73 6f 6e 73 20 74 6f 20 77 68 6f 6d 20 74 68  rsons to whom th
01a0: 65 20 53 6f 66 74 77 61 72 65 20 69 73 0a 20 2a  e Software is. *
01b0: 20 66 75 72 6e 69 73 68 65 64 20 74 6f 20 64 6f   furnished to do
01c0: 20 73 6f 2c 20 73 75 62 6a 65 63 74 20 74 6f 20   so, subject to 
01d0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f  the following co
01e0: 6e 64 69 74 69 6f 6e 73 3a 0a 20 2a 0a 20 2a 20  nditions:. *. * 
01f0: 54 68 65 20 61 62 6f 76 65 20 63 6f 70 79 72 69  The above copyri
0200: 67 68 74 20 6e 6f 74 69 63 65 20 61 6e 64 20 74  ght notice and t
0210: 68 69 73 20 70 65 72 6d 69 73 73 69 6f 6e 20 6e  his permission n
0220: 6f 74 69 63 65 20 73 68 61 6c 6c 20 62 65 20 69  otice shall be i
0230: 6e 63 6c 75 64 65 64 20 69 6e 0a 20 2a 20 61 6c  ncluded in. * al
0240: 6c 20 63 6f 70 69 65 73 20 6f 72 20 73 75 62 73  l copies or subs
0250: 74 61 6e 74 69 61 6c 20 70 6f 72 74 69 6f 6e 73  tantial portions
0260: 20 6f 66 20 74 68 65 20 53 6f 66 74 77 61 72 65   of the Software
0270: 2e 0a 20 2a 0a 20 2a 20 54 48 45 20 53 4f 46 54  .. *. * THE SOFT
0280: 57 41 52 45 20 49 53 20 50 52 4f 56 49 44 45 44  WARE IS PROVIDED
0290: 20 22 41 53 20 49 53 22 2c 20 57 49 54 48 4f 55   "AS IS", WITHOU
02a0: 54 20 57 41 52 52 41 4e 54 59 20 4f 46 20 41 4e  T WARRANTY OF AN
02b0: 59 20 4b 49 4e 44 2c 20 45 58 50 52 45 53 53 20  Y KIND, EXPRESS 
02c0: 4f 52 0a 20 2a 20 49 4d 50 4c 49 45 44 2c 20 49  OR. * IMPLIED, I
02d0: 4e 43 4c 55 44 49 4e 47 20 42 55 54 20 4e 4f 54  NCLUDING BUT NOT
02e0: 20 4c 49 4d 49 54 45 44 20 54 4f 20 54 48 45 20   LIMITED TO THE 
02f0: 57 41 52 52 41 4e 54 49 45 53 20 4f 46 20 4d 45  WARRANTIES OF ME
0300: 52 43 48 41 4e 54 41 42 49 4c 49 54 59 2c 0a 20  RCHANTABILITY,. 
0310: 2a 20 46 49 54 4e 45 53 53 20 46 4f 52 20 41 20  * FITNESS FOR A 
0320: 50 41 52 54 49 43 55 4c 41 52 20 50 55 52 50 4f  PARTICULAR PURPO
0330: 53 45 20 41 4e 44 20 4e 4f 4e 49 4e 46 52 49 4e  SE AND NONINFRIN
0340: 47 45 4d 45 4e 54 2e 20 49 4e 20 4e 4f 20 45 56  GEMENT. IN NO EV
0350: 45 4e 54 20 53 48 41 4c 4c 20 54 48 45 0a 20 2a  ENT SHALL THE. *
0360: 20 41 55 54 48 4f 52 53 20 4f 52 20 43 4f 50 59   AUTHORS OR COPY
0370: 52 49 47 48 54 20 48 4f 4c 44 45 52 53 20 42 45  RIGHT HOLDERS BE
0380: 20 4c 49 41 42 4c 45 20 46 4f 52 20 41 4e 59 20   LIABLE FOR ANY 
0390: 43 4c 41 49 4d 2c 20 44 41 4d 41 47 45 53 20 4f  CLAIM, DAMAGES O
03a0: 52 20 4f 54 48 45 52 0a 20 2a 20 4c 49 41 42 49  R OTHER. * LIABI
03b0: 4c 49 54 59 2c 20 57 48 45 54 48 45 52 20 49 4e  LITY, WHETHER IN
03c0: 20 41 4e 20 41 43 54 49 4f 4e 20 4f 46 20 43 4f   AN ACTION OF CO
03d0: 4e 54 52 41 43 54 2c 20 54 4f 52 54 20 4f 52 20  NTRACT, TORT OR 
03e0: 4f 54 48 45 52 57 49 53 45 2c 20 41 52 49 53 49  OTHERWISE, ARISI
03f0: 4e 47 20 46 52 4f 4d 2c 0a 20 2a 20 4f 55 54 20  NG FROM,. * OUT 
0400: 4f 46 20 4f 52 20 49 4e 20 43 4f 4e 4e 45 43 54  OF OR IN CONNECT
0410: 49 4f 4e 20 57 49 54 48 20 54 48 45 20 53 4f 46  ION WITH THE SOF
0420: 54 57 41 52 45 20 4f 52 20 54 48 45 20 55 53 45  TWARE OR THE USE
0430: 20 4f 52 20 4f 54 48 45 52 20 44 45 41 4c 49 4e   OR OTHER DEALIN
0440: 47 53 20 49 4e 0a 20 2a 20 54 48 45 20 53 4f 46  GS IN. * THE SOF
0450: 54 57 41 52 45 2e 0a 20 2a 2f 0a 23 64 65 66 69  TWARE.. */.#defi
0460: 6e 65 20 46 55 53 45 5f 55 53 45 5f 56 45 52 53  ne FUSE_USE_VERS
0470: 49 4f 4e 20 32 36 0a 0a 23 69 6e 63 6c 75 64 65  ION 26..#include
0480: 20 3c 73 79 73 2f 66 73 75 69 64 2e 68 3e 0a 23   <sys/fsuid.h>.#
0490: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 79 70  include <sys/typ
04a0: 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  es.h>.#include <
04b0: 70 74 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c  pthread.h>.#incl
04c0: 75 64 65 20 3c 73 69 67 6e 61 6c 2e 68 3e 0a 23  ude <signal.h>.#
04d0: 69 6e 63 6c 75 64 65 20 3c 6c 69 6d 69 74 73 2e  include <limits.
04e0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72  h>.#include <str
04f0: 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ing.h>.#include 
0500: 3c 73 74 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c  <stdarg.h>.#incl
0510: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23  ude <stdlib.h>.#
0520: 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e  include <unistd.
0530: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 65 72 72  h>.#include <err
0540: 6e 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  no.h>.#include <
0550: 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64  fcntl.h>.#includ
0560: 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63  e <stdio.h>.#inc
0570: 6c 75 64 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69  lude <fuse.h>.#i
0580: 6e 63 6c 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23  nclude <pwd.h>.#
0590: 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a  include <tcl.h>.
05a0: 0a 2f 2a 0a 20 2a 20 44 65 66 61 75 6c 74 20 63  ./*. * Default c
05b0: 61 63 68 65 20 64 69 72 65 63 74 6f 72 79 0a 20  ache directory. 
05c0: 2a 2f 0a 23 69 66 6e 64 65 66 20 41 50 50 46 53  */.#ifndef APPFS
05d0: 5f 43 41 43 48 45 44 49 52 0a 23 64 65 66 69 6e  _CACHEDIR.#defin
05e0: 65 20 41 50 50 46 53 5f 43 41 43 48 45 44 49 52  e APPFS_CACHEDIR
05f0: 20 22 2f 76 61 72 2f 63 61 63 68 65 2f 61 70 70   "/var/cache/app
0600: 66 73 22 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44  fs".#endif../* D
0610: 65 62 75 67 67 69 6e 67 20 6d 61 63 72 6f 73 20  ebugging macros 
0620: 2a 2f 0a 23 69 66 64 65 66 20 44 45 42 55 47 0a  */.#ifdef DEBUG.
0630: 69 6e 74 20 61 70 70 66 73 5f 64 65 62 75 67 5f  int appfs_debug_
0640: 66 64 20 3d 20 53 54 44 45 52 52 5f 46 49 4c 45  fd = STDERR_FILE
0650: 4e 4f 3b 0a 23 64 65 66 69 6e 65 20 41 50 50 46  NO;.#define APPF
0660: 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b 20  S_DEBUG(x...) { 
0670: 5c 0a 09 63 68 61 72 20 62 75 66 5b 38 31 39 32  \..char buf[8192
0680: 5d 3b 20 5c 0a 09 69 6e 74 20 62 75 66 6f 66 66  ]; \..int bufoff
0690: 20 3d 20 30 3b 20 5c 0a 09 69 66 20 28 61 70 70   = 0; \..if (app
06a0: 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 3d 20 2d  fs_debug_fd == -
06b0: 31 29 20 7b 20 5c 0a 09 09 61 70 70 66 73 5f 64  1) { \...appfs_d
06c0: 65 62 75 67 5f 66 64 20 3d 20 6f 70 65 6e 28 22  ebug_fd = open("
06d0: 2f 74 6d 70 2f 61 70 70 66 73 64 2e 6c 6f 67 22  /tmp/appfsd.log"
06e0: 2c 20 4f 5f 57 52 4f 4e 4c 59 20 7c 20 4f 5f 41  , O_WRONLY | O_A
06f0: 50 50 45 4e 44 20 7c 20 4f 5f 43 52 45 41 54 2c  PPEND | O_CREAT,
0700: 20 30 36 30 30 29 3b 20 5c 0a 09 7d 3b 20 5c 0a   0600); \..}; \.
0710: 09 62 75 66 6f 66 66 20 3d 20 73 6e 70 72 69 6e  .bufoff = snprin
0720: 74 66 28 62 75 66 2c 20 73 69 7a 65 6f 66 28 62  tf(buf, sizeof(b
0730: 75 66 29 2c 20 22 5b 64 65 62 75 67 5d 20 5b 74  uf), "[debug] [t
0740: 3d 25 6c 6c 78 5d 20 25 73 3a 25 69 3a 25 73 3a  =%llx] %s:%i:%s:
0750: 20 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f   ", (unsigned lo
0760: 6e 67 20 6c 6f 6e 67 29 20 70 74 68 72 65 61 64  ng long) pthread
0770: 5f 73 65 6c 66 28 29 2c 20 5f 5f 46 49 4c 45 5f  _self(), __FILE_
0780: 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66  _, __LINE__, __f
0790: 75 6e 63 5f 5f 29 3b 20 5c 0a 09 69 66 20 28 62  unc__); \..if (b
07a0: 75 66 6f 66 66 20 3c 20 73 69 7a 65 6f 66 28 62  ufoff < sizeof(b
07b0: 75 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66  uf)) { \...bufof
07c0: 66 20 2b 3d 20 73 6e 70 72 69 6e 74 66 28 62 75  f += snprintf(bu
07d0: 66 20 2b 20 62 75 66 6f 66 66 2c 20 73 69 7a 65  f + bufoff, size
07e0: 6f 66 28 62 75 66 29 20 2d 20 62 75 66 6f 66 66  of(buf) - bufoff
07f0: 2c 20 78 29 3b 20 5c 0a 09 7d 3b 20 5c 0a 09 69  , x); \..}; \..i
0800: 66 20 28 62 75 66 6f 66 66 20 3c 20 73 69 7a 65  f (bufoff < size
0810: 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a 09 09 62  of(buf)) { \...b
0820: 75 66 6f 66 66 20 2b 3d 20 73 6e 70 72 69 6e 74  ufoff += snprint
0830: 66 28 62 75 66 20 2b 20 62 75 66 6f 66 66 2c 20  f(buf + bufoff, 
0840: 73 69 7a 65 6f 66 28 62 75 66 29 20 2d 20 62 75  sizeof(buf) - bu
0850: 66 6f 66 66 2c 20 22 5c 6e 22 29 3b 5c 0a 09 7d  foff, "\n");\..}
0860: 20 5c 0a 09 69 66 20 28 62 75 66 6f 66 66 20 3e   \..if (bufoff >
0870: 20 73 69 7a 65 6f 66 28 62 75 66 29 29 20 7b 20   sizeof(buf)) { 
0880: 5c 0a 09 09 62 75 66 6f 66 66 20 3d 20 73 69 7a  \...bufoff = siz
0890: 65 6f 66 28 62 75 66 29 3b 20 5c 0a 09 7d 3b 20  eof(buf); \..}; 
08a0: 5c 0a 09 77 72 69 74 65 28 61 70 70 66 73 5f 64  \..write(appfs_d
08b0: 65 62 75 67 5f 66 64 2c 20 62 75 66 2c 20 62 75  ebug_fd, buf, bu
08c0: 66 6f 66 66 29 3b 20 5c 0a 7d 0a 23 65 6c 73 65  foff); \.}.#else
08d0: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
08e0: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a  EBUG(x...) /**/.
08f0: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48  #endif../*. * SH
0900: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69  A1 Tcl Package i
0910: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d  nitializer, from
0920: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20   sha1.o. */.int 
0930: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  Sha1_Init(Tcl_In
0940: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a  terp *interp);..
0950: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65  /*. * Thread Spe
0960: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29  cific Data (TSD)
0970: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72   for Tcl Interpr
0980: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72  eter for the cur
0990: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a  rent thread. */.
09a0: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b  static pthread_k
09b0: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a  ey_t interpKey;.
09c0: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61  ./*. * Global va
09d0: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20  riables, needed 
09e0: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20  for all threads 
09f0: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c  but only initial
0a00: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a  ized before any.
0a10: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20   * FUSE threads 
0a20: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a  are created. */.
0a30: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
0a40: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65  s_cachedir;.time
0a50: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d  _t appfs_boottim
0a60: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73  e;.int appfs_fus
0a70: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 69  e_started = 0;.i
0a80: 6e 74 20 61 70 70 66 73 5f 74 68 72 65 61 64 65  nt appfs_threade
0a90: 64 5f 74 63 6c 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c  d_tcl;../*. * Gl
0aa0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
0ab0: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67  or AppFS caching
0ac0: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0ad0: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f  ex_t appfs_path_
0ae0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
0af0: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0b00: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e  _INITIALIZER;.in
0b10: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
0b20: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38  o_cache_size = 8
0b30: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66  209;.struct appf
0b40: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66  s_pathinfo *appf
0b50: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
0b60: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 23 69 66 6e 64  e = NULL;..#ifnd
0b70: 65 66 20 54 43 4c 5f 54 48 52 45 41 44 53 0a 2f  ef TCL_THREADS./
0b80: 2a 0a 20 2a 20 48 61 6e 64 6c 65 20 75 6e 74 68  *. * Handle unth
0b90: 72 65 61 64 65 64 20 54 63 6c 0a 20 2a 2f 0a 70  readed Tcl. */.p
0ba0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61  thread_mutex_t a
0bb0: 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f  ppfs_tcl_big_glo
0bc0: 62 61 6c 5f 6c 6f 63 6b 20 3d 20 50 54 48 52 45  bal_lock = PTHRE
0bd0: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c  AD_MUTEX_INITIAL
0be0: 49 5a 45 52 3b 0a 23 64 65 66 69 6e 65 20 61 70  IZER;.#define ap
0bf0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f  pfs_call_libtcl_
0c00: 65 6e 74 65 72 20 70 74 68 72 65 61 64 5f 6d 75  enter pthread_mu
0c10: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
0c20: 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c  tcl_big_global_l
0c30: 6f 63 6b 29 3b 0a 23 64 65 66 69 6e 65 20 61 70  ock);.#define ap
0c40: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f  pfs_call_libtcl_
0c50: 65 78 69 74 20 70 74 68 72 65 61 64 5f 6d 75 74  exit pthread_mut
0c60: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
0c70: 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f  _tcl_big_global_
0c80: 6c 6f 63 6b 29 3b 0a 23 65 6c 73 65 0a 23 64 65  lock);.#else.#de
0c90: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f  fine appfs_call_
0ca0: 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 2f 2a 2a  libtcl_enter /**
0cb0: 2f 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f  /.#define appfs_
0cc0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74  call_libtcl_exit
0cd0: 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 23 64 65   /**/.#endif.#de
0ce0: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f  fine appfs_call_
0cf0: 6c 69 62 74 63 6c 28 78 2e 2e 2e 29 20 61 70 70  libtcl(x...) app
0d00: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65  fs_call_libtcl_e
0d10: 6e 74 65 72 20 78 20 61 70 70 66 73 5f 63 61 6c  nter x appfs_cal
0d20: 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 0a 2f  l_libtcl_exit../
0d30: 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69  *. * Global vari
0d40: 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53 20  ables for AppFS 
0d50: 54 63 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20  Tcl Interpreter 
0d60: 72 65 73 74 61 72 74 69 6e 67 0a 20 2a 2f 0a 69  restarting. */.i
0d70: 6e 74 20 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  nt interp_reset_
0d80: 6b 65 79 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20  key = 0;../*. * 
0d90: 41 70 70 46 53 20 50 61 74 68 20 54 79 70 65 3a  AppFS Path Type:
0da0: 20 20 44 65 73 63 72 69 62 65 73 20 74 68 65 20    Describes the 
0db0: 74 79 70 65 20 6f 66 20 70 61 74 68 20 61 20 67  type of path a g
0dc0: 69 76 65 6e 20 66 69 6c 65 20 69 73 0a 20 2a 2f  iven file is. */
0dd0: 0a 74 79 70 65 64 65 66 20 65 6e 75 6d 20 7b 0a  .typedef enum {.
0de0: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f  .APPFS_PATHTYPE_
0df0: 49 4e 56 41 4c 49 44 2c 0a 09 41 50 50 46 53 5f  INVALID,..APPFS_
0e00: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f  PATHTYPE_DOES_NO
0e10: 54 5f 45 58 49 53 54 2c 0a 09 41 50 50 46 53 5f  T_EXIST,..APPFS_
0e20: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 2c 0a 09  PATHTYPE_FILE,..
0e30: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
0e40: 49 52 45 43 54 4f 52 59 2c 0a 09 41 50 50 46 53  IRECTORY,..APPFS
0e50: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e  _PATHTYPE_SYMLIN
0e60: 4b 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  K,..APPFS_PATHTY
0e70: 50 45 5f 53 4f 43 4b 45 54 2c 0a 09 41 50 50 46  PE_SOCKET,..APPF
0e80: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 2c  S_PATHTYPE_FIFO,
0e90: 0a 7d 20 61 70 70 66 73 5f 70 61 74 68 74 79 70  .} appfs_pathtyp
0ea0: 65 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  e_t;../*. * AppF
0eb0: 53 20 50 61 74 68 20 49 6e 66 6f 72 6d 61 74 69  S Path Informati
0ec0: 6f 6e 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 43  on:. *         C
0ed0: 6f 6d 70 6c 65 74 65 6c 79 20 64 65 73 63 72 69  ompletely descri
0ee0: 62 65 73 20 61 20 73 70 65 63 69 66 69 63 20 70  bes a specific p
0ef0: 61 74 68 2c 20 68 6f 77 20 69 74 20 73 68 6f 75  ath, how it shou
0f00: 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64 20 74  ld be returned t
0f10: 6f 0a 20 2a 20 20 20 20 20 20 20 20 20 74 6f 20  o. *         to 
0f20: 74 68 65 20 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73  the kernel. */.s
0f30: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
0f40: 69 6e 66 6f 20 7b 0a 09 61 70 70 66 73 5f 70 61  info {..appfs_pa
0f50: 74 68 74 79 70 65 5f 74 20 74 79 70 65 3b 0a 09  thtype_t type;..
0f60: 74 69 6d 65 5f 74 20 74 69 6d 65 3b 0a 09 63 68  time_t time;..ch
0f70: 61 72 20 68 6f 73 74 6e 61 6d 65 5b 32 35 36 5d  ar hostname[256]
0f80: 3b 0a 09 69 6e 74 20 70 61 63 6b 61 67 65 64 3b  ;..int packaged;
0f90: 0a 09 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20  ..unsigned long 
0fa0: 6c 6f 6e 67 20 69 6e 6f 64 65 3b 0a 09 75 6e 69  long inode;..uni
0fb0: 6f 6e 20 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a  on {...struct {.
0fc0: 09 09 09 69 6e 74 20 63 68 69 6c 64 63 6f 75 6e  ...int childcoun
0fd0: 74 3b 0a 09 09 7d 20 64 69 72 3b 0a 09 09 73 74  t;...} dir;...st
0fe0: 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 65 78  ruct {....int ex
0ff0: 65 63 75 74 61 62 6c 65 3b 0a 09 09 09 6f 66 66  ecutable;....off
1000: 5f 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c  _t size;...} fil
1010: 65 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09  e;...struct {...
1020: 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09  .off_t size;....
1030: 63 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d  char source[256]
1040: 3b 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09  ;...} symlink;..
1050: 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a  } typeinfo;.../*
1060: 20 41 74 74 72 69 62 75 74 65 73 20 75 73 65 64   Attributes used
1070: 20 6f 6e 6c 79 20 66 6f 72 20 63 61 63 68 69 6e   only for cachin
1080: 67 20 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68  g entries */..ch
1090: 61 72 20 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b  ar *_cache_path;
10a0: 0a 09 75 69 64 5f 74 20 5f 63 61 63 68 65 5f 75  ..uid_t _cache_u
10b0: 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72  id;.};../*. * Cr
10c0: 65 61 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69  eate a new Tcl i
10d0: 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64 20 63  nterpreter and c
10e0: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
10f0: 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74  lize it. */.stat
1100: 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61  ic Tcl_Interp *a
1110: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
1120: 6e 74 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72  nterp(char **err
1130: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63  or_string) {..Tc
1140: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
1150: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
1160: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  .const char *tcl
1170: 5f 73 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41  _setvar_ret;...A
1180: 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61  PPFS_DEBUG("Crea
1190: 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74  ting new Tcl int
11a0: 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44  erpreter for TID
11b0: 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73   = 0x%llx", (uns
11c0: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
11d0: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29   pthread_self())
11e0: 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
11f0: 69 62 74 63 6c 28 0a 09 09 69 6e 74 65 72 70 20  ibtcl(...interp 
1200: 3d 20 54 63 6c 5f 43 72 65 61 74 65 49 6e 74 65  = Tcl_CreateInte
1210: 72 70 28 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e  rp();..)..if (in
1220: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
1230: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1240: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65  , "Unable to cre
1250: 61 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65  ate Tcl Interpre
1260: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ter.  Aborting.\
1270: 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  n");....if (erro
1280: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
1290: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
12a0: 74 72 64 75 70 28 22 55 6e 61 62 6c 65 20 74 6f  trdup("Unable to
12b0: 20 63 72 65 61 74 65 20 54 63 6c 20 69 6e 74 65   create Tcl inte
12c0: 72 70 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a  rpreter.");...}.
12d0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
12e0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
12f0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73  _libtcl(Tcl_Pres
1300: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  erve(interp);)..
1310: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1320: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20  cl(...tcl_ret = 
1330: 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29  Tcl_Init(interp)
1340: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
1350: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
1360: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1370: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74   "Unable to init
1380: 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f  ialize Tcl.  Abo
1390: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70  rting.\n");...ap
13a0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
13b0: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
13c0: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
13d0: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
13e0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
13f0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
1400: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
1410: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
1420: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
1430: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1440: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1450: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1460: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
1470: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1480: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
1490: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
14a0: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
14b0: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
14c0: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
14d0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
14e0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
14f0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
1500: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
1510: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1520: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
1530: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63  val(interp, "pac
1540: 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 73 68  kage ifneeded sh
1550: 61 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61  a1 1.0 [list loa
1560: 64 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09 29  d {} sha1]");..)
1570: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
1580: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
1590: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
15a0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
15b0: 7a 65 20 54 63 6c 20 53 48 41 31 2e 20 20 41 62  ze Tcl SHA1.  Ab
15c0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
15d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
15e0: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
15f0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
1600: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
1610: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1620: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
1630: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
1640: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
1650: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
1660: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
1670: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
1680: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1690: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
16a0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
16b0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
16c0: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
16d0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
16e0: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
16f0: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1700: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1710: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1720: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
1730: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
1740: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1750: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
1760: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61  Eval(interp, "pa
1770: 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 61  ckage ifneeded a
1780: 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20  ppfsd 1.0 [list 
1790: 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22  load {} appfsd]"
17a0: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
17b0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
17c0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
17d0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
17e0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46  tialize Tcl AppF
17f0: 53 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72  S Package.  Abor
1800: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70  ting.\n");...app
1810: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1820: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1830: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
1840: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
1850: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1860: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66  erp));...)....if
1870: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1880: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  {....appfs_call_
1890: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72  libtcl(.....*err
18a0: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
18b0: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
18c0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
18d0: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70  ....)...}....app
18e0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
18f0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
1900: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45  p);)....APPFS_DE
1910: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
1920: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
1930: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
1940: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
1950: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
1960: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e  p);)....return(N
1970: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
1980: 2a 20 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c 22  * Load "pki.tcl"
1990: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 77 61 79   in the same way
19a0: 20 61 73 20 61 70 70 66 73 64 2e 74 63 6c 20 28   as appfsd.tcl (
19b0: 73 65 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f 0a  see below).. */.
19c0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
19d0: 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72  cl_enter...tcl_r
19e0: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
19f0: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
1a00: 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 09  e "pki.tcl.h"...
1a10: 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c  "");..appfs_call
1a20: 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69 66  _libtcl_exit..if
1a30: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
1a40: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
1a50: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
1a60: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
1a70: 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e  cl PKI.  Abortin
1a80: 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f  g.\n");...appfs_
1a90: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
1aa0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
1ab0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
1ac0: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  s\n", Tcl_GetStr
1ad0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
1ae0: 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65  ));...)....if (e
1af0: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
1b00: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1b10: 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f  tcl(.....*error_
1b20: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
1b30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
1b40: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
1b50: 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f  .)...}....appfs_
1b60: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1b70: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
1b80: 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  )....APPFS_DEBUG
1b90: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63  ("Terminating Tc
1ba0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
1bb0: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
1bc0: 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74  libtcl(Tcl_Delet
1bd0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
1be0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  )....return(NULL
1bf0: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c  );..}.../*.. * L
1c00: 6f 61 64 20 74 68 65 20 22 61 70 70 66 73 64 2e  oad the "appfsd.
1c10: 74 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69  tcl" script, whi
1c20: 63 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22  ch is "compiled"
1c30: 20 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72   into a C header
1c40: 0a 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20  .. * so that it 
1c50: 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f  does not need to
1c60: 20 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69   exist on the fi
1c70: 6c 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e  lesystem and can
1c80: 20 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79   be.. * directly
1c90: 20 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f   evaluated... */
1ca0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1cb0: 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f  tcl_enter...tcl_
1cc0: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1cd0: 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75  nterp, "".#inclu
1ce0: 64 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68  de "appfsd.tcl.h
1cf0: 22 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f  "..."");..appfs_
1d00: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74  call_libtcl_exit
1d10: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
1d20: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
1d30: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
1d40: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
1d50: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72  ze Tcl AppFS scr
1d60: 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ipt.  Aborting.\
1d70: 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  n");...appfs_cal
1d80: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72  l_libtcl(....fpr
1d90: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
1da0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
1db0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1dc0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1dd0: 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f  ...)....if (erro
1de0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61  r_string) {....a
1df0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1e00: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72  (.....*error_str
1e10: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
1e20: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1e30: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a  (interp));....).
1e40: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..}....appfs_cal
1e50: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
1e60: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
1e70: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
1e80: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69  erminating Tcl i
1e90: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a  nterpreter.");..
1ea0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1eb0: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e  tcl(Tcl_DeleteIn
1ec0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a  terp(interp);)..
1ed0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1ee0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20  .}.../*.. * Set 
1ef0: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  global variables
1f00: 20 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09   from C to Tcl..
1f10: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f   */..appfs_call_
1f20: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73 65  libtcl(...tcl_se
1f30: 74 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f 53  tvar_ret = Tcl_S
1f40: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a  etVar(interp, ":
1f50: 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72  :appfs::cachedir
1f60: 22 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64 69  ", appfs_cachedi
1f70: 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e  r, TCL_GLOBAL_ON
1f80: 4c 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c  LY);..)..if (tcl
1f90: 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20 4e  _setvar_ret == N
1fa0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
1fb0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
1fc0: 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69   to set cache di
1fd0: 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73  rectory.  This s
1fe0: 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c  hould never fail
1ff0: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72  .\n");....if (er
2000: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
2010: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2020: 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73  cl(.....*error_s
2030: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
2040: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
2050: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09  lt(interp));....
2060: 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63  )...}....appfs_c
2070: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
2080: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
2090: 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
20a0: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c  "Terminating Tcl
20b0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
20c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
20d0: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65  ibtcl(Tcl_Delete
20e0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29  Interp(interp);)
20f0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
2100: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e  ;..}.../*.. * In
2110: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70  itialize the "ap
2120: 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f  pfsd.tcl" enviro
2130: 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73  nment, which mus
2140: 74 20 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a  t be done after.
2150: 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  . * global varia
2160: 62 6c 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20  bles are set... 
2170: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  */..appfs_call_l
2180: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
2190: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
21a0: 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e  rp, "::appfs::in
21b0: 69 74 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  it");..)..if (tc
21c0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
21d0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
21e0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
21f0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
2200: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61  ppFS script (::a
2210: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62  ppfs::init).  Ab
2220: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
2230: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2240: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
2250: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
2260: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
2270: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
2280: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
2290: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
22a0: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
22b0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
22c0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
22d0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
22e0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
22f0: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
2300: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2310: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
2320: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
2330: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
2340: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
2350: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
2360: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
2370: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
2380: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
2390: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  (NULL);..}.../*.
23a0: 09 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63  . * Hide some Tc
23b0: 6c 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20  l commands that 
23c0: 77 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74  we do not care t
23d0: 6f 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20  o use and which 
23e0: 6d 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77  may.. * slow dow
23f0: 6e 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61  n run-time opera
2400: 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  tions... */..app
2410: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
2420: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e  ..Tcl_HideComman
2430: 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f  d(interp, "auto_
2440: 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75  load_index", "au
2450: 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b  to_load_index");
2460: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ...Tcl_HideComma
2470: 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e  nd(interp, "unkn
2480: 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29  own", "unknown")
2490: 3b 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d  ;...Tcl_HideComm
24a0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69  and(interp, "exi
24b0: 74 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a  t", "exit");..).
24c0: 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65  ../*.. * Release
24d0: 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76   the hold we hav
24e0: 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72  e on the interpr
24f0: 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20  eter so that it 
2500: 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74  may be.. * delet
2510: 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a  ed if needed.. *
2520: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  /..appfs_call_li
2530: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
2540: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a  (interp);).../*.
2550: 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63  . * Return the c
2560: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
2570: 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65  lized interprete
2580: 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69  r.. */..return(i
2590: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  nterp);.}../*. *
25a0: 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65   Return the thre
25b0: 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20  ad-specific Tcl 
25c0: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65  interpreter, cre
25d0: 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64  ating it if need
25e0: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63  ed. */.static Tc
25f0: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f  l_Interp *appfs_
2600: 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20  TclInterp(void) 
2610: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
2620: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72  nterp;..int pthr
2630: 65 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63  ead_ret;..static
2640: 20 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68   __thread int th
2650: 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65  read_interp_rese
2660: 74 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20  t_key = 0;..int 
2670: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
2680: 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61  set_key;...globa
2690: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
26a0: 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63  ey = __sync_fetc
26b0: 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72  h_and_add(&inter
26c0: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b  p_reset_key, 0);
26d0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72  ...interp = pthr
26e0: 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28  ead_getspecific(
26f0: 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20  interpKey);..if 
2700: 28 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20  (interp != NULL 
2710: 26 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70  && thread_interp
2720: 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c  _reset_key != gl
2730: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
2740: 74 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53  t_key) {...APPFS
2750: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
2760: 69 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65  ing old interpre
2770: 74 65 72 20 61 6e 64 20 72 65 73 74 61 72 74 69  ter and restarti
2780: 6e 67 20 64 75 65 20 74 6f 20 72 65 73 65 74 20  ng due to reset 
2790: 72 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61  request.");....a
27a0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
27b0: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
27c0: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69  p(interp);)....i
27d0: 6e 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09  nterp = NULL;...
27e0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
27f0: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66  thread_setspecif
2800: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e  ic(interpKey, in
2810: 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  terp);..}...if (
2820: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
2830: 73 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b  set_key == -1) {
2840: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2850: 52 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20 73  Returning NULL s
2860: 69 6e 63 65 20 77 65 20 61 72 65 20 69 6e 20 74  ince we are in t
2870: 68 65 20 70 72 6f 63 65 73 73 20 6f 66 20 74 65  he process of te
2880: 72 6d 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74 68  rminating all th
2890: 72 65 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65 74  reads.");....ret
28a0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
28b0: 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65  thread_interp_re
28c0: 73 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61 6c  set_key = global
28d0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
28e0: 79 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20  y;...if (interp 
28f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74  == NULL) {...int
2900: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
2910: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
2920: 4c 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72  L);....if (inter
2930: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  p == NULL) {....
2940: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65  APPFS_DEBUG("Cre
2950: 61 74 65 20 69 6e 74 65 72 70 20 66 61 69 6c 65  ate interp faile
2960: 64 2c 20 72 65 74 75 72 6e 69 6e 67 69 6e 20 66  d, returningin f
2970: 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09 72  ailure.");.....r
2980: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d  eturn(NULL);...}
2990: 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74 20  ....pthread_ret 
29a0: 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73 70 65  = pthread_setspe
29b0: 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c  cific(interpKey,
29c0: 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28   interp);...if (
29d0: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
29e0: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
29f0: 55 47 28 22 70 74 68 72 65 61 64 5f 73 65 74 73  UG("pthread_sets
2a00: 70 65 63 69 66 69 63 28 29 20 66 61 69 6c 65 64  pecific() failed
2a10: 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e 67 20 54  .  Terminating T
2a20: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
2a30: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  );.....appfs_cal
2a40: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c  l_libtcl(Tcl_Del
2a50: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
2a60: 29 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e  );).....return(N
2a70: 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72  ULL);...}..}...r
2a80: 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d  eturn(interp);.}
2a90: 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65  ../*. * Evaluate
2aa0: 20 61 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f   a Tcl script co
2ab0: 6e 73 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e  nstructed by con
2ac0: 63 61 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e  catenating a bun
2ad0: 63 68 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a  ch of C strings.
2ae0: 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f   * together.. */
2af0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
2b00: 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49  s_Tcl_Eval(Tcl_I
2b10: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
2b20: 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63  nt objc, const c
2b30: 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b  har *cmd, ...) {
2b40: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76  ..Tcl_Obj **objv
2b50: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61  ;..const char *a
2b60: 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67  rg;..va_list arg
2b70: 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  p;..int retval;.
2b80: 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e  .int i;...if (in
2b90: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
2ba0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 49  ..APPFS_DEBUG("I
2bb0: 6e 76 61 6c 69 64 20 69 6e 74 65 72 70 72 65 74  nvalid interpret
2bc0: 65 72 20 70 61 73 73 65 64 20 69 6e 2c 20 72 65  er passed in, re
2bd0: 74 75 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75  turning in failu
2be0: 72 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  re.");....return
2bf0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a  (TCL_ERROR);..}.
2c00: 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a  ..objv = (void *
2c10: 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  ) ckalloc(sizeof
2c20: 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b  (*objv) * objc);
2c30: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2c40: 62 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d 20  btcl(...objv[0] 
2c50: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
2c60: 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 09  bj(cmd, -1);....
2c70: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
2c80: 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76 61  (objv[0]);....va
2c90: 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64  _start(argp, cmd
2ca0: 29 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20 31 3b  );...for (i = 1;
2cb0: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20   i < objc; i++) 
2cc0: 7b 0a 09 09 09 61 72 67 20 3d 20 76 61 5f 61 72  {....arg = va_ar
2cd0: 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68  g(argp, const ch
2ce0: 61 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76 5b  ar *);.....objv[
2cf0: 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  i] = Tcl_NewStri
2d00: 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a  ngObj(arg, -1);.
2d10: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
2d20: 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09  ount(objv[i]);..
2d30: 09 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72 67 70  .}...va_end(argp
2d40: 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61  );..)...appfs_ca
2d50: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 74  ll_libtcl(...ret
2d60: 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62  val = Tcl_EvalOb
2d70: 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c  jv(interp, objc,
2d80: 20 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a 09   objv, 0);..)...
2d90: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2da0: 6c 28 0a 09 09 66 6f 72 20 28 69 20 3d 20 30 3b  l(...for (i = 0;
2db0: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20   i < objc; i++) 
2dc0: 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66  {....Tcl_DecrRef
2dd0: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a  Count(objv[i]);.
2de0: 09 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65 28  ..}..)...ckfree(
2df0: 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a  (void *) objv);.
2e00: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
2e10: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70 66  TCL_OK) {...appf
2e20: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2e30: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
2e40: 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65  cl command faile
2e50: 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63  d, ::errorInfo c
2e60: 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20  ontains: %s\n", 
2e70: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
2e80: 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22  p, "::errorInfo"
2e90: 2c 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09  , 0));...)..}...
2ea0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
2eb0: 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74  }../*. * Request
2ec0: 20 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72   all Tcl interpr
2ed0: 65 74 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a  eters restart. *
2ee0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
2ef0: 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74  pfs_tcl_ResetInt
2f00: 65 72 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50  erps(void) {..AP
2f10: 50 46 53 5f 44 45 42 55 47 28 22 52 65 71 75 65  PFS_DEBUG("Reque
2f20: 73 74 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61  sting reset of a
2f30: 6c 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e  ll interpreters.
2f40: 22 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64  ");...__sync_add
2f50: 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65  _and_fetch(&inte
2f60: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29  rp_reset_key, 1)
2f70: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  ;...return;.}../
2f80: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74  *. * Determine t
2f90: 68 65 20 55 49 44 20 66 6f 72 20 74 68 65 20 75  he UID for the u
2fa0: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63  ser making the c
2fb0: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65  urrent FUSE file
2fc0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a  system request..
2fd0: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20   * This will be 
2fe0: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74  used to lookup t
2ff0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3000: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63  irectory so we c
3010: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a  an search for. *
3020: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65   locally modifie
3030: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61  d files.. */.sta
3040: 74 69 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f  tic uid_t appfs_
3050: 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20  get_fsuid(void) 
3060: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63  {..struct fuse_c
3070: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69  ontext *ctx;...i
3080: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73  f (!appfs_fuse_s
3090: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75  tarted) {...retu
30a0: 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d  rn(getuid());..}
30b0: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65  ...ctx = fuse_ge
30c0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66  t_context();..if
30d0: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (ctx == NULL) {
30e0: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20  .../* Unable to 
30f0: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20  lookup user for 
3100: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09  some reason */..
3110: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e  ./* Return an un
3120: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20  privileged user 
3130: 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45  ID */...APPFS_DE
3140: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
3150: 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73  ookup user for s
3160: 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75  ome reason, retu
3170: 72 6e 69 6e 6e 67 20 75 73 65 72 20 49 44 20 6f  rninng user ID o
3180: 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  f 1");....return
3190: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (1);..}...return
31a0: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f  (ctx->uid);.}../
31b0: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74  *. * Determine t
31c0: 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75  he GID for the u
31d0: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63  ser making the c
31e0: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65  urrent FUSE file
31f0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a  system request..
3200: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20   * This will be 
3210: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74  used to lookup t
3220: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3230: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63  irectory so we c
3240: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a  an search for. *
3250: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65   locally modifie
3260: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61  d files.. */.sta
3270: 74 69 63 20 67 69 64 5f 74 20 61 70 70 66 73 5f  tic gid_t appfs_
3280: 67 65 74 5f 66 73 67 69 64 28 76 6f 69 64 29 20  get_fsgid(void) 
3290: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63  {..struct fuse_c
32a0: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69  ontext *ctx;...i
32b0: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73  f (!appfs_fuse_s
32c0: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75  tarted) {...retu
32d0: 72 6e 28 67 65 74 67 69 64 28 29 29 3b 0a 09 7d  rn(getgid());..}
32e0: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65  ...ctx = fuse_ge
32f0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66  t_context();..if
3300: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (ctx == NULL) {
3310: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20  .../* Unable to 
3320: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20  lookup user for 
3330: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09  some reason */..
3340: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e  ./* Return an un
3350: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20  privileged user 
3360: 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45  ID */...APPFS_DE
3370: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
3380: 6f 6f 6b 75 70 20 67 72 6f 75 70 20 66 6f 72 20  ookup group for 
3390: 73 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74  some reason, ret
33a0: 75 72 6e 69 6e 6e 67 20 67 72 6f 75 70 20 49 44  urninng group ID
33b0: 20 6f 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75   of 1");....retu
33c0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  rn(1);..}...retu
33d0: 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a  rn(ctx->gid);.}.
33e0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
33f0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
3400: 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29 20  _fs_enter(void) 
3410: 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70 66  {..setfsuid(appf
3420: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
3430: 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73 5f  .setfsgid(appfs_
3440: 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d 0a  get_fsgid());.}.
3450: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
3460: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
3470: 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29 20  _fs_leave(void) 
3480: 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b 0a  {..setfsuid(0);.
3490: 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d 0a  .setfsgid(0);.}.
34a0: 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74  ./*. * Look up t
34b0: 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  he home director
34c0: 79 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49  y for a given UI
34d0: 44 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74 75  D. *        Retu
34e0: 72 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20 63  rns a C string c
34f0: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73  ontaining the us
3500: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74  er's home direct
3510: 6f 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20  ory or NULL if. 
3520: 2a 20 20 20 20 20 20 20 20 74 68 65 20 75 73 65  *        the use
3530: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
3540: 72 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  ry does not exis
3550: 74 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72  t or is not corr
3560: 65 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20  ectly. *        
3570: 63 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73  configured. */.s
3580: 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66  tatic char *appf
3590: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69  s_get_homedir(ui
35a0: 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74  d_t fsuid) {..st
35b0: 72 75 63 74 20 70 61 73 73 77 64 20 65 6e 74 72  ruct passwd entr
35c0: 79 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72  y, *result;..str
35d0: 75 63 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a  uct stat stbuf;.
35e0: 09 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c  .char buf[1024],
35f0: 20 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67   *retval;..int g
3600: 70 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74  pu_ret, stat_ret
3610: 3b 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65  ;...gpu_ret = ge
3620: 74 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20  tpwuid_r(fsuid, 
3630: 26 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a  &entry, buf, siz
3640: 65 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c  eof(buf), &resul
3650: 74 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74  t);..if (gpu_ret
3660: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
3670: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64  _DEBUG("getpwuid
3680: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65  _r(%llu, ...) re
3690: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
36a0: 65 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  e", (unsigned lo
36b0: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
36c0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
36d0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c  ;..}...if (resul
36e0: 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  t == NULL) {...A
36f0: 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74 70  PPFS_DEBUG("getp
3700: 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e  wuid_r(%llu, ...
3710: 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20  ) returned NULL 
3720: 72 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e  result", (unsign
3730: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
3740: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  uid);....return(
3750: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
3760: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d  result->pw_dir =
3770: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
3780: 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69  S_DEBUG("getpwui
3790: 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72  d_r(%llu, ...) r
37a0: 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d  eturned NULL hom
37b0: 65 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75  e directory", (u
37c0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
37d0: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65  g) fsuid);....re
37e0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
37f0: 09 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74  .stat_ret = stat
3800: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c  (result->pw_dir,
3810: 20 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73   &stbuf);..if (s
3820: 74 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  tat_ret != 0) {.
3830: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 73  ..APPFS_DEBUG("s
3840: 74 61 74 28 25 73 29 20 72 65 74 75 72 6e 65 64  tat(%s) returned
3850: 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65   in failure", re
3860: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a  sult->pw_dir);..
3870: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
3880: 09 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73  .}...if (stbuf.s
3890: 74 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29 20  t_uid != fsuid) 
38a0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
38b0: 22 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f  "UID mis-match o
38c0: 6e 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f  n user %llu's ho
38d0: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 28 25 73  me directory (%s
38e0: 29 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62  ).  It's owned b
38f0: 79 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20  y %llu.",...    
3900: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
3910: 6f 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20  ong) fsuid,...  
3920: 20 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72    result->pw_dir
3930: 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65  ,...    (unsigne
3940: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62  d long long) stb
3950: 75 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a  uf.st_uid...);..
3960: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
3970: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74  .}...retval = st
3980: 72 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f  rdup(result->pw_
3990: 64 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72  dir);...return(r
39a0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  etval);.}../*. *
39b0: 20 47 65 6e 65 72 61 74 65 20 61 6e 20 69 6e 6f   Generate an ino
39c0: 64 65 20 66 6f 72 20 61 20 67 69 76 65 6e 20 70  de for a given p
39d0: 61 74 68 2e 20 20 54 68 65 20 69 6e 6f 64 65 20  ath.  The inode 
39e0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6d 70 75 74  should be comput
39f0: 65 64 20 69 6e 20 73 75 63 68 0a 20 2a 20 61 20  ed in such. * a 
3a00: 77 61 79 20 74 68 61 74 20 69 74 20 69 73 20 75  way that it is u
3a10: 6e 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20 64 75  nlikely to be du
3a20: 70 6c 69 63 61 74 65 64 20 61 6e 64 20 72 65 6d  plicated and rem
3a30: 61 69 6e 73 20 74 68 65 20 73 61 6d 65 20 66 6f  ains the same fo
3a40: 72 20 61 20 67 69 76 65 6e 0a 20 2a 20 66 69 6c  r a given. * fil
3a50: 65 0a 20 2a 0a 20 2a 20 43 75 72 72 65 6e 74 20  e. *. * Current 
3a60: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 69  implementation i
3a70: 73 20 61 6e 20 46 4e 56 2d 31 61 20 33 32 2d 62  s an FNV-1a 32-b
3a80: 69 74 0a 20 2a 2f 0a 23 69 66 20 55 49 4e 54 5f  it. */.#if UINT_
3a90: 4d 41 58 20 3c 20 34 32 39 34 39 36 37 32 39 35  MAX < 4294967295
3aa0: 0a 23 65 72 72 6f 72 20 49 6e 74 65 67 65 72 20  .#error Integer 
3ab0: 73 69 7a 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c  size is too smal
3ac0: 6c 20 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63  l .#endif.static
3ad0: 20 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c   unsigned long l
3ae0: 6f 6e 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61  ong appfs_get_pa
3af0: 74 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63  th_inode(const c
3b00: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 75 6e  har *path) {..un
3b10: 73 69 67 6e 65 64 20 69 6e 74 20 72 65 74 76 61  signed int retva
3b20: 6c 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67 6e  l;..const unsign
3b30: 65 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65  ed char *p;...re
3b40: 74 76 61 6c 20 3d 20 32 31 36 36 31 33 36 32 36  tval = 216613626
3b50: 31 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d  1; /* FNV-1a 32-
3b60: 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73 69 73  bit offset_basis
3b70: 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20 28   */...for (p = (
3b80: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
3b90: 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29 20   path; *p; p++) 
3ba0: 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20 28 69  {...retval ^= (i
3bb0: 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09 09  nt) *p;.#if 0...
3bc0: 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37 37 36  retval *= 167776
3bd0: 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32  19; /* FNV-1a 32
3be0: 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23 65  -bit prime */.#e
3bf0: 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70 74  lse.../* GCC Opt
3c00: 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65 6d 65  imized replaceme
3c10: 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20 2b  nt */...retval +
3c20: 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31 29 20  = (retval << 1) 
3c30: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34 29 20  + (retval << 4) 
3c40: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37 29 20  + (retval << 7) 
3c50: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38 29 20  + (retval << 8) 
3c60: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32 34 29  + (retval << 24)
3c70: 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 72 65  ;.#endif..}...re
3c80: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
3c90: 0a 2f 2a 0a 20 2a 20 43 61 63 68 65 20 47 65 74  ./*. * Cache Get
3ca0: 20 50 61 74 68 20 49 6e 66 6f 20 6c 6f 6f 6b 75   Path Info looku
3cb0: 70 73 20 66 6f 72 20 73 70 65 65 64 0a 20 2a 2f  ps for speed. */
3cc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
3cd0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
3ce0: 63 61 63 68 65 5f 67 65 74 28 63 6f 6e 73 74 20  cache_get(const 
3cf0: 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f  char *path, uid_
3d00: 74 20 75 69 64 2c 20 73 74 72 75 63 74 20 61 70  t uid, struct ap
3d10: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61  pfs_pathinfo *pa
3d20: 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67  thinfo) {..unsig
3d30: 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78  ned int hash_idx
3d40: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
3d50: 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  et;..int retval;
3d60: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 31 3b 0a 0a  ...retval = 1;..
3d70: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
3d80: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
3d90: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
3da0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
3db0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
3dc0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
3dd0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
3de0: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66  to lock path_inf
3df0: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
3e00: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29  );....return(-1)
3e10: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73  ;..}...if (appfs
3e20: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3e30: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61   != NULL) {...ha
3e40: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f  sh_idx = (appfs_
3e50: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
3e60: 61 74 68 29 20 2b 20 75 69 64 29 20 25 20 61 70  ath) + uid) % ap
3e70: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3e80: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20  che_size;....if 
3e90: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
3ea0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
3eb0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20  ._cache_path != 
3ec0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73  NULL) {....if (s
3ed0: 74 72 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68  trcmp(appfs_path
3ee0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3ef0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
3f00: 68 2c 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26  h, path) == 0 &&
3f10: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
3f20: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
3f30: 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75  ._cache_uid == u
3f40: 69 64 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c  id) {.....retval
3f50: 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70   = 0;......memcp
3f60: 79 28 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70  y(pathinfo, &app
3f70: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3f80: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69  he[hash_idx], si
3f90: 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29  zeof(*pathinfo))
3fa0: 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ;.....pathinfo->
3fb0: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
3fc0: 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a  LL;....}...}..}.
3fd0: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
3fe0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
3ff0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
4000: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
4010: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
4020: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4030: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4040: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74  le to unlock pat
4050: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4060: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4070: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  n(-1);..}...if (
4080: 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09  retval == 0) {..
4090: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
40a0: 63 68 65 20 68 69 74 20 6f 6e 20 25 73 22 2c 20  che hit on %s", 
40b0: 70 61 74 68 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  path);..} else {
40c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
40d0: 43 61 63 68 65 20 6d 69 73 73 20 6f 6e 20 25 73  Cache miss on %s
40e0: 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72  ", path);..}...r
40f0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
4100: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
4110: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4120: 6f 5f 63 61 63 68 65 5f 61 64 64 28 63 6f 6e 73  o_cache_add(cons
4130: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69  t char *path, ui
4140: 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74 20  d_t uid, struct 
4150: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
4160: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73  pathinfo) {..uns
4170: 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69  igned int hash_i
4180: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  dx;..int pthread
4190: 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f  _ret;...pthread_
41a0: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
41b0: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
41c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
41d0: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
41e0: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
41f0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4200: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70  Unable to lock p
4210: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
4220: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
4230: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70  urn;..}...if (ap
4240: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4250: 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che == NULL) {..
4260: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
4270: 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28  _cache = calloc(
4280: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4290: 63 61 63 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65  cache_size, size
42a0: 6f 66 28 2a 61 70 70 66 73 5f 70 61 74 68 5f 69  of(*appfs_path_i
42b0: 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a  nfo_cache));..}.
42c0: 0a 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
42d0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
42e0: 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20  de(path) + uid) 
42f0: 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  % appfs_path_inf
4300: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09  o_cache_size;...
4310: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
4320: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
4330: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
4340: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72 65  != NULL) {...fre
4350: 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  e(appfs_path_inf
4360: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
4370: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a  ]._cache_path);.
4380: 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70 70  .}...memcpy(&app
4390: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
43a0: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70 61  he[hash_idx], pa
43b0: 74 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28 2a  thinfo, sizeof(*
43c0: 70 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61 70  pathinfo));...ap
43d0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
43e0: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
43f0: 61 63 68 65 5f 70 61 74 68 20 3d 20 73 74 72 64  ache_path = strd
4400: 75 70 28 70 61 74 68 29 3b 0a 09 61 70 70 66 73  up(path);..appfs
4410: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4420: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
4430: 65 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a 09  e_uid  = uid;...
4440: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
4450: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
4460: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
4470: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
4480: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
4490: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
44a0: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
44b0: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
44c0: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
44d0: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
44e0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..}...return;.}.
44f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
4500: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4510: 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74 20  _cache_rm(const 
4520: 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f  char *path, uid_
4530: 74 20 75 69 64 29 20 7b 0a 09 75 6e 73 69 67 6e  t uid) {..unsign
4540: 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b  ed int hash_idx;
4550: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
4560: 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  t;...pthread_ret
4570: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
4580: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
4590: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
45a0: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
45b0: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
45c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
45d0: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
45e0: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
45f0: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4600: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73  ;..}...if (appfs
4610: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4620: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61   != NULL) {...ha
4630: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f  sh_idx = (appfs_
4640: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
4650: 61 74 68 29 20 2b 20 75 69 64 29 20 25 20 61 70  ath) + uid) % ap
4660: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4670: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20  che_size;....if 
4680: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
4690: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
46a0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20  ._cache_path != 
46b0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28  NULL) {....free(
46c0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
46d0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
46e0: 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09  _cache_path);...
46f0: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
4700: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
4710: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ]._cache_path = 
4720: 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70  NULL;...}..}...p
4730: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
4740: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
4750: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
4760: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
4770: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4780: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4790: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
47a0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
47b0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
47c0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
47d0: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .}...return;.}..
47e0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
47f0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
4800: 63 61 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f  cache_flush(uid_
4810: 74 20 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73  t uid, int new_s
4820: 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64  ize) {..unsigned
4830: 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70   int idx;..int p
4840: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50  thread_ret;...AP
4850: 50 46 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68  PFS_DEBUG("Flush
4860: 69 6e 67 20 41 70 70 46 53 20 63 61 63 68 65 20  ing AppFS cache 
4870: 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77  (uid = %lli, new
4880: 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c  _size = %i)", (l
4890: 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e  ong long) uid, n
48a0: 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72  ew_size);...pthr
48b0: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
48c0: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70  d_mutex_lock(&ap
48d0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
48e0: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
48f0: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
4900: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
4910: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  UG("Unable to lo
4920: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
4930: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
4940: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66  .return;..}...if
4950: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
4960: 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29  o_cache != NULL)
4970: 20 7b 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20   {...for (idx = 
4980: 30 3b 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70  0; idx < appfs_p
4990: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
49a0: 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09  ize; idx++) {...
49b0: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
49c0: 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e  info_cache[idx].
49d0: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e  _cache_path != N
49e0: 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75  ULL) {.....if (u
49f0: 69 64 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d  id != ((uid_t) -
4a00: 31 29 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61  1)) {......if (a
4a10: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4a20: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4a30: 5f 75 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09  _uid != uid) {..
4a40: 09 09 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09  .....continue;..
4a50: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09  ....}.....}.....
4a60: 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68  .free(appfs_path
4a70: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
4a80: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a  ._cache_path);..
4a90: 09 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69  ....appfs_path_i
4aa0: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
4ab0: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c  cache_path = NUL
4ac0: 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a  L;....}...}..}..
4ad0: 09 69 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69  .if (uid == ((ui
4ae0: 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72  d_t) -1)) {...fr
4af0: 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ee(appfs_path_in
4b00: 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70  fo_cache);....ap
4b10: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4b20: 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69  che = NULL;....i
4b30: 66 20 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d  f (new_size != -
4b40: 31 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61  1) {....appfs_pa
4b50: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69  th_info_cache_si
4b60: 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09  ze = new_size;..
4b70: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f  .}..}...pthread_
4b80: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4b90: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
4ba0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4bb0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4bc0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
4bd0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4be0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
4bf0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
4c00: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
4c10: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
4c20: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20  turn;.}../* Get 
4c30: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75  information abou
4c40: 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70  t a path, and op
4c50: 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68  tionally list ch
4c60: 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63  ildren */.static
4c70: 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70   int appfs_get_p
4c80: 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63  ath_info(const c
4c90: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
4ca0: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
4cb0: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54   *pathinfo) {..T
4cc0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
4cd0: 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74  p;..Tcl_Obj *att
4ce0: 72 73 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76  rs_dict, *attr_v
4cf0: 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61  alue;..const cha
4d00: 72 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  r *attr_value_st
4d10: 72 3b 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74 20  r;..Tcl_WideInt 
4d20: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
4d30: 0a 09 69 6e 74 20 61 74 74 72 5f 76 61 6c 75 65  ..int attr_value
4d40: 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f  _int;..static __
4d50: 74 68 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a  thread Tcl_Obj *
4d60: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20  attr_key_type = 
4d70: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
4d80: 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61  perms = NULL, *a
4d90: 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e  ttr_key_size = N
4da0: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74  ULL, *attr_key_t
4db0: 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  ime = NULL, *att
4dc0: 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e  r_key_source = N
4dd0: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63  ULL, *attr_key_c
4de0: 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c  hildcount = NULL
4df0: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b  , *attr_key_pack
4e00: 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e  aged = NULL;..in
4e10: 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e  t cache_ret;..in
4e20: 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  t tcl_ret;..int 
4e30: 72 65 74 76 61 6c 3b 0a 09 75 69 64 5f 74 20 66  retval;..uid_t f
4e40: 73 75 69 64 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  suid;...retval =
4e50: 20 30 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70   0;...fsuid = ap
4e60: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
4e70: 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20 61  ...cache_ret = a
4e80: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4e90: 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 70 61 74  fo_cache_get(pat
4ea0: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e  h, fsuid, pathin
4eb0: 66 6f 29 3b 0a 09 69 66 20 28 63 61 63 68 65 5f  fo);..if (cache_
4ec0: 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66  ret == 0) {...if
4ed0: 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65   (pathinfo->type
4ee0: 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59   == APPFS_PATHTY
4ef0: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53  PE_DOES_NOT_EXIS
4f00: 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  T) {....APPFS_DE
4f10: 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66  BUG("Returning f
4f20: 72 6f 6d 20 63 61 63 68 65 3a 20 64 6f 65 73 20  rom cache: does 
4f30: 6e 6f 74 20 65 78 69 73 74 20 5c 22 25 73 5c 22  not exist \"%s\"
4f40: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65  ", path);.....re
4f50: 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09  turn(-ENOENT);..
4f60: 09 7d 0a 0a 09 09 69 66 20 28 70 61 74 68 69 6e  .}....if (pathin
4f70: 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46  fo->type == APPF
4f80: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
4f90: 49 44 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44  ID) {....APPFS_D
4fa0: 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20  EBUG("Returning 
4fb0: 66 72 6f 6d 20 63 61 63 68 65 3a 20 69 6e 76 61  from cache: inva
4fc0: 6c 69 64 20 6f 62 6a 65 63 74 20 5c 22 25 73 5c  lid object \"%s\
4fd0: 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72  "", path);.....r
4fe0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d  eturn(-EIO);...}
4ff0: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
5000: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  }...interp = app
5010: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
5020: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
5030: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
5040: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61  EBUG("error: Una
5050: 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e  ble to get an in
5060: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09  terpreter");....
5070: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
5080: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
5090: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
50a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63  e(interp);)...tc
50b0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
50c0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
50d0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  , "::appfs::geta
50e0: 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ttr", path);..if
50f0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
5100: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
5110: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67  EBUG("::appfs::g
5120: 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65  etattr(%s) faile
5130: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
5140: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5150: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
5160: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
5170: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
5180: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
5190: 3b 0a 09 09 29 0a 0a 09 09 70 61 74 68 69 6e 66  ;...)....pathinf
51a0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
51b0: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f  PATHTYPE_DOES_NO
51c0: 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61 70 70 66  T_EXIST;....appf
51d0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
51e0: 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20  cache_add(path, 
51f0: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29  fsuid, pathinfo)
5200: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
5210: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
5220: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
5230: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b  return(-ENOENT);
5240: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b  ..}...if (attr_k
5250: 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29  ey_type == NULL)
5260: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f   {...appfs_call_
5270: 6c 69 62 74 63 6c 28 0a 09 09 09 61 74 74 72 5f  libtcl(....attr_
5280: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d  key_type       =
5290: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
52a0: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09  j("type", -1);..
52b0: 09 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73  ..attr_key_perms
52c0: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
52d0: 74 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22  tringObj("perms"
52e0: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b  , -1);....attr_k
52f0: 65 79 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20  ey_size       = 
5300: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5310: 28 22 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09  ("size", -1);...
5320: 09 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20  .attr_key_time  
5330: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
5340: 72 69 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20  ringObj("time", 
5350: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79  -1);....attr_key
5360: 5f 73 6f 75 72 63 65 20 20 20 20 20 3d 20 54 63  _source     = Tc
5370: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
5380: 73 6f 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09  source", -1);...
5390: 09 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63  .attr_key_childc
53a0: 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74  ount = Tcl_NewSt
53b0: 72 69 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f  ringObj("childco
53c0: 75 6e 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  unt", -1);....at
53d0: 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20  tr_key_packaged 
53e0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
53f0: 67 4f 62 6a 28 22 70 61 63 6b 61 67 65 64 22 2c  gObj("packaged",
5400: 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e   -1);.....Tcl_In
5410: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
5420: 6b 65 79 5f 74 79 70 65 29 3b 0a 09 09 09 54 63  key_type);....Tc
5430: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5440: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a  ttr_key_perms);.
5450: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
5460: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a  unt(attr_key_siz
5470: 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  e);....Tcl_IncrR
5480: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
5490: 5f 74 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49  _time);....Tcl_I
54a0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
54b0: 5f 6b 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09  _key_source);...
54c0: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
54d0: 74 28 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64  t(attr_key_child
54e0: 63 6f 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49  count);....Tcl_I
54f0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
5500: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a  _key_packaged);.
5510: 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  ..)..}...appfs_c
5520: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74  all_libtcl(...at
5530: 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47  trs_dict = Tcl_G
5540: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
5550: 72 70 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d  rp);...tcl_ret =
5560: 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28   Tcl_DictObjGet(
5570: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
5580: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70  ct, attr_key_typ
5590: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
55a0: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
55b0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
55c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69  APPFS_DEBUG("[di
55d0: 63 74 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d  ct get \"type\"]
55e0: 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 61 70 70   failed");...app
55f0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
5600: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5610: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
5620: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
5630: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
5640: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...)....appfs_ca
5650: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
5660: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
5670: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
5680: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76  ..}...if (attr_v
5690: 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  alue == NULL) {.
56a0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65  ..APPFS_DEBUG("e
56b0: 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20  rror: Unable to 
56c0: 67 65 74 20 74 79 70 65 20 66 6f 72 20 5c 22 25  get type for \"%
56d0: 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70  s\" from Tcl", p
56e0: 61 74 68 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  ath);....appfs_c
56f0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
5700: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
5710: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
5720: 3b 0a 09 7d 0a 0a 09 70 61 74 68 69 6e 66 6f 2d  ;..}...pathinfo-
5730: 3e 70 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 09  >packaged = 0;..
5740: 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20  pathinfo->inode 
5750: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
5760: 5f 69 6e 6f 64 65 28 70 61 74 68 29 3b 0a 0a 09  _inode(path);...
5770: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5780: 6c 28 0a 09 09 61 74 74 72 5f 76 61 6c 75 65 5f  l(...attr_value_
5790: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
57a0: 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b  ing(attr_value);
57b0: 0a 0a 09 09 73 77 69 74 63 68 20 28 61 74 74 72  ....switch (attr
57c0: 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b  _value_str[0]) {
57d0: 0a 09 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a  ....case 'd': /*
57e0: 20 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09   directory */...
57f0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5800: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
5810: 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09  E_DIRECTORY;....
5820: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5830: 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75  nfo.dir.childcou
5840: 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c  nt = 0;......Tcl
5850: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5860: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5870: 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f  attr_key_childco
5880: 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  unt, &attr_value
5890: 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f  );.....if (attr_
58a0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
58b0: 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20  ......tcl_ret = 
58c0: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
58d0: 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72  omObj(NULL, attr
58e0: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
58f0: 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09  lue_wide);......
5900: 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54  if (tcl_ret == T
5910: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70  CL_OK) {.......p
5920: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5930: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74  o.dir.childcount
5940: 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69   = attr_value_wi
5950: 64 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d  de;......}.....}
5960: 0a 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  ......break;....
5970: 63 61 73 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c  case 'f': /* fil
5980: 65 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66  e */.....pathinf
5990: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
59a0: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09  PATHTYPE_FILE;..
59b0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
59c0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20  einfo.file.size 
59d0: 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  = 0;.....pathinf
59e0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
59f0: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b  .executable = 0;
5a00: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ......Tcl_DictOb
5a10: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5a20: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5a30: 79 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61  y_size, &attr_va
5a40: 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74  lue);.....if (at
5a50: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
5a60: 29 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74  ) {......tcl_ret
5a70: 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e   = Tcl_GetWideIn
5a80: 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61  tFromObj(NULL, a
5a90: 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72  ttr_value, &attr
5aa0: 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09  _value_wide);...
5ab0: 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d  ...if (tcl_ret =
5ac0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09  = TCL_OK) {.....
5ad0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5ae0: 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d  info.file.size =
5af0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
5b00: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
5b10: 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
5b20: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
5b30: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
5b40: 70 65 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c  perms, &attr_val
5b50: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74  ue);.....if (att
5b60: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
5b70: 20 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c   {......attr_val
5b80: 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74  ue_str = Tcl_Get
5b90: 53 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75  String(attr_valu
5ba0: 65 29 3b 0a 09 09 09 09 09 69 66 20 28 61 74 74  e);......if (att
5bb0: 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 20 3d  r_value_str[0] =
5bc0: 3d 20 27 78 27 29 20 7b 0a 09 09 09 09 09 09 70  = 'x') {.......p
5bd0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5be0: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c  o.file.executabl
5bf0: 65 20 3d 20 31 3b 0a 09 09 09 09 09 7d 0a 09 09  e = 1;......}...
5c00: 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09  ..}.....break;..
5c10: 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73  ..case 's': /* s
5c20: 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 09 70 61  ymlink */.....pa
5c30: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
5c40: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
5c50: 4d 4c 49 4e 4b 3b 0a 09 09 09 09 70 61 74 68 69  MLINK;.....pathi
5c60: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
5c70: 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a  mlink.size = 0;.
5c80: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5c90: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5ca0: 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b  ource[0] = '\0';
5cb0: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ......Tcl_DictOb
5cc0: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5cd0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5ce0: 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74 72 5f  y_source, &attr_
5cf0: 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28  value);.....if (
5d00: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
5d10: 4c 4c 29 20 7b 0a 09 09 09 09 09 61 74 74 72 5f  LL) {......attr_
5d20: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f  value_str = Tcl_
5d30: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
5d40: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74  (attr_value, &at
5d50: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a  tr_value_int); .
5d60: 0a 09 09 09 09 09 69 66 20 28 28 61 74 74 72 5f  ......if ((attr_
5d70: 76 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c  value_int + 1) <
5d80: 3d 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66  = sizeof(pathinf
5d90: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
5da0: 69 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09  ink.source)) {..
5db0: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5dc0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
5dd0: 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75  size = attr_valu
5de0: 65 5f 69 6e 74 3b 0a 09 09 09 09 09 09 70 61 74  e_int;.......pat
5df0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5e00: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61  symlink.source[a
5e10: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d  ttr_value_int] =
5e20: 20 27 5c 30 27 3b 0a 0a 09 09 09 09 09 09 6d 65   '\0';........me
5e30: 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2d 3e 74  mcpy(pathinfo->t
5e40: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
5e50: 73 6f 75 72 63 65 2c 20 61 74 74 72 5f 76 61 6c  source, attr_val
5e60: 75 65 5f 73 74 72 2c 20 61 74 74 72 5f 76 61 6c  ue_str, attr_val
5e70: 75 65 5f 69 6e 74 29 3b 0a 09 09 09 09 09 7d 0a  ue_int);......}.
5e80: 09 09 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b  ....}.....break;
5e90: 0a 09 09 09 63 61 73 65 20 27 46 27 3a 20 2f 2a  ....case 'F': /*
5ea0: 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09 09   pipe/fifo */...
5eb0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5ec0: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
5ed0: 45 5f 46 49 46 4f 3b 0a 09 09 09 09 62 72 65 61  E_FIFO;.....brea
5ee0: 6b 3b 0a 09 09 09 63 61 73 65 20 27 53 27 3a 20  k;....case 'S': 
5ef0: 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73  /* UNIX domain s
5f00: 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 09 70 61 74  ocket */.....pat
5f10: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
5f20: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43  PFS_PATHTYPE_SOC
5f30: 4b 45 54 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  KET;.....break;.
5f40: 09 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09  ...default:.....
5f50: 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 09  retval = -EIO;..
5f60: 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62  .}....Tcl_DictOb
5f70: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5f80: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5f90: 79 5f 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74  y_packaged, &att
5fa0: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28  r_value);...if (
5fb0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
5fc0: 4c 4c 29 20 7b 0a 09 09 09 70 61 74 68 69 6e 66  LL) {....pathinf
5fd0: 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b  o->packaged = 1;
5fe0: 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74  ...}....Tcl_Dict
5ff0: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
6000: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
6010: 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f  key_time, &attr_
6020: 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74  value);...if (at
6030: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
6040: 29 20 7b 0a 09 09 09 74 63 6c 5f 72 65 74 20 3d  ) {....tcl_ret =
6050: 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46   Tcl_GetWideIntF
6060: 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74  romObj(NULL, att
6070: 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76  r_value, &attr_v
6080: 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 69  alue_wide);....i
6090: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
60a0: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 70 61 74 68  L_OK) {.....path
60b0: 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74  info->time = att
60c0: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09  r_value_wide;...
60d0: 09 7d 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09  .}...} else {...
60e0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20  .pathinfo->time 
60f0: 3d 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65  = appfs_boottime
6100: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c  ;...}....Tcl_Rel
6110: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 09 29  ease(interp);..)
6120: 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d  ...if (retval ==
6130: 20 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 67 65   0) {...appfs_ge
6140: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
6150: 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69  e_add(path, fsui
6160: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 7d  d, pathinfo);..}
6170: 20 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f   else {...APPFS_
6180: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 49 6e  DEBUG("error: In
6190: 76 61 6c 69 64 20 74 79 70 65 20 66 6f 72 20 5c  valid type for \
61a0: 22 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22 2c  "%s\" from Tcl",
61b0: 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 65 74   path);..}...ret
61c0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
61d0: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70  static char *app
61e0: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72  fs_prepare_to_cr
61f0: 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20  eate(const char 
6200: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
6210: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
6220: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
6230: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
6240: 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  et;...appfs_get_
6250: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
6260: 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f  flush(appfs_get_
6270: 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09  fsuid(), -1);...
6280: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
6290: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
62a0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
62b0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
62c0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
62d0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72  ll_libtcl(Tcl_Pr
62e0: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29  eserve(interp);)
62f0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6300: 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20  btcl(...tcl_ret 
6310: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
6320: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
6330: 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f  ppfs::prepare_to
6340: 5f 63 72 65 61 74 65 22 2c 20 70 61 74 68 29 3b  _create", path);
6350: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
6360: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
6370: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
6380: 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f  ppfs::prepare_to
6390: 5f 63 72 65 61 74 65 28 25 73 29 20 66 61 69 6c  _create(%s) fail
63a0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
63b0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
63c0: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
63d0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
63e0: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
63f0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
6400: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
6410: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
6420: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
6430: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  )....return(NULL
6440: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
6450: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61  ll_libtcl(...rea
6460: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
6470: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
6480: 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73  erp);..)...appfs
6490: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
64a0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
64b0: 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  ;)...if (real_pa
64c0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
64d0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
64e0: 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70  ...return(strdup
64f0: 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a  (real_path));.}.
6500: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70  .static char *ap
6510: 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63 6f  pfs_localpath(co
6520: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
6530: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
6540: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
6550: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
6560: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
6570: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
6580: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
6590: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
65a0: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
65b0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
65c0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
65d0: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
65e0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
65f0: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d  tcl(...tcl_ret =
6600: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
6610: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70  interp, 2, "::ap
6620: 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 22 2c  pfs::localpath",
6630: 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28   path);..)..if (
6640: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
6650: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
6660: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63  UG("::appfs::loc
6670: 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c 65  alpath(%s) faile
6680: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
6690: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
66a0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
66b0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
66c0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
66d0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
66e0: 3b 0a 09 09 29 0a 0a 09 09 72 65 74 75 72 6e 28  ;...)....return(
66f0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
6700: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
6710: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
6720: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
6730: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61  (interp);..)...a
6740: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6750: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
6760: 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61  erp);)...if (rea
6770: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
6780: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
6790: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74  ;..}...return(st
67a0: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29  rdup(real_path))
67b0: 3b 0a 7d 0a 0a 23 69 66 20 28 64 65 66 69 6e 65  ;.}..#if (define
67c0: 64 28 44 45 42 55 47 29 20 26 26 20 64 65 66 69  d(DEBUG) && defi
67d0: 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50  ned(APPFS_EXIT_P
67e0: 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65 64  ATH)) || defined
67f0: 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48  (APPFS_EXIT_PATH
6800: 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45  _ENABLE_MAJOR_SE
6810: 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73 74 61  CURITY_HOLE).sta
6820: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 65  tic void appfs_e
6830: 78 69 74 28 76 6f 69 64 29 20 7b 0a 09 69 6e 74  xit(void) {..int
6840: 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72   global_interp_r
6850: 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62  eset_key;...glob
6860: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
6870: 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74  key = __sync_fet
6880: 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65  ch_and_add(&inte
6890: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29  rp_reset_key, 0)
68a0: 3b 0a 09 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f  ;..__sync_fetch_
68b0: 61 6e 64 5f 73 75 62 28 26 69 6e 74 65 72 70 5f  and_sub(&interp_
68c0: 72 65 73 65 74 5f 6b 65 79 2c 20 67 6c 6f 62 61  reset_key, globa
68d0: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
68e0: 65 79 29 3b 0a 0a 09 77 68 69 6c 65 20 28 5f 5f  ey);...while (__
68f0: 73 79 6e 63 5f 73 75 62 5f 61 6e 64 5f 66 65 74  sync_sub_and_fet
6900: 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  ch(&interp_reset
6910: 5f 6b 65 79 2c 20 31 29 20 3e 3d 20 30 29 20 7b  _key, 1) >= 0) {
6920: 0a 09 09 2f 2a 20 42 75 73 79 20 4c 6f 6f 70 20  .../* Busy Loop 
6930: 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f 62 61 6c 5f 69  */..}...global_i
6940: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
6950: 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61  = __sync_fetch_a
6960: 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72  nd_add(&interp_r
6970: 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 69  eset_key, 0);..i
6980: 66 20 28 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  f (global_interp
6990: 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 2d 31  _reset_key != -1
69a0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
69b0: 47 28 22 45 72 72 6f 72 20 73 65 6e 64 69 6e 67  G("Error sending
69c0: 20 6b 69 6c 6c 20 73 69 67 6e 61 6c 20 74 6f 20   kill signal to 
69d0: 61 6c 6c 20 74 68 72 65 61 64 73 2c 20 61 62 6f  all threads, abo
69e0: 72 74 69 6e 67 20 61 6e 79 77 61 79 2e 22 29 3b  rting anyway.");
69f0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  ..}...appfs_get_
6a00: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
6a10: 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a  flush(-1, -1);..
6a20: 09 66 75 73 65 5f 65 78 69 74 28 66 75 73 65 5f  .fuse_exit(fuse_
6a30: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 2d 3e 66  get_context()->f
6a40: 75 73 65 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a  use);...return;.
6a50: 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74 69 63  }.#endif..static
6a60: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
6a70: 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63  readlink(const c
6a80: 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20  har *path, char 
6a90: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
6aa0: 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70  e) {..struct app
6ab0: 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68  fs_pathinfo path
6ac0: 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61  info;..int retva
6ad0: 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44  l = 0;...APPFS_D
6ae0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
6af0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
6b00: 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f  ath);...pathinfo
6b10: 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  .type = APPFS_PA
6b20: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a  THTYPE_INVALID;.
6b30: 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73  ..retval = appfs
6b40: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
6b50: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b  ath, &pathinfo);
6b60: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
6b70: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65  0) {...return(re
6b80: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  tval);..}...if (
6b90: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d  pathinfo.type !=
6ba0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
6bb0: 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74  SYMLINK) {...ret
6bc0: 75 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d  urn(-EINVAL);..}
6bd0: 0a 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70  ...if ((strlen(p
6be0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
6bf0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29  .symlink.source)
6c00: 20 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a   + 1) > size) {.
6c10: 09 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54  ..return(-ENAMET
6c20: 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65  OOLONG);..}...me
6c30: 6d 63 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e  mcpy(buf, pathin
6c40: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
6c50: 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c  ink.source, strl
6c60: 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  en(pathinfo.type
6c70: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
6c80: 72 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74  rce) + 1);...ret
6c90: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
6ca0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
6cb0: 5f 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63  _getattr(const c
6cc0: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
6cd0: 74 20 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b  t stat *stbuf) {
6ce0: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
6cf0: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
6d00: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a  ;..int retval;..
6d10: 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41  .retval = 0;...A
6d20: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
6d30: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
6d40: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66  .)", path);..#if
6d50: 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47 29   (defined(DEBUG)
6d60: 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50 46   && defined(APPF
6d70: 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c  S_EXIT_PATH)) ||
6d80: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45   defined(APPFS_E
6d90: 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f  XIT_PATH_ENABLE_
6da0: 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48  MAJOR_SECURITY_H
6db0: 4f 4c 45 29 0a 09 2f 2a 0a 09 20 2a 20 54 68 69  OLE)../*.. * Thi
6dc0: 73 20 69 73 20 61 20 6d 61 6a 6f 72 20 73 65 63  s is a major sec
6dd0: 75 72 69 74 79 20 69 73 73 75 65 20 73 6f 20 77  urity issue so w
6de0: 65 20 63 61 6e 6e 6f 74 20 6c 65 74 20 69 74 20  e cannot let it 
6df0: 62 65 20 63 6f 6d 70 69 6c 65 64 20 69 6e 74 6f  be compiled into
6e00: 0a 09 20 2a 20 61 6e 79 20 72 65 6c 65 61 73 65  .. * any release
6e10: 0a 09 20 2a 2f 0a 0a 09 69 66 20 28 73 74 72 63  .. */...if (strc
6e20: 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 69 74 22  mp(path, "/exit"
6e30: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70 66  ) == 0) {...appf
6e40: 73 5f 65 78 69 74 28 29 3b 0a 09 7d 0a 23 65 6e  s_exit();..}.#en
6e50: 64 69 66 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74  dif...pathinfo.t
6e60: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
6e70: 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09  TYPE_INVALID;...
6e80: 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67  retval = appfs_g
6e90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74  et_path_info(pat
6ea0: 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09  h, &pathinfo);..
6eb0: 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29  if (retval != 0)
6ec0: 20 7b 0a 09 09 69 66 20 28 72 65 74 76 61 6c 20   {...if (retval 
6ed0: 3d 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09 09  == -ENOENT) {...
6ee0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
6ef0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 72 65 74 75  t_path_info retu
6f00: 72 6e 65 64 20 45 4e 4f 45 4e 54 2c 20 72 65 74  rned ENOENT, ret
6f10: 75 72 6e 69 6e 67 20 69 74 20 61 73 20 77 65 6c  urning it as wel
6f20: 6c 2e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b  l.");...} else {
6f30: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
6f40: 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68  "error: get_path
6f50: 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a  _info failed");.
6f60: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 72 65  ..}....return(re
6f70: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 73  tval);..}...mems
6f80: 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69 7a  et(stbuf, 0, siz
6f90: 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74 29  eof(struct stat)
6fa0: 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  );...stbuf->st_m
6fb0: 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e  time = pathinfo.
6fc0: 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  time;..stbuf->st
6fd0: 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66  _ctime = pathinf
6fe0: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e  o.time;..stbuf->
6ff0: 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68 69  st_atime = pathi
7000: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
7010: 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61 74  ->st_ino   = pat
7020: 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74  hinfo.inode;..st
7030: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20  buf->st_mode  = 
7040: 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70 61 74  0;...switch (pat
7050: 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a 09 09  hinfo.type) {...
7060: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
7070: 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a 0a 09  YPE_DIRECTORY:..
7080: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
7090: 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30 35 35   = S_IFDIR | 055
70a0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
70b0: 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68  nlink = 2 + path
70c0: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69  info.typeinfo.di
70d0: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09  r.childcount;...
70e0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
70f0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
7100: 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74 68 69  LE:....if (pathi
7110: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
7120: 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a  e.executable) {.
7130: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7140: 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30  de = S_IFREG | 0
7150: 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65 20 7b  555;....} else {
7160: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
7170: 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20  ode = S_IFREG | 
7180: 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09 09 73  0444;....}.....s
7190: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
71a0: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
71b0: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f  _size = pathinfo
71c0: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
71d0: 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  ize;....break;..
71e0: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
71f0: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09  TYPE_SYMLINK:...
7200: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7210: 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35  = S_IFLNK | 0555
7220: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e  ;....stbuf->st_n
7230: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62  link = 1;....stb
7240: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61  uf->st_size = pa
7250: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
7260: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09  symlink.size;...
7270: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
7280: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f  PPFS_PATHTYPE_SO
7290: 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d 3e  CKET:....stbuf->
72a0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53 4f  st_mode = S_IFSO
72b0: 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74  CK | 0555;....st
72c0: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20  buf->st_nlink = 
72d0: 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  1;....stbuf->st_
72e0: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65  size = 0;....bre
72f0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7300: 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a 0a  _PATHTYPE_FIFO:.
7310: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7320: 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30 35  e = S_IFIFO | 05
7330: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
7340: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
7350: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
7360: 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  0;....break;...c
7370: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
7380: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53  PE_DOES_NOT_EXIS
7390: 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  T:....retval = -
73a0: 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61  ENOENT;.....brea
73b0: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
73c0: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
73d0: 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45  :....retval = -E
73e0: 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09  IO;.....break;..
73f0: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
7400: 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 73  .packaged) {...s
7410: 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20 3d  tbuf->st_uid   =
7420: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
7430: 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f  ();...stbuf->st_
7440: 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65  gid   = appfs_ge
7450: 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74 62  t_fsgid();...stb
7460: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30  uf->st_mode |= 0
7470: 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  200;..}...return
7480: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61  (retval);.}..sta
7490: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
74a0: 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73 74  se_readdir(const
74b0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f 69   char *path, voi
74c0: 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69 6c  d *buf, fuse_fil
74d0: 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20  l_dir_t filler, 
74e0: 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74  off_t offset, st
74f0: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
7500: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f  nfo *fi) {..Tcl_
7510: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
7520: 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64  .Tcl_Obj **child
7530: 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72  ren;..int childr
7540: 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09  en_count, idx;..
7550: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41  int tcl_ret;...A
7560: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
7570: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
7580: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e  .)", path);...in
7590: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
75a0: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
75b0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
75c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
75d0: 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f  error: Unable to
75e0: 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72 65   get an interpre
75f0: 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ter");....return
7600: 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  (0);..}...appfs_
7610: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
7620: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
7630: 3b 29 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c  ;)...filler(buf,
7640: 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a   ".", NULL, 0);.
7650: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e  .filler(buf, "..
7660: 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74  ", NULL, 0);...t
7670: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
7680: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
7690: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  2, "::appfs::get
76a0: 63 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68 29  children", path)
76b0: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
76c0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
76d0: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
76e0: 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 28  fs::getchildren(
76f0: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
7700: 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  th);...appfs_cal
7710: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
7720: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
7730: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
7740: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
7750: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
7760: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
7770: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
7780: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
7790: 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70  urn(0);..}...app
77a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
77b0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
77c0: 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e  ListObjGetElemen
77d0: 74 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  ts(interp, Tcl_G
77e0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
77f0: 72 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63  rp), &children_c
7800: 6f 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e 29  ount, &children)
7810: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
7820: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
7830: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50 61  .APPFS_DEBUG("Pa
7840: 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20 63 68  rsing list of ch
7850: 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68 20 25  ildren on path %
7860: 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  s failed.", path
7870: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
7880: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
7890: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
78a0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
78b0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
78c0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
78d0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
78e0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
78f0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
7900: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28  n(0);..}...for (
7910: 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 63  idx = 0; idx < c
7920: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69  hildren_count; i
7930: 64 78 2b 2b 29 20 7b 0a 09 09 61 70 70 66 73 5f  dx++) {...appfs_
7940: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
7950: 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f  filler(buf, Tcl_
7960: 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64 72  GetString(childr
7970: 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20  en[idx]), NULL, 
7980: 30 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70  0);...)..}...app
7990: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
79a0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
79b0: 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30 29  p);)...return(0)
79c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
79d0: 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28  appfs_fuse_open(
79e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
79f0: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
7a00: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
7a10: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7a20: 72 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66  rp;..struct appf
7a30: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69  s_pathinfo pathi
7a40: 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  nfo;..const char
7a50: 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f   *real_path, *mo
7a60: 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74  de;..int gpi_ret
7a70: 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  , tcl_ret;..int 
7a80: 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  fh;...APPFS_DEBU
7a90: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
7aa0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
7ab0: 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61  );...gpi_ret = a
7ac0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
7ad0: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e  fo(path, &pathin
7ae0: 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e  fo);...if ((fi->
7af0: 66 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c  flags & (O_WRONL
7b00: 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28  Y|O_CREAT)) == (
7b10: 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59  O_CREAT|O_WRONLY
7b20: 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69  )) {.../* The fi
7b30: 6c 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74  le will be creat
7b40: 65 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f  ed if it does no
7b50: 74 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20  t exist */...if 
7b60: 28 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26  (gpi_ret != 0 &&
7b70: 20 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f   gpi_ret != -ENO
7b80: 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  ENT) {....APPFS_
7b90: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65  DEBUG("error: ge
7ba0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c  t_path_info fail
7bb0: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ed");.....return
7bc0: 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a  (gpi_ret);...}..
7bd0: 09 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65  ..mode = "create
7be0: 22 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65  ";..../*... * We
7bf0: 20 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20 74   have to clear t
7c00: 68 65 20 63 61 63 68 65 20 68 65 72 65 20 73 6f  he cache here so
7c10: 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72   that the number
7c20: 20 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67   of... * links g
7c30: 65 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f  ets maintained o
7c40: 6e 20 74 68 65 20 70 61 72 65 6e 74 20 64 69 72  n the parent dir
7c50: 65 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61  ectory... */...a
7c60: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
7c70: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
7c80: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
7c90: 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  , -1);..} else {
7ca0: 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d  .../* The file m
7cb0: 75 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73  ust already exis
7cc0: 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72  t */...if (gpi_r
7cd0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41 50  et != 0) {....AP
7ce0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
7cf0: 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20  : get_path_info 
7d00: 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65  failed");.....re
7d10: 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09  turn(gpi_ret);..
7d20: 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b  .}....mode = "";
7d30: 0a 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61  ....if ((fi->fla
7d40: 67 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d  gs & O_WRONLY) =
7d50: 3d 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09  = O_WRONLY) {...
7d60: 09 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b  .mode = "write";
7d70: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61  ...}..}...if (pa
7d80: 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41  thinfo.type == A
7d90: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
7da0: 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 41 50 50  RECTORY) {...APP
7db0: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7dc0: 20 41 73 6b 65 64 20 74 6f 20 6f 70 65 6e 20 61   Asked to open a
7dd0: 20 64 69 72 65 63 74 6f 72 79 2e 22 29 3b 0a 0a   directory.");..
7de0: 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44 49 52  ..return(-EISDIR
7df0: 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d  );..}...interp =
7e00: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
7e10: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
7e20: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
7e30: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7e40: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61   Unable to get a
7e50: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  n interpreter");
7e60: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
7e70: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
7e80: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
7e90: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
7ea0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
7eb0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
7ec0: 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 3, "::appfs::
7ed0: 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c  openpath", path,
7ee0: 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63 6c   mode);..if (tcl
7ef0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
7f00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
7f10: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
7f20: 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65  th(%s, %s) faile
7f30: 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29  d.", path, mode)
7f40: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
7f50: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
7f60: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
7f70: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
7f80: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
7f90: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
7fa0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7fb0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
7fc0: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
7fd0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
7fe0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
7ff0: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
8000: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
8010: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  t(interp);..)...
8020: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8030: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
8040: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65  terp);)...if (re
8050: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
8060: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8070: 28 22 65 72 72 6f 72 3a 20 72 65 61 6c 5f 70 61  ("error: real_pa
8080: 74 68 20 77 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a  th was NULL.")..
8090: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
80a0: 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  .}...APPFS_DEBUG
80b0: 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65 71  ("Translated req
80c0: 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73 20  uest to open %s 
80d0: 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d  to opening %s (m
80e0: 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20  ode = \"%s\")", 
80f0: 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c  path, real_path,
8100: 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f   mode);...fh = o
8110: 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 66  pen(real_path, f
8120: 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29 3b  i->flags, 0600);
8130: 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20 7b  ...if (fh < 0) {
8140: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8150: 65 72 72 6f 72 3a 20 6f 70 65 6e 20 66 61 69 6c  error: open fail
8160: 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  ed");....return(
8170: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
8180: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a  ..fi->fh = fh;..
8190: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
81a0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
81b0: 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74  fuse_close(const
81c0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72   char *path, str
81d0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
81e0: 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63  fo *fi) {..int c
81f0: 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66  lose_ret;...appf
8200: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
8210: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61  cache_rm(path, a
8220: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
8230: 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d  );...close_ret =
8240: 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a   close(fi->fh);.
8250: 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21  .if (close_ret !
8260: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
8270: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 63 6c 6f  EBUG("error: clo
8280: 73 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09  se failed");....
8290: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
82a0: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
82b0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
82c0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  t appfs_fuse_rea
82d0: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  d(const char *pa
82e0: 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73  th, char *buf, s
82f0: 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f  ize_t size, off_
8300: 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74  t offset, struct
8310: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
8320: 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74 20  *fi) {..ssize_t 
8330: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72  read_ret;..int r
8340: 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44  etval;...APPFS_D
8350: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
8360: 68 20 3d 20 25 73 2c 20 62 75 66 2c 20 25 6c 6c  h = %s, buf, %ll
8370: 69 2c 20 25 6c 6c 69 2c 20 66 64 3d 25 6c 6c 69  i, %lli, fd=%lli
8380: 29 22 2c 20 70 61 74 68 2c 20 28 6c 6f 6e 67 20  )", path, (long 
8390: 6c 6f 6e 67 29 20 73 69 7a 65 2c 20 28 6c 6f 6e  long) size, (lon
83a0: 67 20 6c 6f 6e 67 29 20 6f 66 66 73 65 74 2c 20  g long) offset, 
83b0: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 2d 3e  (long long) fi->
83c0: 66 68 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  fh);...retval = 
83d0: 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65  0;...while (size
83e0: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 61 64 5f   != 0) {...read_
83f0: 72 65 74 20 3d 20 70 72 65 61 64 28 66 69 2d 3e  ret = pread(fi->
8400: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f  fh, buf, size, o
8410: 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28 72  ffset);....if (r
8420: 65 61 64 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09  ead_ret < 0) {..
8430: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65  ..APPFS_DEBUG("e
8440: 72 72 6f 72 3a 20 72 65 61 64 20 66 61 69 6c 65  rror: read faile
8450: 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  d");.....return(
8460: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d  errno * -1);...}
8470: 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65 74  ....if (read_ret
8480: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62 72 65 61   == 0) {....brea
8490: 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20 2d  k;...}....size -
84a0: 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 62 75  = read_ret;...bu
84b0: 66 20 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a  f  += read_ret;.
84c0: 09 09 6f 66 66 73 65 74 20 2b 3d 20 72 65 61 64  ..offset += read
84d0: 5f 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b  _ret;...retval +
84e0: 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 7d 0a 0a  = read_ret;..}..
84f0: 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20  .if (size != 0) 
8500: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
8510: 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65  "error: incomple
8520: 74 65 20 72 65 61 64 20 28 74 68 69 73 20 6d 69  te read (this mi
8530: 67 68 74 20 62 65 20 61 6e 20 65 72 72 6f 72 20  ght be an error 
8540: 62 65 63 61 75 73 65 20 46 55 53 45 20 77 69 6c  because FUSE wil
8550: 6c 20 72 65 71 75 65 73 74 20 74 68 65 20 65 78  l request the ex
8560: 61 63 74 20 6c 65 6e 67 74 68 20 6f 66 20 74 68  act length of th
8570: 65 20 66 69 6c 65 29 22 29 3b 0a 09 7d 0a 0a 09  e file)");..}...
8580: 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65 74  APPFS_DEBUG("Ret
8590: 75 72 6e 69 6e 67 3a 20 25 69 22 2c 20 72 65 74  urning: %i", ret
85a0: 76 61 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72  val);...return(r
85b0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69  etval);.}..stati
85c0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
85d0: 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63 68 61  _write(const cha
85e0: 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74 20 63  r *path, const c
85f0: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
8600: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66   size, off_t off
8610: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
8620: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
8630: 7b 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65  {..ssize_t write
8640: 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61  _ret;..int retva
8650: 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  l;...APPFS_DEBUG
8660: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
8670: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
8680: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
8690: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
86a0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
86b0: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 72 65 74  _fsuid());...ret
86c0: 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65  val = 0;...while
86d0: 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09   (size != 0) {..
86e0: 09 77 72 69 74 65 5f 72 65 74 20 3d 20 70 77 72  .write_ret = pwr
86f0: 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c  ite(fi->fh, buf,
8700: 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a   size, offset);.
8710: 0a 09 09 69 66 20 28 77 72 69 74 65 5f 72 65 74  ...if (write_ret
8720: 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53   < 0) {....APPFS
8730: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 77  _DEBUG("error: w
8740: 72 69 74 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a  rite failed");..
8750: 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
8760: 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66  * -1);...}....if
8770: 20 28 77 72 69 74 65 5f 72 65 74 20 3d 3d 20 30   (write_ret == 0
8780: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  ) {....break;...
8790: 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 77 72 69  }....size -= wri
87a0: 74 65 5f 72 65 74 3b 0a 09 09 62 75 66 20 20 2b  te_ret;...buf  +
87b0: 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 6f  = write_ret;...o
87c0: 66 66 73 65 74 20 2b 3d 20 77 72 69 74 65 5f 72  ffset += write_r
87d0: 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20  et;...retval += 
87e0: 77 72 69 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a 09  write_ret;..}...
87f0: 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b  if (size != 0) {
8800: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8810: 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 74  error: incomplet
8820: 65 20 77 72 69 74 65 22 29 3b 0a 09 7d 0a 0a 09  e write");..}...
8830: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
8840: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
8850: 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63  pfs_fuse_mknod(c
8860: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
8870: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65   mode_t mode, de
8880: 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63  v_t device) {..c
8890: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
88a0: 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a  .int mknod_ret;.
88b0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
88c0: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
88d0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
88e0: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
88f0: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52  FCHR) == S_IFCHR
8900: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
8910: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  ERM);..}...if ((
8920: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20  mode & S_IFBLK) 
8930: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09  == S_IFBLK) {...
8940: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
8950: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  .}...real_path =
8960: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
8970: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
8980: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
8990: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
89a0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
89b0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
89c0: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
89d0: 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e  .mknod_ret = mkn
89e0: 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  od(real_path, mo
89f0: 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61  de, device);...a
8a00: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
8a10: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
8a20: 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29  .free(real_path)
8a30: 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65  ;...if (mknod_re
8a40: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
8a50: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
8a60: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
8a70: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
8a80: 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28  pfs_fuse_create(
8a90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
8aa0: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73  , mode_t mode, s
8ab0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
8ac0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61  info *fi) {..cha
8ad0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
8ae0: 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44  nt fd;...APPFS_D
8af0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
8b00: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
8b10: 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64  ath);...if ((mod
8b20: 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20  e & S_IFCHR) == 
8b30: 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74  S_IFCHR) {...ret
8b40: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
8b50: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
8b60: 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c  IFBLK) == S_IFBL
8b70: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  K) {...return(-E
8b80: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c  PERM);..}...real
8b90: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
8ba0: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
8bb0: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
8bc0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
8bd0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
8be0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
8bf0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
8c00: 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65  er();...fd = cre
8c10: 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  at(real_path, mo
8c20: 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  de);...appfs_sim
8c30: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
8c40: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
8c50: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
8c60: 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75  fd < 0) {...retu
8c70: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
8c80: 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64  .}...fi->fh = fd
8c90: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
8ca0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
8cb0: 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65  fs_fuse_truncate
8cc0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8cd0: 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b  h, off_t size) {
8ce0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
8cf0: 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65  h;..int truncate
8d00: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
8d10: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
8d20: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
8d30: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68  th);...real_path
8d40: 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61   = appfs_localpa
8d50: 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  th(path);..if (r
8d60: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
8d70: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
8d80: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67  O);..}...appfs_g
8d90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
8da0: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66  he_rm(path, appf
8db0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
8dc0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
8dd0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
8de0: 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74  ;...truncate_ret
8df0: 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c   = truncate(real
8e00: 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09  _path, size);...
8e10: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8e20: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
8e30: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
8e40: 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74  );...if (truncat
8e50: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  e_ret != 0) {...
8e60: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
8e70: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
8e80: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
8e90: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c  t appfs_fuse_unl
8ea0: 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20  ink_rmdir(const 
8eb0: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
8ec0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
8ed0: 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  p;..int tcl_ret;
8ee0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8ef0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
8f00: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
8f10: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
8f20: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
8f30: 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  h(appfs_get_fsui
8f40: 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65  d(), -1);...inte
8f50: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
8f60: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
8f70: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
8f80: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
8f90: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
8fa0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
8fb0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
8fc0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
8fd0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
8fe0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c  2, "::appfs::unl
8ff0: 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b  inkpath", path);
9000: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
9010: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
9020: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
9030: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73  s::unlinkpath(%s
9040: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
9050: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
9060: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
9070: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
9080: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
9090: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
90a0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
90b0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
90c0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
90d0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
90e0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
90f0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
9100: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
9110: 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30  rp);)...return(0
9120: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9130: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69   appfs_fuse_mkdi
9140: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
9150: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29  th, mode_t mode)
9160: 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70   {..char *real_p
9170: 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f  ath;..int mkdir_
9180: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
9190: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
91a0: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
91b0: 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  h);...real_path 
91c0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
91d0: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
91e0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
91f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
9200: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
9210: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
9220: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
9230: 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b  ..mkdir_ret = mk
9240: 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  dir(real_path, m
9250: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
9260: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
9270: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
9280: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
9290: 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20 30 29  (mkdir_ret != 0)
92a0: 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f 20 21   {...if (errno !
92b0: 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09 09 72  = EEXIST) {....r
92c0: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
92d0: 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75  );...}..}...retu
92e0: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
92f0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
9300: 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61 72  chmod(const char
9310: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d   *path, mode_t m
9320: 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ode) {..Tcl_Inte
9330: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e  rp *interp;..con
9340: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
9350: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  th;..int tcl_ret
9360: 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41  , chmod_ret;...A
9370: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9380: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
9390: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70  .)", path);...ap
93a0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
93b0: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c  o_cache_rm(path,
93c0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
93d0: 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ());...interp = 
93e0: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
93f0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
9400: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9410: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9420: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
9430: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
9440: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65  terp);)...tcl_re
9450: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
9460: 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a  al(interp, 3, ":
9470: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
9480: 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22  ", path, "write"
9490: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
94a0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
94b0: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
94c0: 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73  pfs::openpath(%s
94d0: 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  , %s) failed.", 
94e0: 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a  path, "write");.
94f0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
9500: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
9510: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
9520: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
9530: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
9540: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
9550: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
9560: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
9570: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p);)....return(-
9580: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
9590: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
95a0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f  real_path = Tcl_
95b0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
95c0: 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70  interp);..)...ap
95d0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
95e0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
95f0: 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c  rp);)...if (real
9600: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
9610: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9620: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
9630: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
9640: 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65  er();...chmod_re
9650: 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f 70  t = chmod(real_p
9660: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
9670: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
9680: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
9690: 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65 74  return(chmod_ret
96a0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
96b0: 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d 6c   appfs_fuse_syml
96c0: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
96d0: 6f 6c 64 70 61 74 68 2c 20 63 6f 6e 73 74 20 63  oldpath, const c
96e0: 68 61 72 20 2a 6e 65 77 70 61 74 68 29 20 7b 0a  har *newpath) {.
96f0: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
9700: 3b 0a 09 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f 72  ;..int symlink_r
9710: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
9720: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
9730: 20 25 73 2c 20 25 73 29 22 2c 20 6f 6c 64 70 61   %s, %s)", oldpa
9740: 74 68 2c 20 6e 65 77 70 61 74 68 29 3b 0a 0a 09  th, newpath);...
9750: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
9760: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
9770: 61 74 65 28 6e 65 77 70 61 74 68 29 3b 0a 09 69  ate(newpath);..i
9780: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
9790: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
97a0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
97b0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
97c0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 73  _fs_enter();...s
97d0: 79 6d 6c 69 6e 6b 5f 72 65 74 20 3d 20 73 79 6d  ymlink_ret = sym
97e0: 6c 69 6e 6b 28 6f 6c 64 70 61 74 68 2c 20 72 65  link(oldpath, re
97f0: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  al_path);...appf
9800: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9810: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
9820: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
9830: 09 69 66 20 28 73 79 6d 6c 69 6e 6b 5f 72 65 74  .if (symlink_ret
9840: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
9850: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
9860: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
9870: 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20  ../*. * SQLite3 
9880: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61  mode: Execute ra
9890: 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e  w SQL and return
98a0: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c   success or fail
98b0: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ure. */.static i
98c0: 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33  nt appfs_sqlite3
98d0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c  (const char *sql
98e0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
98f0: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
9900: 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09  char *sql_ret;..
9910: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
9920: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
9930: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e  eate_TclInterp(N
9940: 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  ULL);..if (inter
9950: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  p == NULL) {...f
9960: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
9970: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
9980: 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74   a Tcl interpret
9990: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
99a0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
99b0: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
99c0: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
99d0: 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70  interp, 5, "::ap
99e0: 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22  pfs::db", "eval"
99f0: 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75  , sql, "row", "u
9a00: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
9a10: 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20   row(*); parray 
9a20: 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d  row; puts \"----
9a30: 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d  \"");..sql_ret =
9a40: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
9a50: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
9a60: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
9a70: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
9a80: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72  tf(stderr, "[err
9a90: 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72  or] %s\n", sql_r
9aa0: 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  et);....return(1
9ab0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f  );..}...if (sql_
9ac0: 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30  ret && sql_ret[0
9ad0: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
9ae0: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71  rintf("%s\n", sq
9af0: 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74  l_ret);..}...ret
9b00: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  urn(0);.}../*. *
9b10: 20 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75   Tcl mode: Execu
9b20: 74 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72  te raw Tcl and r
9b30: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72  eturn success or
9b40: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61   failure. */.sta
9b50: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63  tic int appfs_tc
9b60: 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63  l(const char *tc
9b70: 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  l) {..Tcl_Interp
9b80: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
9b90: 20 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c   char *tcl_resul
9ba0: 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  t;..int tcl_ret;
9bb0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
9bc0: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
9bd0: 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69  rp(NULL);..if (i
9be0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
9bf0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
9c00: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  r, "Unable to cr
9c10: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
9c20: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e  preter.  Abortin
9c30: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72  g.\n");....retur
9c40: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  n(1);..}...tcl_r
9c50: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
9c60: 74 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c  terp, tcl);..tcl
9c70: 5f 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65  _result = Tcl_Ge
9c80: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
9c90: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c  terp);...if (tcl
9ca0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
9cb0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
9cc0: 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c  rr, "[error] %s\
9cd0: 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69  n", Tcl_GetVar(i
9ce0: 6e 74 65 72 70 2c 20 22 65 72 72 6f 72 49 6e 66  nterp, "errorInf
9cf0: 6f 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  o", TCL_GLOBAL_O
9d00: 4e 4c 59 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  NLY));....return
9d10: 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63  (1);..}...if (tc
9d20: 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f  l_result && tcl_
9d30: 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30  result[0] != '\0
9d40: 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25  ') {...printf("%
9d50: 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74  s\n", tcl_result
9d60: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
9d70: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46  );.}../*. * AppF
9d80: 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54  Sd Package for T
9d90: 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42  cl:. *         B
9da0: 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70  ridge for I/O op
9db0: 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75  erations to requ
9dc0: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  est information 
9dd0: 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e  about the curren
9de0: 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61  t. *         tra
9df0: 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a  nsaction. */./*.
9e00: 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65   * Tcl interface
9e10: 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65   to get the home
9e20: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74   directory for t
9e30: 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74  he user making t
9e40: 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20  he "current". * 
9e50: 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74  FUSE I/O request
9e60: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
9e70: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
9e80: 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61  medir(ClientData
9e90: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
9ea0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
9eb0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
9ec0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61  T objv[]) {..cha
9ed0: 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c  r *homedir;..Tcl
9ee0: 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62  _Obj *homedir_ob
9ef0: 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b  j;..uid_t fsuid;
9f00: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61  ..static __threa
9f10: 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f  d Tcl_Obj *last_
9f20: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55  homedir_obj = NU
9f30: 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  LL;..static __th
9f40: 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f  read uid_t last_
9f50: 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20  fsuid = -1;..   
9f60: 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d       if (objc !=
9f70: 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20   1) {.          
9f80: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e        Tcl_WrongN
9f90: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
9fa0: 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20  , objv, NULL);. 
9fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
9fc0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
9fd0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73  ;.        }...fs
9fe0: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  uid = appfs_get_
9ff0: 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66  fsuid();...if (f
a000: 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75  suid == last_fsu
a010: 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64  id && last_homed
a020: 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20  ir_obj != NULL) 
a030: 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  {...homedir_obj 
a040: 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  = last_homedir_o
a050: 62 6a 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52  bj;....Tcl_IncrR
a060: 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f  efCount(homedir_
a070: 6f 62 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  obj);..} else {.
a080: 09 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66  ..homedir = appf
a090: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70  s_get_homedir(ap
a0a0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
a0b0: 3b 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72  ;....if (homedir
a0c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72   == NULL) {....r
a0d0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
a0e0: 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72  ;...}....homedir
a0f0: 5f 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74  _obj = Tcl_NewSt
a100: 72 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c  ringObj(homedir,
a110: 20 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f   -1);....free(ho
a120: 6d 65 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f 49  medir);....Tcl_I
a130: 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65  ncrRefCount(home
a140: 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66 20  dir_obj);....if 
a150: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  (last_homedir_ob
a160: 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  j != NULL) {....
a170: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
a180: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  (last_homedir_ob
a190: 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f  j);...}....last_
a1a0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f  homedir_obj = ho
a1b0: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73  medir_obj;...las
a1c0: 74 5f 66 73 75 69 64 20 3d 20 66 73 75 69 64 3b  t_fsuid = fsuid;
a1d0: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
a1e0: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a  ount(homedir_obj
a1f0: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
a200: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
a210: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
a220: 6f 62 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63 72  obj);...Tcl_Decr
a230: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72  RefCount(homedir
a240: 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20  _obj);..        
a250: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
a260: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
a270: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
a280: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43  _user_fs_enter(C
a290: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a2a0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a2b0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a2c0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a2d0: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
a2e0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
a2f0: 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  er();...return(T
a300: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
a310: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
a320: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
a330: 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74  _leave(ClientDat
a340: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
a350: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
a360: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
a370: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
a380: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
a390: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
a3a0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
a3b0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
a3c0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
a3d0: 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  d(ClientData cd,
a3e0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
a3f0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
a400: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
a410: 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66  jv[]) {..uid_t f
a420: 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20  suid;...fsuid = 
a430: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
a440: 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f  );..       .Tcl_
a450: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
a460: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65  erp, Tcl_NewWide
a470: 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a  IntObj(fsuid));.
a480: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
a490: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a4a0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73  tcl_appfs_get_fs
a4b0: 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63  gid(ClientData c
a4c0: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
a4d0: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
a4e0: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
a4f0: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74  objv[]) {..gid_t
a500: 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20   fsgid;...fsgid 
a510: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
a520: 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63  d();..       .Tc
a530: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
a540: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69  nterp, Tcl_NewWi
a550: 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29  deIntObj(fsgid))
a560: 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f  ;...return(TCL_O
a570: 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  K);.}..static in
a580: 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f  t tcl_appfs_get_
a590: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
a5a0: 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61  flush(ClientData
a5b0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
a5c0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
a5d0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
a5e0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74  T objv[]) {..int
a5f0: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e   tcl_ret;..int n
a600: 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73  ew_size;...new_s
a610: 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28  ize = -1;...if (
a620: 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74  objc == 2) {...t
a630: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
a640: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
a650: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77  p, objv[1], &new
a660: 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63  _size);...if (tc
a670: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
a680: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c   {....return(tcl
a690: 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c  _ret);...}..} el
a6a0: 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20  se if (objc > 2 
a6b0: 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20  || objc < 1) {. 
a6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
a6d0: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
a6e0: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
a6f0: 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a   "?new_cache_siz
a700: 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54  e?");...return(T
a710: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
a720: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
a730: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
a740: 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a  -1, new_size);..
a750: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
a760: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41  .}..static int A
a770: 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49  ppfsd_Init(Tcl_I
a780: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b  nterp *interp) {
a790: 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f  .#ifdef USE_TCL_
a7a0: 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49  STUBS..if (Tcl_I
a7b0: 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c  nitStubs(interp,
a7c0: 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29   TCL_VERSION, 0)
a7d0: 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75   == 0L) {...retu
a7e0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
a7f0: 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43  }.#endif...Tcl_C
a800: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
a810: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
a820: 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74  :get_homedir", t
a830: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
a840: 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  edir, NULL, NULL
a850: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
a860: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
a870: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73   "appfsd::get_fs
a880: 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  uid", tcl_appfs_
a890: 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c  get_fsuid, NULL,
a8a0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
a8b0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
a8c0: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67  terp, "appfsd::g
a8d0: 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61  et_fsgid", tcl_a
a8e0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20  ppfs_get_fsgid, 
a8f0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
a900: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
a910: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
a920: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
a930: 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c  r_fs_enter", tcl
a940: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
a950: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e  user_fs_enter, N
a960: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
a970: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
a980: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
a990: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  d::simulate_user
a9a0: 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f  _fs_leave", tcl_
a9b0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
a9c0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55  ser_fs_leave, NU
a9d0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
a9e0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
a9f0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
aa00: 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  ::get_path_info_
aa10: 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63  cache_flush", tc
aa20: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  l_appfs_get_path
aa30: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
aa40: 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  h, NULL, NULL);.
aa50: 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65  ..Tcl_PkgProvide
aa60: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
aa70: 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74  ", "1.0");...ret
aa80: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
aa90: 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72  /*. * Hot-restar
aaa0: 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a  t support. */./*
aab0: 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d   Initiate a hot-
aac0: 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69  restart */.stati
aad0: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74  c void appfs_hot
aae0: 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b  _restart(void) {
aaf0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41  ..APPFS_DEBUG("A
ab00: 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65  sked to initiate
ab10: 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a   hot restart");.
ab20: 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65  ..appfs_tcl_Rese
ab30: 74 49 6e 74 65 72 70 73 28 29 3b 0a 0a 09 61 70  tInterps();...ap
ab40: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
ab50: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31  o_cache_flush(-1
ab60: 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  , -1);...return;
ab70: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c  .}../*. * Signal
ab80: 20 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20   handler. *     
ab90: 20 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69      SIGHUP initi
aba0: 61 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61  ates a hot resta
abb0: 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rt. */.static vo
abc0: 69 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f  id appfs_signal_
abd0: 68 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29  handler(int sig)
abe0: 20 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61   {../* Do not ha
abf0: 6e 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74  ndle signals unt
ac00: 69 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e  il FUSE has been
ac10: 20 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20   started */..if 
ac20: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
ac30: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
ac40: 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73  ;..}.../* Reques
ac50: 74 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22  t to perform a "
ac60: 68 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a  hot" restart */.
ac70: 09 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48  .if (sig == SIGH
ac80: 55 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f  UP) {...appfs_ho
ac90: 74 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a  t_restart();..}.
aca0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
acb0: 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74   * Terminate a t
acc0: 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63  hread. */.static
acd0: 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d   void appfs_term
ace0: 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64  inate_interp_and
acf0: 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a 5f 69  _thread(void *_i
ad00: 6e 74 65 72 70 29 20 7b 0a 09 54 63 6c 5f 49 6e  nterp) {..Tcl_In
ad10: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 0a 09  terp *interp;...
ad20: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 6c  APPFS_DEBUG("Cal
ad30: 6c 65 64 3a 20 5f 69 6e 74 65 72 70 20 3d 20 25  led: _interp = %
ad40: 70 22 2c 20 5f 69 6e 74 65 72 70 29 3b 0a 0a 09  p", _interp);...
ad50: 69 66 20 28 5f 69 6e 74 65 72 70 20 3d 3d 20 4e  if (_interp == N
ad60: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
ad70: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
ad80: 67 20 74 68 72 65 61 64 20 77 69 74 68 20 6e 6f  g thread with no
ad90: 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a   interpreter");.
ada0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
adb0: 69 6e 74 65 72 70 20 3d 20 5f 69 6e 74 65 72 70  interp = _interp
adc0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
add0: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 69 6e 74  "Terminating int
ade0: 65 72 70 72 65 74 65 72 20 64 75 65 20 74 6f 20  erpreter due to 
adf0: 74 68 72 65 61 64 20 74 65 72 6d 69 6e 61 74 69  thread terminati
ae00: 6f 6e 22 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61  on");...appfs_ca
ae10: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c  ll_libtcl(...Tcl
ae20: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
ae30: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66  terp);..)...appf
ae40: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
ae50: 09 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 54 68 72  .Tcl_FinalizeThr
ae60: 65 61 64 28 29 3b 0a 09 29 0a 0a 09 72 65 74 75  ead();..)...retu
ae70: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d  rn;.}../*. * Com
ae80: 6d 61 6e 64 2d 6c 69 6e 65 20 70 61 72 73 69 6e  mand-line parsin
ae90: 67 20 74 6f 6f 6c 73 0a 20 2a 2f 0a 73 74 61 74  g tools. */.stat
aea0: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 70 72  ic void appfs_pr
aeb0: 69 6e 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a 63  int_help(FILE *c
aec0: 68 61 6e 6e 65 6c 29 20 7b 0a 09 66 70 72 69 6e  hannel) {..fprin
aed0: 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 55 73 61  tf(channel, "Usa
aee0: 67 65 3a 20 7b 61 70 70 66 73 64 7c 6d 6f 75 6e  ge: {appfsd|moun
aef0: 74 2e 61 70 70 66 73 7d 20 5b 2d 6f 20 3c 6f 70  t.appfs} [-o <op
af00: 74 69 6f 6e 3e 5d 20 5b 2d 64 66 73 68 5d 20 3c  tion>] [-dfsh] <
af10: 63 61 63 68 65 64 69 72 3e 20 3c 6d 6f 75 6e 74  cachedir> <mount
af20: 70 6f 69 6e 74 3e 5c 6e 22 29 3b 0a 09 66 70 72  point>\n");..fpr
af30: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 5c  intf(channel, "\
af40: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
af50: 61 6e 6e 65 6c 2c 20 22 4f 70 74 69 6f 6e 73 3a  annel, "Options:
af60: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
af70: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 64 20 20 20  hannel, "  -d   
af80: 20 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c             Enabl
af90: 65 20 46 55 53 45 20 64 65 62 75 67 20 6d 6f 64  e FUSE debug mod
afa0: 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66  e.\n");..fprintf
afb0: 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 66 20  (channel, "  -f 
afc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 52 75 6e               Run
afd0: 20 69 6e 20 66 6f 72 65 67 72 6f 75 6e 64 2e 5c   in foreground.\
afe0: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
aff0: 61 6e 6e 65 6c 2c 20 22 20 20 2d 73 20 20 20 20  annel, "  -s    
b000: 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c 65            Enable
b010: 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64   single threaded
b020: 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72   mode.\n");..fpr
b030: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20  intf(channel, " 
b040: 20 2d 68 20 20 20 20 20 20 20 20 20 20 20 20 20   -h             
b050: 20 47 69 76 65 20 74 68 69 73 20 68 65 6c 70 2e   Give this help.
b060: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b070: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 6e 6f  hannel, "  -o no
b080: 74 68 72 65 61 64 73 20 20 20 20 45 6e 61 62 6c  threads    Enabl
b090: 65 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65  e single threade
b0a0: 64 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70  d mode.\n");..fp
b0b0: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b0c0: 20 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68 65 72    -o allow_other
b0d0: 20 20 41 6c 6c 6f 77 20 6f 74 68 65 72 20 75 73    Allow other us
b0e0: 65 72 73 20 74 6f 20 61 63 63 65 73 73 20 74 68  ers to access th
b0f0: 69 73 20 6d 6f 75 6e 74 70 6f 69 6e 74 20 28 64  is mountpoint (d
b100: 65 66 61 75 6c 74 5c 6e 22 29 3b 0a 09 66 70 72  efault\n");..fpr
b110: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20  intf(channel, " 
b120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b130: 20 69 66 20 72 6f 6f 74 29 2e 5c 6e 22 29 3b 0a   if root).\n");.
b140: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61  ..return;.}..sta
b150: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 6f 70  tic int appfs_op
b160: 74 5f 70 61 72 73 65 28 69 6e 74 20 61 72 67 63  t_parse(int argc
b170: 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 20 20  , char **argv,  
b180: 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73  struct fuse_args
b190: 20 2a 61 72 67 73 29 20 7b 0a 09 69 6e 74 20 63   *args) {..int c
b1a0: 68 3b 0a 09 63 68 61 72 20 2a 6f 70 74 73 74 72  h;..char *optstr
b1b0: 2c 20 2a 6f 70 74 73 74 72 5f 6e 65 78 74 2c 20  , *optstr_next, 
b1c0: 2a 6f 70 74 73 74 72 5f 73 3b 0a 09 63 68 61 72  *optstr_s;..char
b1d0: 20 66 61 6b 65 5f 61 72 67 5b 33 5d 20 3d 20 7b   fake_arg[3] = {
b1e0: 27 2d 27 2c 20 30 2c 20 30 7d 3b 0a 0a 09 2f 2a  '-', 0, 0};.../*
b1f0: 0a 09 20 2a 20 44 65 66 61 75 6c 74 20 76 61 6c  .. * Default val
b200: 75 65 73 0a 09 20 2a 2f 0a 23 69 66 64 65 66 20  ues.. */.#ifdef 
b210: 54 43 4c 5f 54 48 52 45 41 44 53 0a 09 61 70 70  TCL_THREADS..app
b220: 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20  fs_threaded_tcl 
b230: 3d 20 31 3b 0a 23 65 6c 73 65 0a 09 61 70 70 66  = 1;.#else..appf
b240: 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d  s_threaded_tcl =
b250: 20 30 3b 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a 2a   0;.#endif.../**
b260: 0a 09 20 2a 2a 20 41 64 64 20 46 55 53 45 20 61  .. ** Add FUSE a
b270: 72 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20 77  rguments which w
b280: 65 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79 0a  e always supply.
b290: 09 20 2a 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f  . **/..fuse_opt_
b2a0: 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d  add_arg(args, "-
b2b0: 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73  odefault_permiss
b2c0: 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66  ions,fsname=appf
b2d0: 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73 64  s,subtype=appfsd
b2e0: 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f  ,use_ino,kernel_
b2f0: 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65  cache,entry_time
b300: 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d 65 6f  out=0,attr_timeo
b310: 75 74 3d 30 2c 62 69 67 5f 77 72 69 74 65 73 2c  ut=0,big_writes,
b320: 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d 6f 76 65  intr,hard_remove
b330: 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75 69 64  ");...if (getuid
b340: 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66 75 73  () == 0) {...fus
b350: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
b360: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
b370: 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f  LL);...fuse_opt_
b380: 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d  add_arg(args, "-
b390: 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a  oallow_other");.
b3a0: 09 7d 0a 0a 09 77 68 69 6c 65 20 28 28 63 68 20  .}...while ((ch 
b3b0: 3d 20 67 65 74 6f 70 74 28 61 72 67 63 2c 20 61  = getopt(argc, a
b3c0: 72 67 76 2c 20 22 64 66 73 68 6f 3a 22 29 29 20  rgv, "dfsho:")) 
b3d0: 21 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63  != -1) {...switc
b3e0: 68 20 28 63 68 29 20 7b 0a 09 09 09 63 61 73 65  h (ch) {....case
b3f0: 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73 74 72   'o':.....optstr
b400: 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72 20 3d  _next = optstr =
b410: 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74 72 64   optstr_s = strd
b420: 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09 09 09  up(optarg);.....
b430: 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09  .while (1) {....
b440: 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74  ..optstr = optst
b450: 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09 69 66  r_next;.......if
b460: 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09 09 09   (!optstr) {....
b470: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 7d  ...break;......}
b480: 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65  .......optstr_ne
b490: 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70 74 73  xt = strchr(opts
b4a0: 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09 09 69  tr, ',');......i
b4b0: 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74 29 20  f (optstr_next) 
b4c0: 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74 72 5f  {.......*optstr_
b4d0: 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09 09 09  next = '\0';....
b4e0: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 2b 2b  ...optstr_next++
b4f0: 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 69  ;......}.......i
b500: 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72  f (strcmp(optstr
b510: 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29 20 3d  , "nothreads") =
b520: 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41 50 50  = 0) {.......APP
b530: 46 53 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e  FS_DEBUG("Passin
b540: 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45  g option to FUSE
b550: 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09 66  : -s");........f
b560: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
b570: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
b580: 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73  NULL);.......fus
b590: 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72  e_opt_add_arg(ar
b5a0: 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09 09 09  gs, "-s");......
b5b0: 09 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64  ..appfs_threaded
b5c0: 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 09 7d  _tcl = 0;......}
b5d0: 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d 70   else if (strcmp
b5e0: 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f 77 5f  (optstr, "allow_
b5f0: 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20 7b 0a  other") == 0) {.
b600: 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55  ......APPFS_DEBU
b610: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f  G("Passing optio
b620: 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20 61 6c  n to FUSE: -o al
b630: 6c 6f 77 5f 4f 74 68 65 72 22 29 3b 0a 0a 09 09  low_Other");....
b640: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72  ....fuse_opt_par
b650: 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e  se(args, NULL, N
b660: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09  ULL, NULL);.....
b670: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
b680: 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f  rg(args, "-oallo
b690: 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09 09 09  w_other");......
b6a0: 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d  } else if (strcm
b6b0: 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22 29 20  p(optstr, "rw") 
b6c0: 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 2f 2a  == 0) {......./*
b6d0: 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09 09   Ignored */.....
b6e0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09  .} else {.......
b6f0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
b700: 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c 69 64  "appfsd: invalid
b710: 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20 25 73   option: \"-o %s
b720: 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29 3b 0a  \"\n", optstr);.
b730: 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70 74 73  .......free(opts
b740: 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09 72 65  tr_s);........re
b750: 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09 7d 0a  turn(1);......}.
b760: 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28  ....}......free(
b770: 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09  optstr_s);......
b780: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
b790: 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66 27 3a  d':....case 'f':
b7a0: 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a 09 09  ....case 's':...
b7b0: 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73 27 29  ..if (ch == 's')
b7c0: 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f 74 68   {......appfs_th
b7d0: 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a  readed_tcl = 0;.
b7e0: 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b 65 5f  ....}......fake_
b7f0: 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a 09 09  arg[1] = ch;....
b800: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50  ..APPFS_DEBUG("P
b810: 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f  assing option to
b820: 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61 6b 65   FUSE: %s", fake
b830: 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75 73 65  _arg);......fuse
b840: 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c  _opt_parse(args,
b850: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c   NULL, NULL, NUL
b860: 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f 70 74  L);.....fuse_opt
b870: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 66  _add_arg(args, f
b880: 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09 62 72  ake_arg);.....br
b890: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 68 27  eak;....case 'h'
b8a0: 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72 69 6e  :.....appfs_prin
b8b0: 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29 3b 0a  t_help(stdout);.
b8c0: 0a 09 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  .....return(0);.
b8d0: 09 09 09 63 61 73 65 20 27 3a 27 3a 0a 09 09 09  ...case ':':....
b8e0: 63 61 73 65 20 27 3f 27 3a 0a 09 09 09 64 65 66  case '?':....def
b8f0: 61 75 6c 74 3a 0a 09 09 09 09 61 70 70 66 73 5f  ault:.....appfs_
b900: 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72  print_help(stder
b910: 72 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28  r);......return(
b920: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20  1);...}..}...if 
b930: 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 21 3d  ((optind + 2) !=
b940: 20 61 72 67 63 29 20 7b 0a 09 09 69 66 20 28 28   argc) {...if ((
b950: 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c 20 61 72  optind + 2) < ar
b960: 67 63 29 20 7b 0a 09 09 09 66 70 72 69 6e 74 66  gc) {....fprintf
b970: 28 73 74 64 65 72 72 2c 20 22 54 6f 6f 20 6d 61  (stderr, "Too ma
b980: 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c 6e 22 29  ny arguments\n")
b990: 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ;...} else {....
b9a0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
b9b0: 22 4d 69 73 73 69 6e 67 20 63 61 63 68 65 64 69  "Missing cachedi
b9c0: 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69 6e 74 5c  r or mountpoint\
b9d0: 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61 70 70 66  n");...}....appf
b9e0: 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64  s_print_help(std
b9f0: 65 72 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  err);....return(
ba00: 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  1);..}.../*.. * 
ba10: 53 65 74 20 63 61 63 68 65 20 64 69 72 20 61 73  Set cache dir as
ba20: 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20   first argument 
ba30: 28 74 68 65 20 22 64 65 76 69 63 65 22 2c 20 65  (the "device", e
ba40: 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09 20 2a 2f  ssentially).. */
ba50: 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
ba60: 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e 64 5d 3b   = argv[optind];
ba70: 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73 73 20 74  .../*.. * Pass t
ba80: 68 65 20 72 65 6d 61 69 6e 69 6e 67 20 61 72 67  he remaining arg
ba90: 75 6d 65 6e 74 20 74 6f 20 46 55 53 45 20 61 73  ument to FUSE as
baa0: 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 0a 09   the directory..
bab0: 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61   */..fuse_opt_pa
bac0: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20  rse(args, NULL, 
bad0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 66 75  NULL, NULL);..fu
bae0: 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61  se_opt_add_arg(a
baf0: 72 67 73 2c 20 61 72 67 76 5b 6f 70 74 69 6e 64  rgs, argv[optind
bb00: 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74 75 72 6e   + 1]);...return
bb10: 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a 20 46  (0);.}.../*. * F
bb20: 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 73  USE operations s
bb30: 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73 74 61  tructure. */.sta
bb40: 74 69 63 20 73 74 72 75 63 74 20 66 75 73 65 5f  tic struct fuse_
bb50: 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70 66 73  operations appfs
bb60: 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20 7b 0a  _operations = {.
bb70: 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20 61 70  ..getattr   = ap
bb80: 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72  pfs_fuse_getattr
bb90: 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20 3d 20  ,...readdir   = 
bba0: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64  appfs_fuse_readd
bbb0: 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b 20 20  ir,...readlink  
bbc0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
bbd0: 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20  dlink,...open   
bbe0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
bbf0: 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73 65 20  open,...release 
bc00: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63    = appfs_fuse_c
bc10: 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20 20 20  lose,...read    
bc20: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
bc30: 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20 20 20  ead,...write    
bc40: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72   = appfs_fuse_wr
bc50: 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20  ite,...mknod    
bc60: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b   = appfs_fuse_mk
bc70: 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20 20 20  nod,...create   
bc80: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72   = appfs_fuse_cr
bc90: 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61 74 65  eate,...truncate
bca0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 74    = appfs_fuse_t
bcb0: 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e  runcate,...unlin
bcc0: 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  k    = appfs_fus
bcd0: 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a  e_unlink_rmdir,.
bce0: 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20 61 70  ..rmdir     = ap
bcf0: 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f  pfs_fuse_unlink_
bd00: 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72 20 20  rmdir,...mkdir  
bd10: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
bd20: 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64 20 20  mkdir,...chmod  
bd30: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
bd40: 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e 6b  chmod,...symlink
bd50: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
bd60: 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f 2a 0a  symlink,.};../*.
bd70: 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20 69   * Entry point i
bd80: 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61 6d  nto this program
bd90: 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69  .. */.int main(i
bda0: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
bdb0: 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  argv) {..Tcl_Int
bdc0: 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72 70  erp *test_interp
bdd0: 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69 6e  ;..char *test_in
bde0: 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72  terp_error;..str
bdf0: 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61 72  uct fuse_args ar
be00: 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f 49  gs = FUSE_ARGS_I
be10: 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b 0a 09 69  NIT(0, NULL);..i
be20: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 2c 20  nt pthread_ret, 
be30: 61 6f 70 5f 72 65 74 3b 0a 09 76 6f 69 64 20 2a  aop_ret;..void *
be40: 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63 68 61  signal_ret;..cha
be50: 72 20 2a 61 72 67 76 30 3b 0a 0a 09 2f 2a 0a 09  r *argv0;.../*..
be60: 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20 70   * Skip passed p
be70: 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f  rogram name.. */
be80: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30 20  ..if (argc == 0 
be90: 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c 29  || argv == NULL)
bea0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a   {...return(1);.
beb0: 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61 72 67  .}...argv0 = arg
bec0: 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b 0a  v[0];...argc--;.
bed0: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20  .argv++;.../*.. 
bee0: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
bef0: 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68  iables, these sh
bf00: 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72  ould be configur
bf10: 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09  ation options...
bf20: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65   */..appfs_cache
bf30: 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48  dir = APPFS_CACH
bf40: 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  EDIR;.../*.. * S
bf50: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  et global variab
bf60: 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d  le for "boot tim
bf70: 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65  e" to set a time
bf80: 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a   on directories.
bf90: 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65  . * that we fake
bfa0: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f  ... */..appfs_bo
bfb0: 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55  ottime = time(NU
bfc0: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65  LL);.../*.. * Re
bfd0: 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e  gister "sha1" an
bfe0: 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61  d "appfsd" packa
bff0: 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73  ge with libtcl s
c000: 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09  o that any new..
c010: 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20   * interpreters 
c020: 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61  created (which a
c030: 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61  re done dynamica
c040: 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e  lly by FUSE) can
c050: 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70   have.. * the ap
c060: 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67  propriate config
c070: 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74  uration done aut
c080: 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f  omatically... */
c090: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b  ..Tcl_StaticPack
c0a0: 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22  age(NULL, "sha1"
c0b0: 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c  , Sha1_Init, NUL
c0c0: 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50  L);..Tcl_StaticP
c0d0: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70  ackage(NULL, "ap
c0e0: 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e  pfsd", Appfsd_In
c0f0: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a  it, NULL);.../*.
c100: 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72  . * Create a thr
c110: 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74  ead-specific-dat
c120: 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20  a (TSD) key for 
c130: 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72  each thread to r
c140: 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20  efer.. * to its 
c150: 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65  own Tcl interpre
c160: 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70  ter.  Tcl interp
c170: 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75  reters must be u
c180: 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68  nique per.. * th
c190: 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72  read and new thr
c1a0: 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63  eads are dynamic
c1b0: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20  ally created by 
c1c0: 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72  FUSE... */..pthr
c1d0: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
c1e0: 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e  d_key_create(&in
c1f0: 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74  terpKey, appfs_t
c200: 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f  erminate_interp_
c210: 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09 69 66  and_thread);..if
c220: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
c230: 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28   0) {...fprintf(
c240: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
c250: 74 6f 20 63 72 65 61 74 65 20 54 53 44 20 6b 65  to create TSD ke
c260: 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72  y for Tcl.  Abor
c270: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65  ting.\n");....re
c280: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a  turn(1);..}.../*
c290: 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70  .. * Manually sp
c2a0: 65 63 69 66 79 20 63 61 63 68 65 20 64 69 72 65  ecify cache dire
c2b0: 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74 20 46  ctory, without F
c2c0: 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a  USE callback.. *
c2d0: 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c   This option onl
c2e0: 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74  y works when not
c2f0: 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73 69 6e   using FUSE, sin
c300: 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74  ce we.. * do not
c310: 20 70 72 6f 63 65 73 73 20 69 74 20 77 69 74 68   process it with
c320: 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20 70 72   FUSEs option pr
c330: 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09  ocessing... */..
c340: 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29 20 7b  if (argc >= 2) {
c350: 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28 61 72  ...if (strcmp(ar
c360: 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64  gv[0], "--cached
c370: 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09  ir") == 0) {....
c380: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d  appfs_cachedir =
c390: 20 73 74 72 64 75 70 28 61 72 67 76 5b 31 5d 29   strdup(argv[1])
c3a0: 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20 32 3b  ;.....argc -= 2;
c3b0: 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09  ....argv += 2;..
c3c0: 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53  .}..}.../*.. * S
c3d0: 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72  QLite3 mode, for
c3e0: 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c   running raw SQL
c3f0: 20 61 67 61 69 6e 73 74 20 74 68 65 20 63 61 63   against the cac
c400: 68 65 20 64 61 74 61 62 61 73 65 0a 09 20 2a 2f  he database.. */
c410: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20  ..if (argc == 2 
c420: 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30  && strcmp(argv[0
c430: 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22 29 20  ], "--sqlite3") 
c440: 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  == 0) {...return
c450: 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28 61  (appfs_sqlite3(a
c460: 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f  rgv[1]));..}.../
c470: 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20  *.. * Tcl mode, 
c480: 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20  for running raw 
c490: 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d 65 20  Tcl in the same 
c4a0: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46  environment AppF
c4b0: 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e  Sd would.. * run
c4c0: 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20   code... */..if 
c4d0: 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20 73 74  (argc == 2 && st
c4e0: 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d  rcmp(argv[0], "-
c4f0: 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09  -tcl") == 0) {..
c500: 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f 74 63  .return(appfs_tc
c510: 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a  l(argv[1]));..}.
c520: 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74 65  ../*.. * Registe
c530: 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c  r a signal handl
c540: 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61  er for hot-resta
c550: 72 74 20 72 65 71 75 65 73 74 73 0a 09 20 2a 2f  rt requests.. */
c560: 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73  ..signal_ret = s
c570: 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20 61 70  ignal(SIGHUP, ap
c580: 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c  pfs_signal_handl
c590: 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c  er);..if (signal
c5a0: 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52 52 29  _ret == SIG_ERR)
c5b0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
c5c0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
c5d0: 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c 20 68  install signal h
c5e0: 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72  andler for hot-r
c5f0: 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09 66 70  estart\n");...fp
c600: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 48  rintf(stderr, "H
c610: 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c 6c 20  ot-restart will 
c620: 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65  not be available
c630: 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  .\n");..}.../*..
c640: 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d 61 6e 64   * Parse command
c650: 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74 73 0a   line arguments.
c660: 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 52  . */../**.. ** R
c670: 65 73 74 6f 72 65 20 61 72 67 63 2f 61 72 67 76  estore argc/argv
c680: 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20 76 61 6c   to original val
c690: 75 65 73 2c 20 72 65 70 6c 61 63 69 6e 67 20 61  ues, replacing a
c6a0: 72 67 76 5b 30 5d 20 69 6e 20 63 61 73 65 0a 09  rgv[0] in case..
c6b0: 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f 69 66 69   ** it was moifi
c6c0: 65 64 20 62 79 20 2d 2d 63 61 63 68 65 64 69 72  ed by --cachedir
c6d0: 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a 2f 0a 09   option... **/..
c6e0: 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76 2d 2d 3b  argc++;..argv--;
c6f0: 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61 72 67 76  ..argv[0] = argv
c700: 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 50 65  0;.../**.. ** Pe
c710: 72 66 6f 72 6d 20 74 68 65 20 61 72 67 75 6d 65  rform the argume
c720: 6e 74 20 70 61 72 73 69 6e 67 0a 09 20 2a 2a 2f  nt parsing.. **/
c730: 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61 70 70 66  ..aop_ret = appf
c740: 73 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 63  s_opt_parse(argc
c750: 2c 20 61 72 67 76 2c 20 26 61 72 67 73 29 3b 0a  , argv, &args);.
c760: 09 69 66 20 28 61 6f 70 5f 72 65 74 20 21 3d 20  .if (aop_ret != 
c770: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 6f  0) {...return(ao
c780: 70 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  p_ret);..}.../*.
c790: 09 20 2a 20 43 72 65 61 74 65 20 61 20 54 63 6c  . * Create a Tcl
c7a0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 6a 75 73   interpreter jus
c7b0: 74 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74  t to verify that
c7c0: 20 74 68 69 6e 67 73 20 61 72 65 20 69 6e 20 77   things are in w
c7d0: 6f 72 6b 69 6e 67 20 0a 09 20 2a 20 6f 72 64 65  orking .. * orde
c7e0: 72 20 62 65 66 6f 72 65 20 77 65 20 62 65 63 6f  r before we beco
c7f0: 6d 65 20 61 20 64 61 65 6d 6f 6e 2e 0a 09 20 2a  me a daemon... *
c800: 2f 0a 09 74 65 73 74 5f 69 6e 74 65 72 70 20 3d  /..test_interp =
c810: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63   appfs_create_Tc
c820: 6c 49 6e 74 65 72 70 28 26 74 65 73 74 5f 69 6e  lInterp(&test_in
c830: 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 09 69 66  terp_error);..if
c840: 20 28 74 65 73 74 5f 69 6e 74 65 72 70 20 3d 3d   (test_interp ==
c850: 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 66 20 28 74   NULL) {...if (t
c860: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72  est_interp_error
c870: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74   == NULL) {....t
c880: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72  est_interp_error
c890: 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20 65 72 72 6f   = "Unknown erro
c8a0: 72 22 3b 0a 09 09 7d 0a 0a 09 09 66 70 72 69 6e  r";...}....fprin
c8b0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
c8c0: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
c8d0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
c8e0: 20 66 6f 72 20 41 70 70 46 53 64 3a 5c 6e 22 29   for AppFSd:\n")
c8f0: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
c900: 72 72 2c 20 22 25 73 5c 6e 22 2c 20 74 65 73 74  rr, "%s\n", test
c910: 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a  _interp_error);.
c920: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
c930: 0a 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
c940: 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29  erp(test_interp)
c950: 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 74 68  ;...if (appfs_th
c960: 72 65 61 64 65 64 5f 74 63 6c 29 20 7b 0a 09 09  readed_tcl) {...
c970: 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69  Tcl_FinalizeNoti
c980: 66 69 65 72 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  fier(NULL);..}..
c990: 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68  ./*.. * Enter th
c9a0: 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70  e FUSE main loop
c9b0: 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72   -- this will pr
c9c0: 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65  ocess any argume
c9d0: 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72  nts.. * and star
c9e0: 74 20 73 65 72 76 69 63 69 6e 67 20 72 65 71 75  t servicing requ
c9f0: 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  ests... */..appf
ca00: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d  s_fuse_started =
ca10: 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65   1;..return(fuse
ca20: 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c  _main(args.argc,
ca30: 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70   args.argv, &app
ca40: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e  fs_operations, N
ca50: 55 4c 4c 29 29 3b 0a 7d 0a                       ULL));.}.