Hex Artifact Content

Artifact 3e9adabf4960ce704921698f92d01992f6233ab5:


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 69 6e 74  ecutable;....int
1000: 20 73 75 69 64 3b 0a 09 09 09 69 6e 74 20 77 6f   suid;....int wo
1010: 72 6c 64 61 63 63 65 73 73 69 62 6c 65 3b 0a 09  rldaccessible;..
1020: 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09  ..off_t size;...
1030: 7d 20 66 69 6c 65 3b 0a 09 09 73 74 72 75 63 74  } file;...struct
1040: 20 7b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65   {....off_t size
1050: 3b 0a 09 09 09 63 68 61 72 20 73 6f 75 72 63 65  ;....char source
1060: 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 79 6d 6c 69  [256];...} symli
1070: 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 6e 66 6f 3b  nk;..} typeinfo;
1080: 0a 0a 09 2f 2a 20 41 74 74 72 69 62 75 74 65 73  .../* Attributes
1090: 20 75 73 65 64 20 6f 6e 6c 79 20 66 6f 72 20 63   used only for c
10a0: 61 63 68 69 6e 67 20 65 6e 74 72 69 65 73 20 2a  aching entries *
10b0: 2f 0a 09 63 68 61 72 20 2a 5f 63 61 63 68 65 5f  /..char *_cache_
10c0: 70 61 74 68 3b 0a 09 75 69 64 5f 74 20 5f 63 61  path;..uid_t _ca
10d0: 63 68 65 5f 75 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a  che_uid;.};../*.
10e0: 20 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20   * Create a new 
10f0: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20  Tcl interpreter 
1100: 61 6e 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 69  and completely i
1110: 6e 69 74 69 61 6c 69 7a 65 20 69 74 0a 20 2a 2f  nitialize it. */
1120: 0a 73 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65  .static Tcl_Inte
1130: 72 70 20 2a 61 70 70 66 73 5f 63 72 65 61 74 65  rp *appfs_create
1140: 5f 54 63 6c 49 6e 74 65 72 70 28 63 68 61 72 20  _TclInterp(char 
1150: 2a 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20  **error_string) 
1160: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
1170: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f  nterp;..int tcl_
1180: 72 65 74 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  ret;..const char
1190: 20 2a 74 63 6c 5f 73 65 74 76 61 72 5f 72 65 74   *tcl_setvar_ret
11a0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
11b0: 22 43 72 65 61 74 69 6e 67 20 6e 65 77 20 54 63  "Creating new Tc
11c0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 66 6f  l interpreter fo
11d0: 72 20 54 49 44 20 3d 20 30 78 25 6c 6c 78 22 2c  r TID = 0x%llx",
11e0: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
11f0: 6c 6f 6e 67 29 20 70 74 68 72 65 61 64 5f 73 65  long) pthread_se
1200: 6c 66 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f 63  lf());...appfs_c
1210: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 69 6e  all_libtcl(...in
1220: 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65 61 74  terp = Tcl_Creat
1230: 65 49 6e 74 65 72 70 28 29 3b 0a 09 29 0a 09 69  eInterp();..)..i
1240: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
1250: 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  L) {...fprintf(s
1260: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
1270: 6f 20 63 72 65 61 74 65 20 54 63 6c 20 49 6e 74  o create Tcl Int
1280: 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74  erpreter.  Abort
1290: 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20  ing.\n");....if 
12a0: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b  (error_string) {
12b0: 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e  ....*error_strin
12c0: 67 20 3d 20 73 74 72 64 75 70 28 22 55 6e 61 62  g = strdup("Unab
12d0: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c  le to create Tcl
12e0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
12f0: 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ...}....return(N
1300: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ULL);..}...appfs
1310: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
1320: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
1330: 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  );)...appfs_call
1340: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72  _libtcl(...tcl_r
1350: 65 74 20 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e  et = Tcl_Init(in
1360: 74 65 72 70 29 3b 0a 09 29 0a 09 69 66 20 28 74  terp);..)..if (t
1370: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
1380: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
1390: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
13a0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 2e   initialize Tcl.
13b0: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
13c0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
13d0: 62 74 63 6c 28 0a 09 09 09 66 70 72 69 6e 74 66  btcl(....fprintf
13e0: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
13f0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
1400: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
1410: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
1420: 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74  ....if (error_st
1430: 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73  ring) {....appfs
1440: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1450: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
1460: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(Tcl_Get
1470: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1480: 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a  erp));....)...}.
1490: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
14a0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
14b0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50  (interp);)....AP
14c0: 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69  PFS_DEBUG("Termi
14d0: 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72  nating Tcl inter
14e0: 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70  preter.");....ap
14f0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1500: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
1510: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
1520: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1530: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1540: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20  cl(...tcl_ret = 
1550: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
1560: 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65 65 64   "package ifneed
1570: 65 64 20 73 68 61 31 20 31 2e 30 20 5b 6c 69 73  ed sha1 1.0 [lis
1580: 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61 31 5d 22  t load {} sha1]"
1590: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
15a0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
15b0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
15c0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
15d0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 53 48 41 31  tialize Tcl SHA1
15e0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
15f0: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
1600: 69 62 74 63 6c 28 0a 09 09 09 66 70 72 69 6e 74  ibtcl(....fprint
1610: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
1620: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
1630: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
1640: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
1650: 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  )....if (error_s
1660: 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66  tring) {....appf
1670: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1680: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
1690: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
16a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
16b0: 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d  terp));....)...}
16c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
16d0: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
16e0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41  e(interp);)....A
16f0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
1700: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
1710: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61  rpreter.");....a
1720: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1730: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
1740: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  p(interp);)....r
1750: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
1760: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1770: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d  tcl(...tcl_ret =
1780: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
1790: 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65 65  , "package ifnee
17a0: 64 65 64 20 61 70 70 66 73 64 20 31 2e 30 20 5b  ded appfsd 1.0 [
17b0: 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 61 70 70  list load {} app
17c0: 66 73 64 5d 22 29 3b 0a 09 29 0a 09 69 66 20 28  fsd]");..)..if (
17d0: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
17e0: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
17f0: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
1800: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
1810: 20 41 70 70 46 53 20 50 61 63 6b 61 67 65 2e 20   AppFS Package. 
1820: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
1830: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1840: 74 63 6c 28 0a 09 09 09 66 70 72 69 6e 74 66 28  tcl(....fprintf(
1850: 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72  stderr, "Tcl Err
1860: 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63  or is: %s\n", Tc
1870: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1880: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
1890: 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72  ...if (error_str
18a0: 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f  ing) {....appfs_
18b0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
18c0: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
18d0: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
18e0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
18f0: 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a  rp));....)...}..
1900: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1910: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
1920: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50  interp);)....APP
1930: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
1940: 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70  ating Tcl interp
1950: 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70  reter.");....app
1960: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
1970: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
1980: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
1990: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
19a0: 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 22 70 6b 69  /*.. * Load "pki
19b0: 2e 74 63 6c 22 20 69 6e 20 74 68 65 20 73 61 6d  .tcl" in the sam
19c0: 65 20 77 61 79 20 61 73 20 61 70 70 66 73 64 2e  e way as appfsd.
19d0: 74 63 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a  tcl (see below).
19e0: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c  . */..appfs_call
19f0: 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72 0a 09 09  _libtcl_enter...
1a00: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
1a10: 61 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69  al(interp, "".#i
1a20: 6e 63 6c 75 64 65 20 22 70 6b 69 2e 74 63 6c 2e  nclude "pki.tcl.
1a30: 68 22 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73  h"..."");..appfs
1a40: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69  _call_libtcl_exi
1a50: 74 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  t..if (tcl_ret !
1a60: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
1a70: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1a80: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1a90: 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20 41 62  ize Tcl PKI.  Ab
1aa0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
1ab0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1ac0: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
1ad0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
1ae0: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
1af0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1b00: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
1b10: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
1b20: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
1b30: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
1b40: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
1b50: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
1b60: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1b70: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
1b80: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1b90: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
1ba0: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
1bb0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
1bc0: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
1bd0: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1be0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1bf0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1c00: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
1c10: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  (NULL);..}.../*.
1c20: 09 20 2a 20 4c 6f 61 64 20 74 68 65 20 22 61 70  . * Load the "ap
1c30: 70 66 73 64 2e 74 63 6c 22 20 73 63 72 69 70 74  pfsd.tcl" script
1c40: 2c 20 77 68 69 63 68 20 69 73 20 22 63 6f 6d 70  , which is "comp
1c50: 69 6c 65 64 22 20 69 6e 74 6f 20 61 20 43 20 68  iled" into a C h
1c60: 65 61 64 65 72 0a 09 20 2a 20 73 6f 20 74 68 61  eader.. * so tha
1c70: 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 6e 65  t it does not ne
1c80: 65 64 20 74 6f 20 65 78 69 73 74 20 6f 6e 20 74  ed to exist on t
1c90: 68 65 20 66 69 6c 65 73 79 73 74 65 6d 20 61 6e  he filesystem an
1ca0: 64 20 63 61 6e 20 62 65 0a 09 20 2a 20 64 69 72  d can be.. * dir
1cb0: 65 63 74 6c 79 20 65 76 61 6c 75 61 74 65 64 2e  ectly evaluated.
1cc0: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c  .. */..appfs_cal
1cd0: 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72 0a 09  l_libtcl_enter..
1ce0: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
1cf0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23  val(interp, "".#
1d00: 69 6e 63 6c 75 64 65 20 22 61 70 70 66 73 64 2e  include "appfsd.
1d10: 74 63 6c 2e 68 22 0a 09 09 22 22 29 3b 0a 09 61  tcl.h"..."");..a
1d20: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1d30: 5f 65 78 69 74 0a 09 69 66 20 28 74 63 6c 5f 72  _exit..if (tcl_r
1d40: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
1d50: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1d60: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
1d70: 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46  tialize Tcl AppF
1d80: 53 20 73 63 72 69 70 74 2e 20 20 41 62 6f 72 74  S script.  Abort
1d90: 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66  ing.\n");...appf
1da0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1db0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1dc0: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
1dd0: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
1de0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1df0: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20  rp));...)....if 
1e00: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b  (error_string) {
1e10: 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
1e20: 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f  ibtcl(.....*erro
1e30: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
1e40: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
1e50: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1e60: 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66  ...)...}....appf
1e70: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
1e80: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
1e90: 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42  );)....APPFS_DEB
1ea0: 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20  UG("Terminating 
1eb0: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
1ec0: 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ");....appfs_cal
1ed0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c  l_libtcl(Tcl_Del
1ee0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
1ef0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  );)....return(NU
1f00: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  LL);..}.../*.. *
1f10: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
1f20: 61 62 6c 65 73 20 66 72 6f 6d 20 43 20 74 6f 20  ables from C to 
1f30: 54 63 6c 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  Tcl.. */..appfs_
1f40: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
1f50: 63 6c 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 20  cl_setvar_ret = 
1f60: 54 63 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72  Tcl_SetVar(inter
1f70: 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 63 61 63  p, "::appfs::cac
1f80: 68 65 64 69 72 22 2c 20 61 70 70 66 73 5f 63 61  hedir", appfs_ca
1f90: 63 68 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f 42  chedir, TCL_GLOB
1fa0: 41 4c 5f 4f 4e 4c 59 29 3b 0a 09 29 0a 09 69 66  AL_ONLY);..)..if
1fb0: 20 28 74 63 6c 5f 73 65 74 76 61 72 5f 72 65 74   (tcl_setvar_ret
1fc0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70   == NULL) {...fp
1fd0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1fe0: 6e 61 62 6c 65 20 74 6f 20 73 65 74 20 63 61 63  nable to set cac
1ff0: 68 65 20 64 69 72 65 63 74 6f 72 79 2e 20 20 54  he directory.  T
2000: 68 69 73 20 73 68 6f 75 6c 64 20 6e 65 76 65 72  his should never
2010: 20 66 61 69 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 69   fail.\n");....i
2020: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
2030: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
2040: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
2050: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
2060: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
2070: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
2080: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
2090: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
20a0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
20b0: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
20c0: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
20d0: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
20e0: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
20f0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
2100: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
2110: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
2120: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
2130: 20 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68   * Initialize th
2140: 65 20 22 61 70 70 66 73 64 2e 74 63 6c 22 20 65  e "appfsd.tcl" e
2150: 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20 77 68 69 63  nvironment, whic
2160: 68 20 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 61  h must be done a
2170: 66 74 65 72 0a 09 20 2a 20 67 6c 6f 62 61 6c 20  fter.. * global 
2180: 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 73 65  variables are se
2190: 74 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63  t... */..appfs_c
21a0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
21b0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
21c0: 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66  (interp, "::appf
21d0: 73 3a 3a 69 6e 69 74 22 29 3b 0a 09 29 0a 09 69  s::init");..)..i
21e0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
21f0: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
2200: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
2210: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
2220: 54 63 6c 20 41 70 70 46 53 20 73 63 72 69 70 74  Tcl AppFS script
2230: 20 28 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74 29   (::appfs::init)
2240: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
2250: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
2260: 69 62 74 63 6c 28 0a 09 09 09 66 70 72 69 6e 74  ibtcl(....fprint
2270: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
2280: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
2290: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
22a0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
22b0: 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  )....if (error_s
22c0: 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66  tring) {....appf
22d0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
22e0: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
22f0: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
2300: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
2310: 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d  terp));....)...}
2320: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
2330: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
2340: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41  e(interp);)....A
2350: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
2360: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
2370: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61  rpreter.");....a
2380: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2390: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
23a0: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  p(interp);)....r
23b0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
23c0: 0a 09 2f 2a 0a 09 20 2a 20 48 69 64 65 20 73 6f  ../*.. * Hide so
23d0: 6d 65 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 73 20  me Tcl commands 
23e0: 74 68 61 74 20 77 65 20 64 6f 20 6e 6f 74 20 63  that we do not c
23f0: 61 72 65 20 74 6f 20 75 73 65 20 61 6e 64 20 77  are to use and w
2400: 68 69 63 68 20 6d 61 79 0a 09 20 2a 20 73 6c 6f  hich may.. * slo
2410: 77 20 64 6f 77 6e 20 72 75 6e 2d 74 69 6d 65 20  w down run-time 
2420: 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 09 20 2a 2f  operations... */
2430: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2440: 74 63 6c 28 0a 09 09 54 63 6c 5f 48 69 64 65 43  tcl(...Tcl_HideC
2450: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
2460: 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22  auto_load_index"
2470: 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64  , "auto_load_ind
2480: 65 78 22 29 3b 0a 09 09 54 63 6c 5f 48 69 64 65  ex");...Tcl_Hide
2490: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
24a0: 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e  "unknown", "unkn
24b0: 6f 77 6e 22 29 3b 0a 09 09 54 63 6c 5f 48 69 64  own");...Tcl_Hid
24c0: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
24d0: 20 22 65 78 69 74 22 2c 20 22 65 78 69 74 22 29   "exit", "exit")
24e0: 3b 0a 09 29 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65  ;..).../*.. * Re
24f0: 6c 65 61 73 65 20 74 68 65 20 68 6f 6c 64 20 77  lease the hold w
2500: 65 20 68 61 76 65 20 6f 6e 20 74 68 65 20 69 6e  e have on the in
2510: 74 65 72 70 72 65 74 65 72 20 73 6f 20 74 68 61  terpreter so tha
2520: 74 20 69 74 20 6d 61 79 20 62 65 0a 09 20 2a 20  t it may be.. * 
2530: 64 65 6c 65 74 65 64 20 69 66 20 6e 65 65 64 65  deleted if neede
2540: 64 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61  d.. */..appfs_ca
2550: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
2560: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
2570: 0a 09 2f 2a 0a 09 20 2a 20 52 65 74 75 72 6e 20  ../*.. * Return 
2580: 74 68 65 20 63 6f 6d 70 6c 65 74 65 6c 79 20 69  the completely i
2590: 6e 69 74 69 61 6c 69 7a 65 64 20 69 6e 74 65 72  nitialized inter
25a0: 70 72 65 74 65 72 0a 09 20 2a 2f 0a 09 72 65 74  preter.. */..ret
25b0: 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  urn(interp);.}..
25c0: 2f 2a 0a 20 2a 20 52 65 74 75 72 6e 20 74 68 65  /*. * Return the
25d0: 20 74 68 72 65 61 64 2d 73 70 65 63 69 66 69 63   thread-specific
25e0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
25f0: 2c 20 63 72 65 61 74 69 6e 67 20 69 74 20 69 66  , creating it if
2600: 20 6e 65 65 64 65 64 0a 20 2a 2f 0a 73 74 61 74   needed. */.stat
2610: 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61  ic Tcl_Interp *a
2620: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 76  ppfs_TclInterp(v
2630: 6f 69 64 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  oid) {..Tcl_Inte
2640: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74  rp *interp;..int
2650: 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09 73   pthread_ret;..s
2660: 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 69  tatic __thread i
2670: 6e 74 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70  nt thread_interp
2680: 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 30 3b 0a  _reset_key = 0;.
2690: 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e 74 65  .int global_inte
26a0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09  rp_reset_key;...
26b0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
26c0: 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63  set_key = __sync
26d0: 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26  _fetch_and_add(&
26e0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
26f0: 2c 20 30 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  , 0);...interp =
2700: 20 70 74 68 72 65 61 64 5f 67 65 74 73 70 65 63   pthread_getspec
2710: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 29 3b  ific(interpKey);
2720: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 21 3d 20  ..if (interp != 
2730: 4e 55 4c 4c 20 26 26 20 74 68 72 65 61 64 5f 69  NULL && thread_i
2740: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
2750: 21 3d 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  != global_interp
2760: 5f 72 65 73 65 74 5f 6b 65 79 29 20 7b 0a 09 09  _reset_key) {...
2770: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72  APPFS_DEBUG("Ter
2780: 6d 69 6e 61 74 69 6e 67 20 6f 6c 64 20 69 6e 74  minating old int
2790: 65 72 70 72 65 74 65 72 20 61 6e 64 20 72 65 73  erpreter and res
27a0: 74 61 72 74 69 6e 67 20 64 75 65 20 74 6f 20 72  tarting due to r
27b0: 65 73 65 74 20 72 65 71 75 65 73 74 2e 22 29 3b  eset request.");
27c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
27d0: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65  ibtcl(Tcl_Delete
27e0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29  Interp(interp);)
27f0: 0a 0a 09 09 69 6e 74 65 72 70 20 3d 20 4e 55 4c  ....interp = NUL
2800: 4c 3b 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65  L;....pthread_re
2810: 74 20 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73  t = pthread_sets
2820: 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65  pecific(interpKe
2830: 79 2c 20 69 6e 74 65 72 70 29 3b 0a 09 7d 0a 0a  y, interp);..}..
2840: 09 69 66 20 28 67 6c 6f 62 61 6c 5f 69 6e 74 65  .if (global_inte
2850: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 3d 20  rp_reset_key == 
2860: 2d 31 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  -1) {...APPFS_DE
2870: 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 4e  BUG("Returning N
2880: 55 4c 4c 20 73 69 6e 63 65 20 77 65 20 61 72 65  ULL since we are
2890: 20 69 6e 20 74 68 65 20 70 72 6f 63 65 73 73 20   in the process 
28a0: 6f 66 20 74 65 72 6d 69 6e 61 74 69 6e 67 20 61  of terminating a
28b0: 6c 6c 20 74 68 72 65 61 64 73 2e 22 29 3b 0a 0a  ll threads.");..
28c0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
28d0: 09 7d 0a 0a 09 74 68 72 65 61 64 5f 69 6e 74 65  .}...thread_inte
28e0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 67  rp_reset_key = g
28f0: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
2900: 65 74 5f 6b 65 79 3b 0a 0a 09 69 66 20 28 69 6e  et_key;...if (in
2910: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
2920: 09 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
2930: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
2940: 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69 66 20 28  p(NULL);....if (
2950: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
2960: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
2970: 28 22 43 72 65 61 74 65 20 69 6e 74 65 72 70 20  ("Create interp 
2980: 66 61 69 6c 65 64 2c 20 72 65 74 75 72 6e 69 6e  failed, returnin
2990: 67 69 6e 20 66 61 69 6c 75 72 65 2e 22 29 3b 0a  gin failure.");.
29a0: 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
29b0: 3b 0a 09 09 7d 0a 0a 09 09 70 74 68 72 65 61 64  ;...}....pthread
29c0: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 73  _ret = pthread_s
29d0: 65 74 73 70 65 63 69 66 69 63 28 69 6e 74 65 72  etspecific(inter
29e0: 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b 0a 09  pKey, interp);..
29f0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
2a00: 20 21 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46   != 0) {....APPF
2a10: 53 5f 44 45 42 55 47 28 22 70 74 68 72 65 61 64  S_DEBUG("pthread
2a20: 5f 73 65 74 73 70 65 63 69 66 69 63 28 29 20 66  _setspecific() f
2a30: 61 69 6c 65 64 2e 20 20 54 65 72 6d 69 6e 61 74  ailed.  Terminat
2a40: 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ing Tcl interpre
2a50: 74 65 72 2e 22 29 3b 0a 0a 09 09 09 61 70 70 66  ter.");.....appf
2a60: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
2a70: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
2a80: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 09 72 65 74  nterp);).....ret
2a90: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09  urn(NULL);...}..
2aa0: 7d 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65 72  }...return(inter
2ab0: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61  p);.}../*. * Eva
2ac0: 6c 75 61 74 65 20 61 20 54 63 6c 20 73 63 72 69  luate a Tcl scri
2ad0: 70 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 62  pt constructed b
2ae0: 79 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67 20  y concatenating 
2af0: 61 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74 72  a bunch of C str
2b00: 69 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65 72  ings. * together
2b10: 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  .. */.static int
2b20: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
2b30: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
2b40: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63 6f  rp, int objc, co
2b50: 6e 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20 2e  nst char *cmd, .
2b60: 2e 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a  ..) {..Tcl_Obj *
2b70: 2a 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 68  *objv;..const ch
2b80: 61 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 73  ar *arg;..va_lis
2b90: 74 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65 74  t argp;..int ret
2ba0: 76 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 69  val;..int i;...i
2bb0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
2bc0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
2bd0: 55 47 28 22 49 6e 76 61 6c 69 64 20 69 6e 74 65  UG("Invalid inte
2be0: 72 70 72 65 74 65 72 20 70 61 73 73 65 64 20 69  rpreter passed i
2bf0: 6e 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 6e 20  n, returning in 
2c00: 66 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 72  failure.");....r
2c10: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29  eturn(TCL_ERROR)
2c20: 3b 0a 09 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76  ;..}...objv = (v
2c30: 6f 69 64 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73  oid *) ckalloc(s
2c40: 69 7a 65 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f  izeof(*objv) * o
2c50: 62 6a 63 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61  bjc);...appfs_ca
2c60: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 6f 62 6a  ll_libtcl(...obj
2c70: 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74  v[0] = Tcl_NewSt
2c80: 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20 2d 31 29  ringObj(cmd, -1)
2c90: 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
2ca0: 43 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a  Count(objv[0]);.
2cb0: 0a 09 09 76 61 5f 73 74 61 72 74 28 61 72 67 70  ...va_start(argp
2cc0: 2c 20 63 6d 64 29 3b 0a 09 09 66 6f 72 20 28 69  , cmd);...for (i
2cd0: 20 3d 20 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20   = 1; i < objc; 
2ce0: 69 2b 2b 29 20 7b 0a 09 09 09 61 72 67 20 3d 20  i++) {....arg = 
2cf0: 76 61 5f 61 72 67 28 61 72 67 70 2c 20 63 6f 6e  va_arg(argp, con
2d00: 73 74 20 63 68 61 72 20 2a 29 3b 0a 0a 09 09 09  st char *);.....
2d10: 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65  objv[i] = Tcl_Ne
2d20: 77 53 74 72 69 6e 67 4f 62 6a 28 61 72 67 2c 20  wStringObj(arg, 
2d30: 2d 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63  -1);.....Tcl_Inc
2d40: 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69  rRefCount(objv[i
2d50: 5d 29 3b 0a 09 09 7d 0a 09 09 76 61 5f 65 6e 64  ]);...}...va_end
2d60: 28 61 72 67 70 29 3b 0a 09 29 0a 0a 09 61 70 70  (argp);..)...app
2d70: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
2d80: 09 09 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45  ..retval = Tcl_E
2d90: 76 61 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20  valObjv(interp, 
2da0: 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a  objc, objv, 0);.
2db0: 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .)...appfs_call_
2dc0: 6c 69 62 74 63 6c 28 0a 09 09 66 6f 72 20 28 69  libtcl(...for (i
2dd0: 20 3d 20 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20   = 0; i < objc; 
2de0: 69 2b 2b 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65  i++) {....Tcl_De
2df0: 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b  crRefCount(objv[
2e00: 69 5d 29 3b 0a 09 09 7d 0a 09 29 0a 0a 09 63 6b  i]);...}..)...ck
2e10: 66 72 65 65 28 28 76 6f 69 64 20 2a 29 20 6f 62  free((void *) ob
2e20: 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65 74 76 61  jv);...if (retva
2e30: 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  l != TCL_OK) {..
2e40: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2e50: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
2e60: 55 47 28 22 54 63 6c 20 63 6f 6d 6d 61 6e 64 20  UG("Tcl command 
2e70: 66 61 69 6c 65 64 2c 20 3a 3a 65 72 72 6f 72 49  failed, ::errorI
2e80: 6e 66 6f 20 63 6f 6e 74 61 69 6e 73 3a 20 25 73  nfo contains: %s
2e90: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72 28  \n", Tcl_GetVar(
2ea0: 69 6e 74 65 72 70 2c 20 22 3a 3a 65 72 72 6f 72  interp, "::error
2eb0: 49 6e 66 6f 22 2c 20 30 29 29 3b 0a 09 09 29 0a  Info", 0));...).
2ec0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  .}...return(retv
2ed0: 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65  al);.}../*. * Re
2ee0: 71 75 65 73 74 20 61 6c 6c 20 54 63 6c 20 69 6e  quest all Tcl in
2ef0: 74 65 72 70 72 65 74 65 72 73 20 72 65 73 74 61  terpreters resta
2f00: 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rt. */.static vo
2f10: 69 64 20 61 70 70 66 73 5f 74 63 6c 5f 52 65 73  id appfs_tcl_Res
2f20: 65 74 49 6e 74 65 72 70 73 28 76 6f 69 64 29 20  etInterps(void) 
2f30: 7b 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  {..APPFS_DEBUG("
2f40: 52 65 71 75 65 73 74 69 6e 67 20 72 65 73 65 74  Requesting reset
2f50: 20 6f 66 20 61 6c 6c 20 69 6e 74 65 72 70 72 65   of all interpre
2f60: 74 65 72 73 2e 22 29 3b 0a 0a 09 5f 5f 73 79 6e  ters.");...__syn
2f70: 63 5f 61 64 64 5f 61 6e 64 5f 66 65 74 63 68 28  c_add_and_fetch(
2f80: 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  &interp_reset_ke
2f90: 79 2c 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b  y, 1);...return;
2fa0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d  .}../*. * Determ
2fb0: 69 6e 65 20 74 68 65 20 55 49 44 20 66 6f 72 20  ine the UID for 
2fc0: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
2fd0: 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53 45  the current FUSE
2fe0: 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71 75   filesystem requ
2ff0: 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c  est.. * This wil
3000: 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  l be used to loo
3010: 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20 68  kup the user's h
3020: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73 6f  ome directory so
3030: 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20 66   we can search f
3040: 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f  or. * locally mo
3050: 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a  dified files.. *
3060: 2f 0a 73 74 61 74 69 63 20 75 69 64 5f 74 20 61  /.static uid_t a
3070: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 76  ppfs_get_fsuid(v
3080: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66  oid) {..struct f
3090: 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  use_context *ctx
30a0: 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66  ;...if (!appfs_f
30b0: 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09  use_started) {..
30c0: 09 72 65 74 75 72 6e 28 67 65 74 75 69 64 28 29  .return(getuid()
30d0: 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75  );..}...ctx = fu
30e0: 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29  se_get_context()
30f0: 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e 55  ;..if (ctx == NU
3100: 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c  LL) {.../* Unabl
3110: 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72  e to lookup user
3120: 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e   for some reason
3130: 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20   */.../* Return 
3140: 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64 20  an unprivileged 
3150: 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 41 50 50  user ID */...APP
3160: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
3170: 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20   to lookup user 
3180: 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 2c  for some reason,
3190: 20 72 65 74 75 72 6e 69 6e 6e 67 20 75 73 65 72   returninng user
31a0: 20 49 44 20 6f 66 20 31 22 29 3b 0a 0a 09 09 72   ID of 1");....r
31b0: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72  eturn(1);..}...r
31c0: 65 74 75 72 6e 28 63 74 78 2d 3e 75 69 64 29 3b  eturn(ctx->uid);
31d0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d  .}../*. * Determ
31e0: 69 6e 65 20 74 68 65 20 47 49 44 20 66 6f 72 20  ine the GID for 
31f0: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
3200: 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53 45  the current FUSE
3210: 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71 75   filesystem requ
3220: 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c  est.. * This wil
3230: 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  l be used to loo
3240: 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20 68  kup the user's h
3250: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73 6f  ome directory so
3260: 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20 66   we can search f
3270: 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f  or. * locally mo
3280: 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a  dified files.. *
3290: 2f 0a 73 74 61 74 69 63 20 67 69 64 5f 74 20 61  /.static gid_t a
32a0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 76  ppfs_get_fsgid(v
32b0: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66  oid) {..struct f
32c0: 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  use_context *ctx
32d0: 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66  ;...if (!appfs_f
32e0: 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09  use_started) {..
32f0: 09 72 65 74 75 72 6e 28 67 65 74 67 69 64 28 29  .return(getgid()
3300: 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75  );..}...ctx = fu
3310: 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28 29  se_get_context()
3320: 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e 55  ;..if (ctx == NU
3330: 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c  LL) {.../* Unabl
3340: 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72  e to lookup user
3350: 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e   for some reason
3360: 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20   */.../* Return 
3370: 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64 20  an unprivileged 
3380: 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 41 50 50  user ID */...APP
3390: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
33a0: 20 74 6f 20 6c 6f 6f 6b 75 70 20 67 72 6f 75 70   to lookup group
33b0: 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e   for some reason
33c0: 2c 20 72 65 74 75 72 6e 69 6e 6e 67 20 67 72 6f  , returninng gro
33d0: 75 70 20 49 44 20 6f 66 20 31 22 29 3b 0a 0a 09  up ID of 1");...
33e0: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
33f0: 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67 69 64  .return(ctx->gid
3400: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
3410: 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  d appfs_simulate
3420: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 76  _user_fs_enter(v
3430: 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69 64  oid) {..setfsuid
3440: 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  (appfs_get_fsuid
3450: 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64 28 61  ());..setfsgid(a
3460: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29  ppfs_get_fsgid()
3470: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
3480: 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  d appfs_simulate
3490: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 76  _user_fs_leave(v
34a0: 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69 64  oid) {..setfsuid
34b0: 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64 28 30  (0);..setfsgid(0
34c0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b  );.}../*. * Look
34d0: 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69 72   up the home dir
34e0: 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69 76  ectory for a giv
34f0: 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20 20  en UID. *       
3500: 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74 72   Returns a C str
3510: 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ing containing t
3520: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3530: 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c 4c  irectory or NULL
3540: 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74 68   if. *        th
3550: 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69  e user's home di
3560: 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f 74  rectory does not
3570: 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f 74   exist or is not
3580: 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20 20   correctly. *   
3590: 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64 0a       configured.
35a0: 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20   */.static char 
35b0: 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64  *appfs_get_homed
35c0: 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29 20  ir(uid_t fsuid) 
35d0: 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77 64  {..struct passwd
35e0: 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74 3b   entry, *result;
35f0: 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73 74  ..struct stat st
3600: 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b 31  buf;..char buf[1
3610: 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a 09  024], *retval;..
3620: 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74 61  int gpu_ret, sta
3630: 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65 74  t_ret;...gpu_ret
3640: 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66 73   = getpwuid_r(fs
3650: 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75 66  uid, &entry, buf
3660: 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20 26  , sizeof(buf), &
3670: 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67 70  result);..if (gp
3680: 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  u_ret != 0) {...
3690: 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74  APPFS_DEBUG("get
36a0: 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e  pwuid_r(%llu, ..
36b0: 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20 66  .) returned in f
36c0: 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67 6e  ailure", (unsign
36d0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
36e0: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  uid);....return(
36f0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
3700: 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29 20  result == NULL) 
3710: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3720: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
3730: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
3740: 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28 75  NULL result", (u
3750: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
3760: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65  g) fsuid);....re
3770: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
3780: 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77 5f  .if (result->pw_
3790: 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  dir == NULL) {..
37a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
37b0: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
37c0: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c  ..) returned NUL
37d0: 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  L home directory
37e0: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
37f0: 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a  g long) fsuid);.
3800: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3810: 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20 3d  ..}...stat_ret =
3820: 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70 77   stat(result->pw
3830: 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a 09  _dir, &stbuf);..
3840: 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d 20  if (stat_ret != 
3850: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
3860: 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65 74  UG("stat(%s) ret
3870: 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65  urned in failure
3880: 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69  ", result->pw_di
3890: 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  r);....return(NU
38a0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 74  LL);..}...if (st
38b0: 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66 73  buf.st_uid != fs
38c0: 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  uid) {...APPFS_D
38d0: 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d 61  EBUG("UID mis-ma
38e0: 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c 75  tch on user %llu
38f0: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
3900: 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f 77  y (%s).  It's ow
3910: 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a 09  ned by %llu.",..
3920: 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20 6c  .    (unsigned l
3930: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 2c  ong long) fsuid,
3940: 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e 70  ...    result->p
3950: 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75 6e  w_dir,...    (un
3960: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
3970: 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a 09  ) stbuf.st_uid..
3980: 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  .);....return(NU
3990: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  LL);..}...retval
39a0: 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c 74   = strdup(result
39b0: 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65 74  ->pw_dir);...ret
39c0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
39d0: 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20 61  /*. * Generate a
39e0: 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67 69  n inode for a gi
39f0: 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20 69  ven path.  The i
3a00: 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20 63  node should be c
3a10: 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68 0a  omputed in such.
3a20: 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69 74   * a way that it
3a30: 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f 20   is unlikely to 
3a40: 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61 6e  be duplicated an
3a50: 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73 61  d remains the sa
3a60: 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a 20  me for a given. 
3a70: 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a 20 43 75 72  * file. *. * Cur
3a80: 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74  rent implementat
3a90: 69 6f 6e 20 69 73 20 61 6e 20 46 4e 56 2d 31 61  ion is an FNV-1a
3aa0: 20 33 32 2d 62 69 74 0a 20 2a 2f 0a 23 69 66 20   32-bit. */.#if 
3ab0: 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34 39  UINT_MAX < 42949
3ac0: 36 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e 74  67295.#error Int
3ad0: 65 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f 6f  eger size is too
3ae0: 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a 73   small .#endif.s
3af0: 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 6c  tatic unsigned l
3b00: 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f 67  ong long appfs_g
3b10: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63 6f  et_path_inode(co
3b20: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
3b30: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
3b40: 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74 20 75  retval;..const u
3b50: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 70 3b  nsigned char *p;
3b60: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 32 31 36 36  ...retval = 2166
3b70: 31 33 36 32 36 31 3b 20 2f 2a 20 46 4e 56 2d 31  136261; /* FNV-1
3b80: 61 20 33 32 2d 62 69 74 20 6f 66 66 73 65 74 5f  a 32-bit offset_
3b90: 62 61 73 69 73 20 2a 2f 0a 0a 09 66 6f 72 20 28  basis */...for (
3ba0: 70 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68  p = (unsigned ch
3bb0: 61 72 20 2a 29 20 70 61 74 68 3b 20 2a 70 3b 20  ar *) path; *p; 
3bc0: 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c 20  p++) {...retval 
3bd0: 5e 3d 20 28 69 6e 74 29 20 2a 70 3b 0a 23 69 66  ^= (int) *p;.#if
3be0: 20 30 0a 09 09 72 65 74 76 61 6c 20 2a 3d 20 31   0...retval *= 1
3bf0: 36 37 37 37 36 31 39 3b 20 2f 2a 20 46 4e 56 2d  6777619; /* FNV-
3c00: 31 61 20 33 32 2d 62 69 74 20 70 72 69 6d 65 20  1a 32-bit prime 
3c10: 2a 2f 0a 23 65 6c 73 65 0a 09 09 2f 2a 20 47 43  */.#else.../* GC
3c20: 43 20 4f 70 74 69 6d 69 7a 65 64 20 72 65 70 6c  C Optimized repl
3c30: 61 63 65 6d 65 6e 74 20 2a 2f 0a 09 09 72 65 74  acement */...ret
3c40: 76 61 6c 20 2b 3d 20 28 72 65 74 76 61 6c 20 3c  val += (retval <
3c50: 3c 20 31 29 20 2b 20 28 72 65 74 76 61 6c 20 3c  < 1) + (retval <
3c60: 3c 20 34 29 20 2b 20 28 72 65 74 76 61 6c 20 3c  < 4) + (retval <
3c70: 3c 20 37 29 20 2b 20 28 72 65 74 76 61 6c 20 3c  < 7) + (retval <
3c80: 3c 20 38 29 20 2b 20 28 72 65 74 76 61 6c 20 3c  < 8) + (retval <
3c90: 3c 20 32 34 29 3b 0a 23 65 6e 64 69 66 0a 09 7d  < 24);.#endif..}
3ca0: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
3cb0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68  );.}../*. * Cach
3cc0: 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20  e Get Path Info 
3cd0: 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65  lookups for spee
3ce0: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
3cf0: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
3d00: 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63  info_cache_get(c
3d10: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
3d20: 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75   uid_t uid, stru
3d30: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
3d40: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
3d50: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73  unsigned int has
3d60: 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72  h_idx;..int pthr
3d70: 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  ead_ret;..int re
3d80: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
3d90: 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65   1;...pthread_re
3da0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3db0: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
3dc0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
3dd0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
3de0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
3df0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
3e00: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
3e10: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
3e20: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
3e30: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  n(-1);..}...if (
3e40: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3e50: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
3e60: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61  ...hash_idx = (a
3e70: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
3e80: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29  ode(path) + uid)
3e90: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
3ea0: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
3eb0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
3ec0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3ed0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
3ee0: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  h != NULL) {....
3ef0: 69 66 20 28 73 74 72 63 6d 70 28 61 70 70 66 73  if (strcmp(appfs
3f00: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3f10: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
3f20: 65 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d 3d  e_path, path) ==
3f30: 20 30 20 26 26 20 61 70 70 66 73 5f 70 61 74 68   0 && appfs_path
3f40: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3f50: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64  _idx]._cache_uid
3f60: 20 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 72   == uid) {.....r
3f70: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09  etval = 0;......
3f80: 6d 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2c  memcpy(pathinfo,
3f90: 20 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   &appfs_path_inf
3fa0: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
3fb0: 5d 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69  ], sizeof(*pathi
3fc0: 6e 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 69  nfo));.....pathi
3fd0: 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68  nfo->_cache_path
3fe0: 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09   = NULL;....}...
3ff0: 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72  }..}...pthread_r
4000: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
4010: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
4020: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4030: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
4040: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
4050: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
4060: 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63  "Unable to unloc
4070: 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68  k path_info cach
4080: 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09  e mutex !");....
4090: 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a  return(-1);..}..
40a0: 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30  .if (retval == 0
40b0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
40c0: 47 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e 20  G("Cache hit on 
40d0: 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65  %s", path);..} e
40e0: 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  lse {...APPFS_DE
40f0: 42 55 47 28 22 43 61 63 68 65 20 6d 69 73 73 20  BUG("Cache miss 
4100: 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09  on %s", path);..
4110: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
4120: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  l);.}..static vo
4130: 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  id appfs_get_pat
4140: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64  h_info_cache_add
4150: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
4160: 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74  h, uid_t uid, st
4170: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
4180: 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b  nfo *pathinfo) {
4190: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  ..unsigned int h
41a0: 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74  ash_idx;..int pt
41b0: 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68  hread_ret;...pth
41c0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
41d0: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
41e0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
41f0: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
4200: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
4210: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
4220: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
4230: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
4240: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
4250: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
4260: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
4270: 66 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c  fo_cache == NULL
4280: 29 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 68  ) {...appfs_path
4290: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 61  _info_cache = ca
42a0: 6c 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68 5f  lloc(appfs_path_
42b0: 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c  info_cache_size,
42c0: 20 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70   sizeof(*appfs_p
42d0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29  ath_info_cache))
42e0: 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20  ;..}...hash_idx 
42f0: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
4300: 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20  h_inode(path) + 
4310: 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74  uid) % appfs_pat
4320: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
4330: 65 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  e;...if (appfs_p
4340: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
4350: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4360: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
4370: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
4380: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
4390: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
43a0: 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  th);..}...memcpy
43b0: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
43c0: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
43d0: 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a  ], pathinfo, siz
43e0: 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b  eof(*pathinfo));
43f0: 0a 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
4400: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
4410: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
4420: 20 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a 09   strdup(path);..
4430: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4440: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
4450: 5f 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75 69  _cache_uid  = ui
4460: 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  d;...pthread_ret
4470: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
4480: 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  _unlock(&appfs_p
4490: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
44a0: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
44b0: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
44c0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
44d0: 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20  nable to unlock 
44e0: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
44f0: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
4500: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  turn;..}...retur
4510: 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  n;.}..static voi
4520: 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  d appfs_get_path
4530: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63  _info_cache_rm(c
4540: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
4550: 20 75 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75   uid_t uid) {..u
4560: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
4570: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
4580: 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61  ad_ret;...pthrea
4590: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
45a0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
45b0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
45c0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
45d0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
45e0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
45f0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
4600: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
4610: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
4620: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
4630: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4640: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
4650: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61  ...hash_idx = (a
4660: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4670: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29  ode(path) + uid)
4680: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
4690: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
46a0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
46b0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
46c0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
46d0: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  h != NULL) {....
46e0: 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f  free(appfs_path_
46f0: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
4700: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
4710: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74  );.....appfs_pat
4720: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
4730: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
4740: 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09  th = NULL;...}..
4750: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  }...pthread_ret 
4760: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
4770: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
4780: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
4790: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
47a0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
47b0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
47c0: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
47d0: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
47e0: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
47f0: 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  urn;..}...return
4800: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
4810: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
4820: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
4830: 28 75 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20  (uid_t uid, int 
4840: 6e 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73  new_size) {..uns
4850: 69 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09  igned int idx;..
4860: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
4870: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4880: 46 6c 75 73 68 69 6e 67 20 41 70 70 46 53 20 63  Flushing AppFS c
4890: 61 63 68 65 20 28 75 69 64 20 3d 20 25 6c 6c 69  ache (uid = %lli
48a0: 2c 20 6e 65 77 5f 73 69 7a 65 20 3d 20 25 69 29  , new_size = %i)
48b0: 22 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75  ", (long long) u
48c0: 69 64 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a  id, new_size);..
48d0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
48e0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
48f0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
4900: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
4910: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4920: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4930: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
4940: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66  to lock path_inf
4950: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4960: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4970: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
4980: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20  h_info_cache != 
4990: 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20 28 69  NULL) {...for (i
49a0: 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 61 70  dx = 0; idx < ap
49b0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
49c0: 63 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b 2b 29  che_size; idx++)
49d0: 20 7b 0a 09 09 09 69 66 20 28 61 70 70 66 73 5f   {....if (appfs_
49e0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
49f0: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
4a00: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
4a10: 69 66 20 28 75 69 64 20 21 3d 20 28 28 75 69 64  if (uid != ((uid
4a20: 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 09 09 09  _t) -1)) {......
4a30: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
4a40: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
4a50: 63 61 63 68 65 5f 75 69 64 20 21 3d 20 75 69 64  cache_uid != uid
4a60: 29 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74 69 6e  ) {.......contin
4a70: 75 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d  ue;......}.....}
4a80: 0a 0a 09 09 09 09 66 72 65 65 28 61 70 70 66 73  ......free(appfs
4a90: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4aa0: 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  [idx]._cache_pat
4ab0: 68 29 3b 0a 0a 09 09 09 09 61 70 70 66 73 5f 70  h);......appfs_p
4ac0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69  ath_info_cache[i
4ad0: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
4ae0: 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d  = NULL;....}...}
4af0: 0a 09 7d 0a 0a 09 69 66 20 28 75 69 64 20 3d 3d  ..}...if (uid ==
4b00: 20 28 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b   ((uid_t) -1)) {
4b10: 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61  ...free(appfs_pa
4b20: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 3b 0a  th_info_cache);.
4b30: 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
4b40: 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b  fo_cache = NULL;
4b50: 0a 0a 09 09 69 66 20 28 6e 65 77 5f 73 69 7a 65  ....if (new_size
4b60: 20 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61 70 70   != -1) {....app
4b70: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4b80: 68 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f 73 69  he_size = new_si
4b90: 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68  ze;...}..}...pth
4ba0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
4bb0: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
4bc0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
4bd0: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
4be0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
4bf0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
4c00: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
4c10: 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66   unlock path_inf
4c20: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4c30: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4c40: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a  ...return;.}../*
4c50: 20 47 65 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e   Get information
4c60: 20 61 62 6f 75 74 20 61 20 70 61 74 68 2c 20 61   about a path, a
4c70: 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 6c 69  nd optionally li
4c80: 73 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f 0a 73  st children */.s
4c90: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
4ca0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 63 6f  get_path_info(co
4cb0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
4cc0: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
4cd0: 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29  hinfo *pathinfo)
4ce0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
4cf0: 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a  interp;..Tcl_Obj
4d00: 20 2a 61 74 74 72 73 5f 64 69 63 74 2c 20 2a 61   *attrs_dict, *a
4d10: 74 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f 6e 73  ttr_value;..cons
4d20: 74 20 63 68 61 72 20 2a 61 74 74 72 5f 76 61 6c  t char *attr_val
4d30: 75 65 5f 73 74 72 2c 20 2a 61 74 74 72 5f 76 61  ue_str, *attr_va
4d40: 6c 75 65 5f 73 74 72 5f 69 3b 0a 09 54 63 6c 5f  lue_str_i;..Tcl_
4d50: 57 69 64 65 49 6e 74 20 61 74 74 72 5f 76 61 6c  WideInt attr_val
4d60: 75 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20 61 74  ue_wide;..int at
4d70: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 73  tr_value_int;..s
4d80: 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54  tatic __thread T
4d90: 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b 65 79  cl_Obj *attr_key
4da0: 5f 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61  _type = NULL, *a
4db0: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 3d 20  ttr_key_perms = 
4dc0: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
4dd0: 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  size = NULL, *at
4de0: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20 4e 55  tr_key_time = NU
4df0: 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 6f  LL, *attr_key_so
4e00: 75 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  urce = NULL, *at
4e10: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
4e20: 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  t = NULL, *attr_
4e30: 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 3d 20 4e  key_packaged = N
4e40: 55 4c 4c 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f  ULL;..int cache_
4e50: 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ret;..int tcl_re
4e60: 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  t;..int retval;.
4e70: 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09  .uid_t fsuid;...
4e80: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 66 73  retval = 0;...fs
4e90: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  uid = appfs_get_
4ea0: 66 73 75 69 64 28 29 3b 0a 0a 09 63 61 63 68 65  fsuid();...cache
4eb0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65 74  _ret = appfs_get
4ec0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4ed0: 5f 67 65 74 28 70 61 74 68 2c 20 66 73 75 69 64  _get(path, fsuid
4ee0: 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66  , pathinfo);..if
4ef0: 20 28 63 61 63 68 65 5f 72 65 74 20 3d 3d 20 30   (cache_ret == 0
4f00: 29 20 7b 0a 09 09 69 66 20 28 70 61 74 68 69 6e  ) {...if (pathin
4f10: 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46  fo->type == APPF
4f20: 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f  S_PATHTYPE_DOES_
4f30: 4e 4f 54 5f 45 58 49 53 54 29 20 7b 0a 09 09 09  NOT_EXIST) {....
4f40: 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65 74  APPFS_DEBUG("Ret
4f50: 75 72 6e 69 6e 67 20 66 72 6f 6d 20 63 61 63 68  urning from cach
4f60: 65 3a 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  e: does not exis
4f70: 74 20 5c 22 25 73 5c 22 22 2c 20 70 61 74 68 29  t \"%s\"", path)
4f80: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 4e  ;.....return(-EN
4f90: 4f 45 4e 54 29 3b 0a 09 09 7d 0a 0a 09 09 69 66  OENT);...}....if
4fa0: 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65   (pathinfo->type
4fb0: 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59   == APPFS_PATHTY
4fc0: 50 45 5f 49 4e 56 41 4c 49 44 29 20 7b 0a 09 09  PE_INVALID) {...
4fd0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65  .APPFS_DEBUG("Re
4fe0: 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20 63 61 63  turning from cac
4ff0: 68 65 3a 20 69 6e 76 61 6c 69 64 20 6f 62 6a 65  he: invalid obje
5000: 63 74 20 5c 22 25 73 5c 22 22 2c 20 70 61 74 68  ct \"%s\"", path
5010: 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 2d 45  );.....return(-E
5020: 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  IO);...}....retu
5030: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65  rn(0);..}...inte
5040: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
5050: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
5060: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
5070: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
5080: 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67  ror: Unable to g
5090: 65 74 20 61 6e 20 69 6e 74 65 72 70 72 65 74 65  et an interprete
50a0: 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d  r");....return(-
50b0: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
50c0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
50d0: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
50e0: 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  );)...tcl_ret = 
50f0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
5100: 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70  nterp, 2, "::app
5110: 66 73 3a 3a 67 65 74 61 74 74 72 22 2c 20 70 61  fs::getattr", pa
5120: 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  th);..if (tcl_re
5130: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
5140: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
5150: 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72 28 25  appfs::getattr(%
5160: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
5170: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
5180: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
5190: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
51a0: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
51b0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
51c0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
51d0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
51e0: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
51f0: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3b  _DOES_NOT_EXIST;
5200: 0a 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ....appfs_get_pa
5210: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64  th_info_cache_ad
5220: 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70  d(path, fsuid, p
5230: 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 09 61 70 70  athinfo);....app
5240: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
5250: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
5260: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p);)....return(-
5270: 45 4e 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66  ENOENT);..}...if
5280: 20 28 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20   (attr_key_type 
5290: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70  == NULL) {...app
52a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
52b0: 09 09 09 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  ...attr_key_type
52c0: 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77         = Tcl_New
52d0: 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70 65 22  StringObj("type"
52e0: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b  , -1);....attr_k
52f0: 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20 3d 20  ey_perms      = 
5300: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5310: 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b 0a 09  ("perms", -1);..
5320: 09 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20  ..attr_key_size 
5330: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
5340: 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65 22 2c  tringObj("size",
5350: 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65   -1);....attr_ke
5360: 79 5f 74 69 6d 65 20 20 20 20 20 20 20 3d 20 54  y_time       = T
5370: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
5380: 22 74 69 6d 65 22 2c 20 2d 31 29 3b 0a 09 09 09  "time", -1);....
5390: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20  attr_key_source 
53a0: 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72      = Tcl_NewStr
53b0: 69 6e 67 4f 62 6a 28 22 73 6f 75 72 63 65 22 2c  ingObj("source",
53c0: 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65   -1);....attr_ke
53d0: 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 54  y_childcount = T
53e0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
53f0: 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c 20 2d 31  "childcount", -1
5400: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 70  );....attr_key_p
5410: 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63 6c 5f  ackaged   = Tcl_
5420: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 70 61  NewStringObj("pa
5430: 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a 0a 09  ckaged", -1);...
5440: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
5450: 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  nt(attr_key_type
5460: 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
5470: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
5480: 70 65 72 6d 73 29 3b 0a 09 09 09 54 63 6c 5f 49  perms);....Tcl_I
5490: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
54a0: 5f 6b 65 79 5f 73 69 7a 65 29 3b 0a 09 09 09 54  _key_size);....T
54b0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
54c0: 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 29 3b 0a  attr_key_time);.
54d0: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
54e0: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73 6f 75  unt(attr_key_sou
54f0: 72 63 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  rce);....Tcl_Inc
5500: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
5510: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 29 3b 0a  ey_childcount);.
5520: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
5530: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 70 61 63  unt(attr_key_pac
5540: 6b 61 67 65 64 29 3b 0a 09 09 29 0a 09 7d 0a 0a  kaged);...)..}..
5550: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5560: 63 6c 28 0a 09 09 61 74 74 72 73 5f 64 69 63 74  cl(...attrs_dict
5570: 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73   = Tcl_GetObjRes
5580: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 09 74  ult(interp);...t
5590: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 44 69 63  cl_ret = Tcl_Dic
55a0: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
55b0: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
55c0: 5f 6b 65 79 5f 74 79 70 65 2c 20 26 61 74 74 72  _key_type, &attr
55d0: 5f 76 61 6c 75 65 29 3b 0a 09 29 0a 09 69 66 20  _value);..)..if 
55e0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
55f0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
5600: 42 55 47 28 22 5b 64 69 63 74 20 67 65 74 20 5c  BUG("[dict get \
5610: 22 74 79 70 65 5c 22 5d 20 66 61 69 6c 65 64 22  "type\"] failed"
5620: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
5630: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
5640: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
5650: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
5660: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
5670: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
5680: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5690: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
56a0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
56b0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66  n(-EIO);..}...if
56c0: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 3d 3d 20   (attr_value == 
56d0: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
56e0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e  DEBUG("error: Un
56f0: 61 62 6c 65 20 74 6f 20 67 65 74 20 74 79 70 65  able to get type
5700: 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f 6d   for \"%s\" from
5710: 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 0a 09   Tcl", path);...
5720: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5730: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
5740: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
5750: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70  rn(-EIO);..}...p
5760: 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65  athinfo->package
5770: 64 20 3d 20 30 3b 0a 09 70 61 74 68 69 6e 66 6f  d = 0;..pathinfo
5780: 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f  ->inode = appfs_
5790: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
57a0: 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61  ath);...appfs_ca
57b0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74 74  ll_libtcl(...att
57c0: 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63  r_value_str = Tc
57d0: 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72  l_GetString(attr
57e0: 5f 76 61 6c 75 65 29 3b 0a 0a 09 09 73 77 69 74  _value);....swit
57f0: 63 68 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73  ch (attr_value_s
5800: 74 72 5b 30 5d 29 20 7b 0a 09 09 09 63 61 73 65  tr[0]) {....case
5810: 20 27 64 27 3a 20 2f 2a 20 64 69 72 65 63 74 6f   'd': /* directo
5820: 72 79 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e  ry */.....pathin
5830: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
5840: 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54  _PATHTYPE_DIRECT
5850: 4f 52 59 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  ORY;.....pathinf
5860: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e  o->typeinfo.dir.
5870: 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 30 3b 0a  childcount = 0;.
5880: 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a  .....Tcl_DictObj
5890: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
58a0: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
58b0: 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20 26 61 74  _childcount, &at
58c0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69  tr_value);.....i
58d0: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
58e0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 74 63   NULL) {......tc
58f0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
5900: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
5910: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
5920: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
5930: 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63 6c 5f  );......if (tcl_
5940: 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret == TCL_OK) {
5950: 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  .......pathinfo-
5960: 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  >typeinfo.dir.ch
5970: 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f  ildcount = attr_
5980: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09  value_wide;.....
5990: 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 62 72  .}.....}......br
59a0: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 66 27  eak;....case 'f'
59b0: 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09 09  : /* file */....
59c0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
59d0: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
59e0: 5f 46 49 4c 45 3b 0a 09 09 09 09 70 61 74 68 69  _FILE;.....pathi
59f0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5a00: 6c 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09  le.size = 0;....
5a10: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5a20: 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61  nfo.file.executa
5a30: 62 6c 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74  ble = 0;.....pat
5a40: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5a50: 66 69 6c 65 2e 73 75 69 64 20 3d 20 30 3b 0a 09  file.suid = 0;..
5a60: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5a70: 65 69 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64  einfo.file.world
5a80: 61 63 63 65 73 73 69 62 6c 65 20 3d 20 30 3b 0a  accessible = 0;.
5a90: 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a  .....Tcl_DictObj
5aa0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
5ab0: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
5ac0: 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c  _size, &attr_val
5ad0: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74  ue);.....if (att
5ae0: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
5af0: 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20   {......tcl_ret 
5b00: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
5b10: 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74  FromObj(NULL, at
5b20: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
5b30: 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09  value_wide);....
5b40: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d  ..if (tcl_ret ==
5b50: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09   TCL_OK) {......
5b60: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5b70: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20  nfo.file.size = 
5b80: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
5b90: 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09  ......}.....}...
5ba0: 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
5bb0: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
5bc0: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70  dict, attr_key_p
5bd0: 65 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75  erms, &attr_valu
5be0: 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72  e);.....if (attr
5bf0: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
5c00: 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c 75  {......attr_valu
5c10: 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53  e_str = Tcl_GetS
5c20: 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65  tring(attr_value
5c30: 29 3b 0a 09 09 09 09 09 66 6f 72 20 28 61 74 74  );......for (att
5c40: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 3d 20  r_value_str_i = 
5c50: 26 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  &attr_value_str[
5c60: 30 5d 3b 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f  0]; *attr_value_
5c70: 73 74 72 5f 69 20 21 3d 20 27 5c 30 27 3b 20 61  str_i != '\0'; a
5c80: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 2b  ttr_value_str_i+
5c90: 2b 29 20 7b 0a 09 09 09 09 09 09 73 77 69 74 63  +) {.......switc
5ca0: 68 20 28 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73  h (*attr_value_s
5cb0: 74 72 5f 69 29 20 7b 0a 09 09 09 09 09 09 09 63  tr_i) {........c
5cc0: 61 73 65 20 27 78 27 3a 0a 09 09 09 09 09 09 09  ase 'x':........
5cd0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5ce0: 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61  nfo.file.executa
5cf0: 62 6c 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09  ble = 1;........
5d00: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 09  ..break;........
5d10: 63 61 73 65 20 27 55 27 3a 0a 09 09 09 09 09 09  case 'U':.......
5d20: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5d30: 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 20 3d  info.file.suid =
5d40: 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65   1;..........bre
5d50: 61 6b 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20  ak;........case 
5d60: 27 2d 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74  '-':.........pat
5d70: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5d80: 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73  file.worldaccess
5d90: 69 62 6c 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09  ible = 1;.......
5da0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09  ...break;.......
5db0: 7d 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09  }......}.....}..
5dc0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
5dd0: 65 20 27 73 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e  e 's': /* symlin
5de0: 6b 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66  k */.....pathinf
5df0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
5e00: 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b  PATHTYPE_SYMLINK
5e10: 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ;.....pathinfo->
5e20: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
5e30: 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70  .size = 0;.....p
5e40: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5e50: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
5e60: 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09  [0] = '\0';.....
5e70: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
5e80: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
5e90: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ct, attr_key_sou
5ea0: 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rce, &attr_value
5eb0: 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f  );.....if (attr_
5ec0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
5ed0: 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65  ......attr_value
5ee0: 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74  _str = Tcl_GetSt
5ef0: 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72  ringFromObj(attr
5f00: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
5f10: 6c 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09  lue_int); ......
5f20: 09 69 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65  .if ((attr_value
5f30: 5f 69 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a  _int + 1) <= siz
5f40: 65 6f 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79  eof(pathinfo->ty
5f50: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5f60: 6f 75 72 63 65 29 29 20 7b 0a 09 09 09 09 09 09  ource)) {.......
5f70: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5f80: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20  fo.symlink.size 
5f90: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  = attr_value_int
5fa0: 3b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  ;.......pathinfo
5fb0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
5fc0: 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72 5f 76  nk.source[attr_v
5fd0: 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27  alue_int] = '\0'
5fe0: 3b 0a 0a 09 09 09 09 09 09 6d 65 6d 63 70 79 28  ;........memcpy(
5ff0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
6000: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
6010: 65 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  e, attr_value_st
6020: 72 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e  r, attr_value_in
6030: 74 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d  t);......}.....}
6040: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
6050: 61 73 65 20 27 46 27 3a 20 2f 2a 20 70 69 70 65  ase 'F': /* pipe
6060: 2f 66 69 66 6f 20 2a 2f 0a 09 09 09 09 70 61 74  /fifo */.....pat
6070: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
6080: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46  PFS_PATHTYPE_FIF
6090: 4f 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  O;.....break;...
60a0: 09 63 61 73 65 20 27 53 27 3a 20 2f 2a 20 55 4e  .case 'S': /* UN
60b0: 49 58 20 64 6f 6d 61 69 6e 20 73 6f 63 6b 65 74  IX domain socket
60c0: 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f   */.....pathinfo
60d0: 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  ->type = APPFS_P
60e0: 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 3b 0a  ATHTYPE_SOCKET;.
60f0: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 64 65  ....break;....de
6100: 66 61 75 6c 74 3a 0a 09 09 09 09 72 65 74 76 61  fault:.....retva
6110: 6c 20 3d 20 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09  l = -EIO;...}...
6120: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
6130: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
6140: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 61 63  ct, attr_key_pac
6150: 6b 61 67 65 64 2c 20 26 61 74 74 72 5f 76 61 6c  kaged, &attr_val
6160: 75 65 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f  ue);...if (attr_
6170: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
6180: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61  ....pathinfo->pa
6190: 63 6b 61 67 65 64 20 3d 20 31 3b 0a 09 09 7d 0a  ckaged = 1;...}.
61a0: 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
61b0: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
61c0: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74  dict, attr_key_t
61d0: 69 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  ime, &attr_value
61e0: 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61  );...if (attr_va
61f0: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
6200: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
6210: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
6220: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
6230: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
6240: 77 69 64 65 29 3b 0a 09 09 09 69 66 20 28 74 63  wide);....if (tc
6250: 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29  l_ret == TCL_OK)
6260: 20 7b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d   {.....pathinfo-
6270: 3e 74 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c  >time = attr_val
6280: 75 65 5f 77 69 64 65 3b 0a 09 09 09 7d 0a 09 09  ue_wide;....}...
6290: 7d 20 65 6c 73 65 20 7b 0a 09 09 09 70 61 74 68  } else {....path
62a0: 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 70 70  info->time = app
62b0: 66 73 5f 62 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d  fs_boottime;...}
62c0: 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ....Tcl_Release(
62d0: 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 69 66  interp);..)...if
62e0: 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b   (retval == 0) {
62f0: 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
6300: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64  h_info_cache_add
6310: 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61  (path, fsuid, pa
6320: 74 68 69 6e 66 6f 29 3b 0a 09 7d 20 65 6c 73 65  thinfo);..} else
6330: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
6340: 28 22 65 72 72 6f 72 3a 20 49 6e 76 61 6c 69 64  ("error: Invalid
6350: 20 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22   type for \"%s\"
6360: 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68   from Tcl", path
6370: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72  );..}...return(r
6380: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69  etval);.}..stati
6390: 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 70 72  c char *appfs_pr
63a0: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
63b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
63c0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
63d0: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
63e0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
63f0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a  ..int tcl_ret;..
6400: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
6410: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
6420: 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  (appfs_get_fsuid
6430: 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72  (), -1);...inter
6440: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
6450: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
6460: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
6470: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
6480: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6490: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
64a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70  e(interp);)...ap
64b0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
64c0: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
64d0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
64e0: 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 2, "::appfs:
64f0: 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  :prepare_to_crea
6500: 74 65 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09  te", path);..)..
6510: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
6520: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
6530: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
6540: 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  :prepare_to_crea
6550: 74 65 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  te(%s) failed.",
6560: 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f   path);...appfs_
6570: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
6580: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
6590: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
65a0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
65b0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
65c0: 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  )....appfs_call_
65d0: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
65e0: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
65f0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
6600: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6610: 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74  btcl(...real_pat
6620: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
6630: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
6640: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
6650: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
6660: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
6670: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
6680: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6690: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
66a0: 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c  turn(strdup(real
66b0: 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74  _path));.}..stat
66c0: 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 6c  ic char *appfs_l
66d0: 6f 63 61 6c 70 61 74 68 28 63 6f 6e 73 74 20 63  ocalpath(const c
66e0: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
66f0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6700: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
6710: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
6720: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
6730: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
6740: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
6750: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
6760: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
6770: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
6780: 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65  tcl(Tcl_Preserve
6790: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70 70  (interp);)...app
67a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
67b0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
67c0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
67d0: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
67e0: 6c 6f 63 61 6c 70 61 74 68 22 2c 20 70 61 74 68  localpath", path
67f0: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
6800: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
6810: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
6820: 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74  :appfs::localpat
6830: 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  h(%s) failed.", 
6840: 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63  path);...appfs_c
6850: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41  all_libtcl(....A
6860: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
6870: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
6880: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
6890: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
68a0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
68b0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
68c0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c  l_libtcl(...real
68d0: 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53  _path = Tcl_GetS
68e0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
68f0: 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f  rp);..)...appfs_
6900: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
6910: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
6920: 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  )...if (real_pat
6930: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
6940: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
6950: 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70 28  ..return(strdup(
6960: 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a  real_path));.}..
6970: 23 69 66 20 28 64 65 66 69 6e 65 64 28 44 45 42  #if (defined(DEB
6980: 55 47 29 20 26 26 20 64 65 66 69 6e 65 64 28 41  UG) && defined(A
6990: 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29  PPFS_EXIT_PATH))
69a0: 20 7c 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46   || defined(APPF
69b0: 53 5f 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42  S_EXIT_PATH_ENAB
69c0: 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54  LE_MAJOR_SECURIT
69d0: 59 5f 48 4f 4c 45 29 0a 73 74 61 74 69 63 20 76  Y_HOLE).static v
69e0: 6f 69 64 20 61 70 70 66 73 5f 65 78 69 74 28 76  oid appfs_exit(v
69f0: 6f 69 64 29 20 7b 0a 09 69 6e 74 20 67 6c 6f 62  oid) {..int glob
6a00: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
6a10: 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e  key;...global_in
6a20: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d  terp_reset_key =
6a30: 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e   __sync_fetch_an
6a40: 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72 65  d_add(&interp_re
6a50: 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f  set_key, 0);..__
6a60: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 73  sync_fetch_and_s
6a70: 75 62 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  ub(&interp_reset
6a80: 5f 6b 65 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74  _key, global_int
6a90: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 3b 0a  erp_reset_key);.
6aa0: 0a 09 77 68 69 6c 65 20 28 5f 5f 73 79 6e 63 5f  ..while (__sync_
6ab0: 73 75 62 5f 61 6e 64 5f 66 65 74 63 68 28 26 69  sub_and_fetch(&i
6ac0: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c  nterp_reset_key,
6ad0: 20 31 29 20 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a   1) >= 0) {.../*
6ae0: 20 42 75 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d   Busy Loop */..}
6af0: 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  ...global_interp
6b00: 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73  _reset_key = __s
6b10: 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64  ync_fetch_and_ad
6b20: 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  d(&interp_reset_
6b30: 6b 65 79 2c 20 30 29 3b 0a 09 69 66 20 28 67 6c  key, 0);..if (gl
6b40: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
6b50: 74 5f 6b 65 79 20 21 3d 20 2d 31 29 20 7b 0a 09  t_key != -1) {..
6b60: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 72  .APPFS_DEBUG("Er
6b70: 72 6f 72 20 73 65 6e 64 69 6e 67 20 6b 69 6c 6c  ror sending kill
6b80: 20 73 69 67 6e 61 6c 20 74 6f 20 61 6c 6c 20 74   signal to all t
6b90: 68 72 65 61 64 73 2c 20 61 62 6f 72 74 69 6e 67  hreads, aborting
6ba0: 20 61 6e 79 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a   anyway.");..}..
6bb0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
6bc0: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
6bd0: 28 2d 31 2c 20 2d 31 29 3b 0a 0a 09 66 75 73 65  (-1, -1);...fuse
6be0: 5f 65 78 69 74 28 66 75 73 65 5f 67 65 74 5f 63  _exit(fuse_get_c
6bf0: 6f 6e 74 65 78 74 28 29 2d 3e 66 75 73 65 29 3b  ontext()->fuse);
6c00: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e  ...return;.}.#en
6c10: 64 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  dif..static int 
6c20: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c  appfs_fuse_readl
6c30: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
6c40: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
6c50: 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a   size_t size) {.
6c60: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
6c70: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
6c80: 0a 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30  ..int retval = 0
6c90: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
6ca0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
6cb0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
6cc0: 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  ...pathinfo.type
6cd0: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
6ce0: 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74  E_INVALID;...ret
6cf0: 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  val = appfs_get_
6d00: 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20  path_info(path, 
6d10: 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20  &pathinfo);..if 
6d20: 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a  (retval != 0) {.
6d30: 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
6d40: 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  ;..}...if (pathi
6d50: 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46  nfo.type != APPF
6d60: 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49  S_PATHTYPE_SYMLI
6d70: 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  NK) {...return(-
6d80: 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66  EINVAL);..}...if
6d90: 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e   ((strlen(pathin
6da0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
6db0: 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29  ink.source) + 1)
6dc0: 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74   > size) {...ret
6dd0: 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e  urn(-ENAMETOOLON
6de0: 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28  G);..}...memcpy(
6df0: 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79  buf, pathinfo.ty
6e00: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
6e10: 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61  ource, strlen(pa
6e20: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
6e30: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20  symlink.source) 
6e40: 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30  + 1);...return(0
6e50: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
6e60: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
6e70: 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ttr(const char *
6e80: 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74 61  path, struct sta
6e90: 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72  t *stbuf) {..str
6ea0: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
6eb0: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e  fo pathinfo;..in
6ec0: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76  t retval;...retv
6ed0: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
6ee0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
6ef0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
6f00: 70 61 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66  path);..#if (def
6f10: 69 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64  ined(DEBUG) && d
6f20: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49  efined(APPFS_EXI
6f30: 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69  T_PATH)) || defi
6f40: 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50  ned(APPFS_EXIT_P
6f50: 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52  ATH_ENABLE_MAJOR
6f60: 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a  _SECURITY_HOLE).
6f70: 09 2f 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20  ./*.. * This is 
6f80: 61 20 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79  a major security
6f90: 20 69 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e   issue so we can
6fa0: 6e 6f 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f  not let it be co
6fb0: 6d 70 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20  mpiled into.. * 
6fc0: 61 6e 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f  any release.. */
6fd0: 0a 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61  ...if (strcmp(pa
6fe0: 74 68 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20  th, "/exit") == 
6ff0: 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69  0) {...appfs_exi
7000: 74 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  t();..}.#endif..
7010: 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d  .pathinfo.type =
7020: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7030: 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61  INVALID;...retva
7040: 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61  l = appfs_get_pa
7050: 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70  th_info(path, &p
7060: 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72  athinfo);..if (r
7070: 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09  etval != 0) {...
7080: 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 2d 45  if (retval == -E
7090: 4e 4f 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46  NOENT) {....APPF
70a0: 53 5f 44 45 42 55 47 28 22 67 65 74 5f 70 61 74  S_DEBUG("get_pat
70b0: 68 5f 69 6e 66 6f 20 72 65 74 75 72 6e 65 64 20  h_info returned 
70c0: 45 4e 4f 45 4e 54 2c 20 72 65 74 75 72 6e 69 6e  ENOENT, returnin
70d0: 67 20 69 74 20 61 73 20 77 65 6c 6c 2e 22 29 3b  g it as well.");
70e0: 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 41  ...} else {....A
70f0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
7100: 72 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  r: get_path_info
7110: 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a   failed");...}..
7120: 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
7130: 3b 0a 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74  ;..}...memset(st
7140: 62 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73  buf, 0, sizeof(s
7150: 74 72 75 63 74 20 73 74 61 74 29 29 3b 0a 0a 09  truct stat));...
7160: 73 74 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20  stbuf->st_mtime 
7170: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
7180: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d  ..stbuf->st_ctim
7190: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d  e = pathinfo.tim
71a0: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61 74  e;..stbuf->st_at
71b0: 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74  ime = pathinfo.t
71c0: 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ime;..stbuf->st_
71d0: 69 6e 6f 20 20 20 3d 20 70 61 74 68 69 6e 66 6f  ino   = pathinfo
71e0: 2e 69 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e  .inode;..stbuf->
71f0: 73 74 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09  st_mode  = 0;...
7200: 73 77 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f  switch (pathinfo
7210: 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20  .type) {...case 
7220: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
7230: 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62  IRECTORY:....stb
7240: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
7250: 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09  IFDIR | 0555;...
7260: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
7270: 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e   = 2 + pathinfo.
7280: 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69  typeinfo.dir.chi
7290: 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61  ldcount;....brea
72a0: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
72b0: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09  PATHTYPE_FILE:..
72c0: 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74  ..if (pathinfo.t
72d0: 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65  ypeinfo.file.exe
72e0: 63 75 74 61 62 6c 65 29 20 7b 0a 09 09 09 09 73  cutable) {.....s
72f0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
7300: 53 5f 49 46 52 45 47 20 7c 20 30 35 35 35 3b 0a  S_IFREG | 0555;.
7310: 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09  ...} else {.....
7320: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d  stbuf->st_mode =
7330: 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34 3b   S_IFREG | 0444;
7340: 0a 09 09 09 7d 0a 0a 09 09 09 69 66 20 28 70 61  ....}.....if (pa
7350: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
7360: 66 69 6c 65 2e 73 75 69 64 29 20 7b 0a 09 09 09  file.suid) {....
7370: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7380: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 30 30  = S_IFREG | 0400
7390: 30 3b 0a 09 09 09 7d 0a 0a 09 09 09 69 66 20 28  0;....}.....if (
73a0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
73b0: 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65  o.file.worldacce
73c0: 73 73 69 62 6c 65 29 20 7b 0a 09 09 09 09 73 74  ssible) {.....st
73d0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 26 3d 20  buf->st_mode &= 
73e0: 7e 30 37 37 3b 0a 09 09 09 7d 0a 0a 09 09 09 73  ~077;....}.....s
73f0: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7400: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7410: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f  _size = pathinfo
7420: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
7430: 69 7a 65 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ize;.....break;.
7440: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
7450: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09  HTYPE_SYMLINK:..
7460: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
7470: 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35   = S_IFLNK | 055
7480: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
7490: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
74a0: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
74b0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
74c0: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09  .symlink.size;..
74d0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
74e0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
74f0: 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d  OCKET:....stbuf-
7500: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53  >st_mode = S_IFS
7510: 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  OCK | 0555;....s
7520: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7530: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7540: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
7550: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
7560: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a  S_PATHTYPE_FIFO:
7570: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7580: 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30  de = S_IFIFO | 0
7590: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
75a0: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
75b0: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
75c0: 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09   0;....break;...
75d0: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
75e0: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
75f0: 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ST:....retval = 
7600: 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65  -ENOENT;.....bre
7610: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7620: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
7630: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
7640: 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  EIO;.....break;.
7650: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
7660: 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09  o.packaged) {...
7670: 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20  stbuf->st_uid   
7680: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
7690: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
76a0: 5f 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67  _gid   = appfs_g
76b0: 65 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74  et_fsgid();...st
76c0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20  buf->st_mode |= 
76d0: 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  0200;..}...retur
76e0: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
76f0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
7700: 75 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73  use_readdir(cons
7710: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f  t char *path, vo
7720: 69 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69  id *buf, fuse_fi
7730: 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c  ll_dir_t filler,
7740: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
7750: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
7760: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
7770: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
7780: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c  ..Tcl_Obj **chil
7790: 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64  dren;..int child
77a0: 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a  ren_count, idx;.
77b0: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
77c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
77d0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
77e0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
77f0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
7800: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
7810: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
7820: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
7830: 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74  "error: Unable t
7840: 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72  o get an interpr
7850: 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72  eter");....retur
7860: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  n(0);..}...appfs
7870: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
7880: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
7890: 29 3b 29 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66  );)...filler(buf
78a0: 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b  , ".", NULL, 0);
78b0: 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e  ..filler(buf, ".
78c0: 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09  .", NULL, 0);...
78d0: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
78e0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
78f0: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65   2, "::appfs::ge
7900: 74 63 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68  tchildren", path
7910: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
7920: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
7930: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
7940: 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e  pfs::getchildren
7950: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
7960: 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  ath);...appfs_ca
7970: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
7980: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
7990: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
79a0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
79b0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
79c0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
79d0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
79e0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
79f0: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70  turn(0);..}...ap
7a00: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7a10: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
7a20: 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65  _ListObjGetEleme
7a30: 6e 74 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  nts(interp, Tcl_
7a40: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
7a50: 65 72 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f  erp), &children_
7a60: 63 6f 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e  count, &children
7a70: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
7a80: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
7a90: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50  ..APPFS_DEBUG("P
7aa0: 61 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20 63  arsing list of c
7ab0: 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68 20  hildren on path 
7ac0: 25 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  %s failed.", pat
7ad0: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
7ae0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
7af0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
7b00: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
7b10: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
7b20: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
7b30: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7b40: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
7b50: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
7b60: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20  rn(0);..}...for 
7b70: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
7b80: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20  children_count; 
7b90: 69 64 78 2b 2b 29 20 7b 0a 09 09 61 70 70 66 73  idx++) {...appfs
7ba0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
7bb0: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c  .filler(buf, Tcl
7bc0: 5f 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64  _GetString(child
7bd0: 72 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c  ren[idx]), NULL,
7be0: 20 30 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70   0);...)..}...ap
7bf0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7c00: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
7c10: 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30  rp);)...return(0
7c20: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
7c30: 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e   appfs_fuse_open
7c40: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
7c50: 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  h, struct fuse_f
7c60: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
7c70: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
7c80: 65 72 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70  erp;..struct app
7c90: 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68  fs_pathinfo path
7ca0: 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61  info;..const cha
7cb0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d  r *real_path, *m
7cc0: 6f 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65  ode;..int gpi_re
7cd0: 74 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74  t, tcl_ret;..int
7ce0: 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42   fh;...APPFS_DEB
7cf0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
7d00: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
7d10: 68 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20  h);...gpi_ret = 
7d20: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7d30: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
7d40: 6e 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d  nfo);...if ((fi-
7d50: 3e 66 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e  >flags & (O_WRON
7d60: 4c 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20  LY|O_CREAT)) == 
7d70: 28 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c  (O_CREAT|O_WRONL
7d80: 59 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66  Y)) {.../* The f
7d90: 69 6c 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61  ile will be crea
7da0: 74 65 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e  ted if it does n
7db0: 6f 74 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66  ot exist */...if
7dc0: 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26   (gpi_ret != 0 &
7dd0: 26 20 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e  & gpi_ret != -EN
7de0: 4f 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53  OENT) {....APPFS
7df0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
7e00: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
7e10: 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  led");.....retur
7e20: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a  n(gpi_ret);...}.
7e30: 0a 09 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74  ...mode = "creat
7e40: 65 22 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57  e";..../*... * W
7e50: 65 20 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20  e have to clear 
7e60: 74 68 65 20 63 61 63 68 65 20 68 65 72 65 20 73  the cache here s
7e70: 6f 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65  o that the numbe
7e80: 72 20 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20  r of... * links 
7e90: 67 65 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20  gets maintained 
7ea0: 6f 6e 20 74 68 65 20 70 61 72 65 6e 74 20 64 69  on the parent di
7eb0: 72 65 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09  rectory... */...
7ec0: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7ed0: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
7ee0: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
7ef0: 29 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20  ), -1);..} else 
7f00: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20  {.../* The file 
7f10: 6d 75 73 74 20 61 6c 72 65 61 64 79 20 65 78 69  must already exi
7f20: 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f  st */...if (gpi_
7f30: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41  ret != 0) {....A
7f40: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
7f50: 72 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  r: get_path_info
7f60: 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72   failed");.....r
7f70: 65 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a  eturn(gpi_ret);.
7f80: 09 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22  ..}....mode = ""
7f90: 3b 0a 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c  ;....if ((fi->fl
7fa0: 61 67 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20  ags & O_WRONLY) 
7fb0: 3d 3d 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09  == O_WRONLY) {..
7fc0: 09 09 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22  ..mode = "write"
7fd0: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70  ;...}..}...if (p
7fe0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20  athinfo.type == 
7ff0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
8000: 49 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 41 50  IRECTORY) {...AP
8010: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8020: 3a 20 41 73 6b 65 64 20 74 6f 20 6f 70 65 6e 20  : Asked to open 
8030: 61 20 64 69 72 65 63 74 6f 72 79 2e 22 29 3b 0a  a directory.");.
8040: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44 49  ...return(-EISDI
8050: 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20  R);..}...interp 
8060: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
8070: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
8080: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
8090: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
80a0: 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20  : Unable to get 
80b0: 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29  an interpreter")
80c0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  ;....return(-EIO
80d0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
80e0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72  ll_libtcl(Tcl_Pr
80f0: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29  eserve(interp);)
8100: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
8110: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
8120: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
8130: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
8140: 2c 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63  , mode);..if (tc
8150: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
8160: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8170: 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70  ("::appfs::openp
8180: 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c  ath(%s, %s) fail
8190: 65 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65  ed.", path, mode
81a0: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
81b0: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
81c0: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
81d0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
81e0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
81f0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
8200: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8210: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
8220: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
8230: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
8240: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
8250: 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
8260: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
8270: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a  lt(interp);..)..
8280: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8290: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
82a0: 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72  nterp);)...if (r
82b0: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
82c0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
82d0: 47 28 22 65 72 72 6f 72 3a 20 72 65 61 6c 5f 70  G("error: real_p
82e0: 61 74 68 20 77 61 73 20 4e 55 4c 4c 2e 22 29 0a  ath was NULL.").
82f0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
8300: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  ..}...APPFS_DEBU
8310: 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65  G("Translated re
8320: 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73  quest to open %s
8330: 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28   to opening %s (
8340: 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c  mode = \"%s\")",
8350: 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68   path, real_path
8360: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20  , mode);...fh = 
8370: 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20  open(real_path, 
8380: 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29  fi->flags, 0600)
8390: 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20  ;...if (fh < 0) 
83a0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
83b0: 22 65 72 72 6f 72 3a 20 6f 70 65 6e 20 66 61 69  "error: open fai
83c0: 6c 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  led");....return
83d0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
83e0: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a  ...fi->fh = fh;.
83f0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
8400: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
8410: 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73  _fuse_close(cons
8420: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
8430: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
8440: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20  nfo *fi) {..int 
8450: 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70  close_ret;...app
8460: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
8470: 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20  _cache_rm(path, 
8480: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
8490: 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20  ));...close_ret 
84a0: 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b  = close(fi->fh);
84b0: 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20  ..if (close_ret 
84c0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
84d0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 63 6c  DEBUG("error: cl
84e0: 6f 73 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09  ose failed");...
84f0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
8500: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
8510: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
8520: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
8530: 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ad(const char *p
8540: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
8550: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
8560: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
8570: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
8580: 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74   *fi) {..ssize_t
8590: 20 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20   read_ret;..int 
85a0: 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f  retval;...APPFS_
85b0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
85c0: 74 68 20 3d 20 25 73 2c 20 62 75 66 2c 20 25 6c  th = %s, buf, %l
85d0: 6c 69 2c 20 25 6c 6c 69 2c 20 66 64 3d 25 6c 6c  li, %lli, fd=%ll
85e0: 69 29 22 2c 20 70 61 74 68 2c 20 28 6c 6f 6e 67  i)", path, (long
85f0: 20 6c 6f 6e 67 29 20 73 69 7a 65 2c 20 28 6c 6f   long) size, (lo
8600: 6e 67 20 6c 6f 6e 67 29 20 6f 66 66 73 65 74 2c  ng long) offset,
8610: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 2d   (long long) fi-
8620: 3e 66 68 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  >fh);...retval =
8630: 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a   0;...while (siz
8640: 65 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 61 64  e != 0) {...read
8650: 5f 72 65 74 20 3d 20 70 72 65 61 64 28 66 69 2d  _ret = pread(fi-
8660: 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20  >fh, buf, size, 
8670: 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28  offset);....if (
8680: 72 65 61 64 5f 72 65 74 20 3c 20 30 29 20 7b 0a  read_ret < 0) {.
8690: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
86a0: 65 72 72 6f 72 3a 20 72 65 61 64 20 66 61 69 6c  error: read fail
86b0: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ed");.....return
86c0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09  (errno * -1);...
86d0: 7d 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65  }....if (read_re
86e0: 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62 72 65  t == 0) {....bre
86f0: 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20  ak;...}....size 
8700: 2d 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 62  -= read_ret;...b
8710: 75 66 20 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b  uf  += read_ret;
8720: 0a 09 09 6f 66 66 73 65 74 20 2b 3d 20 72 65 61  ...offset += rea
8730: 64 5f 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20  d_ret;...retval 
8740: 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 7d 0a  += read_ret;..}.
8750: 0a 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29  ..if (size != 0)
8760: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8770: 28 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c  ("error: incompl
8780: 65 74 65 20 72 65 61 64 20 28 74 68 69 73 20 6d  ete read (this m
8790: 69 67 68 74 20 62 65 20 61 6e 20 65 72 72 6f 72  ight be an error
87a0: 20 62 65 63 61 75 73 65 20 46 55 53 45 20 77 69   because FUSE wi
87b0: 6c 6c 20 72 65 71 75 65 73 74 20 74 68 65 20 65  ll request the e
87c0: 78 61 63 74 20 6c 65 6e 67 74 68 20 6f 66 20 74  xact length of t
87d0: 68 65 20 66 69 6c 65 29 22 29 3b 0a 09 7d 0a 0a  he file)");..}..
87e0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65  .APPFS_DEBUG("Re
87f0: 74 75 72 6e 69 6e 67 3a 20 25 69 22 2c 20 72 65  turning: %i", re
8800: 74 76 61 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28  tval);...return(
8810: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
8820: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8830: 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63 68  e_write(const ch
8840: 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74 20  ar *path, const 
8850: 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f  char *buf, size_
8860: 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66  t size, off_t of
8870: 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73  fset, struct fus
8880: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
8890: 20 7b 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74   {..ssize_t writ
88a0: 65 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  e_ret;..int retv
88b0: 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  al;...APPFS_DEBU
88c0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
88d0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
88e0: 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  );...appfs_get_p
88f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72  ath_info_cache_r
8900: 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65  m(path, appfs_ge
8910: 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 72 65  t_fsuid());...re
8920: 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c  tval = 0;...whil
8930: 65 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a  e (size != 0) {.
8940: 09 09 77 72 69 74 65 5f 72 65 74 20 3d 20 70 77  ..write_ret = pw
8950: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66  rite(fi->fh, buf
8960: 2c 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b  , size, offset);
8970: 0a 0a 09 09 69 66 20 28 77 72 69 74 65 5f 72 65  ....if (write_re
8980: 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46  t < 0) {....APPF
8990: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
89a0: 77 72 69 74 65 20 66 61 69 6c 65 64 22 29 3b 0a  write failed");.
89b0: 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
89c0: 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69   * -1);...}....i
89d0: 66 20 28 77 72 69 74 65 5f 72 65 74 20 3d 3d 20  f (write_ret == 
89e0: 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  0) {....break;..
89f0: 09 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 77 72  .}....size -= wr
8a00: 69 74 65 5f 72 65 74 3b 0a 09 09 62 75 66 20 20  ite_ret;...buf  
8a10: 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09  += write_ret;...
8a20: 6f 66 66 73 65 74 20 2b 3d 20 77 72 69 74 65 5f  offset += write_
8a30: 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d  ret;...retval +=
8a40: 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a   write_ret;..}..
8a50: 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20  .if (size != 0) 
8a60: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
8a70: 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65  "error: incomple
8a80: 74 65 20 77 72 69 74 65 22 29 3b 0a 09 7d 0a 0a  te write");..}..
8a90: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
8aa0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
8ab0: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28  ppfs_fuse_mknod(
8ac0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
8ad0: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64  , mode_t mode, d
8ae0: 65 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09  ev_t device) {..
8af0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
8b00: 0a 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b  ..int mknod_ret;
8b10: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8b20: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
8b30: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
8b40: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
8b50: 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48  IFCHR) == S_IFCH
8b60: 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  R) {...return(-E
8b70: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  PERM);..}...if (
8b80: 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29  (mode & S_IFBLK)
8b90: 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09   == S_IFBLK) {..
8ba0: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
8bb0: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
8bc0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
8bd0: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
8be0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
8bf0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
8c00: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8c10: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8c20: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
8c30: 0a 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b  ..mknod_ret = mk
8c40: 6e 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  nod(real_path, m
8c50: 6f 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09  ode, device);...
8c60: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8c70: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
8c80: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
8c90: 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72  );...if (mknod_r
8ca0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
8cb0: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8cc0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
8cd0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
8ce0: 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65  ppfs_fuse_create
8cf0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8d00: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20  h, mode_t mode, 
8d10: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
8d20: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68  _info *fi) {..ch
8d30: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
8d40: 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f  int fd;...APPFS_
8d50: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
8d60: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
8d70: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
8d80: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
8d90: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
8da0: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
8db0: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
8dc0: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
8dd0: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
8de0: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
8df0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
8e00: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
8e10: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
8e20: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
8e30: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
8e40: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
8e50: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
8e60: 74 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72  ter();...fd = cr
8e70: 65 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  eat(real_path, m
8e80: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
8e90: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
8ea0: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
8eb0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
8ec0: 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74  (fd < 0) {...ret
8ed0: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8ee0: 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66  ..}...fi->fh = f
8ef0: 64 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  d;...return(0);.
8f00: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
8f10: 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74  pfs_fuse_truncat
8f20: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
8f30: 74 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20  th, off_t size) 
8f40: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
8f50: 74 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74  th;..int truncat
8f60: 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  e_ret;...APPFS_D
8f70: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
8f80: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
8f90: 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74  ath);...real_pat
8fa0: 68 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70  h = appfs_localp
8fb0: 61 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ath(path);..if (
8fc0: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
8fd0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
8fe0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
8ff0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
9000: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
9010: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
9020: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
9030: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
9040: 29 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65  );...truncate_re
9050: 74 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61  t = truncate(rea
9060: 6c 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a  l_path, size);..
9070: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
9080: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
9090: 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74  ...free(real_pat
90a0: 68 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61  h);...if (trunca
90b0: 74 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  te_ret != 0) {..
90c0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
90d0: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
90e0: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
90f0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e  nt appfs_fuse_un
9100: 6c 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74  link_rmdir(const
9110: 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09   char *path) {..
9120: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9130: 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  rp;..int tcl_ret
9140: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
9150: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
9160: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
9170: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
9180: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
9190: 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75  sh(appfs_get_fsu
91a0: 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74  id(), -1);...int
91b0: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
91c0: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
91d0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
91e0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
91f0: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
9200: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
9210: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
9220: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
9230: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
9240: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e   2, "::appfs::un
9250: 6c 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29  linkpath", path)
9260: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
9270: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
9280: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
9290: 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25  fs::unlinkpath(%
92a0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
92b0: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
92c0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
92d0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
92e0: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
92f0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
9300: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
9310: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
9320: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
9330: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
9340: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9350: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
9360: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
9370: 65 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28  erp);)...return(
9380: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
9390: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64  t appfs_fuse_mkd
93a0: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
93b0: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
93c0: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
93d0: 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72  path;..int mkdir
93e0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
93f0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
9400: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
9410: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68  th);...real_path
9420: 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65   = appfs_prepare
9430: 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29  _to_create(path)
9440: 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ;..if (real_path
9450: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
9460: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
9470: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
9480: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
9490: 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d  ...mkdir_ret = m
94a0: 6b 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c 20  kdir(real_path, 
94b0: 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  mode);...appfs_s
94c0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
94d0: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
94e0: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
94f0: 20 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20 30   (mkdir_ret != 0
9500: 29 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f 20  ) {...if (errno 
9510: 21 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09 09  != EEXIST) {....
9520: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
9530: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  1);...}..}...ret
9540: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
9550: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
9560: 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61  _chmod(const cha
9570: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
9580: 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  mode) {..Tcl_Int
9590: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
95a0: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
95b0: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ath;..int tcl_re
95c0: 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09  t, chmod_ret;...
95d0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
95e0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
95f0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
9600: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
9610: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
9620: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
9630: 64 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  d());...interp =
9640: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
9650: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
9660: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
9670: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
9680: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
9690: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
96a0: 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72  nterp);)...tcl_r
96b0: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
96c0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22  val(interp, 3, "
96d0: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
96e0: 68 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65  h", path, "write
96f0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
9700: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
9710: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
9720: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25  ppfs::openpath(%
9730: 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  s, %s) failed.",
9740: 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b   path, "write");
9750: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
9760: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
9770: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
9780: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
9790: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
97a0: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70  erp));...)....ap
97b0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
97c0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
97d0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
97e0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
97f0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
9800: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
9810: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
9820: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61  (interp);..)...a
9830: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
9840: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
9850: 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61  erp);)...if (rea
9860: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
9870: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
9880: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
9890: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
98a0: 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72  ter();...chmod_r
98b0: 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f  et = chmod(real_
98c0: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
98d0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
98e0: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
98f0: 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65  .return(chmod_re
9900: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
9910: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d  t appfs_fuse_sym
9920: 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20  link(const char 
9930: 2a 6f 6c 64 70 61 74 68 2c 20 63 6f 6e 73 74 20  *oldpath, const 
9940: 63 68 61 72 20 2a 6e 65 77 70 61 74 68 29 20 7b  char *newpath) {
9950: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
9960: 68 3b 0a 09 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f  h;..int symlink_
9970: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
9980: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
9990: 3d 20 25 73 2c 20 25 73 29 22 2c 20 6f 6c 64 70  = %s, %s)", oldp
99a0: 61 74 68 2c 20 6e 65 77 70 61 74 68 29 3b 0a 0a  ath, newpath);..
99b0: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70  .real_path = app
99c0: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72  fs_prepare_to_cr
99d0: 65 61 74 65 28 6e 65 77 70 61 74 68 29 3b 0a 09  eate(newpath);..
99e0: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
99f0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
9a00: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
9a10: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
9a20: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
9a30: 73 79 6d 6c 69 6e 6b 5f 72 65 74 20 3d 20 73 79  symlink_ret = sy
9a40: 6d 6c 69 6e 6b 28 6f 6c 64 70 61 74 68 2c 20 72  mlink(oldpath, r
9a50: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 61 70 70  eal_path);...app
9a60: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
9a70: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
9a80: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
9a90: 0a 09 69 66 20 28 73 79 6d 6c 69 6e 6b 5f 72 65  ..if (symlink_re
9aa0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
9ab0: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
9ac0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
9ad0: 7d 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33  }../*. * SQLite3
9ae0: 20 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72   mode: Execute r
9af0: 61 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72  aw SQL and retur
9b00: 6e 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69  n success or fai
9b10: 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20  lure. */.static 
9b20: 69 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65  int appfs_sqlite
9b30: 33 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71  3(const char *sq
9b40: 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  l) {..Tcl_Interp
9b50: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
9b60: 20 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a   char *sql_ret;.
9b70: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
9b80: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63  interp = appfs_c
9b90: 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28  reate_TclInterp(
9ba0: 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65  NULL);..if (inte
9bb0: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
9bc0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
9bd0: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
9be0: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
9bf0: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ter.  Aborting.\
9c00: 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  n");....return(1
9c10: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
9c20: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
9c30: 28 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61  (interp, 5, "::a
9c40: 70 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c  ppfs::db", "eval
9c50: 22 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22  ", sql, "row", "
9c60: 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69  unset -nocomplai
9c70: 6e 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79  n row(*); parray
9c80: 20 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d   row; puts \"---
9c90: 2d 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20  -\"");..sql_ret 
9ca0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
9cb0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a  esult(interp);..
9cc0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
9cd0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
9ce0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72  ntf(stderr, "[er
9cf0: 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f  ror] %s\n", sql_
9d00: 72 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  ret);....return(
9d10: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c  1);..}...if (sql
9d20: 5f 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b  _ret && sql_ret[
9d30: 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09  0] != '\0') {...
9d40: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73  printf("%s\n", s
9d50: 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65  ql_ret);..}...re
9d60: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20  turn(0);.}../*. 
9d70: 2a 20 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63  * Tcl mode: Exec
9d80: 75 74 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20  ute raw Tcl and 
9d90: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
9da0: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
9db0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74  atic int appfs_t
9dc0: 63 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74  cl(const char *t
9dd0: 63 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  cl) {..Tcl_Inter
9de0: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73  p *interp;..cons
9df0: 74 20 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75  t char *tcl_resu
9e00: 6c 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  lt;..int tcl_ret
9e10: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
9e20: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
9e30: 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28  erp(NULL);..if (
9e40: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
9e50: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
9e60: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
9e70: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
9e80: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69  rpreter.  Aborti
9e90: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75  ng.\n");....retu
9ea0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  rn(1);..}...tcl_
9eb0: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
9ec0: 6e 74 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63  nterp, tcl);..tc
9ed0: 6c 5f 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47  l_result = Tcl_G
9ee0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
9ef0: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63  nterp);...if (tc
9f00: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
9f10: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
9f20: 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73  err, "[error] %s
9f30: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72 28  \n", Tcl_GetVar(
9f40: 69 6e 74 65 72 70 2c 20 22 65 72 72 6f 72 49 6e  interp, "errorIn
9f50: 66 6f 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f  fo", TCL_GLOBAL_
9f60: 4f 4e 4c 59 29 29 3b 0a 0a 09 09 72 65 74 75 72  ONLY));....retur
9f70: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74  n(1);..}...if (t
9f80: 63 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c  cl_result && tcl
9f90: 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c  _result[0] != '\
9fa0: 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22  0') {...printf("
9fb0: 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c  %s\n", tcl_resul
9fc0: 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  t);..}...return(
9fd0: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70  0);.}../*. * App
9fe0: 46 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20  FSd Package for 
9ff0: 54 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20  Tcl:. *         
a000: 42 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f  Bridge for I/O o
a010: 70 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71  perations to req
a020: 75 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  uest information
a030: 20 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65   about the curre
a040: 6e 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72  nt. *         tr
a050: 61 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a  ansaction. */./*
a060: 0a 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63  . * Tcl interfac
a070: 65 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d  e to get the hom
a080: 65 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20  e directory for 
a090: 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20  the user making 
a0a0: 74 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a  the "current". *
a0b0: 20 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73   FUSE I/O reques
a0c0: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t. */.static int
a0d0: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68   tcl_appfs_get_h
a0e0: 6f 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74  omedir(ClientDat
a0f0: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
a100: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
a110: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
a120: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68  ST objv[]) {..ch
a130: 61 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63  ar *homedir;..Tc
a140: 6c 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f  l_Obj *homedir_o
a150: 62 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  bj;..uid_t fsuid
a160: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
a170: 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74  ad Tcl_Obj *last
a180: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e  _homedir_obj = N
a190: 55 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74  ULL;..static __t
a1a0: 68 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74  hread uid_t last
a1b0: 5f 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20  _fsuid = -1;..  
a1c0: 20 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21        if (objc !
a1d0: 3d 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  = 1) {.         
a1e0: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
a1f0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
a200: 31 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a  1, objv, NULL);.
a210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a220: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
a230: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66  );.        }...f
a240: 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74  suid = appfs_get
a250: 5f 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28  _fsuid();...if (
a260: 66 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73  fsuid == last_fs
a270: 75 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65  uid && last_home
a280: 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29  dir_obj != NULL)
a290: 20 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a   {...homedir_obj
a2a0: 20 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f   = last_homedir_
a2b0: 6f 62 6a 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72  obj;....Tcl_Incr
a2c0: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72  RefCount(homedir
a2d0: 5f 6f 62 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  _obj);..} else {
a2e0: 0a 09 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70  ...homedir = app
a2f0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61  fs_get_homedir(a
a300: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
a310: 29 3b 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69  );....if (homedi
a320: 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  r == NULL) {....
a330: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
a340: 29 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69  );...}....homedi
a350: 72 5f 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53  r_obj = Tcl_NewS
a360: 74 72 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72  tringObj(homedir
a370: 2c 20 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68  , -1);....free(h
a380: 6f 6d 65 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f  omedir);....Tcl_
a390: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d  IncrRefCount(hom
a3a0: 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66  edir_obj);....if
a3b0: 20 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f   (last_homedir_o
a3c0: 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  bj != NULL) {...
a3d0: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e  .Tcl_DecrRefCoun
a3e0: 74 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  t(last_homedir_o
a3f0: 62 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74  bj);...}....last
a400: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68  _homedir_obj = h
a410: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61  omedir_obj;...la
a420: 73 74 5f 66 73 75 69 64 20 3d 20 66 73 75 69 64  st_fsuid = fsuid
a430: 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
a440: 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62  Count(homedir_ob
a450: 6a 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09  j);..}..       .
a460: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
a470: 28 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72  (interp, homedir
a480: 5f 6f 62 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63  _obj);...Tcl_Dec
a490: 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69  rRefCount(homedi
a4a0: 72 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20  r_obj);..       
a4b0: 20 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b   return(TCL_OK);
a4c0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
a4d0: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
a4e0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
a4f0: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
a500: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
a510: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
a520: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
a530: 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d  []) {..appfs_sim
a540: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
a550: 74 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ter();...return(
a560: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
a570: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
a580: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
a590: 73 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61  s_leave(ClientDa
a5a0: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
a5b0: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
a5c0: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
a5d0: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61  NST objv[]) {..a
a5e0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
a5f0: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
a600: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
a610: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
a620: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75  cl_appfs_get_fsu
a630: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
a640: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
a650: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
a660: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
a670: 62 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20  bjv[]) {..uid_t 
a680: 66 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d  fsuid;...fsuid =
a690: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
a6a0: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
a6b0: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
a6c0: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
a6d0: 65 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b  eIntObj(fsuid));
a6e0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
a6f0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
a700: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
a710: 73 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20  sgid(ClientData 
a720: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
a730: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
a740: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
a750: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f   objv[]) {..gid_
a760: 74 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64  t fsgid;...fsgid
a770: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67   = appfs_get_fsg
a780: 69 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54  id();..       .T
a790: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
a7a0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57  interp, Tcl_NewW
a7b0: 69 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29  ideIntObj(fsgid)
a7c0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
a7d0: 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  OK);.}..static i
a7e0: 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  nt tcl_appfs_get
a7f0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
a800: 5f 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74  _flush(ClientDat
a810: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
a820: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
a830: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
a840: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e  ST objv[]) {..in
a850: 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20  t tcl_ret;..int 
a860: 6e 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f  new_size;...new_
a870: 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20  size = -1;...if 
a880: 28 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09  (objc == 2) {...
a890: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
a8a0: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
a8b0: 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65  rp, objv[1], &ne
a8c0: 77 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74  w_size);...if (t
a8d0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
a8e0: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63  ) {....return(tc
a8f0: 6c 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65  l_ret);...}..} e
a900: 6c 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32  lse if (objc > 2
a910: 20 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a   || objc < 1) {.
a920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a930: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
a940: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
a950: 2c 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69  , "?new_cache_si
a960: 7a 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28  ze?");...return(
a970: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a  TCL_ERROR);..}..
a980: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
a990: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
a9a0: 28 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a  (-1, new_size);.
a9b0: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
a9c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a9d0: 41 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f  Appfsd_Init(Tcl_
a9e0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20  Interp *interp) 
a9f0: 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c  {.#ifdef USE_TCL
aa00: 5f 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f  _STUBS..if (Tcl_
aa10: 49 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70  InitStubs(interp
aa20: 2c 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30  , TCL_VERSION, 0
aa30: 29 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74  ) == 0L) {...ret
aa40: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
aa50: 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f  .}.#endif...Tcl_
aa60: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
aa70: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
aa80: 3a 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20  ::get_homedir", 
aa90: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f  tcl_appfs_get_ho
aaa0: 6d 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  medir, NULL, NUL
aab0: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
aac0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
aad0: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66  , "appfsd::get_f
aae0: 73 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73  suid", tcl_appfs
aaf0: 5f 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c  _get_fsuid, NULL
ab00: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
ab10: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
ab20: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
ab30: 67 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f  get_fsgid", tcl_
ab40: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c  appfs_get_fsgid,
ab50: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
ab60: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
ab70: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
ab80: 66 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73  fsd::simulate_us
ab90: 65 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63  er_fs_enter", tc
aba0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
abb0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20  _user_fs_enter, 
abc0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63  NULL, NULL);..Tc
abd0: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
abe0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66  nd(interp, "appf
abf0: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65  sd::simulate_use
ac00: 72 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c  r_fs_leave", tcl
ac10: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
ac20: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e  user_fs_leave, N
ac30: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
ac40: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
ac50: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
ac60: 64 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  d::get_path_info
ac70: 5f 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74  _cache_flush", t
ac80: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74  cl_appfs_get_pat
ac90: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
aca0: 73 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  sh, NULL, NULL);
acb0: 0a 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64  ...Tcl_PkgProvid
acc0: 65 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  e(interp, "appfs
acd0: 64 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65  d", "1.0");...re
ace0: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
acf0: 0a 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61  ./*. * Hot-resta
ad00: 72 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f  rt support. */./
ad10: 2a 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74  * Initiate a hot
ad20: 2d 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74  -restart */.stat
ad30: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f  ic void appfs_ho
ad40: 74 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20  t_restart(void) 
ad50: 7b 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  {..APPFS_DEBUG("
ad60: 41 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74  Asked to initiat
ad70: 65 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b  e hot restart");
ad80: 0a 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73  ...appfs_tcl_Res
ad90: 65 74 49 6e 74 65 72 70 73 28 29 3b 0a 0a 09 61  etInterps();...a
ada0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
adb0: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d  fo_cache_flush(-
adc0: 31 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e  1, -1);...return
add0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61  ;.}../*. * Signa
ade0: 6c 20 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20  l handler. *    
adf0: 20 20 20 20 20 53 49 47 48 55 50 20 69 6e 69 74       SIGHUP init
ae00: 69 61 74 65 73 20 61 20 68 6f 74 20 72 65 73 74  iates a hot rest
ae10: 61 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76  art. */.static v
ae20: 6f 69 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c  oid appfs_signal
ae30: 5f 68 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67  _handler(int sig
ae40: 29 20 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68  ) {../* Do not h
ae50: 61 6e 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e  andle signals un
ae60: 74 69 6c 20 46 55 53 45 20 68 61 73 20 62 65 65  til FUSE has bee
ae70: 6e 20 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66  n started */..if
ae80: 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74   (!appfs_fuse_st
ae90: 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72  arted) {...retur
aea0: 6e 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65  n;..}.../* Reque
aeb0: 73 74 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20  st to perform a 
aec0: 22 68 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f  "hot" restart */
aed0: 0a 09 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47  ..if (sig == SIG
aee0: 48 55 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68  HUP) {...appfs_h
aef0: 6f 74 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d  ot_restart();..}
af00: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a  ...return;.}../*
af10: 0a 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20  . * Terminate a 
af20: 74 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69  thread. */.stati
af30: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72  c void appfs_ter
af40: 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e  minate_interp_an
af50: 64 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a 5f  d_thread(void *_
af60: 69 6e 74 65 72 70 29 20 7b 0a 09 54 63 6c 5f 49  interp) {..Tcl_I
af70: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 0a  nterp *interp;..
af80: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
af90: 6c 6c 65 64 3a 20 5f 69 6e 74 65 72 70 20 3d 20  lled: _interp = 
afa0: 25 70 22 2c 20 5f 69 6e 74 65 72 70 29 3b 0a 0a  %p", _interp);..
afb0: 09 69 66 20 28 5f 69 6e 74 65 72 70 20 3d 3d 20  .if (_interp == 
afc0: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
afd0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
afe0: 6e 67 20 74 68 72 65 61 64 20 77 69 74 68 20 6e  ng thread with n
aff0: 6f 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  o interpreter");
b000: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
b010: 09 69 6e 74 65 72 70 20 3d 20 5f 69 6e 74 65 72  .interp = _inter
b020: 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  p;...APPFS_DEBUG
b030: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 69 6e  ("Terminating in
b040: 74 65 72 70 72 65 74 65 72 20 64 75 65 20 74 6f  terpreter due to
b050: 20 74 68 72 65 61 64 20 74 65 72 6d 69 6e 61 74   thread terminat
b060: 69 6f 6e 22 29 3b 0a 0a 09 61 70 70 66 73 5f 63  ion");...appfs_c
b070: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63  all_libtcl(...Tc
b080: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
b090: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70  nterp);..)...app
b0a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
b0b0: 09 09 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 54 68  ..Tcl_FinalizeTh
b0c0: 72 65 61 64 28 29 3b 0a 09 29 0a 0a 09 72 65 74  read();..)...ret
b0d0: 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 6f  urn;.}../*. * Co
b0e0: 6d 6d 61 6e 64 2d 6c 69 6e 65 20 70 61 72 73 69  mmand-line parsi
b0f0: 6e 67 20 74 6f 6f 6c 73 0a 20 2a 2f 0a 73 74 61  ng tools. */.sta
b100: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 70  tic void appfs_p
b110: 72 69 6e 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a  rint_help(FILE *
b120: 63 68 61 6e 6e 65 6c 29 20 7b 0a 09 66 70 72 69  channel) {..fpri
b130: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 55 73  ntf(channel, "Us
b140: 61 67 65 3a 20 7b 61 70 70 66 73 64 7c 6d 6f 75  age: {appfsd|mou
b150: 6e 74 2e 61 70 70 66 73 7d 20 5b 2d 6f 20 3c 6f  nt.appfs} [-o <o
b160: 70 74 69 6f 6e 3e 5d 20 5b 2d 64 66 73 68 5d 20  ption>] [-dfsh] 
b170: 3c 63 61 63 68 65 64 69 72 3e 20 3c 6d 6f 75 6e  <cachedir> <moun
b180: 74 70 6f 69 6e 74 3e 5c 6e 22 29 3b 0a 09 66 70  tpoint>\n");..fp
b190: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b1a0: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b1b0: 68 61 6e 6e 65 6c 2c 20 22 4f 70 74 69 6f 6e 73  hannel, "Options
b1c0: 3a 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  :\n");..fprintf(
b1d0: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 64 20 20  channel, "  -d  
b1e0: 20 20 20 20 20 20 20 20 20 20 20 20 45 6e 61 62              Enab
b1f0: 6c 65 20 46 55 53 45 20 64 65 62 75 67 20 6d 6f  le FUSE debug mo
b200: 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74  de.\n");..fprint
b210: 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 66  f(channel, "  -f
b220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 52 75                Ru
b230: 6e 20 69 6e 20 66 6f 72 65 67 72 6f 75 6e 64 2e  n in foreground.
b240: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b250: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 73 20 20 20  hannel, "  -s   
b260: 20 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c             Enabl
b270: 65 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65  e single threade
b280: 64 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70  d mode.\n");..fp
b290: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b2a0: 20 20 2d 68 20 20 20 20 20 20 20 20 20 20 20 20    -h            
b2b0: 20 20 47 69 76 65 20 74 68 69 73 20 68 65 6c 70    Give this help
b2c0: 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  .\n");..fprintf(
b2d0: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 6e  channel, "  -o n
b2e0: 6f 74 68 72 65 61 64 73 20 20 20 20 45 6e 61 62  othreads    Enab
b2f0: 6c 65 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64  le single thread
b300: 65 64 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66  ed mode.\n");..f
b310: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b320: 22 20 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68 65  "  -o allow_othe
b330: 72 20 20 41 6c 6c 6f 77 20 6f 74 68 65 72 20 75  r  Allow other u
b340: 73 65 72 73 20 74 6f 20 61 63 63 65 73 73 20 74  sers to access t
b350: 68 69 73 20 6d 6f 75 6e 74 70 6f 69 6e 74 20 28  his mountpoint (
b360: 64 65 66 61 75 6c 74 5c 6e 22 29 3b 0a 09 66 70  default\n");..fp
b370: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b390: 20 20 69 66 20 72 6f 6f 74 29 2e 5c 6e 22 29 3b    if root).\n");
b3a0: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74  ...return;.}..st
b3b0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 6f  atic int appfs_o
b3c0: 70 74 5f 70 61 72 73 65 28 69 6e 74 20 61 72 67  pt_parse(int arg
b3d0: 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 20  c, char **argv, 
b3e0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67   struct fuse_arg
b3f0: 73 20 2a 61 72 67 73 29 20 7b 0a 09 69 6e 74 20  s *args) {..int 
b400: 63 68 3b 0a 09 63 68 61 72 20 2a 6f 70 74 73 74  ch;..char *optst
b410: 72 2c 20 2a 6f 70 74 73 74 72 5f 6e 65 78 74 2c  r, *optstr_next,
b420: 20 2a 6f 70 74 73 74 72 5f 73 3b 0a 09 63 68 61   *optstr_s;..cha
b430: 72 20 66 61 6b 65 5f 61 72 67 5b 33 5d 20 3d 20  r fake_arg[3] = 
b440: 7b 27 2d 27 2c 20 30 2c 20 30 7d 3b 0a 0a 09 2f  {'-', 0, 0};.../
b450: 2a 0a 09 20 2a 20 44 65 66 61 75 6c 74 20 76 61  *.. * Default va
b460: 6c 75 65 73 0a 09 20 2a 2f 0a 23 69 66 64 65 66  lues.. */.#ifdef
b470: 20 54 43 4c 5f 54 48 52 45 41 44 53 0a 09 61 70   TCL_THREADS..ap
b480: 70 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c  pfs_threaded_tcl
b490: 20 3d 20 31 3b 0a 23 65 6c 73 65 0a 09 61 70 70   = 1;.#else..app
b4a0: 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20  fs_threaded_tcl 
b4b0: 3d 20 30 3b 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a  = 0;.#endif.../*
b4c0: 2a 0a 09 20 2a 2a 20 41 64 64 20 46 55 53 45 20  *.. ** Add FUSE 
b4d0: 61 72 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20  arguments which 
b4e0: 77 65 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79  we always supply
b4f0: 0a 09 20 2a 2a 2f 0a 09 66 75 73 65 5f 6f 70 74  .. **/..fuse_opt
b500: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22  _add_arg(args, "
b510: 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73  -odefault_permis
b520: 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70  sions,fsname=app
b530: 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73  fs,subtype=appfs
b540: 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c  d,use_ino,kernel
b550: 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69 6d  _cache,entry_tim
b560: 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d 65  eout=0,attr_time
b570: 6f 75 74 3d 30 2c 62 69 67 5f 77 72 69 74 65 73  out=0,big_writes
b580: 2c 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d 6f 76  ,intr,hard_remov
b590: 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75 69  e");...if (getui
b5a0: 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66 75  d() == 0) {...fu
b5b0: 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67  se_opt_parse(arg
b5c0: 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e  s, NULL, NULL, N
b5d0: 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74  ULL);...fuse_opt
b5e0: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22  _add_arg(args, "
b5f0: 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b  -oallow_other");
b600: 0a 09 7d 0a 0a 09 77 68 69 6c 65 20 28 28 63 68  ..}...while ((ch
b610: 20 3d 20 67 65 74 6f 70 74 28 61 72 67 63 2c 20   = getopt(argc, 
b620: 61 72 67 76 2c 20 22 64 66 73 68 76 6f 3a 22 29  argv, "dfshvo:")
b630: 29 20 21 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69  ) != -1) {...swi
b640: 74 63 68 20 28 63 68 29 20 7b 0a 09 09 09 63 61  tch (ch) {....ca
b650: 73 65 20 27 76 27 3a 0a 09 09 09 09 2f 2a 20 49  se 'v':...../* I
b660: 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09 09 62 72  gnored */.....br
b670: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 6f 27  eak;....case 'o'
b680: 3a 0a 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78  :.....optstr_nex
b690: 74 20 3d 20 6f 70 74 73 74 72 20 3d 20 6f 70 74  t = optstr = opt
b6a0: 73 74 72 5f 73 20 3d 20 73 74 72 64 75 70 28 6f  str_s = strdup(o
b6b0: 70 74 61 72 67 29 3b 0a 0a 09 09 09 09 77 68 69  ptarg);......whi
b6c0: 6c 65 20 28 31 29 20 7b 0a 09 09 09 09 09 6f 70  le (1) {......op
b6d0: 74 73 74 72 20 3d 20 6f 70 74 73 74 72 5f 6e 65  tstr = optstr_ne
b6e0: 78 74 3b 0a 0a 09 09 09 09 09 69 66 20 28 21 6f  xt;.......if (!o
b6f0: 70 74 73 74 72 29 20 7b 0a 09 09 09 09 09 09 62  ptstr) {.......b
b700: 72 65 61 6b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09  reak;......}....
b710: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d  ...optstr_next =
b720: 20 73 74 72 63 68 72 28 6f 70 74 73 74 72 2c 20   strchr(optstr, 
b730: 27 2c 27 29 3b 0a 09 09 09 09 09 69 66 20 28 6f  ',');......if (o
b740: 70 74 73 74 72 5f 6e 65 78 74 29 20 7b 0a 09 09  ptstr_next) {...
b750: 09 09 09 09 2a 6f 70 74 73 74 72 5f 6e 65 78 74  ....*optstr_next
b760: 20 3d 20 27 5c 30 27 3b 0a 09 09 09 09 09 09 6f   = '\0';.......o
b770: 70 74 73 74 72 5f 6e 65 78 74 2b 2b 3b 0a 09 09  ptstr_next++;...
b780: 09 09 09 7d 0a 0a 09 09 09 09 09 69 66 20 28 73  ...}.......if (s
b790: 74 72 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 6e  trcmp(optstr, "n
b7a0: 6f 74 68 72 65 61 64 73 22 29 20 3d 3d 20 30 29  othreads") == 0)
b7b0: 20 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f 44   {.......APPFS_D
b7c0: 45 42 55 47 28 22 50 61 73 73 69 6e 67 20 6f 70  EBUG("Passing op
b7d0: 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d 73  tion to FUSE: -s
b7e0: 22 29 3b 0a 0a 09 09 09 09 09 09 66 75 73 65 5f  ");........fuse_
b7f0: 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20  opt_parse(args, 
b800: 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  NULL, NULL, NULL
b810: 29 3b 0a 09 09 09 09 09 09 66 75 73 65 5f 6f 70  );.......fuse_op
b820: 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20  t_add_arg(args, 
b830: 22 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09 61 70  "-s");........ap
b840: 70 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c  pfs_threaded_tcl
b850: 20 3d 20 30 3b 0a 09 09 09 09 09 7d 20 65 6c 73   = 0;......} els
b860: 65 20 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74  e if (strcmp(opt
b870: 73 74 72 2c 20 22 61 6c 6c 6f 77 5f 6f 74 68 65  str, "allow_othe
b880: 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09  r") == 0) {.....
b890: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50  ..APPFS_DEBUG("P
b8a0: 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f  assing option to
b8b0: 20 46 55 53 45 3a 20 2d 6f 20 61 6c 6c 6f 77 5f   FUSE: -o allow_
b8c0: 4f 74 68 65 72 22 29 3b 0a 0a 09 09 09 09 09 09  Other");........
b8d0: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61  fuse_opt_parse(a
b8e0: 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  rgs, NULL, NULL,
b8f0: 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75   NULL);.......fu
b900: 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61  se_opt_add_arg(a
b910: 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74  rgs, "-oallow_ot
b920: 68 65 72 22 29 3b 0a 09 09 09 09 09 7d 20 65 6c  her");......} el
b930: 73 65 20 69 66 20 28 73 74 72 63 6d 70 28 6f 70  se if (strcmp(op
b940: 74 73 74 72 2c 20 22 72 77 22 29 20 3d 3d 20 30  tstr, "rw") == 0
b950: 29 20 7b 0a 09 09 09 09 09 09 2f 2a 20 49 67 6e  ) {......./* Ign
b960: 6f 72 65 64 20 2a 2f 0a 09 09 09 09 09 7d 20 65  ored */......} e
b970: 6c 73 65 20 7b 0a 09 09 09 09 09 09 66 70 72 69  lse {.......fpri
b980: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 61 70 70  ntf(stderr, "app
b990: 66 73 64 3a 20 69 6e 76 61 6c 69 64 20 6f 70 74  fsd: invalid opt
b9a0: 69 6f 6e 3a 20 5c 22 2d 6f 20 25 73 5c 22 5c 6e  ion: \"-o %s\"\n
b9b0: 22 2c 20 6f 70 74 73 74 72 29 3b 0a 0a 09 09 09  ", optstr);.....
b9c0: 09 09 09 66 72 65 65 28 6f 70 74 73 74 72 5f 73  ...free(optstr_s
b9d0: 29 3b 0a 0a 09 09 09 09 09 09 72 65 74 75 72 6e  );........return
b9e0: 28 31 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09  (1);......}.....
b9f0: 7d 0a 0a 09 09 09 09 66 72 65 65 28 6f 70 74 73  }......free(opts
ba00: 74 72 5f 73 29 3b 0a 0a 09 09 09 09 62 72 65 61  tr_s);......brea
ba10: 6b 3b 0a 09 09 09 63 61 73 65 20 27 64 27 3a 0a  k;....case 'd':.
ba20: 09 09 09 63 61 73 65 20 27 66 27 3a 0a 09 09 09  ...case 'f':....
ba30: 63 61 73 65 20 27 73 27 3a 0a 09 09 09 09 69 66  case 's':.....if
ba40: 20 28 63 68 20 3d 3d 20 27 73 27 29 20 7b 0a 09   (ch == 's') {..
ba50: 09 09 09 09 61 70 70 66 73 5f 74 68 72 65 61 64  ....appfs_thread
ba60: 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09  ed_tcl = 0;.....
ba70: 7d 0a 0a 09 09 09 09 66 61 6b 65 5f 61 72 67 5b  }......fake_arg[
ba80: 31 5d 20 3d 20 63 68 3b 0a 0a 09 09 09 09 41 50  1] = ch;......AP
ba90: 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73 69  PFS_DEBUG("Passi
baa0: 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53  ng option to FUS
bab0: 45 3a 20 25 73 22 2c 20 66 61 6b 65 5f 61 72 67  E: %s", fake_arg
bac0: 29 3b 0a 0a 09 09 09 09 66 75 73 65 5f 6f 70 74  );......fuse_opt
bad0: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
bae0: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
baf0: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ....fuse_opt_add
bb00: 5f 61 72 67 28 61 72 67 73 2c 20 66 61 6b 65 5f  _arg(args, fake_
bb10: 61 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b  arg);.....break;
bb20: 0a 09 09 09 63 61 73 65 20 27 68 27 3a 0a 09 09  ....case 'h':...
bb30: 09 09 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65  ..appfs_print_he
bb40: 6c 70 28 73 74 64 6f 75 74 29 3b 0a 0a 09 09 09  lp(stdout);.....
bb50: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 09 09  .return(-1);....
bb60: 63 61 73 65 20 27 3a 27 3a 0a 09 09 09 63 61 73  case ':':....cas
bb70: 65 20 27 3f 27 3a 0a 09 09 09 64 65 66 61 75 6c  e '?':....defaul
bb80: 74 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72 69  t:.....appfs_pri
bb90: 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 72 29 3b  nt_help(stderr);
bba0: 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 31 29 3b  ......return(1);
bbb0: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 28 6f  ...}..}...if ((o
bbc0: 70 74 69 6e 64 20 2b 20 32 29 20 21 3d 20 61 72  ptind + 2) != ar
bbd0: 67 63 29 20 7b 0a 09 09 69 66 20 28 28 6f 70 74  gc) {...if ((opt
bbe0: 69 6e 64 20 2b 20 32 29 20 3c 20 61 72 67 63 29  ind + 2) < argc)
bbf0: 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74   {....fprintf(st
bc00: 64 65 72 72 2c 20 22 54 6f 6f 20 6d 61 6e 79 20  derr, "Too many 
bc10: 61 72 67 75 6d 65 6e 74 73 5c 6e 22 29 3b 0a 09  arguments\n");..
bc20: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 66 70 72  .} else {....fpr
bc30: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 4d 69  intf(stderr, "Mi
bc40: 73 73 69 6e 67 20 63 61 63 68 65 64 69 72 20 6f  ssing cachedir o
bc50: 72 20 6d 6f 75 6e 74 70 6f 69 6e 74 5c 6e 22 29  r mountpoint\n")
bc60: 3b 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 70  ;...}....appfs_p
bc70: 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 72  rint_help(stderr
bc80: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
bc90: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74  ..}.../*.. * Set
bca0: 20 63 61 63 68 65 20 64 69 72 20 61 73 20 66 69   cache dir as fi
bcb0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 28 74 68  rst argument (th
bcc0: 65 20 22 64 65 76 69 63 65 22 2c 20 65 73 73 65  e "device", esse
bcd0: 6e 74 69 61 6c 6c 79 29 0a 09 20 2a 2f 0a 09 61  ntially).. */..a
bce0: 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20  ppfs_cachedir = 
bcf0: 61 72 67 76 5b 6f 70 74 69 6e 64 5d 3b 0a 0a 09  argv[optind];...
bd00: 2f 2a 0a 09 20 2a 20 50 61 73 73 20 74 68 65 20  /*.. * Pass the 
bd10: 72 65 6d 61 69 6e 69 6e 67 20 61 72 67 75 6d 65  remaining argume
bd20: 6e 74 20 74 6f 20 46 55 53 45 20 61 73 20 74 68  nt to FUSE as th
bd30: 65 20 64 69 72 65 63 74 6f 72 79 0a 09 20 2a 2f  e directory.. */
bd40: 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
bd50: 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  (args, NULL, NUL
bd60: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 66 75 73 65 5f  L, NULL);..fuse_
bd70: 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73  opt_add_arg(args
bd80: 2c 20 61 72 67 76 5b 6f 70 74 69 6e 64 20 2b 20  , argv[optind + 
bd90: 31 5d 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29  1]);...return(0)
bda0: 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45  ;.}.../*. * FUSE
bdb0: 20 6f 70 65 72 61 74 69 6f 6e 73 20 73 74 72 75   operations stru
bdc0: 63 74 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63  cture. */.static
bdd0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 6f 70 65   struct fuse_ope
bde0: 72 61 74 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70  rations appfs_op
bdf0: 65 72 61 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e 67  erations = {...g
be00: 65 74 61 74 74 72 20 20 20 3d 20 61 70 70 66 73  etattr   = appfs
be10: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 2c 0a 09  _fuse_getattr,..
be20: 2e 72 65 61 64 64 69 72 20 20 20 3d 20 61 70 70  .readdir   = app
be30: 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72 2c  fs_fuse_readdir,
be40: 0a 09 2e 72 65 61 64 6c 69 6e 6b 20 20 3d 20 61  ...readlink  = a
be50: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69  ppfs_fuse_readli
be60: 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20 20 20 20  nk,...open      
be70: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65  = appfs_fuse_ope
be80: 6e 2c 0a 09 2e 72 65 6c 65 61 73 65 20 20 20 3d  n,...release   =
be90: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73   appfs_fuse_clos
bea0: 65 2c 0a 09 2e 72 65 61 64 20 20 20 20 20 20 3d  e,...read      =
beb0: 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64   appfs_fuse_read
bec0: 2c 0a 09 2e 77 72 69 74 65 20 20 20 20 20 3d 20  ,...write     = 
bed0: 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65  appfs_fuse_write
bee0: 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d 20  ,...mknod     = 
bef0: 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64  appfs_fuse_mknod
bf00: 2c 0a 09 2e 63 72 65 61 74 65 20 20 20 20 3d 20  ,...create    = 
bf10: 61 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74  appfs_fuse_creat
bf20: 65 2c 0a 09 2e 74 72 75 6e 63 61 74 65 20 20 3d  e,...truncate  =
bf30: 20 61 70 70 66 73 5f 66 75 73 65 5f 74 72 75 6e   appfs_fuse_trun
bf40: 63 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20 20  cate,...unlink  
bf50: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75    = appfs_fuse_u
bf60: 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 72  nlink_rmdir,...r
bf70: 6d 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73  mdir     = appfs
bf80: 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64  _fuse_unlink_rmd
bf90: 69 72 2c 0a 09 2e 6d 6b 64 69 72 20 20 20 20 20  ir,...mkdir     
bfa0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64  = appfs_fuse_mkd
bfb0: 69 72 2c 0a 09 2e 63 68 6d 6f 64 20 20 20 20 20  ir,...chmod     
bfc0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d  = appfs_fuse_chm
bfd0: 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e 6b 20 20 20  od,...symlink   
bfe0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d  = appfs_fuse_sym
bff0: 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20  link,.};../*. * 
c000: 45 6e 74 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f  Entry point into
c010: 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20   this program.. 
c020: 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20  */.int main(int 
c030: 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67  argc, char **arg
c040: 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  v) {..Tcl_Interp
c050: 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09   *test_interp;..
c060: 63 68 61 72 20 2a 74 65 73 74 5f 69 6e 74 65 72  char *test_inter
c070: 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72 75 63 74  p_error;..struct
c080: 20 66 75 73 65 5f 61 72 67 73 20 61 72 67 73 20   fuse_args args 
c090: 3d 20 46 55 53 45 5f 41 52 47 53 5f 49 4e 49 54  = FUSE_ARGS_INIT
c0a0: 28 30 2c 20 4e 55 4c 4c 29 3b 0a 09 69 6e 74 20  (0, NULL);..int 
c0b0: 70 74 68 72 65 61 64 5f 72 65 74 2c 20 61 6f 70  pthread_ret, aop
c0c0: 5f 72 65 74 3b 0a 09 76 6f 69 64 20 2a 73 69 67  _ret;..void *sig
c0d0: 6e 61 6c 5f 72 65 74 3b 0a 09 63 68 61 72 20 2a  nal_ret;..char *
c0e0: 61 72 67 76 30 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  argv0;.../*.. * 
c0f0: 53 6b 69 70 20 70 61 73 73 65 64 20 70 72 6f 67  Skip passed prog
c100: 72 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f 0a 09 69  ram name.. */..i
c110: 66 20 28 61 72 67 63 20 3d 3d 20 30 20 7c 7c 20  f (argc == 0 || 
c120: 61 72 67 76 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  argv == NULL) {.
c130: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
c140: 0a 09 61 72 67 76 30 20 3d 20 61 72 67 76 5b 30  ..argv0 = argv[0
c150: 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b 0a 09 61 72  ];...argc--;..ar
c160: 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  gv++;.../*.. * S
c170: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  et global variab
c180: 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f 75 6c  les, these shoul
c190: 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61 74 69  d be configurati
c1a0: 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20 2a 2f  on options... */
c1b0: 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
c1c0: 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45 44 49   = APPFS_CACHEDI
c1d0: 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20  R;.../*.. * Set 
c1e0: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20  global variable 
c1f0: 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65 22 20  for "boot time" 
c200: 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20 6f 6e  to set a time on
c210: 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09 20 2a   directories.. *
c220: 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e 0a 09   that we fake...
c230: 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f 74 74   */..appfs_boott
c240: 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c 4c 29  ime = time(NULL)
c250: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73  ;.../*.. * Regis
c260: 74 65 72 20 22 73 68 61 31 22 20 61 6e 64 20 22  ter "sha1" and "
c270: 61 70 70 66 73 64 22 20 70 61 63 6b 61 67 65 20  appfsd" package 
c280: 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f 20 74  with libtcl so t
c290: 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20 2a 20  hat any new.. * 
c2a0: 69 6e 74 65 72 70 72 65 74 65 72 73 20 63 72 65  interpreters cre
c2b0: 61 74 65 64 20 28 77 68 69 63 68 20 61 72 65 20  ated (which are 
c2c0: 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c 6c 79  done dynamically
c2d0: 20 62 79 20 46 55 53 45 29 20 63 61 6e 20 68 61   by FUSE) can ha
c2e0: 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70 72 6f  ve.. * the appro
c2f0: 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75 72 61  priate configura
c300: 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f 6d 61  tion done automa
c310: 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a 09 54  tically... */..T
c320: 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61 67 65  cl_StaticPackage
c330: 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c 20 53  (NULL, "sha1", S
c340: 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b  ha1_Init, NULL);
c350: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b  ..Tcl_StaticPack
c360: 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70 66 73  age(NULL, "appfs
c370: 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69 74 2c  d", Appfsd_Init,
c380: 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a   NULL);.../*.. *
c390: 20 43 72 65 61 74 65 20 61 20 74 68 72 65 61 64   Create a thread
c3a0: 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61 20 28  -specific-data (
c3b0: 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65 61 63  TSD) key for eac
c3c0: 68 20 74 68 72 65 61 64 20 74 6f 20 72 65 66 65  h thread to refe
c3d0: 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f 77 6e  r.. * to its own
c3e0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
c3f0: 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  .  Tcl interpret
c400: 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e 69 71  ers must be uniq
c410: 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72 65 61  ue per.. * threa
c420: 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65 61 64  d and new thread
c430: 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61 6c 6c  s are dynamicall
c440: 79 20 63 72 65 61 74 65 64 20 62 79 20 46 55 53  y created by FUS
c450: 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65 61 64  E... */..pthread
c460: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6b  _ret = pthread_k
c470: 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74 65 72  ey_create(&inter
c480: 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 65 72 6d  pKey, appfs_term
c490: 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64  inate_interp_and
c4a0: 5f 74 68 72 65 61 64 29 3b 0a 09 69 66 20 28 70  _thread);..if (p
c4b0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
c4c0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
c4d0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
c4e0: 63 72 65 61 74 65 20 54 53 44 20 6b 65 79 20 66  create TSD key f
c4f0: 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e  or Tcl.  Abortin
c500: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72  g.\n");....retur
c510: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  n(1);..}.../*.. 
c520: 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70 65 63 69  * Manually speci
c530: 66 79 20 63 61 63 68 65 20 64 69 72 65 63 74 6f  fy cache directo
c540: 72 79 2c 20 77 69 74 68 6f 75 74 20 46 55 53 45  ry, without FUSE
c550: 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a 20 54 68   callback.. * Th
c560: 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c 79 20 77  is option only w
c570: 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74 20 75 73  orks when not us
c580: 69 6e 67 20 46 55 53 45 2c 20 73 69 6e 63 65 20  ing FUSE, since 
c590: 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 20 70 72  we.. * do not pr
c5a0: 6f 63 65 73 73 20 69 74 20 77 69 74 68 20 46 55  ocess it with FU
c5b0: 53 45 73 20 6f 70 74 69 6f 6e 20 70 72 6f 63 65  SEs option proce
c5c0: 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 69 66 20  ssing... */..if 
c5d0: 28 61 72 67 63 20 3e 3d 20 32 29 20 7b 0a 09 09  (argc >= 2) {...
c5e0: 69 66 20 28 73 74 72 63 6d 70 28 61 72 67 76 5b  if (strcmp(argv[
c5f0: 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64 69 72 22  0], "--cachedir"
c600: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 61 70 70  ) == 0) {....app
c610: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74  fs_cachedir = st
c620: 72 64 75 70 28 61 72 67 76 5b 31 5d 29 3b 0a 0a  rdup(argv[1]);..
c630: 09 09 09 61 72 67 63 20 2d 3d 20 32 3b 0a 09 09  ...argc -= 2;...
c640: 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09 09 7d 0a  .argv += 2;...}.
c650: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 51 4c 69  .}.../*.. * SQLi
c660: 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75  te3 mode, for ru
c670: 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c 20 61 67  nning raw SQL ag
c680: 61 69 6e 73 74 20 74 68 65 20 63 61 63 68 65 20  ainst the cache 
c690: 64 61 74 61 62 61 73 65 0a 09 20 2a 2f 0a 09 69  database.. */..i
c6a0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
c6b0: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
c6c0: 22 2d 2d 73 71 6c 69 74 65 33 22 29 20 3d 3d 20  "--sqlite3") == 
c6d0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70  0) {...return(ap
c6e0: 70 66 73 5f 73 71 6c 69 74 65 33 28 61 72 67 76  pfs_sqlite3(argv
c6f0: 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  [1]));..}.../*..
c700: 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 66 6f 72   * Tcl mode, for
c710: 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 54 63 6c   running raw Tcl
c720: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 65 6e 76   in the same env
c730: 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46 53 64 20  ironment AppFSd 
c740: 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e 20 63 6f  would.. * run co
c750: 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72  de... */..if (ar
c760: 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d  gc == 2 && strcm
c770: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 74 63  p(argv[0], "--tc
c780: 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  l") == 0) {...re
c790: 74 75 72 6e 28 61 70 70 66 73 5f 74 63 6c 28 61  turn(appfs_tcl(a
c7a0: 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f  rgv[1]));..}.../
c7b0: 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 72 20 61  *.. * Register a
c7c0: 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20   signal handler 
c7d0: 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74 20  for hot-restart 
c7e0: 72 65 71 75 65 73 74 73 0a 09 20 2a 2f 0a 09 73  requests.. */..s
c7f0: 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73 69 67 6e  ignal_ret = sign
c800: 61 6c 28 53 49 47 48 55 50 2c 20 61 70 70 66 73  al(SIGHUP, appfs
c810: 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 29  _signal_handler)
c820: 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c 5f 72 65  ;..if (signal_re
c830: 74 20 3d 3d 20 53 49 47 5f 45 52 52 29 20 7b 0a  t == SIG_ERR) {.
c840: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
c850: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 73  , "Unable to ins
c860: 74 61 6c 6c 20 73 69 67 6e 61 6c 20 68 61 6e 64  tall signal hand
c870: 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74  ler for hot-rest
c880: 61 72 74 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  art\n");...fprin
c890: 74 66 28 73 74 64 65 72 72 2c 20 22 48 6f 74 2d  tf(stderr, "Hot-
c8a0: 72 65 73 74 61 72 74 20 77 69 6c 6c 20 6e 6f 74  restart will not
c8b0: 20 62 65 20 61 76 61 69 6c 61 62 6c 65 2e 5c 6e   be available.\n
c8c0: 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  ");..}.../*.. * 
c8d0: 50 61 72 73 65 20 63 6f 6d 6d 61 6e 64 20 6c 69  Parse command li
c8e0: 6e 65 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a  ne arguments.. *
c8f0: 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 52 65 73 74  /../**.. ** Rest
c900: 6f 72 65 20 61 72 67 63 2f 61 72 67 76 20 74 6f  ore argc/argv to
c910: 20 6f 72 69 67 69 6e 61 6c 20 76 61 6c 75 65 73   original values
c920: 2c 20 72 65 70 6c 61 63 69 6e 67 20 61 72 67 76  , replacing argv
c930: 5b 30 5d 20 69 6e 20 63 61 73 65 0a 09 20 2a 2a  [0] in case.. **
c940: 20 69 74 20 77 61 73 20 6d 6f 69 66 69 65 64 20   it was moified 
c950: 62 79 20 2d 2d 63 61 63 68 65 64 69 72 20 6f 70  by --cachedir op
c960: 74 69 6f 6e 2e 0a 09 20 2a 2a 2f 0a 09 61 72 67  tion... **/..arg
c970: 63 2b 2b 3b 0a 09 61 72 67 76 2d 2d 3b 0a 09 61  c++;..argv--;..a
c980: 72 67 76 5b 30 5d 20 3d 20 61 72 67 76 30 3b 0a  rgv[0] = argv0;.
c990: 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 50 65 72 66 6f  ../**.. ** Perfo
c9a0: 72 6d 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20  rm the argument 
c9b0: 70 61 72 73 69 6e 67 0a 09 20 2a 2a 2f 0a 09 61  parsing.. **/..a
c9c0: 6f 70 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 6f  op_ret = appfs_o
c9d0: 70 74 5f 70 61 72 73 65 28 61 72 67 63 2c 20 61  pt_parse(argc, a
c9e0: 72 67 76 2c 20 26 61 72 67 73 29 3b 0a 09 69 66  rgv, &args);..if
c9f0: 20 28 61 6f 70 5f 72 65 74 20 21 3d 20 30 29 20   (aop_ret != 0) 
ca00: 7b 0a 09 09 69 66 20 28 61 6f 70 5f 72 65 74 20  {...if (aop_ret 
ca10: 3c 20 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  < 0) {....return
ca20: 28 30 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  (0);...}....retu
ca30: 72 6e 28 61 6f 70 5f 72 65 74 29 3b 0a 09 7d 0a  rn(aop_ret);..}.
ca40: 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20  ../*.. * Create 
ca50: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
ca60: 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69 66 79  r just to verify
ca70: 20 74 68 61 74 20 74 68 69 6e 67 73 20 61 72 65   that things are
ca80: 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09 20 2a   in working .. *
ca90: 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20 77 65   order before we
caa0: 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e   become a daemon
cab0: 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69 6e 74  ... */..test_int
cac0: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
cad0: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26 74 65  te_TclInterp(&te
cae0: 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29  st_interp_error)
caf0: 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65  ;..if (test_inte
cb00: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
cb10: 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 5f  if (test_interp_
cb20: 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b  error == NULL) {
cb30: 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72 70 5f  ....test_interp_
cb40: 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e  error = "Unknown
cb50: 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09   error";...}....
cb60: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
cb70: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
cb80: 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65 72 70  alize Tcl interp
cb90: 72 65 74 65 72 20 66 6f 72 20 41 70 70 46 53 64  reter for AppFSd
cba0: 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  :\n");...fprintf
cbb0: 28 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c  (stderr, "%s\n",
cbc0: 20 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72   test_interp_err
cbd0: 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  or);....return(1
cbe0: 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 65 6c 65  );..}...Tcl_Dele
cbf0: 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f 69 6e  teInterp(test_in
cc00: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 61 70 70  terp);...if (app
cc10: 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 29  fs_threaded_tcl)
cc20: 20 7b 0a 09 09 54 63 6c 5f 46 69 6e 61 6c 69 7a   {...Tcl_Finaliz
cc30: 65 4e 6f 74 69 66 69 65 72 28 4e 55 4c 4c 29 3b  eNotifier(NULL);
cc40: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74  ..}.../*.. * Ent
cc50: 65 72 20 74 68 65 20 46 55 53 45 20 6d 61 69 6e  er the FUSE main
cc60: 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77 69   loop -- this wi
cc70: 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e 79 20 61  ll process any a
cc80: 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64  rguments.. * and
cc90: 20 73 74 61 72 74 20 73 65 72 76 69 63 69 6e 67   start servicing
cca0: 20 72 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a   requests... */.
ccb0: 09 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  .appfs_fuse_star
ccc0: 74 65 64 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e  ted = 1;..return
ccd0: 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e  (fuse_main(args.
cce0: 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c  argc, args.argv,
ccf0: 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f   &appfs_operatio
cd00: 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a        ns, NULL));.}.